Fixing a shit ton of warning / code style and stuff (code inspector from IDEA)
This commit is contained in:
parent
276b1d323a
commit
b6104a76c1
@ -33,9 +33,7 @@ import net.md_5.bungee.api.plugin.TabExecutor;
|
||||
import net.md_5.bungee.command.ConsoleCommandSender;
|
||||
|
||||
public abstract class BrigadierCommand extends ChatStatic {
|
||||
|
||||
private LiteralCommandNode<CommandSender> commandNode;
|
||||
|
||||
|
||||
protected BrigadierDispatcher dispatcher;
|
||||
|
||||
public BrigadierCommand() {
|
||||
@ -56,8 +54,8 @@ public abstract class BrigadierCommand extends ChatStatic {
|
||||
}
|
||||
if (aliases == null)
|
||||
aliases = new String[0];
|
||||
|
||||
commandNode = dispatcher.register(builder);
|
||||
|
||||
LiteralCommandNode<CommandSender> commandNode = dispatcher.register(builder);
|
||||
|
||||
// still have to be registered for console
|
||||
BungeeCord.getInstance().getPluginManager().registerCommand(dispatcher.plugin, new CommandRelay(commandNode.getLiteral()));
|
||||
@ -75,7 +73,7 @@ public abstract class BrigadierCommand extends ChatStatic {
|
||||
}
|
||||
|
||||
private class CommandRelay extends Command implements TabExecutor {
|
||||
private String alias;
|
||||
private final String alias;
|
||||
public CommandRelay(String alias) {
|
||||
super(alias);
|
||||
this.alias = alias;
|
||||
@ -98,7 +96,7 @@ public abstract class BrigadierCommand extends ChatStatic {
|
||||
return suggestions.getList()
|
||||
.stream()
|
||||
.filter(s -> s.getRange().equals(supportedRange))
|
||||
.map(s -> s.getText())
|
||||
.map(Suggestion::getText)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@ -125,7 +123,7 @@ public abstract class BrigadierCommand extends ChatStatic {
|
||||
}
|
||||
|
||||
public static Predicate<CommandSender> isPlayer() {
|
||||
return sender -> isPlayer(sender);
|
||||
return BrigadierCommand::isPlayer;
|
||||
}
|
||||
|
||||
public static boolean isPlayer(CommandSender sender) {
|
||||
@ -133,7 +131,7 @@ public abstract class BrigadierCommand extends ChatStatic {
|
||||
}
|
||||
|
||||
public static Predicate<CommandSender> isConsole() {
|
||||
return sender -> isConsole(sender);
|
||||
return BrigadierCommand::isConsole;
|
||||
}
|
||||
|
||||
public static boolean isConsole(CommandSender sender) {
|
||||
@ -172,16 +170,14 @@ public abstract class BrigadierCommand extends ChatStatic {
|
||||
String message = builder.getInput();
|
||||
try {
|
||||
int tokenStartPos = builder.getStart();
|
||||
|
||||
List<String> results = Collections.emptyList();
|
||||
|
||||
|
||||
int firstSpacePos = message.indexOf(" ");
|
||||
String[] args = (firstSpacePos + 1 > tokenStartPos - 1) ? new String[0]
|
||||
: message.substring(firstSpacePos + 1, tokenStartPos - 1).split(" ", -1);
|
||||
args = Arrays.copyOf(args, args.length + 1);
|
||||
args[args.length - 1] = message.substring(tokenStartPos);
|
||||
|
||||
results = suggestions.getSuggestions(sender, args.length - 1, args[args.length - 1], args);
|
||||
|
||||
List<String> results = suggestions.getSuggestions(sender, args.length - 1, args[args.length - 1], args);
|
||||
|
||||
for (String s : results) {
|
||||
if (s != null)
|
||||
|
@ -46,8 +46,8 @@ public class BrigadierDispatcher implements Listener {
|
||||
|
||||
|
||||
|
||||
private CommandDispatcher<CommandSender> dispatcher;
|
||||
/* package */ Plugin plugin;
|
||||
private final CommandDispatcher<CommandSender> dispatcher;
|
||||
/* package */ final Plugin plugin;
|
||||
|
||||
private BrigadierDispatcher(Plugin pl) {
|
||||
plugin = pl;
|
||||
@ -114,27 +114,23 @@ public class BrigadierDispatcher implements Listener {
|
||||
|
||||
event.setCancelled(true);
|
||||
|
||||
ProxyServer.getInstance().getScheduler().runAsync(plugin, () -> {
|
||||
execute((ProxiedPlayer) event.getSender(), commandLine);
|
||||
});
|
||||
ProxyServer.getInstance().getScheduler().runAsync(plugin, () -> execute((ProxiedPlayer) event.getSender(), commandLine));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* package */ int execute(CommandSender sender, String commandWithoutSlash) {
|
||||
/* package */ void execute(CommandSender sender, String commandWithoutSlash) {
|
||||
ParseResults<CommandSender> parsed = dispatcher.parse(commandWithoutSlash, sender);
|
||||
|
||||
try {
|
||||
return dispatcher.execute(parsed);
|
||||
dispatcher.execute(parsed);
|
||||
} catch (CommandSyntaxException e) {
|
||||
sender.sendMessage(Chat.failureText("Erreur d'utilisation de la commande : " + e.getMessage()).get());
|
||||
return 0;
|
||||
} catch (Throwable e) {
|
||||
sender.sendMessage(Chat.failureText("Erreur lors de l'exécution de la commande : " + e.getMessage()).get());
|
||||
Log.severe(e);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ public class PluginMessagePassthrough implements Listener {
|
||||
|
||||
public static void clear() {
|
||||
synchronized (channels) {
|
||||
new ArrayList<>(channels).forEach(c -> unregister(c));
|
||||
unregisterAll(channels.toArray(new String[0]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package fr.pandacube.lib.cli;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@ -22,16 +21,14 @@ import fr.pandacube.lib.core.util.Log;
|
||||
import fr.pandacube.lib.core.util.Reflect;
|
||||
|
||||
public abstract class BrigadierCommand extends ChatStatic {
|
||||
|
||||
private LiteralCommandNode<Object> commandNode;
|
||||
|
||||
|
||||
public BrigadierCommand() {
|
||||
LiteralArgumentBuilder<Object> builder = buildCommand();
|
||||
String[] aliases = getAliases();
|
||||
if (aliases == null)
|
||||
aliases = new String[0];
|
||||
|
||||
commandNode = BrigadierDispatcher.instance.register(builder);
|
||||
|
||||
LiteralCommandNode<Object> commandNode = BrigadierDispatcher.instance.register(builder);
|
||||
|
||||
|
||||
for (String alias : aliases) {
|
||||
@ -94,16 +91,14 @@ public abstract class BrigadierCommand extends ChatStatic {
|
||||
String message = builder.getInput();
|
||||
try {
|
||||
int tokenStartPos = builder.getStart();
|
||||
|
||||
List<String> results = Collections.emptyList();
|
||||
|
||||
int firstSpacePos = message.indexOf(" ");
|
||||
String[] args = (firstSpacePos + 1 > tokenStartPos - 1) ? new String[0]
|
||||
: message.substring(firstSpacePos + 1, tokenStartPos - 1).split(" ", -1);
|
||||
args = Arrays.copyOf(args, args.length + 1);
|
||||
args[args.length - 1] = message.substring(tokenStartPos);
|
||||
|
||||
results = suggestions.getSuggestions(sender, args.length - 1, args[args.length - 1], args);
|
||||
|
||||
List<String> results = suggestions.getSuggestions(sender, args.length - 1, args[args.length - 1], args);
|
||||
|
||||
for (String s : results) {
|
||||
if (s != null)
|
||||
|
@ -31,9 +31,9 @@ public class BrigadierDispatcher implements Completer {
|
||||
|
||||
|
||||
|
||||
private CommandDispatcher<Object> dispatcher;
|
||||
private final CommandDispatcher<Object> dispatcher;
|
||||
|
||||
private Object sender = new Object();
|
||||
private final Object sender = new Object();
|
||||
|
||||
public BrigadierDispatcher() {
|
||||
dispatcher = new CommandDispatcher<>();
|
||||
@ -69,7 +69,9 @@ public class BrigadierDispatcher implements Completer {
|
||||
|
||||
Suggestions completeResult = getSuggestions(bufferBeforeCursor);
|
||||
|
||||
completeResult.getList().stream().map(s -> s.getText()).forEach(candidates::add);
|
||||
completeResult.getList().stream()
|
||||
.map(Suggestion::getText)
|
||||
.forEach(candidates::add);
|
||||
|
||||
return completeResult.getRange().getStart();
|
||||
}
|
||||
|
@ -38,8 +38,8 @@ public class CLI {
|
||||
|
||||
|
||||
|
||||
private ConsoleReader reader;
|
||||
private Logger logger;
|
||||
private final ConsoleReader reader;
|
||||
private final Logger logger;
|
||||
|
||||
|
||||
public CLI() throws IOException {
|
||||
@ -78,9 +78,7 @@ public class CLI {
|
||||
if (line.trim().equals(""))
|
||||
continue;
|
||||
String cmdLine = line;
|
||||
new Thread(() -> {
|
||||
BrigadierDispatcher.instance.execute(cmdLine);
|
||||
}, "CLICmdThread #"+(i++)).start();
|
||||
new Thread(() -> BrigadierDispatcher.instance.execute(cmdLine), "CLICmdThread #"+(i++)).start();
|
||||
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
@ -12,9 +12,9 @@ import java.util.logging.Handler;
|
||||
import java.util.logging.LogRecord;
|
||||
|
||||
class DailyLogRotateFileHandler extends Handler {
|
||||
private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||
|
||||
private BufferedWriter currentFile = null;
|
||||
private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||
private String currentFileDate = getCurrentDay();
|
||||
private boolean closed = false;
|
||||
|
||||
@ -24,7 +24,7 @@ class DailyLogRotateFileHandler extends Handler {
|
||||
closed = true;
|
||||
if (currentFile != null) try {
|
||||
currentFile.close();
|
||||
} catch (IOException e) {}
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -33,7 +33,7 @@ class DailyLogRotateFileHandler extends Handler {
|
||||
if (currentFile == null) return;
|
||||
try {
|
||||
currentFile.flush();
|
||||
} catch (IOException e) {}
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -68,7 +68,7 @@ class DailyLogRotateFileHandler extends Handler {
|
||||
try {
|
||||
currentFile.flush();
|
||||
currentFile.close();
|
||||
} catch (IOException e) {}
|
||||
} catch (IOException ignored) {}
|
||||
new File("logs/latest.log").renameTo(new File("logs/" + currentFileDate + ".log"));
|
||||
}
|
||||
|
||||
@ -76,11 +76,10 @@ class DailyLogRotateFileHandler extends Handler {
|
||||
try {
|
||||
File logDir = new File("logs");
|
||||
logDir.mkdir();
|
||||
currentFile = new BufferedWriter(new FileWriter(new File("logs/latest.log"), true));
|
||||
currentFile = new BufferedWriter(new FileWriter("logs/latest.log", true));
|
||||
} catch (SecurityException | IOException e) {
|
||||
reportError("Erreur lors de l'initialisation d'un fichier log", e, ErrorManager.OPEN_FAILURE);
|
||||
currentFile = null;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -36,24 +36,24 @@
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-api</artifactId>
|
||||
<version>4.8.1</version>
|
||||
<version>4.11.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-platform-bungeecord</artifactId>
|
||||
<version>4.0.1-SNAPSHOT</version>
|
||||
<version>4.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-text-serializer-plain</artifactId>
|
||||
<version>4.8.1</version>
|
||||
<version>4.11.0</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>io.github.classgraph</groupId>
|
||||
<artifactId>classgraph</artifactId>
|
||||
<version>4.8.108</version>
|
||||
<version>4.8.147</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
@ -36,7 +36,7 @@ import net.md_5.bungee.api.chat.BaseComponent;
|
||||
|
||||
public abstract sealed class Chat extends ChatStatic implements HoverEventSource<Component>, ComponentLike {
|
||||
|
||||
protected ComponentBuilder<?, ?> builder;
|
||||
protected final ComponentBuilder<?, ?> builder;
|
||||
protected boolean console = false;
|
||||
|
||||
/* package */ Chat(ComponentBuilder<?, ?> b) {
|
||||
@ -76,12 +76,11 @@ public abstract sealed class Chat extends ChatStatic implements HoverEventSource
|
||||
|
||||
|
||||
public Chat then(Component comp) {
|
||||
if (comp instanceof TextComponent) {
|
||||
TextComponent txtComp = (TextComponent) comp;
|
||||
if (!txtComp.hasStyling() && (txtComp.content() == null || txtComp.content().isEmpty())) {
|
||||
if (comp instanceof TextComponent txtComp) {
|
||||
if (!txtComp.hasStyling() && (txtComp.content().isEmpty())) {
|
||||
// no need to add the provided component to the current component.
|
||||
// but eventual child component must be added
|
||||
if (txtComp.children() != null && !txtComp.children().isEmpty()) {
|
||||
if (!txtComp.children().isEmpty()) {
|
||||
for (Component child : txtComp.children())
|
||||
then(child);
|
||||
}
|
||||
@ -313,9 +312,8 @@ public abstract sealed class Chat extends ChatStatic implements HoverEventSource
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null || !(obj instanceof Chat))
|
||||
return false;
|
||||
return getAdv().equals(((Chat)obj).getAdv());
|
||||
return obj instanceof Chat c
|
||||
&& getAdv().equals(c.getAdv());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -330,18 +328,7 @@ public abstract sealed class Chat extends ChatStatic implements HoverEventSource
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* package */ static Object[] filterChatToBaseComponent(Object[] values) {
|
||||
if (values == null)
|
||||
return null;
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
Object v = values[i];
|
||||
if (v instanceof Chat)
|
||||
values[i] = ((Chat) v).get();
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
/* package */ static ComponentLike[] filterObjToComponentLike(Object[] values) {
|
||||
if (values == null)
|
||||
|
@ -18,18 +18,16 @@ public class ChatColorUtil {
|
||||
public static final String ALL_COLORS = "0123456789AaBbCcDdEeFf";
|
||||
|
||||
|
||||
private static Pattern HEX_COLOR_PATTERN = Pattern.compile("§x(?>§[0-9a-f]){6}", Pattern.CASE_INSENSITIVE);
|
||||
private static Pattern ESS_COLOR_PATTERN = Pattern.compile("§#[0-9a-f]{6}", Pattern.CASE_INSENSITIVE);
|
||||
private static final Pattern HEX_COLOR_PATTERN = Pattern.compile("§x(?>§[\\da-f]){6}", Pattern.CASE_INSENSITIVE);
|
||||
private static final Pattern ESS_COLOR_PATTERN = Pattern.compile("§#[\\da-f]{6}", Pattern.CASE_INSENSITIVE);
|
||||
|
||||
/**
|
||||
* Return the legacy format needed to reproduce the format at the end of the provided legacy text.
|
||||
* Supports standard chat colors and formats, BungeeCord Chat rgb format and EssentialsX rgb format.
|
||||
* The RGB value from EssentialsX format is converted to BungeeCord Chat when included in the returned value.
|
||||
* @param legacyText
|
||||
* @return
|
||||
*/
|
||||
public static String getLastColors(String legacyText) {
|
||||
String result = "";
|
||||
StringBuilder result = new StringBuilder();
|
||||
int length = legacyText.length();
|
||||
|
||||
for (int index = length - 2; index >= 0; index--) {
|
||||
@ -42,7 +40,7 @@ public class ChatColorUtil {
|
||||
&& (legacyText.charAt(index - 11) == 'x'
|
||||
|| legacyText.charAt(index - 11) == 'X')
|
||||
&& HEX_COLOR_PATTERN.matcher(rgb = legacyText.substring(index - 12, index + 2)).matches()) {
|
||||
result = rgb + result;
|
||||
result.insert(0, rgb);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -53,7 +51,7 @@ public class ChatColorUtil {
|
||||
rgb = "§x§" + rgb.charAt(2) + "§" + rgb.charAt(3)
|
||||
+ "§" + rgb.charAt(4) + "§" + rgb.charAt(5)
|
||||
+ "§" + rgb.charAt(6) + "§" + rgb.charAt(7);
|
||||
result = rgb + result;
|
||||
result.insert(0, rgb);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -62,7 +60,7 @@ public class ChatColorUtil {
|
||||
ChatColor legacyColor = getChatColorByChar(colorChar);
|
||||
|
||||
if (legacyColor != null) {
|
||||
result = legacyColor.toString() + result;
|
||||
result.insert(0, legacyColor);
|
||||
|
||||
// Once we find a color or reset we can stop searching
|
||||
char col = legacyColor.toString().charAt(1);
|
||||
@ -75,7 +73,7 @@ public class ChatColorUtil {
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public static ChatColor getChatColorByChar(char code) {
|
||||
@ -215,7 +213,7 @@ public class ChatColorUtil {
|
||||
private static String forceFormat(String legacyText, ChatColor format) {
|
||||
return format + legacyText
|
||||
.replace(format.toString(), "") // remove previous tag to make the result cleaner
|
||||
.replaceAll("§([a-frA-FR0-9])", "§$1" + format);
|
||||
.replaceAll("§([a-frA-FR\\d])", "§$1" + format);
|
||||
}
|
||||
|
||||
|
||||
@ -270,7 +268,7 @@ public class ChatColorUtil {
|
||||
public static class ChatValueGradient {
|
||||
private record GradientValueColor(float value, TextColor color) { } // Java 16
|
||||
|
||||
List<GradientValueColor> colors = new ArrayList<>();
|
||||
final List<GradientValueColor> colors = new ArrayList<>();
|
||||
|
||||
public synchronized ChatValueGradient add(float v, TextColor col) {
|
||||
colors.add(new GradientValueColor(v, col));
|
||||
|
@ -114,16 +114,5 @@ public abstract class ChatStatic {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// for (Chat c : new Chat[] {
|
||||
// chat(),
|
||||
// text("toto").color(NamedTextColor.GRAY),
|
||||
// legacyText("tot§9o").color(NamedTextColor.GRAY),
|
||||
// }) {
|
||||
// System.out.println(GsonComponentSerializer.gson().serialize(c.getAdv()));
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
@ -1,9 +1,5 @@
|
||||
package fr.pandacube.lib.core.chat;
|
||||
|
||||
import static fr.pandacube.lib.core.chat.ChatStatic.chat;
|
||||
import static fr.pandacube.lib.core.chat.ChatStatic.legacyText;
|
||||
import static fr.pandacube.lib.core.chat.ChatStatic.text;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@ -13,8 +9,6 @@ import java.util.TreeSet;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import fr.pandacube.lib.core.chat.Chat.FormatableChat;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
import net.kyori.adventure.text.TranslatableComponent;
|
||||
@ -24,6 +18,12 @@ import net.kyori.adventure.text.format.TextDecoration;
|
||||
import net.kyori.adventure.text.format.TextDecoration.State;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
|
||||
import fr.pandacube.lib.core.chat.Chat.FormatableChat;
|
||||
|
||||
import static fr.pandacube.lib.core.chat.ChatStatic.chat;
|
||||
import static fr.pandacube.lib.core.chat.ChatStatic.legacyText;
|
||||
import static fr.pandacube.lib.core.chat.ChatStatic.text;
|
||||
|
||||
public class ChatUtil {
|
||||
|
||||
public static final int DEFAULT_CHAR_SIZE = 6;
|
||||
@ -328,12 +328,10 @@ public class ChatUtil {
|
||||
for (Component c : ((TranslatableComponent)component).args())
|
||||
count += componentWidth(c, console, actuallyBold);
|
||||
}
|
||||
|
||||
if (component.children() != null) {
|
||||
for (Component c : component.children())
|
||||
count += componentWidth(c, console, actuallyBold);
|
||||
}
|
||||
|
||||
|
||||
for (Component c : component.children())
|
||||
count += componentWidth(c, console, actuallyBold);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@ -345,7 +343,7 @@ public class ChatUtil {
|
||||
int count = 0;
|
||||
for (char c : str.toCharArray())
|
||||
count += charW(c, console, bold);
|
||||
return (count < 0) ? 0 : count;
|
||||
return Math.max(count, 0);
|
||||
}
|
||||
|
||||
public static int charW(char c, boolean console, boolean bold) {
|
||||
@ -364,7 +362,7 @@ public class ChatUtil {
|
||||
|
||||
public static List<Chat> wrapInLimitedPixelsToChat(String legacyText, int pixelWidth) {
|
||||
return wrapInLimitedPixels(legacyText, pixelWidth).stream()
|
||||
.map(t -> legacyText(t))
|
||||
.map(ChatStatic::legacyText)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@ -377,7 +375,7 @@ public class ChatUtil {
|
||||
int currentLineSize = 0;
|
||||
int index = 0;
|
||||
|
||||
String currentWord = "";
|
||||
StringBuilder currentWord = new StringBuilder();
|
||||
int currentWordSize = 0;
|
||||
boolean bold = false;
|
||||
boolean firstCharCurrentWordBold = false;
|
||||
@ -385,9 +383,9 @@ public class ChatUtil {
|
||||
do {
|
||||
char c = legacyText.charAt(index);
|
||||
if (c == ChatColor.COLOR_CHAR && index < legacyText.length() - 1) {
|
||||
currentWord += c;
|
||||
currentWord.append(c);
|
||||
c = legacyText.charAt(++index);
|
||||
currentWord += c;
|
||||
currentWord.append(c);
|
||||
|
||||
if (c == 'l' || c == 'L') // bold
|
||||
bold = true;
|
||||
@ -404,7 +402,7 @@ public class ChatUtil {
|
||||
lines.add(currentLine);
|
||||
String lastStyle = ChatColorUtil.getLastColors(currentLine);
|
||||
if (currentWord.charAt(0) == ' ') {
|
||||
currentWord = currentWord.substring(1);
|
||||
currentWord = new StringBuilder(currentWord.substring(1));
|
||||
currentWordSize -= charW(' ', false, firstCharCurrentWordBold);
|
||||
}
|
||||
currentLine = (lastStyle.equals("§r") ? "" : lastStyle) + currentWord;
|
||||
@ -414,7 +412,7 @@ public class ChatUtil {
|
||||
currentLine += currentWord;
|
||||
currentLineSize += currentWordSize;
|
||||
}
|
||||
currentWord = ""+c;
|
||||
currentWord = new StringBuilder("" + c);
|
||||
currentWordSize = charW(c, false, bold);
|
||||
firstCharCurrentWordBold = bold;
|
||||
}
|
||||
@ -423,15 +421,12 @@ public class ChatUtil {
|
||||
lines.add(currentLine);
|
||||
String lastStyle = ChatColorUtil.getLastColors(currentLine);
|
||||
if (currentWord.charAt(0) == ' ') {
|
||||
currentWord = currentWord.substring(1);
|
||||
currentWordSize -= charW(' ', false, firstCharCurrentWordBold);
|
||||
currentWord = new StringBuilder(currentWord.substring(1));
|
||||
}
|
||||
currentLine = (lastStyle.equals("§r") ? "" : lastStyle) + currentWord;
|
||||
currentLineSize = currentWordSize;
|
||||
}
|
||||
else {
|
||||
currentLine += currentWord;
|
||||
currentLineSize += currentWordSize;
|
||||
}
|
||||
// wrap after
|
||||
lines.add(currentLine);
|
||||
@ -439,12 +434,12 @@ public class ChatUtil {
|
||||
|
||||
currentLine = lastStyle.equals("§r") ? "" : lastStyle;
|
||||
currentLineSize = 0;
|
||||
currentWord = "";
|
||||
currentWord = new StringBuilder();
|
||||
currentWordSize = 0;
|
||||
firstCharCurrentWordBold = bold;
|
||||
}
|
||||
else {
|
||||
currentWord += c;
|
||||
currentWord.append(c);
|
||||
currentWordSize += charW(c, false, bold);
|
||||
}
|
||||
|
||||
@ -674,7 +669,6 @@ public class ChatUtil {
|
||||
*
|
||||
* Each element in the returned list represent 1 line of the tree view.
|
||||
* Thus, the caller may send each line separately or at once depending of the quantity of data.
|
||||
* @param node
|
||||
* @return A array of component, each element being a single line.
|
||||
*/
|
||||
public static List<Chat> treeView(DisplayTreeNode node, boolean console) {
|
||||
|
@ -30,11 +30,8 @@ public class AbstractCommand extends ChatStatic {
|
||||
* Le premier élément est l'argument qui suit le nom de la commande.
|
||||
* Usuellement, ce paramètre correspond au paramètre
|
||||
* <code>args</code> de la méthode onCommand
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
public static String getLastParams(String[] args, int index) {
|
||||
if (index < 0 || index >= args.length) return null;
|
||||
return String.join(" ", Arrays.copyOfRange(args, index, args.length));
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@ import java.util.logging.Logger;
|
||||
*
|
||||
*/
|
||||
public class BadCommandUsage extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public BadCommandUsage() {
|
||||
super();
|
||||
|
@ -19,17 +19,17 @@ public interface SuggestionsSupplier<S> {
|
||||
/**
|
||||
* Number of suggestion visible at once without having to scroll
|
||||
*/
|
||||
public static int VISIBLE_SUGGESTION_COUNT = 10;
|
||||
int VISIBLE_SUGGESTION_COUNT = 10;
|
||||
|
||||
|
||||
public abstract List<String> getSuggestions(S sender, int tokenIndex, String token, String[] args);
|
||||
List<String> getSuggestions(S sender, int tokenIndex, String token, String[] args);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static Predicate<String> filter(String token) {
|
||||
static Predicate<String> filter(String token) {
|
||||
return suggestion -> suggestion != null && suggestion.toLowerCase().startsWith(token.toLowerCase());
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ public interface SuggestionsSupplier<S> {
|
||||
*
|
||||
* This methods consume the provided stream, so will not be usable anymore.
|
||||
*/
|
||||
public static List<String> collectFilteredStream(Stream<String> stream, String token) {
|
||||
static List<String> collectFilteredStream(Stream<String> stream, String token) {
|
||||
return stream.filter(filter(token)).sorted().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@ -47,40 +47,40 @@ public interface SuggestionsSupplier<S> {
|
||||
|
||||
|
||||
|
||||
public static <S> SuggestionsSupplier<S> empty() { return (s, ti, t, a) -> Collections.emptyList(); }
|
||||
static <S> SuggestionsSupplier<S> empty() { return (s, ti, t, a) -> Collections.emptyList(); }
|
||||
|
||||
public static <S> SuggestionsSupplier<S> fromCollectionsSupplier(Supplier<Collection<String>> streamSupplier) {
|
||||
static <S> SuggestionsSupplier<S> fromCollectionsSupplier(Supplier<Collection<String>> streamSupplier) {
|
||||
return (s, ti, token, a) -> collectFilteredStream(streamSupplier.get().stream(), token);
|
||||
}
|
||||
|
||||
public static <S> SuggestionsSupplier<S> fromStreamSupplier(Supplier<Stream<String>> streamSupplier) {
|
||||
static <S> SuggestionsSupplier<S> fromStreamSupplier(Supplier<Stream<String>> streamSupplier) {
|
||||
return (s, ti, token, a) -> collectFilteredStream(streamSupplier.get(), token);
|
||||
}
|
||||
|
||||
public static <S> SuggestionsSupplier<S> fromCollection(Collection<String> suggestions) {
|
||||
static <S> SuggestionsSupplier<S> fromCollection(Collection<String> suggestions) {
|
||||
return fromStreamSupplier(suggestions::stream);
|
||||
}
|
||||
|
||||
public static <S> SuggestionsSupplier<S> fromArray(String... suggestions) {
|
||||
static <S> SuggestionsSupplier<S> fromArray(String... suggestions) {
|
||||
return fromStreamSupplier(() -> Arrays.stream(suggestions));
|
||||
}
|
||||
|
||||
|
||||
public static <E extends Enum<E>, S> SuggestionsSupplier<S> fromEnum(Class<E> enumClass) {
|
||||
static <E extends Enum<E>, S> SuggestionsSupplier<S> fromEnum(Class<E> enumClass) {
|
||||
return fromEnumValues(enumClass.getEnumConstants());
|
||||
}
|
||||
|
||||
public static <E extends Enum<E>, S> SuggestionsSupplier<S> fromEnum(Class<E> enumClass, boolean lowerCase) {
|
||||
static <E extends Enum<E>, S> SuggestionsSupplier<S> fromEnum(Class<E> enumClass, boolean lowerCase) {
|
||||
return fromEnumValues(lowerCase, enumClass.getEnumConstants());
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <E extends Enum<E>, S> SuggestionsSupplier<S> fromEnumValues(E... enumValues) {
|
||||
static <E extends Enum<E>, S> SuggestionsSupplier<S> fromEnumValues(E... enumValues) {
|
||||
return fromEnumValues(false, enumValues);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <E extends Enum<E>, S> SuggestionsSupplier<S> fromEnumValues(boolean lowerCase, E... enumValues) {
|
||||
static <E extends Enum<E>, S> SuggestionsSupplier<S> fromEnumValues(boolean lowerCase, E... enumValues) {
|
||||
return (s, ti, token, a) -> {
|
||||
Stream<String> st = Arrays.stream(enumValues).map(Enum::name);
|
||||
if (lowerCase)
|
||||
@ -91,7 +91,7 @@ public interface SuggestionsSupplier<S> {
|
||||
|
||||
|
||||
|
||||
public static <S> SuggestionsSupplier<S> booleanValues() {
|
||||
static <S> SuggestionsSupplier<S> booleanValues() {
|
||||
return fromCollection(Arrays.asList("true", "false"));
|
||||
}
|
||||
|
||||
@ -103,11 +103,8 @@ public interface SuggestionsSupplier<S> {
|
||||
* Create a {@link SuggestionsSupplier} that suggest numbers according to the provided range.
|
||||
*
|
||||
* The current implementation only support range that include either -1 or 1.
|
||||
* @param min
|
||||
* @param max
|
||||
* @return
|
||||
*/
|
||||
public static <S> SuggestionsSupplier<S> fromIntRange(int min, int max, boolean compact) {
|
||||
static <S> SuggestionsSupplier<S> fromIntRange(int min, int max, boolean compact) {
|
||||
return fromLongRange(min, max, compact);
|
||||
}
|
||||
|
||||
@ -118,11 +115,8 @@ public interface SuggestionsSupplier<S> {
|
||||
* Create a {@link SuggestionsSupplier} that suggest numbers according to the provided range.
|
||||
*
|
||||
* The current implementation only support range that include either -1 or 1.
|
||||
* @param min
|
||||
* @param max
|
||||
* @return
|
||||
*/
|
||||
public static <S> SuggestionsSupplier<S> fromLongRange(long min, long max, boolean compact) {
|
||||
static <S> SuggestionsSupplier<S> fromLongRange(long min, long max, boolean compact) {
|
||||
if (max < min) {
|
||||
throw new IllegalArgumentException("min should be less or equals than max");
|
||||
}
|
||||
@ -179,7 +173,7 @@ public interface SuggestionsSupplier<S> {
|
||||
}
|
||||
}
|
||||
|
||||
return collectFilteredStream(proposedValues.stream().map(i -> i.toString()), token);
|
||||
return collectFilteredStream(proposedValues.stream().map(Object::toString), token);
|
||||
} catch (NumberFormatException e) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@ -196,9 +190,8 @@ public interface SuggestionsSupplier<S> {
|
||||
/**
|
||||
* Create a {@link SuggestionsSupplier} that support greedy strings argument using the suggestion from this {@link SuggestionsSupplier}.
|
||||
* @param index the index of the first argument of the greedy string argument
|
||||
* @return
|
||||
*/
|
||||
public default SuggestionsSupplier<S> greedyString(int index) {
|
||||
default SuggestionsSupplier<S> greedyString(int index) {
|
||||
|
||||
return (s, ti, token, args) -> {
|
||||
|
||||
@ -233,7 +226,7 @@ public interface SuggestionsSupplier<S> {
|
||||
|
||||
|
||||
|
||||
public default SuggestionsSupplier<S> quotableString() {
|
||||
default SuggestionsSupplier<S> quotableString() {
|
||||
return (s, ti, token, a) -> {
|
||||
boolean startWithQuote = token.length() > 0 && (token.charAt(0) == '"' || token.charAt(0) == '\'');
|
||||
String realToken = startWithQuote ? unescapeBrigadierQuotable(token.substring(1), token.charAt(0)) : token;
|
||||
@ -309,10 +302,8 @@ public interface SuggestionsSupplier<S> {
|
||||
|
||||
|
||||
|
||||
public default SuggestionsSupplier<S> requires(Predicate<S> check) {
|
||||
return (s, ti, to, a) -> {
|
||||
return check.test(s) ? getSuggestions(s, ti, to, a) : Collections.emptyList();
|
||||
};
|
||||
default SuggestionsSupplier<S> requires(Predicate<S> check) {
|
||||
return (s, ti, to, a) -> check.test(s) ? getSuggestions(s, ti, to, a) : Collections.emptyList();
|
||||
}
|
||||
|
||||
|
||||
@ -320,10 +311,8 @@ public interface SuggestionsSupplier<S> {
|
||||
/**
|
||||
* Returns a new {@link SuggestionsSupplier} containing all the element of this instance then the element of the provided one,
|
||||
* with all duplicated values removed using {@link Stream#distinct()}.
|
||||
* @param other
|
||||
* @return
|
||||
*/
|
||||
public default SuggestionsSupplier<S> merge(SuggestionsSupplier<S> other) {
|
||||
default SuggestionsSupplier<S> merge(SuggestionsSupplier<S> other) {
|
||||
return (s, ti, to, a) -> {
|
||||
List<String> l1 = getSuggestions(s, ti, to, a);
|
||||
List<String> l2 = other.getSuggestions(s, ti, to, a);
|
||||
@ -337,10 +326,8 @@ public interface SuggestionsSupplier<S> {
|
||||
/**
|
||||
* Returns a new {@link SuggestionsSupplier} containing all the suggestions of this instance,
|
||||
* but if this list is still empty, returns the suggestions from the provided one.
|
||||
* @param other
|
||||
* @return
|
||||
*/
|
||||
public default SuggestionsSupplier<S> orIfEmpty(SuggestionsSupplier<S> other) {
|
||||
default SuggestionsSupplier<S> orIfEmpty(SuggestionsSupplier<S> other) {
|
||||
return (s, ti, to, a) -> {
|
||||
List<String> l1 = getSuggestions(s, ti, to, a);
|
||||
return !l1.isEmpty() ? l1 : other.getSuggestions(s, ti, to, a);
|
||||
|
@ -6,14 +6,12 @@ import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import fr.pandacube.lib.core.chat.ChatColorUtil;
|
||||
import fr.pandacube.lib.core.util.Log;
|
||||
/**
|
||||
* Classe chargeant en mémoire un fichier de configuration ou un dossier donné
|
||||
* @author Marc Baloup
|
||||
* Class tht loads a specific config file or directory
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractConfig {
|
||||
@ -22,12 +20,13 @@ public abstract class AbstractConfig {
|
||||
* Correspond au dossier ou au fichier de configuration traité par la sous-classe
|
||||
* courante de {@link AbstractConfig}
|
||||
*/
|
||||
protected File configFile;
|
||||
protected final File configFile;
|
||||
|
||||
/**
|
||||
* @param fileOrDirName le nom du fichier ou du dossier correspondant à la sous-classe de {@link AbstractConfig}
|
||||
* @param isDir <code>true</code> si il s'agit d'un dossier, <code>false</code> sinon
|
||||
* @throws IOException si le fichier est impossible à créer
|
||||
* @param configDir the parent directory
|
||||
* @param fileOrDirName The name of the config file or folder
|
||||
* @param type if the provided name is a file or a directory
|
||||
* @throws IOException if we cannot create the file
|
||||
*/
|
||||
public AbstractConfig(File configDir, String fileOrDirName, FileType type) throws IOException {
|
||||
configFile = new File(configDir, fileOrDirName);
|
||||
@ -38,13 +37,12 @@ public abstract class AbstractConfig {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne toutes les lignes d'un fichier donné
|
||||
* @param ignoreEmpty <code>true</code> si on doit ignorer les lignes vides
|
||||
* @param ignoreHashtagComment <code>true</code> si on doit ignorer les lignes commentés (commençant par un #)
|
||||
* @param trimOutput <code>true</code> si on doit appeller la méthode String.trim() sur chaque ligne retournée
|
||||
* @param f le fichier à lire
|
||||
* @return la liste des lignes utiles
|
||||
* @throws IOException
|
||||
* Gets the lines from the config file
|
||||
* @param ignoreEmpty <code>true</code> if we ignore the empty lines
|
||||
* @param ignoreHashtagComment <code>true</code> if we ignore the comment lines (starting with {@code #})
|
||||
* @param trimOutput <code>true</code> if we want to trim all lines using {@link String#trim()}
|
||||
* @param f the file to read
|
||||
* @return the list of lines, filtered according to the parameters
|
||||
*/
|
||||
protected List<String> getFileLines(boolean ignoreEmpty, boolean ignoreHashtagComment, boolean trimOutput, File f) throws IOException {
|
||||
if (!f.isFile())
|
||||
@ -83,7 +81,6 @@ public abstract class AbstractConfig {
|
||||
* @param ignoreHashtagComment <code>true</code> si on doit ignorer les lignes commentés (commençant par un #)
|
||||
* @param trimOutput <code>true</code> si on doit appeller la méthode String.trim() sur chaque ligne retournée
|
||||
* @return la liste des lignes utiles
|
||||
* @throws IOException
|
||||
*/
|
||||
protected List<String> getFileLines(boolean ignoreEmpty, boolean ignoreHashtagComment, boolean trimOutput) throws IOException {
|
||||
return getFileLines(ignoreEmpty, ignoreHashtagComment, trimOutput, configFile);
|
||||
@ -119,7 +116,7 @@ public abstract class AbstractConfig {
|
||||
|
||||
|
||||
public static List<String> getSplittedString(String value, String split) {
|
||||
return Collections.unmodifiableList(Arrays.asList(value.split(split)));
|
||||
return List.of(value.split(split));
|
||||
}
|
||||
|
||||
|
||||
|
@ -17,13 +17,11 @@ public abstract class AbstractConfigManager {
|
||||
|
||||
/**
|
||||
* Implementation must close all closeable configuration (saving for example)
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract void close() throws IOException;
|
||||
|
||||
/**
|
||||
* Implementation must init all config data
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract void init() throws IOException;
|
||||
|
||||
|
@ -18,15 +18,15 @@ import fr.pandacube.lib.core.util.Log;
|
||||
/**
|
||||
* Static class to handle most of the database operations.
|
||||
*
|
||||
* To use this database library, first call {@link #init(DBConnection)} with an appropriate {@link DBConnection},
|
||||
* To use this database library, first call {@link #init(DBConnection, String)} with an appropriate {@link DBConnection},
|
||||
* they you can initialize every table you need for your application, using {@link #initTable(Class)}.
|
||||
*
|
||||
* @author Marc Baloup
|
||||
*/
|
||||
public final class DB {
|
||||
|
||||
private static List<Class<? extends SQLElement<?>>> tables = new ArrayList<>();
|
||||
private static Map<Class<? extends SQLElement<?>>, String> tableNames = new HashMap<>();
|
||||
private static final List<Class<? extends SQLElement<?>>> tables = new ArrayList<>();
|
||||
private static final Map<Class<? extends SQLElement<?>>, String> tableNames = new HashMap<>();
|
||||
|
||||
private static DBConnection connection;
|
||||
/* package */ static String tablePrefix = "";
|
||||
@ -35,7 +35,7 @@ public final class DB {
|
||||
return connection;
|
||||
}
|
||||
|
||||
public synchronized static <E extends SQLElement<E>> void init(DBConnection conn, String tablePrefix) {
|
||||
public synchronized static void init(DBConnection conn, String tablePrefix) {
|
||||
connection = conn;
|
||||
DB.tablePrefix = Objects.requireNonNull(tablePrefix);
|
||||
}
|
||||
@ -62,7 +62,7 @@ public final class DB {
|
||||
|
||||
String tableName = tablePrefix + elem.tableName();
|
||||
|
||||
String sql = "CREATE TABLE IF NOT EXISTS " + tableName + " (";
|
||||
StringBuilder sql = new StringBuilder("CREATE TABLE IF NOT EXISTS " + tableName + " (");
|
||||
List<Object> params = new ArrayList<>();
|
||||
|
||||
Collection<SQLField<E, ?>> tableFields = elem.getFields().values();
|
||||
@ -71,14 +71,15 @@ public final class DB {
|
||||
ParameterizedSQLString statementPart = f.forSQLPreparedStatement();
|
||||
params.addAll(statementPart.parameters());
|
||||
|
||||
if (!first) sql += ", ";
|
||||
if (!first)
|
||||
sql.append(", ");
|
||||
first = false;
|
||||
sql += statementPart.sqlString();
|
||||
sql.append(statementPart.sqlString());
|
||||
}
|
||||
|
||||
sql += ", PRIMARY KEY id(id))";
|
||||
sql.append(", PRIMARY KEY id(id))");
|
||||
|
||||
try (PreparedStatement ps = connection.getNativeConnection().prepareStatement(sql)) {
|
||||
try (PreparedStatement ps = connection.getNativeConnection().prepareStatement(sql.toString())) {
|
||||
int i = 1;
|
||||
for (Object val : params)
|
||||
ps.setObject(i++, val);
|
||||
@ -93,11 +94,9 @@ public final class DB {
|
||||
}
|
||||
|
||||
private static boolean tableExistInDB(String tableName) throws SQLException {
|
||||
boolean exist = false;
|
||||
try (ResultSet set = connection.getNativeConnection().getMetaData().getTables(null, null, tableName, null)) {
|
||||
exist = set.next();
|
||||
return set.next();
|
||||
}
|
||||
return exist;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -277,7 +276,7 @@ public final class DB {
|
||||
|
||||
|
||||
|
||||
public static <E extends SQLElement<E>> SQLUpdate<E> update(Class<E> elemClass, SQLWhere<E> where) throws DBException {
|
||||
public static <E extends SQLElement<E>> SQLUpdate<E> update(Class<E> elemClass, SQLWhere<E> where) {
|
||||
return new SQLUpdate<>(elemClass, where);
|
||||
}
|
||||
|
||||
@ -291,7 +290,6 @@ public final class DB {
|
||||
* @param elemClass the SQLElement representing the table.
|
||||
* @param where the condition to meet for an element to be deleted from the table. If null, the table is truncated using {@link #truncateTable(Class)}.
|
||||
* @return The return value of {@link PreparedStatement#executeUpdate()}, for an SQL query {@code DELETE}.
|
||||
* @throws DBException
|
||||
*/
|
||||
public static <E extends SQLElement<E>> int delete(Class<E> elemClass, SQLWhere<E> where) throws DBException {
|
||||
initTable(elemClass);
|
||||
@ -369,7 +367,7 @@ public final class DB {
|
||||
val = ((SQLCustomType<Object, Object>)sqlField.type).dbToJavaConv.apply(val);
|
||||
} catch (Exception e) {
|
||||
throw new DBException("Error while converting value of field '"+sqlField.getName()+"' with SQLCustomType from "+((SQLCustomType<Object, Object>)sqlField.type).intermediateJavaType
|
||||
+"(jdbc source) to "+sqlField.type.getJavaType()+"(java destination). The original value is '"+val.toString()+"'", e);
|
||||
+"(jdbc source) to "+sqlField.type.getJavaType()+"(java destination). The original value is '"+ val +"'", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -383,7 +381,7 @@ public final class DB {
|
||||
}
|
||||
|
||||
if (!instance.isValidForSave()) throw new DBException(
|
||||
"This SQLElement representing a database entry is not valid for save : " + instance.toString());
|
||||
"This SQLElement representing a database entry is not valid for save : " + instance);
|
||||
|
||||
return instance;
|
||||
} catch (ReflectiveOperationException | IllegalArgumentException | SecurityException | SQLException e) {
|
||||
|
@ -11,15 +11,14 @@ public class DBConnection {
|
||||
private static final long CONNECTION_CHECK_TIMEOUT = 30000; // in ms
|
||||
|
||||
private Connection conn;
|
||||
private String url;
|
||||
private String login;
|
||||
private String pass;
|
||||
private final String url;
|
||||
private final String login;
|
||||
private final String pass;
|
||||
|
||||
private long timeOfLastCheck = 0;
|
||||
|
||||
public DBConnection(String host, int port, String dbname, String l, String p)
|
||||
throws ClassNotFoundException, SQLException {
|
||||
//Class.forName("com.mysql.jdbc.Driver"); // apparently this is deprecated now
|
||||
throws SQLException {
|
||||
url = "jdbc:mysql://" + host + ":" + port + "/" + dbname
|
||||
+ "?autoReconnect=true"
|
||||
+ "&useUnicode=true"
|
||||
@ -58,7 +57,7 @@ public class DBConnection {
|
||||
return true;
|
||||
|
||||
try (ResultSet rs = conn.createStatement().executeQuery("SELECT 1;")) {
|
||||
return rs == null ? false : rs.next();
|
||||
return rs != null && rs.next();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
@ -78,7 +77,7 @@ public class DBConnection {
|
||||
public void close() {
|
||||
try {
|
||||
conn.close();
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package fr.pandacube.lib.core.db;
|
||||
|
||||
public class DBException extends Exception {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public DBException(Throwable initCause) {
|
||||
super(initCause);
|
||||
|
@ -1,11 +1,6 @@
|
||||
package fr.pandacube.lib.core.db;
|
||||
|
||||
public class DBInitTableException extends DBException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/* package */ <E extends SQLElement<E>> DBInitTableException(Class<E> tableElem) {
|
||||
super("Error while initializing table " + ((tableElem != null) ? tableElem.getName() : "null"));
|
||||
}
|
||||
|
||||
/* package */ <E extends SQLElement<E>> DBInitTableException(Class<E> tableElem, Throwable t) {
|
||||
super("Error while initializing table " + ((tableElem != null) ? tableElem.getName() : "null"), t);
|
||||
|
@ -2,13 +2,7 @@ package fr.pandacube.lib.core.db;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
//public record ParameterizedSQLString(String sqlString, List<Object> parameters) { } // Java 16
|
||||
public class ParameterizedSQLString {
|
||||
private final String sqlString;
|
||||
private final List<Object> parameters;
|
||||
public ParameterizedSQLString(String sqlString, List<Object> parameters) {
|
||||
this.sqlString = sqlString; this.parameters = parameters;
|
||||
}
|
||||
public String sqlString() { return sqlString; }
|
||||
public List<Object> parameters() { return parameters; }
|
||||
public record ParameterizedSQLString(String sqlString, List<Object> parameters) {
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,12 @@
|
||||
package fr.pandacube.lib.core.db;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.base.MoreObjects.ToStringHelper;
|
||||
import com.google.gson.JsonObject;
|
||||
import fr.pandacube.lib.core.util.EnumUtil;
|
||||
import fr.pandacube.lib.core.util.Json;
|
||||
import fr.pandacube.lib.core.util.Log;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.sql.Date;
|
||||
import java.sql.PreparedStatement;
|
||||
@ -17,19 +24,11 @@ import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.base.MoreObjects.ToStringHelper;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import fr.pandacube.lib.core.util.EnumUtil;
|
||||
import fr.pandacube.lib.core.util.Json;
|
||||
import fr.pandacube.lib.core.util.Log;
|
||||
|
||||
public abstract class SQLElement<E extends SQLElement<E>> {
|
||||
/** cache for fields for each subclass of SQLElement */
|
||||
/* package */ static final Map<Class<? extends SQLElement<?>>, SQLFieldMap<? extends SQLElement<?>>> fieldsCache = new HashMap<>();
|
||||
|
||||
DBConnection db = DB.getConnection();
|
||||
private final DBConnection db = DB.getConnection();
|
||||
|
||||
private boolean stored = false;
|
||||
private int id;
|
||||
@ -109,7 +108,7 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
||||
field.setAccessible(true);
|
||||
try {
|
||||
Object val = field.get(null);
|
||||
if (val == null || !(val instanceof SQLField)) {
|
||||
if (!(val instanceof SQLField)) {
|
||||
Log.severe("[ORM] The field " + field.getDeclaringClass().getName() + "." + field.getName() + " can't be initialized because its value is null.");
|
||||
continue;
|
||||
}
|
||||
@ -122,7 +121,7 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
||||
checkedF.setSQLElementType((Class<E>) getClass());
|
||||
listToFill.addField((SQLField<?, ?>) val);
|
||||
} catch (IllegalArgumentException | IllegalAccessException e) {
|
||||
Log.severe("Can't get value of static field " + field.toString(), e);
|
||||
Log.severe("Can't get value of static field " + field, e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,20 +146,18 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
||||
if (!fields.containsValue(sqlField)) // should not append at runtime because of generic type check at compilation
|
||||
throw new IllegalStateException("In the table "+getClass().getName()+ ": the field asked for modification is not initialized properly.");
|
||||
|
||||
boolean modify = false;
|
||||
if (value == null) {
|
||||
if (sqlField.canBeNull || (sqlField.autoIncrement && !stored)) modify = true;
|
||||
else
|
||||
if (!sqlField.canBeNull && (!sqlField.autoIncrement || stored))
|
||||
throw new IllegalArgumentException(
|
||||
"SQLField '" + sqlField.getName() + "' of " + getClass().getName() + " is a NOT NULL field");
|
||||
}
|
||||
else if (sqlField.type.isAssignableFrom(value)) modify = true;
|
||||
else
|
||||
else if (!sqlField.type.isInstance(value)) {
|
||||
throw new IllegalArgumentException("SQLField '" + sqlField.getName() + "' of " + getClass().getName()
|
||||
+ " type is '" + sqlField.type.toString() + "' and can't accept values of type "
|
||||
+ " type is '" + sqlField.type + "' and can't accept values of type "
|
||||
+ value.getClass().getName());
|
||||
}
|
||||
|
||||
if (modify) if (!values.containsKey(sqlField)) {
|
||||
if (!values.containsKey(sqlField)) {
|
||||
values.put(sqlField, value);
|
||||
if (setModified) modifiedSinceLastSave.add(sqlField.getName());
|
||||
}
|
||||
@ -227,7 +224,7 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
||||
@SuppressWarnings("unchecked")
|
||||
public E save() throws DBException {
|
||||
if (!isValidForSave())
|
||||
throw new IllegalStateException(toString() + " has at least one undefined value and can't be saved.");
|
||||
throw new IllegalStateException(this + " has at least one undefined value and can't be saved.");
|
||||
|
||||
DB.initTable((Class<E>)getClass());
|
||||
try {
|
||||
@ -251,24 +248,24 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
||||
// values
|
||||
values.put(fields.get("id"), null);
|
||||
|
||||
String concat_vals = "";
|
||||
String concat_fields = "";
|
||||
StringBuilder concatValues = new StringBuilder();
|
||||
StringBuilder concatFields = new StringBuilder();
|
||||
List<Object> psValues = new ArrayList<>();
|
||||
|
||||
boolean first = true;
|
||||
for (Map.Entry<SQLField<E, ?>, Object> entry : values.entrySet()) {
|
||||
if (!first) {
|
||||
concat_vals += ",";
|
||||
concat_fields += ",";
|
||||
concatValues.append(",");
|
||||
concatFields.append(",");
|
||||
}
|
||||
first = false;
|
||||
concat_vals += " ? ";
|
||||
concat_fields += "`" + entry.getKey().getName() + "`";
|
||||
concatValues.append(" ? ");
|
||||
concatFields.append("`").append(entry.getKey().getName()).append("`");
|
||||
addValueToSQLObjectList(psValues, entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
try (PreparedStatement ps = db.getNativeConnection().prepareStatement(
|
||||
"INSERT INTO " + DB.tablePrefix + tableName() + " (" + concat_fields + ") VALUES (" + concat_vals + ")",
|
||||
"INSERT INTO " + DB.tablePrefix + tableName() + " (" + concatFields + ") VALUES (" + concatValues + ")",
|
||||
Statement.RETURN_GENERATED_KEYS)) {
|
||||
|
||||
int i = 1;
|
||||
@ -300,7 +297,7 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
||||
jValue = ((SQLCustomType)field.type).javaToDbConv.apply(jValue);
|
||||
} catch (Exception e) {
|
||||
throw new DBException("Error while converting value of field '"+field.getName()+"' with SQLCustomType from "+field.type.getJavaType()
|
||||
+"(java source) to "+((SQLCustomType<?, ?>)field.type).intermediateJavaType+"(jdbc destination). The original value is '"+jValue.toString()+"'", e);
|
||||
+"(java source) to "+((SQLCustomType<?, ?>)field.type).intermediateJavaType+"(jdbc destination). The original value is '"+jValue+"'", e);
|
||||
}
|
||||
}
|
||||
list.add(jValue);
|
||||
@ -346,8 +343,6 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
||||
}
|
||||
|
||||
protected static class SQLFieldMap<E extends SQLElement<E>> extends LinkedHashMap<String, SQLField<E, ?>> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Class<E> sqlElemClass;
|
||||
|
||||
private SQLFieldMap(Class<E> elemClass) {
|
||||
@ -382,7 +377,7 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == null || !(getClass().isInstance(o))) return false;
|
||||
if (!(getClass().isInstance(o))) return false;
|
||||
SQLElement<?> oEl = (SQLElement<?>) o;
|
||||
if (oEl.getId() == null) return false;
|
||||
return oEl.getId().equals(getId());
|
||||
@ -390,7 +385,7 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
return getClass().hashCode() ^ Objects.hashCode(getId());
|
||||
}
|
||||
|
||||
|
||||
@ -466,12 +461,12 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
||||
|
||||
public static final SQLType<Double> DOUBLE = new SQLType<>("DOUBLE", Double.class);
|
||||
|
||||
public static final SQLType<String> CHAR(int charCount) {
|
||||
public static SQLType<String> CHAR(int charCount) {
|
||||
if (charCount <= 0) throw new IllegalArgumentException("charCount must be positive.");
|
||||
return new SQLType<>("CHAR(" + charCount + ")", String.class);
|
||||
}
|
||||
|
||||
public static final SQLType<String> VARCHAR(int charCount) {
|
||||
public static SQLType<String> VARCHAR(int charCount) {
|
||||
if (charCount <= 0) throw new IllegalArgumentException("charCount must be positive.");
|
||||
return new SQLType<>("VARCHAR(" + charCount + ")", String.class);
|
||||
}
|
||||
@ -479,29 +474,29 @@ public abstract class SQLElement<E extends SQLElement<E>> {
|
||||
public static final SQLType<String> TEXT = new SQLType<>("TEXT", String.class);
|
||||
public static final SQLType<String> STRING = TEXT;
|
||||
|
||||
public static final SQLType<byte[]> BINARY(int byteCount) {
|
||||
public static SQLType<byte[]> BINARY(int byteCount) {
|
||||
if (byteCount <= 0) throw new IllegalArgumentException("byteCount must be positive.");
|
||||
return new SQLType<>("BINARY(" + byteCount + ")", byte[].class);
|
||||
}
|
||||
|
||||
public static final SQLType<byte[]> VARBINARY(int byteCount) {
|
||||
public static SQLType<byte[]> VARBINARY(int byteCount) {
|
||||
if (byteCount <= 0) throw new IllegalArgumentException("byteCount must be positive.");
|
||||
return new SQLType<>("VARBINARY(" + byteCount + ")", byte[].class);
|
||||
}
|
||||
|
||||
public static final SQLType<byte[]> BLOB = new SQLType<>("BLOB", byte[].class);
|
||||
|
||||
public static final <T extends Enum<T>> SQLType<T> ENUM(Class<T> enumType) {
|
||||
public static <T extends Enum<T>> SQLType<T> ENUM(Class<T> enumType) {
|
||||
if (enumType == null) throw new IllegalArgumentException("enumType can't be null.");
|
||||
String enumStr = "'";
|
||||
StringBuilder enumStr = new StringBuilder("'");
|
||||
boolean first = true;
|
||||
for (T el : enumType.getEnumConstants()) {
|
||||
if (!first) enumStr += "', '";
|
||||
if (!first) enumStr.append("', '");
|
||||
first = false;
|
||||
enumStr += el.name();
|
||||
enumStr.append(el.name());
|
||||
|
||||
}
|
||||
enumStr += "'";
|
||||
enumStr.append("'");
|
||||
|
||||
return new SQLCustomType<>("VARCHAR(" + enumStr + ")", String.class, enumType, s -> EnumUtil.searchEnum(enumType, s), Enum::name);
|
||||
}
|
||||
|
@ -1,25 +1,23 @@
|
||||
package fr.pandacube.lib.core.db;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import com.google.gson.JsonArray;
|
||||
import fr.pandacube.lib.core.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
|
||||
import fr.pandacube.lib.core.util.Log;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param <E>
|
||||
*/
|
||||
public class SQLElementList<E extends SQLElement<E>> extends ArrayList<E> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Map<SQLField<E, ?>, Object> modifiedValues = new LinkedHashMap<>();
|
||||
|
||||
@ -38,14 +36,13 @@ public class SQLElementList<E extends SQLElement<E>> extends ArrayList<E> {
|
||||
* que lors de
|
||||
* l'appel à {@link #saveCommon()}
|
||||
*
|
||||
* @param <T>
|
||||
* @param field le champs à modifier
|
||||
* @param value la valeur à lui appliquer
|
||||
*/
|
||||
public synchronized <T> void setCommon(SQLField<E, T> field, T value) {
|
||||
if (field == null)
|
||||
throw new IllegalArgumentException("field can't be null");
|
||||
if (field.getName() == "id")
|
||||
if (Objects.equals(field.getName(), "id"))
|
||||
throw new IllegalArgumentException("Can't modify id field in a SQLElementList");
|
||||
|
||||
Class<E> elemClass = field.getSQLElementType();
|
||||
@ -72,8 +69,6 @@ public class SQLElementList<E extends SQLElement<E>> extends ArrayList<E> {
|
||||
* {@link SQLElement#set(SQLField, Object)}.<br/>
|
||||
* Les objets de cette liste qui n'ont pas leur données en base de données
|
||||
* sont ignorées.
|
||||
*
|
||||
* @throws SQLException
|
||||
*/
|
||||
public synchronized int saveCommon() throws DBException {
|
||||
List<E> storedEl = getStoredEl();
|
||||
@ -102,7 +97,7 @@ public class SQLElementList<E extends SQLElement<E>> extends ArrayList<E> {
|
||||
}
|
||||
|
||||
private List<E> getStoredEl() {
|
||||
return stream().filter(SQLElement::isStored).collect(Collectors.toCollection(() -> new ArrayList<>()));
|
||||
return stream().filter(SQLElement::isStored).collect(Collectors.toCollection(ArrayList::new));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -63,7 +63,7 @@ public class SQLField<E extends SQLElement<E>, T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Don't use this {@link #toString()} method in a SQL query, because
|
||||
* <b>Don't use this {@code toString()} method in a SQL query, because
|
||||
* the default value is not escaped correctly</b>
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
@ -76,12 +76,9 @@ public class SQLField<E extends SQLElement<E>, T> {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) return false;
|
||||
if (!(obj instanceof SQLField)) return false;
|
||||
SQLField<?, ?> f = (SQLField<?, ?>) obj;
|
||||
if (!f.getName().equals(getName())) return false;
|
||||
if (!f.sqlElemClass.equals(sqlElemClass)) return false;
|
||||
return true;
|
||||
return obj instanceof SQLField<?, ?> f
|
||||
&& f.getName().equals(getName())
|
||||
&& f.sqlElemClass.equals(sqlElemClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2,10 +2,11 @@ package fr.pandacube.lib.core.db;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SQLOrderBy<E extends SQLElement<E>> {
|
||||
|
||||
private List<OBField> orderByFields = new ArrayList<>();
|
||||
private final List<OBField> orderByFields = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Construit une nouvelle clause ORDER BY
|
||||
@ -45,14 +46,9 @@ public class SQLOrderBy<E extends SQLElement<E>> {
|
||||
}
|
||||
|
||||
/* package */ String toSQL() {
|
||||
String ret = "";
|
||||
boolean first = true;
|
||||
for (OBField f : orderByFields) {
|
||||
if (!first) ret += ", ";
|
||||
first = false;
|
||||
ret += "`" + f.field.getName() + "` " + f.direction.name();
|
||||
}
|
||||
return ret;
|
||||
return orderByFields.stream()
|
||||
.map(f -> "`" + f.field.getName() + "` " + f.direction.name())
|
||||
.collect(Collectors.joining(", "));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -72,7 +68,7 @@ public class SQLOrderBy<E extends SQLElement<E>> {
|
||||
}
|
||||
|
||||
private enum Direction {
|
||||
ASC, DESC;
|
||||
ASC, DESC
|
||||
}
|
||||
|
||||
|
||||
|
@ -15,9 +15,8 @@ public class SQLType<T> {
|
||||
return sqlDeclaration;
|
||||
}
|
||||
|
||||
public boolean isAssignableFrom(Object val) {
|
||||
if (javaTypes.isInstance(val)) return true;
|
||||
return false;
|
||||
public boolean isInstance(Object val) {
|
||||
return javaTypes.isInstance(val);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -27,8 +26,8 @@ public class SQLType<T> {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null || !(obj instanceof SQLType)) return false;
|
||||
return toString().equals(((SQLType<?>) obj).toString());
|
||||
return obj instanceof SQLType o
|
||||
&& toString().equals(o.toString());
|
||||
}
|
||||
|
||||
public Class<T> getJavaType() {
|
||||
|
@ -42,27 +42,27 @@ public class SQLUpdate<E extends SQLElement<E>> {
|
||||
return 0;
|
||||
}
|
||||
|
||||
String sql = "UPDATE " + DB.getTableName(elemClass) + " SET ";
|
||||
StringBuilder sql = new StringBuilder("UPDATE " + DB.getTableName(elemClass) + " SET ");
|
||||
List<Object> params = new ArrayList<>();
|
||||
|
||||
boolean first = true;
|
||||
for (Map.Entry<SQLField<E, ?>, Object> entry : values.entrySet()) {
|
||||
if (!first)
|
||||
sql += ", ";
|
||||
sql += "`" + entry.getKey().getName() + "` = ? ";
|
||||
sql.append(", ");
|
||||
sql.append("`").append(entry.getKey().getName()).append("` = ? ");
|
||||
SQLElement.addValueToSQLObjectList(params, entry.getKey(), entry.getValue());
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (where != null) {
|
||||
ParameterizedSQLString ret = where.toSQL();
|
||||
sql += " WHERE " + ret.sqlString();
|
||||
sql.append(" WHERE ").append(ret.sqlString());
|
||||
params.addAll(ret.parameters());
|
||||
}
|
||||
|
||||
sql += ";";
|
||||
sql.append(";");
|
||||
|
||||
return DB.customUpdateStatement(sql, params);
|
||||
return DB.customUpdateStatement(sql.toString(), params);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -50,8 +50,8 @@ public abstract class SQLWhere<E extends SQLElement<E>> {
|
||||
|
||||
public static abstract class SQLWhereChain<E extends SQLElement<E>> extends SQLWhere<E> {
|
||||
|
||||
private SQLBoolOp operator;
|
||||
protected List<SQLWhere<E>> conditions = new ArrayList<>();
|
||||
private final SQLBoolOp operator;
|
||||
private final List<SQLWhere<E>> conditions = new ArrayList<>();
|
||||
|
||||
private SQLWhereChain(SQLBoolOp op) {
|
||||
if (op == null) throw new IllegalArgumentException("op can't be null");
|
||||
@ -73,20 +73,21 @@ public abstract class SQLWhere<E extends SQLElement<E>> {
|
||||
throw new DBException("SQLWhereChain needs at least one element inside !");
|
||||
}
|
||||
|
||||
String sql = "";
|
||||
StringBuilder sql = new StringBuilder();
|
||||
List<Object> params = new ArrayList<>();
|
||||
boolean first = true;
|
||||
|
||||
for (SQLWhere<E> w : conditions) {
|
||||
if (!first) sql += " " + operator.sql + " ";
|
||||
if (!first)
|
||||
sql.append(" ").append(operator.sql).append(" ");
|
||||
first = false;
|
||||
|
||||
ParameterizedSQLString ret = w.toSQL();
|
||||
sql += "(" + ret.sqlString() + ")";
|
||||
sql.append("(").append(ret.sqlString()).append(")");
|
||||
params.addAll(ret.parameters());
|
||||
}
|
||||
|
||||
return new ParameterizedSQLString(sql, params);
|
||||
return new ParameterizedSQLString(sql.toString(), params);
|
||||
}
|
||||
|
||||
protected enum SQLBoolOp {
|
||||
@ -96,7 +97,7 @@ public abstract class SQLWhere<E extends SQLElement<E>> {
|
||||
OR("OR");
|
||||
/* package */ final String sql;
|
||||
|
||||
private SQLBoolOp(String s) {
|
||||
SQLBoolOp(String s) {
|
||||
sql = s;
|
||||
}
|
||||
|
||||
@ -151,9 +152,9 @@ public abstract class SQLWhere<E extends SQLElement<E>> {
|
||||
|
||||
/* package */ static class SQLWhereComp<E extends SQLElement<E>> extends SQLWhere<E> {
|
||||
|
||||
private SQLField<E, ?> left;
|
||||
private SQLComparator comp;
|
||||
private Object right;
|
||||
private final SQLField<E, ?> left;
|
||||
private final SQLComparator comp;
|
||||
private final Object right;
|
||||
|
||||
/**
|
||||
* Compare a field with a value
|
||||
@ -193,7 +194,7 @@ public abstract class SQLWhere<E extends SQLElement<E>> {
|
||||
|
||||
/* package */ final String sql;
|
||||
|
||||
private SQLComparator(String s) {
|
||||
SQLComparator(String s) {
|
||||
sql = s;
|
||||
}
|
||||
|
||||
@ -208,8 +209,8 @@ public abstract class SQLWhere<E extends SQLElement<E>> {
|
||||
|
||||
/* package */ static class SQLWhereIn<E extends SQLElement<E>> extends SQLWhere<E> {
|
||||
|
||||
private SQLField<E, ?> field;
|
||||
private Collection<?> values;
|
||||
private final SQLField<E, ?> field;
|
||||
private final Collection<?> values;
|
||||
|
||||
/* package */ <T> SQLWhereIn(SQLField<E, T> f, Collection<T> v) {
|
||||
if (f == null || v == null)
|
||||
@ -246,8 +247,8 @@ public abstract class SQLWhere<E extends SQLElement<E>> {
|
||||
|
||||
/* package */ static class SQLWhereLike<E extends SQLElement<E>> extends SQLWhere<E> {
|
||||
|
||||
private SQLField<E, ?> field;
|
||||
private String likeExpr;
|
||||
private final SQLField<E, ?> field;
|
||||
private final String likeExpr;
|
||||
|
||||
/**
|
||||
* Compare a field with a value
|
||||
@ -279,8 +280,8 @@ public abstract class SQLWhere<E extends SQLElement<E>> {
|
||||
|
||||
/* package */ static class SQLWhereNull<E extends SQLElement<E>> extends SQLWhere<E> {
|
||||
|
||||
private SQLField<E, ?> fild;
|
||||
private boolean nulll;
|
||||
private final SQLField<E, ?> field;
|
||||
private final boolean isNull;
|
||||
|
||||
/**
|
||||
* Init a IS NULL / IS NOT NULL expression for a SQL WHERE condition.
|
||||
@ -294,13 +295,13 @@ public abstract class SQLWhere<E extends SQLElement<E>> {
|
||||
if (!field.canBeNull) Log.getLogger().log(Level.WARNING,
|
||||
"Useless : Trying to check IS [NOT] NULL on the field " + field.getSQLElementType().getName() + "#"
|
||||
+ field.getName() + " which is declared in the ORM as 'can't be null'");
|
||||
fild = field;
|
||||
nulll = isNull;
|
||||
this.field = field;
|
||||
this.isNull = isNull;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParameterizedSQLString toSQL() {
|
||||
return new ParameterizedSQLString("`" + fild.getName() + "` IS " + ((nulll) ? "NULL" : "NOT NULL"), new ArrayList<>());
|
||||
return new ParameterizedSQLString("`" + field.getName() + "` IS " + ((isNull) ? "NULL" : "NOT NULL"), new ArrayList<>());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,8 +23,6 @@ public class Array8Bit {
|
||||
|
||||
/**
|
||||
* i = 0 is the lowest significant bit
|
||||
* @param i
|
||||
* @return
|
||||
*/
|
||||
public boolean getBit(int i) {
|
||||
return values[i];
|
||||
@ -32,8 +30,6 @@ public class Array8Bit {
|
||||
|
||||
/**
|
||||
* i = 0 is the lowest significant bit
|
||||
* @param i
|
||||
* @param b
|
||||
*/
|
||||
public void setBit(int i, boolean b) {
|
||||
values[i] = b;
|
||||
|
@ -1,13 +1,14 @@
|
||||
package fr.pandacube.lib.core.net;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public final class ByteBuffer implements Cloneable {
|
||||
|
||||
public static final Charset NETWORK_CHARSET = Charset.forName("UTF-8");
|
||||
public static final Charset NETWORK_CHARSET = StandardCharsets.UTF_8;
|
||||
|
||||
private java.nio.ByteBuffer buff;
|
||||
|
||||
@ -64,7 +65,6 @@ public final class ByteBuffer implements Cloneable {
|
||||
/**
|
||||
* Return the next byte array wich is preceded with his size as integer,
|
||||
* or null if the founded size is negative.
|
||||
* @return
|
||||
*/
|
||||
public byte[] getSizedByteArray() {
|
||||
int size = getInt();
|
||||
@ -218,7 +218,6 @@ public final class ByteBuffer implements Cloneable {
|
||||
/**
|
||||
*
|
||||
* @param s null String are supported
|
||||
* @return
|
||||
*/
|
||||
public ByteBuffer putString(String s) {
|
||||
if (s == null) {
|
||||
@ -229,7 +228,6 @@ public final class ByteBuffer implements Cloneable {
|
||||
|
||||
/**
|
||||
* returned string can be null
|
||||
* @return
|
||||
*/
|
||||
public String getString() {
|
||||
byte[] binaryString = getSizedByteArray();
|
||||
@ -239,7 +237,6 @@ public final class ByteBuffer implements Cloneable {
|
||||
/**
|
||||
*
|
||||
* @param list The list can be null, and any String can be null too.
|
||||
* @return
|
||||
*/
|
||||
public ByteBuffer putListOfString(List<String> list) {
|
||||
if (list == null) {
|
||||
|
@ -3,9 +3,9 @@ package fr.pandacube.lib.core.net;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class PPacket {
|
||||
public String name;
|
||||
public final String name;
|
||||
/* package */ int id;
|
||||
public byte[] content;
|
||||
public final byte[] content;
|
||||
|
||||
/**
|
||||
* Construct a new PPacket based on the content of the provided buffer before his position.
|
||||
|
@ -3,7 +3,7 @@ package fr.pandacube.lib.core.net;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class PPacketAnswer extends PPacket {
|
||||
/* package */ int answer;
|
||||
/* package */ final int answer;
|
||||
|
||||
/**
|
||||
* Construct a new PPacketAnswer based on the content of the provided buffer before his position.
|
||||
|
@ -8,6 +8,6 @@ public interface PPacketListener<P extends PPacket> {
|
||||
* @param connection the connection from where the packet comes
|
||||
* @param packet the received packet
|
||||
*/
|
||||
public void onPacketReceive(PSocket connection, P packet);
|
||||
void onPacketReceive(PSocket connection, P packet);
|
||||
|
||||
}
|
||||
|
@ -17,25 +17,25 @@ import com.google.common.base.MoreObjects;
|
||||
import fr.pandacube.lib.core.util.Log;
|
||||
|
||||
public class PServer extends Thread implements Closeable {
|
||||
private static AtomicInteger connectionCounterId = new AtomicInteger(0);
|
||||
private static final AtomicInteger connectionCounterId = new AtomicInteger(0);
|
||||
|
||||
private int port;
|
||||
private final int port;
|
||||
private ServerSocket socket;
|
||||
private String socketName;
|
||||
private final String socketName;
|
||||
|
||||
private List<TCPServerClientConnection> clients = Collections.synchronizedList(new ArrayList<>());
|
||||
private final List<TCPServerClientConnection> clients = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
private AtomicBoolean isClosed = new AtomicBoolean(false);
|
||||
private final AtomicBoolean isClosed = new AtomicBoolean(false);
|
||||
|
||||
|
||||
private List<PPacketListener<PPacket>> globalPacketListeners = Collections.synchronizedList(new ArrayList<>());
|
||||
private List<PSocketConnectionListener> clientConnectionListeners = Collections.synchronizedList(new ArrayList<>());
|
||||
private final List<PPacketListener<PPacket>> globalPacketListeners = Collections.synchronizedList(new ArrayList<>());
|
||||
private final List<PSocketConnectionListener> clientConnectionListeners = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
|
||||
|
||||
private String password;
|
||||
private final String password;
|
||||
|
||||
public PServer(int port, String sckName, String password) throws IOException {
|
||||
public PServer(int port, String sckName, String password) {
|
||||
super("PServer " + sckName);
|
||||
setDaemon(true);
|
||||
if (port <= 0 || port > 65535) throw new IllegalArgumentException("le numéro de port est invalide");
|
||||
@ -59,17 +59,11 @@ public class PServer extends Thread implements Closeable {
|
||||
socketClient.setSendBufferSize(PSocket.NETWORK_TCP_BUFFER_SIZE);
|
||||
socketClient.setSoTimeout(PSocket.NETWORK_TIMEOUT);
|
||||
|
||||
try {
|
||||
@SuppressWarnings("resource")
|
||||
TCPServerClientConnection co = new TCPServerClientConnection(socketClient,
|
||||
connectionCounterId.getAndIncrement());
|
||||
co.start();
|
||||
} catch (IOException e) {
|
||||
Log.severe("Connexion impossible avec " + socketClient.getInetAddress());
|
||||
}
|
||||
TCPServerClientConnection co = new TCPServerClientConnection(socketClient,
|
||||
connectionCounterId.getAndIncrement());
|
||||
co.start();
|
||||
}
|
||||
} catch(SocketException e) {
|
||||
|
||||
} catch (SocketException ignored) {
|
||||
} catch (Exception e) {
|
||||
Log.warning("Plus aucune connexion ne peux être acceptée", e);
|
||||
}
|
||||
@ -97,7 +91,7 @@ public class PServer extends Thread implements Closeable {
|
||||
|
||||
boolean loggedIn;
|
||||
|
||||
private TCPServerClientConnection(Socket s, int coId) throws IOException {
|
||||
private TCPServerClientConnection(Socket s, int coId) {
|
||||
super(s, "Conn#" + coId + " via TCPSv " + socketName, password);
|
||||
addConnectionListener(new PSocketConnectionListener() {
|
||||
@Override
|
||||
@ -114,16 +108,16 @@ public class PServer extends Thread implements Closeable {
|
||||
clientConnectionListeners.forEach(l -> l.onConnect(connection));
|
||||
}
|
||||
});
|
||||
addPacketListener((conn, packet) -> {
|
||||
globalPacketListeners.forEach(l -> {
|
||||
try {
|
||||
l.onPacketReceive(conn, packet);
|
||||
} catch (Exception e) {
|
||||
Log.severe("Exception while calling PPacketListener.onPacketReceive().", e);
|
||||
sendSilently(PPacketAnswer.buildExceptionPacket(packet, e.toString()));
|
||||
}
|
||||
});
|
||||
});
|
||||
addPacketListener((conn, packet) ->
|
||||
globalPacketListeners.forEach(l -> {
|
||||
try {
|
||||
l.onPacketReceive(conn, packet);
|
||||
} catch (Exception e) {
|
||||
Log.severe("Exception while calling PPacketListener.onPacketReceive().", e);
|
||||
sendSilently(PPacketAnswer.buildExceptionPacket(packet, e.toString()));
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@ -137,7 +131,7 @@ public class PServer extends Thread implements Closeable {
|
||||
clients.forEach(PSocket::close);
|
||||
|
||||
socket.close();
|
||||
} catch (IOException e) {}
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
|
@ -40,17 +40,17 @@ public class PSocket extends Thread implements Closeable {
|
||||
|
||||
private boolean server = false;
|
||||
private Socket socket;
|
||||
private SocketAddress addr;
|
||||
private final SocketAddress addr;
|
||||
private DataInputStream in;
|
||||
private DataOutputStream out;
|
||||
private Object outSynchronizer = new Object();
|
||||
private final Object outSynchronizer = new Object();
|
||||
private String password;
|
||||
|
||||
private AtomicBoolean isClosed = new AtomicBoolean(false);
|
||||
private final AtomicBoolean isClosed = new AtomicBoolean(false);
|
||||
|
||||
private List<PPacketListener<PPacket>> packetListeners = Collections.synchronizedList(new ArrayList<>());
|
||||
private List<PSocketConnectionListener> connectionListeners = Collections.synchronizedList(new ArrayList<>());
|
||||
private Map<Integer, PPacketListener<PPacketAnswer>> answersCallbacks = Collections.synchronizedMap(new HashMap<>());
|
||||
private final List<PPacketListener<PPacket>> packetListeners = Collections.synchronizedList(new ArrayList<>());
|
||||
private final List<PSocketConnectionListener> connectionListeners = Collections.synchronizedList(new ArrayList<>());
|
||||
private final Map<Integer, PPacketListener<PPacketAnswer>> answersCallbacks = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
private int nextSendId = 0;
|
||||
|
||||
@ -58,7 +58,7 @@ public class PSocket extends Thread implements Closeable {
|
||||
* Create a new PSocket that will connect to the specified SocketAddress.
|
||||
* @param a The target server to connect to
|
||||
* @param connName the name of the connection, used to name the Thread used to receive the packet.
|
||||
* @param the password to send to the server.
|
||||
* @param pass the password to send to the server.
|
||||
*/
|
||||
public PSocket(SocketAddress a, String connName, String pass) {
|
||||
super("PSocket " + connName);
|
||||
@ -115,7 +115,6 @@ public class PSocket extends Thread implements Closeable {
|
||||
}
|
||||
send(PPacketAnswer.buildLoginOkPacket(packet));
|
||||
// login ok at this point
|
||||
password = null;
|
||||
}
|
||||
else {
|
||||
send(PPacket.buildLoginPacket(password));
|
||||
@ -136,9 +135,9 @@ public class PSocket extends Thread implements Closeable {
|
||||
return;
|
||||
}
|
||||
// login ok at this point
|
||||
password = null;
|
||||
}
|
||||
|
||||
password = null;
|
||||
|
||||
socket.setSoTimeout(NETWORK_TIMEOUT);
|
||||
|
||||
Log.info(getName() + " connected.");
|
||||
@ -189,7 +188,6 @@ public class PSocket extends Thread implements Closeable {
|
||||
/**
|
||||
* Return the packet read in the socket, or null if the packet is in a bad format.
|
||||
* @return the packet
|
||||
* @throws IOException
|
||||
*
|
||||
*/
|
||||
private PPacket readPacket() throws IOException {
|
||||
@ -232,8 +230,6 @@ public class PSocket extends Thread implements Closeable {
|
||||
|
||||
/**
|
||||
* Send the provided packet, without waiting for an answer.
|
||||
* @param packet
|
||||
* @throws IOException
|
||||
*/
|
||||
public void send(PPacket packet) throws IOException {
|
||||
if (packet == null)
|
||||
@ -271,7 +267,7 @@ public class PSocket extends Thread implements Closeable {
|
||||
public void sendSilently(PPacket packet) {
|
||||
try {
|
||||
send(packet);
|
||||
} catch (IOException e) {}
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
|
||||
|
||||
|
@ -6,12 +6,12 @@ public interface PSocketConnectionListener {
|
||||
* Called when a socket is connected
|
||||
* @param connection the connection
|
||||
*/
|
||||
public void onConnect(PSocket connection);
|
||||
void onConnect(PSocket connection);
|
||||
|
||||
/**
|
||||
* Called just before a socket is disconnected
|
||||
* @param connection the connection
|
||||
*/
|
||||
public void onDisconnect(PSocket connection);
|
||||
void onDisconnect(PSocket connection);
|
||||
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import java.io.PrintStream;
|
||||
public abstract class AbstractRequest {
|
||||
|
||||
private final String pass;
|
||||
private String command;
|
||||
private final String command;
|
||||
private String data;
|
||||
|
||||
protected AbstractRequest(String cmd, String p) {
|
||||
|
@ -35,7 +35,7 @@ public class ResponseAnalyser {
|
||||
if (line == null)
|
||||
throw new IOException("Not enough data to read second line of response.");
|
||||
|
||||
int data_size = 0;
|
||||
int data_size;
|
||||
try {
|
||||
data_size = Integer.parseInt(line);
|
||||
} catch (NumberFormatException e) {
|
||||
@ -45,7 +45,7 @@ public class ResponseAnalyser {
|
||||
// lecture du reste
|
||||
StringBuilder sB_data = new StringBuilder();
|
||||
char[] c = new char[100];
|
||||
int nbC = 0;
|
||||
int nbC;
|
||||
while ((nbC = in.read(c)) != -1)
|
||||
sB_data.append(c, 0, nbC);
|
||||
data = sB_data.toString();
|
||||
|
@ -10,11 +10,11 @@ import fr.pandacube.lib.core.util.Log;
|
||||
@Deprecated
|
||||
public class NetworkAPIListener implements Runnable {
|
||||
|
||||
private int port = 0;
|
||||
String pass;
|
||||
private final int port;
|
||||
final String pass;
|
||||
private ServerSocket serverSocket;
|
||||
private HashMap<String, AbstractRequestExecutor> requestExecutors = new HashMap<>();
|
||||
private String name;
|
||||
private final HashMap<String, AbstractRequestExecutor> requestExecutors = new HashMap<>();
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Instencie le côté serveur du NetworkAPI
|
||||
@ -22,8 +22,6 @@ public class NetworkAPIListener implements Runnable {
|
||||
* @param n nom du networkAPI (permet l'identification dans les logs)
|
||||
* @param p le port d'écoute
|
||||
* @param pa le mot de passe réseau
|
||||
* @param peh PacketExecutionHandler permettant de prendre en charge
|
||||
* l'exécution asynchrone d'une requête reçu pas un client
|
||||
*/
|
||||
public NetworkAPIListener(String n, int p, String pa) {
|
||||
port = p;
|
||||
@ -51,12 +49,13 @@ public class NetworkAPIListener implements Runnable {
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
}
|
||||
} catch (IOException e) {}
|
||||
} catch (IOException ignored) {}
|
||||
|
||||
synchronized (this) {
|
||||
try {
|
||||
if (!serverSocket.isClosed()) serverSocket.close();
|
||||
} catch (IOException e) {}
|
||||
if (!serverSocket.isClosed())
|
||||
serverSocket.close();
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
|
||||
Log.info("NetworkAPI '" + name + "' ferme le port " + port);
|
||||
@ -70,7 +69,7 @@ public class NetworkAPIListener implements Runnable {
|
||||
public synchronized void closeServerSocket() {
|
||||
if (serverSocket != null) try {
|
||||
serverSocket.close();
|
||||
} catch (IOException e) {}
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
|
@ -18,8 +18,8 @@ import fr.pandacube.lib.core.util.Log;
|
||||
*/
|
||||
@Deprecated
|
||||
public class PacketExecutor implements Runnable {
|
||||
private Socket socket;
|
||||
private NetworkAPIListener networkAPIListener;
|
||||
private final Socket socket;
|
||||
private final NetworkAPIListener networkAPIListener;
|
||||
|
||||
public PacketExecutor(Socket s, NetworkAPIListener napiListener) {
|
||||
socket = s;
|
||||
@ -43,9 +43,9 @@ public class PacketExecutor implements Runnable {
|
||||
rep.data = e.toString();
|
||||
try {
|
||||
rep.sendPacket(new PrintStream(socket.getOutputStream()));
|
||||
} catch (IOException e1) {}
|
||||
} catch (IOException ignored) {}
|
||||
if (e instanceof IOException)
|
||||
Log.warning("Unable to read packet from socket " + socket + ": " + e.toString());
|
||||
Log.warning("Unable to read packet from socket " + socket + ": " + e);
|
||||
else if(e instanceof BadRequestException) {
|
||||
if (e.getMessage().equals("wrong_password"))
|
||||
Log.warning("Wrong password received from socket " + socket);
|
||||
@ -60,6 +60,6 @@ public class PacketExecutor implements Runnable {
|
||||
|
||||
try {
|
||||
socket.close();
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import java.net.Socket;
|
||||
@Deprecated
|
||||
public class RequestAnalyser {
|
||||
|
||||
private NetworkAPIListener networkAPIListener;
|
||||
public final String command;
|
||||
public final String data;
|
||||
|
||||
@ -17,8 +16,6 @@ public class RequestAnalyser {
|
||||
throw new IllegalArgumentException(
|
||||
"le socket doit être non null et doit être ouvert sur le flux d'entrée et napiListener ne doit pas être null");
|
||||
|
||||
networkAPIListener = napiListener;
|
||||
|
||||
// on lis la réponse
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||
|
||||
@ -26,18 +23,18 @@ public class RequestAnalyser {
|
||||
|
||||
// lecture de la première ligne
|
||||
line = in.readLine();
|
||||
if (line == null || !line.equals(networkAPIListener.pass)) throw new BadRequestException("wrong_password");
|
||||
if (line == null || !line.equals(napiListener.pass)) throw new BadRequestException("wrong_password");
|
||||
|
||||
// lecture de la deuxième ligne
|
||||
line = in.readLine();
|
||||
if (line == null || networkAPIListener.getRequestExecutor(line) == null)
|
||||
if (line == null || napiListener.getRequestExecutor(line) == null)
|
||||
throw new BadRequestException("command_not_exists");
|
||||
command = line;
|
||||
|
||||
// lecture de la troisième ligne
|
||||
line = in.readLine();
|
||||
|
||||
int data_size = 0;
|
||||
int data_size;
|
||||
try {
|
||||
data_size = Integer.parseInt(line);
|
||||
} catch (NumberFormatException e) {
|
||||
@ -47,7 +44,7 @@ public class RequestAnalyser {
|
||||
// lecture du reste
|
||||
StringBuilder sB_data = new StringBuilder();
|
||||
char[] c = new char[100];
|
||||
int nbC = 0;
|
||||
int nbC;
|
||||
while ((nbC = in.read(c)) != -1)
|
||||
sB_data.append(c, 0, nbC);
|
||||
|
||||
@ -58,9 +55,7 @@ public class RequestAnalyser {
|
||||
socket.shutdownInput();
|
||||
}
|
||||
|
||||
public class BadRequestException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
public static class BadRequestException extends Exception {
|
||||
|
||||
public BadRequestException(String message) {
|
||||
super(message);
|
||||
|
@ -33,12 +33,11 @@ public abstract class PermEntity {
|
||||
* Tells if the current entity inherits directly or indirectly from the specified group
|
||||
* @param group the group to search for
|
||||
* @param recursive true to search in the inheritance tree, or false to search only in the inheritance list of the current entity.
|
||||
* @return
|
||||
*/
|
||||
public boolean inheritsFromGroup(String group, boolean recursive) {
|
||||
if (group == null)
|
||||
return false;
|
||||
return getInheritances().stream().anyMatch(g -> g.name.equals(group) || (recursive && g.inheritsFromGroup(group, recursive)));
|
||||
return getInheritances().stream().anyMatch(g -> g.name.equals(group) || (recursive && g.inheritsFromGroup(group, true)));
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
@ -105,8 +104,8 @@ public abstract class PermEntity {
|
||||
String prefixWithEndingDot = permissionPrefix.endsWith(".") ? permissionPrefix : (permissionPrefix + ".");
|
||||
int prefixLength = prefixWithEndingDot.length();
|
||||
return listEffectivePermissions(server, world).entrySet().stream()
|
||||
.filter(e -> e.getValue()) // permission must be positive
|
||||
.map(e -> e.getKey()) // keep only the permission node (key), since the value is always true
|
||||
.filter(Map.Entry::getValue) // permission must be positive
|
||||
.map(Map.Entry::getKey) // keep only the permission node (key), since the value is always true
|
||||
.filter(p -> p.startsWith(prefixWithEndingDot)) // keep only relevant permissions
|
||||
.map(p -> p.substring(prefixLength)) // keep only what is after the prefix
|
||||
.map(suffix -> { // convert to long
|
||||
@ -117,7 +116,7 @@ public abstract class PermEntity {
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.filter(longSuffix -> longSuffix != null)
|
||||
.filter(Objects::nonNull)
|
||||
.mapToLong(longSuffix -> longSuffix)
|
||||
.sorted();
|
||||
}
|
||||
@ -224,10 +223,9 @@ public abstract class PermEntity {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null || !(obj instanceof PermEntity))
|
||||
return false;
|
||||
PermEntity o = (PermEntity) obj;
|
||||
return Objects.equals(name, o.name) && type == o.type;
|
||||
return obj instanceof PermEntity o
|
||||
&& Objects.equals(name, o.name)
|
||||
&& type == o.type;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -50,7 +50,6 @@ public class PermPlayer extends PermEntity {
|
||||
|
||||
/**
|
||||
* Alias for {@link #getInheritances()}.
|
||||
* @return
|
||||
*/
|
||||
public List<PermGroup> getGroups() {
|
||||
return getInheritances();
|
||||
@ -58,7 +57,6 @@ public class PermPlayer extends PermEntity {
|
||||
|
||||
/**
|
||||
* Alias for {@link #getInheritances()}.
|
||||
* @return
|
||||
*/
|
||||
public List<String> getGroupsString() {
|
||||
return getInheritancesString();
|
||||
@ -68,7 +66,6 @@ public class PermPlayer extends PermEntity {
|
||||
* Tells if the player is directly part of a group.
|
||||
* This is equivalent to {@link #inheritsFromGroup(String, boolean) inheritsFromGroup(group, false)}
|
||||
* @param group the group to search for
|
||||
* @return
|
||||
*/
|
||||
public boolean isInGroup(String group) {
|
||||
return inheritsFromGroup(group, false);
|
||||
|
@ -1,9 +1,11 @@
|
||||
package fr.pandacube.lib.core.permissions;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import fr.pandacube.lib.core.db.DB;
|
||||
import fr.pandacube.lib.core.db.DBConnection;
|
||||
import fr.pandacube.lib.core.db.DBException;
|
||||
import fr.pandacube.lib.core.util.Log;
|
||||
|
||||
@ -16,7 +18,6 @@ public class Permissions {
|
||||
/**
|
||||
* Initialize the permission system.
|
||||
* The connection to the database needs to be initialized first, using {@link DB#init(DBConnection, String)}.
|
||||
* @throws DBException
|
||||
*/
|
||||
public static void init() throws DBException {
|
||||
if (backendReader != null)
|
||||
@ -38,8 +39,7 @@ public class Permissions {
|
||||
checkInitialized();
|
||||
if (specialPermissions == null)
|
||||
return;
|
||||
for (SpecialPermission sp : specialPermissions)
|
||||
resolver.specialPermissions.add(sp);
|
||||
resolver.specialPermissions.addAll(Arrays.asList(specialPermissions));
|
||||
}
|
||||
|
||||
private static void checkInitialized() {
|
||||
|
@ -57,22 +57,20 @@ import fr.pandacube.lib.core.permissions.SQLPermissions.EntityType;
|
||||
.and(SQLPermissions.type.eq(EntityType.Group.getCode()))
|
||||
.and(SQLPermissions.key.like("default"))
|
||||
);
|
||||
if (entry == null && !deflt) {
|
||||
return;
|
||||
if (entry != null) {
|
||||
if (deflt) {
|
||||
// update just in case
|
||||
if ("true".equals(entry.get(SQLPermissions.value)))
|
||||
return;
|
||||
entry.set(SQLPermissions.value, "true");
|
||||
entry.save();
|
||||
}
|
||||
else {
|
||||
// delete
|
||||
entry.delete();
|
||||
}
|
||||
}
|
||||
else if (entry != null && deflt) {
|
||||
// update
|
||||
if ("true".equals(entry.get(SQLPermissions.value)))
|
||||
return;
|
||||
entry.set(SQLPermissions.value, "true");
|
||||
entry.save();
|
||||
return;
|
||||
}
|
||||
else if (entry != null && !deflt) {
|
||||
// delete
|
||||
entry.delete();
|
||||
}
|
||||
else {
|
||||
else if (deflt) {
|
||||
// insert
|
||||
addEntry(name, EntityType.Group, "default", "true", null, null);
|
||||
}
|
||||
@ -97,20 +95,18 @@ import fr.pandacube.lib.core.permissions.SQLPermissions.EntityType;
|
||||
.and(SQLPermissions.type.eq(type.getCode()))
|
||||
.and(SQLPermissions.key.like("prefix"))
|
||||
);
|
||||
if (entry == null && prefix == null) {
|
||||
return;
|
||||
if (entry != null) {
|
||||
if (prefix != null) {
|
||||
// update
|
||||
entry.set(SQLPermissions.value, prefix);
|
||||
entry.save();
|
||||
}
|
||||
else {
|
||||
// delete
|
||||
entry.delete();
|
||||
}
|
||||
}
|
||||
else if (entry != null && prefix != null) {
|
||||
// update
|
||||
entry.set(SQLPermissions.value, prefix);
|
||||
entry.save();
|
||||
return;
|
||||
}
|
||||
else if (entry != null && prefix == null) {
|
||||
// delete
|
||||
entry.delete();
|
||||
}
|
||||
else {
|
||||
else if (prefix != null) {
|
||||
// insert
|
||||
addEntry(name, type, "prefix", prefix, null, null);
|
||||
}
|
||||
@ -130,20 +126,18 @@ import fr.pandacube.lib.core.permissions.SQLPermissions.EntityType;
|
||||
.and(SQLPermissions.type.eq(type.getCode()))
|
||||
.and(SQLPermissions.key.like("suffix"))
|
||||
);
|
||||
if (entry == null && suffix == null) {
|
||||
return;
|
||||
if (entry != null) {
|
||||
if (suffix != null) {
|
||||
// update
|
||||
entry.set(SQLPermissions.value, suffix);
|
||||
entry.save();
|
||||
}
|
||||
else {
|
||||
// delete
|
||||
entry.delete();
|
||||
}
|
||||
}
|
||||
else if (entry != null && suffix != null) {
|
||||
// update
|
||||
entry.set(SQLPermissions.value, suffix);
|
||||
entry.save();
|
||||
return;
|
||||
}
|
||||
else if (entry != null && suffix == null) {
|
||||
// delete
|
||||
entry.delete();
|
||||
}
|
||||
else {
|
||||
else if (suffix != null) {
|
||||
// insert
|
||||
addEntry(name, type, "suffix", suffix, null, null);
|
||||
}
|
||||
@ -175,7 +169,7 @@ import fr.pandacube.lib.core.permissions.SQLPermissions.EntityType;
|
||||
throw new IllegalStateException("Inheritance already set");
|
||||
addEntry(name, type, key, inheritance, null, null);
|
||||
} catch (DBException e) {
|
||||
new RuntimeException(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -29,10 +29,10 @@ import fr.pandacube.lib.core.util.Log;
|
||||
|
||||
|
||||
|
||||
private Cache<UUID, CachedPlayer> usersCache = CacheBuilder.newBuilder()
|
||||
private final Cache<UUID, CachedPlayer> usersCache = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(10, TimeUnit.MINUTES)
|
||||
.build();
|
||||
private Set<String> fullPermissionsList = new TreeSet<String>();
|
||||
private Set<String> fullPermissionsList = new TreeSet<>();
|
||||
|
||||
/* package */ synchronized List<String> getFullPermissionsList() {
|
||||
return new ArrayList<>(fullPermissionsList);
|
||||
@ -105,14 +105,12 @@ import fr.pandacube.lib.core.util.Log;
|
||||
if (playerRawData.containsKey("groups")) {
|
||||
playerRawData.get("groups").stream()
|
||||
.map(e -> e.get(SQLPermissions.value))
|
||||
.forEach(g -> {
|
||||
player.groups.add(getCachedGroup(g));
|
||||
});
|
||||
.forEach(g -> player.groups.add(getCachedGroup(g)));
|
||||
}
|
||||
|
||||
if (player.groups.isEmpty()) {
|
||||
player.usingDefaultGroups = true;
|
||||
getDefaultGroups().forEach(player.groups::add);
|
||||
player.groups.addAll(getDefaultGroups());
|
||||
}
|
||||
|
||||
return player;
|
||||
@ -121,7 +119,7 @@ import fr.pandacube.lib.core.util.Log;
|
||||
|
||||
|
||||
|
||||
private Map<String, CachedGroup> groupsCache = new LinkedHashMap<>();
|
||||
private final Map<String, CachedGroup> groupsCache = new LinkedHashMap<>();
|
||||
private boolean cacheIsUpdating = false;
|
||||
|
||||
|
||||
@ -207,8 +205,7 @@ import fr.pandacube.lib.core.util.Log;
|
||||
Map<String, List<SQLPermissions>> groupRawData = groupsRawData.getOrDefault(groupName, new LinkedHashMap<>());
|
||||
|
||||
boolean groupDefault = groupRawData.containsKey("default")
|
||||
? "true".equals(groupRawData.get("default").get(0).get(SQLPermissions.value))
|
||||
: false;
|
||||
&& "true".equals(groupRawData.get("default").get(0).get(SQLPermissions.value));
|
||||
|
||||
String groupSelfPrefix = null;
|
||||
if (groupRawData.containsKey("prefix")) {
|
||||
|
@ -29,7 +29,7 @@ import net.md_5.bungee.api.ChatColor;
|
||||
|
||||
public class PermissionsResolver {
|
||||
|
||||
private PermissionsCachedBackendReader backendReader;
|
||||
private final PermissionsCachedBackendReader backendReader;
|
||||
|
||||
/* package */ PermissionsResolver(PermissionsCachedBackendReader b) {
|
||||
backendReader = b;
|
||||
@ -74,7 +74,7 @@ public class PermissionsResolver {
|
||||
return debugData(name, type, DataType.SUFFIX);
|
||||
}
|
||||
|
||||
private Cache<DataCacheKey, String> effectiveDataCache = CacheBuilder.newBuilder()
|
||||
private final Cache<DataCacheKey, String> effectiveDataCache = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(10, TimeUnit.MINUTES)
|
||||
.build();
|
||||
|
||||
@ -83,9 +83,7 @@ public class PermissionsResolver {
|
||||
Objects.requireNonNull(type, "type can’t be null");
|
||||
|
||||
try {
|
||||
return effectiveDataCache.get(new DataCacheKey(name, type, dataType), () -> {
|
||||
return resolveData(name, type, dataType);
|
||||
});
|
||||
return effectiveDataCache.get(new DataCacheKey(name, type, dataType), () -> resolveData(name, type, dataType));
|
||||
} catch (ExecutionException e) {
|
||||
Log.severe(e);
|
||||
return null;
|
||||
@ -108,7 +106,7 @@ public class PermissionsResolver {
|
||||
if (resolutionResult.conflict) {
|
||||
Log.warning("For data " + dataType + ":\n"
|
||||
+ ChatUtil.treeView(resolutionResult.toDisplayTreeNode(), true).stream()
|
||||
.map(cmp -> cmp.getLegacyText())
|
||||
.map(Chat::getLegacyText)
|
||||
.collect(Collectors.joining(ChatColor.RESET + "\n")));
|
||||
}
|
||||
|
||||
@ -140,7 +138,7 @@ public class PermissionsResolver {
|
||||
|
||||
Set<String> inheritedPermissions = inheritedResults.stream()
|
||||
.map(g -> g.result)
|
||||
.filter(r -> r != null)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (inheritedPermissions.size() == 1)
|
||||
@ -176,7 +174,7 @@ public class PermissionsResolver {
|
||||
c.thenFailure(" " + conflictMessage);
|
||||
DisplayTreeNode node = new DisplayTreeNode(c);
|
||||
|
||||
if (result == null && conflict == false && !inheritances.isEmpty()) {
|
||||
if (result == null && !conflict && !inheritances.isEmpty()) {
|
||||
// there is nothing interesting to show on current or subnode
|
||||
node.children.add(new DisplayTreeNode(Chat.text("(Inheritances hidden for brevety)").darkGray().italic()));
|
||||
return node;
|
||||
@ -197,10 +195,8 @@ public class PermissionsResolver {
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null || !(obj instanceof DataCacheKey))
|
||||
return false;
|
||||
DataCacheKey o = (DataCacheKey) obj;
|
||||
return Objects.equals(name, o.name)
|
||||
return obj instanceof DataCacheKey o
|
||||
&& Objects.equals(name, o.name)
|
||||
&& Objects.equals(type, o.type)
|
||||
&& dataType == o.dataType;
|
||||
}
|
||||
@ -211,7 +207,7 @@ public class PermissionsResolver {
|
||||
SUFFIX(CachedEntity::getSelfSuffix);
|
||||
|
||||
private final CachedEntityGetter<String> getter;
|
||||
private DataType(CachedEntityGetter<String> g) {
|
||||
DataType(CachedEntityGetter<String> g) {
|
||||
getter = g;
|
||||
}
|
||||
}
|
||||
@ -233,7 +229,7 @@ public class PermissionsResolver {
|
||||
|
||||
|
||||
|
||||
private Cache<PermCacheKey, Map<String, Boolean>> effectivePermissionsListCache = CacheBuilder.newBuilder()
|
||||
private final Cache<PermCacheKey, Map<String, Boolean>> effectivePermissionsListCache = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(10, TimeUnit.MINUTES)
|
||||
.build();
|
||||
|
||||
@ -265,7 +261,7 @@ public class PermissionsResolver {
|
||||
|
||||
}
|
||||
|
||||
private Cache<PermCacheKey, PermState> effectivePermissionsCache = CacheBuilder.newBuilder()
|
||||
private final Cache<PermCacheKey, PermState> effectivePermissionsCache = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(10, TimeUnit.MINUTES)
|
||||
.build();
|
||||
|
||||
@ -281,14 +277,14 @@ public class PermissionsResolver {
|
||||
reversed = true;
|
||||
}
|
||||
|
||||
String fPermission = permission == null ? null : permission.toLowerCase();
|
||||
String fPermission = permission.toLowerCase();
|
||||
String fServer = server == null ? null : server.toLowerCase();
|
||||
String fWorld = world == null ? null : world.toLowerCase();
|
||||
try {
|
||||
Boolean resolved = effectivePermissionsCache.get(new PermCacheKey(name, type, fPermission, fServer, fWorld), () -> {
|
||||
return resolvePermission(name, type, fPermission, fServer, fWorld);
|
||||
}).value;
|
||||
return resolved == null ? null : (reversed != resolved.booleanValue());
|
||||
Boolean resolved = effectivePermissionsCache.get(new PermCacheKey(name, type, fPermission, fServer, fWorld),
|
||||
() -> resolvePermission(name, type, fPermission, fServer, fWorld)
|
||||
).value;
|
||||
return resolved == null ? null : (reversed != resolved);
|
||||
} catch (ExecutionException e) {
|
||||
Log.severe(e);
|
||||
return null;
|
||||
@ -312,7 +308,7 @@ public class PermissionsResolver {
|
||||
if (resolutionResult.conflict) {
|
||||
Log.warning("For permission " + permission + ":\n"
|
||||
+ ChatUtil.treeView(resolutionResult.toDisplayTreeNode(), true).stream()
|
||||
.map(cmp -> cmp.getLegacyText())
|
||||
.map(Chat::getLegacyText)
|
||||
.collect(Collectors.joining(ChatColor.RESET + "\n")));
|
||||
}
|
||||
|
||||
@ -374,7 +370,7 @@ public class PermissionsResolver {
|
||||
if (inheritancesGranted != inheritancesRevoqued) {
|
||||
resolutionNode.result = inheritancesGranted ? PermState.GRANTED : PermState.REVOQUED;
|
||||
}
|
||||
else if (inheritancesGranted && inheritancesRevoqued) {
|
||||
else if (inheritancesGranted) {
|
||||
resolutionNode.conflictMessage = (resolutionNode.conflictMessage == null ? "" : (resolutionNode.conflictMessage + " ; "))
|
||||
+ "Unsolvable conflict between inheritances";
|
||||
resolutionNode.conflict = true;
|
||||
@ -388,7 +384,7 @@ public class PermissionsResolver {
|
||||
|
||||
|
||||
|
||||
/* package */ List<SpecialPermission> specialPermissions = new ArrayList<>();
|
||||
/* package */ final List<SpecialPermission> specialPermissions = new ArrayList<>();
|
||||
|
||||
|
||||
|
||||
@ -436,7 +432,7 @@ public class PermissionsResolver {
|
||||
resNode = new ParsedSelfPermission(p, false, PermType.WILDCARD);
|
||||
return resNode;
|
||||
})
|
||||
.filter(p -> p != null)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
boolean explicitGranted = foundPerms.stream()
|
||||
@ -459,13 +455,13 @@ public class PermissionsResolver {
|
||||
conflict = "Unnecessary explicit permission already granted by self wildcard permissions"; // redundent explicit perm
|
||||
}
|
||||
}
|
||||
else if (explicitGranted && explicitRevoqued) {
|
||||
else if (explicitGranted) {
|
||||
conflict = "Unsolvable conflit between explicit permissions";
|
||||
}
|
||||
else if (wildcardGranted != wildcardRevoqued) {
|
||||
result = PermState.of(wildcardGranted);
|
||||
}
|
||||
else if (wildcardGranted && wildcardRevoqued) {
|
||||
else if (wildcardGranted) {
|
||||
conflict = "Unsolvable conflit between wildcard permissions";
|
||||
}
|
||||
}
|
||||
@ -505,7 +501,7 @@ public class PermissionsResolver {
|
||||
|
||||
selfPermissions.forEach(p -> node.children.add(p.toDisplayTreeNode()));
|
||||
|
||||
if (result == PermState.UNDEFINED && conflict == false && !inheritances.isEmpty()) {
|
||||
if (result == PermState.UNDEFINED && !conflict && !inheritances.isEmpty()) {
|
||||
// there is nothing interesting to show on current or subnode
|
||||
node.children.add(new DisplayTreeNode(Chat.text("(Inheritances hidden for brevety)").darkGray().italic()));
|
||||
return node;
|
||||
@ -542,10 +538,8 @@ public class PermissionsResolver {
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null || !(obj instanceof PermCacheKey))
|
||||
return false;
|
||||
PermCacheKey o = (PermCacheKey) obj;
|
||||
return Objects.equals(name, o.name)
|
||||
return obj instanceof PermCacheKey o
|
||||
&& Objects.equals(name, o.name)
|
||||
&& Objects.equals(type, o.type)
|
||||
&& Objects.equals(permission, o.permission)
|
||||
&& Objects.equals(server, o.server)
|
||||
@ -554,7 +548,7 @@ public class PermissionsResolver {
|
||||
}
|
||||
|
||||
private enum PermType {
|
||||
EXPLICIT, WILDCARD, SPECIAL;
|
||||
EXPLICIT, WILDCARD, SPECIAL
|
||||
}
|
||||
|
||||
private enum PermState {
|
||||
@ -562,7 +556,7 @@ public class PermissionsResolver {
|
||||
REVOQUED(false),
|
||||
UNDEFINED(null);
|
||||
final Boolean value;
|
||||
private PermState(Boolean v) { value = v; }
|
||||
PermState(Boolean v) { value = v; }
|
||||
private static PermState of(Boolean v) {
|
||||
return v == null ? UNDEFINED : v ? GRANTED : REVOQUED;
|
||||
}
|
||||
|
@ -10,10 +10,8 @@ public class ServerWorldKey implements Comparable<ServerWorldKey> {
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null || !(obj instanceof ServerWorldKey))
|
||||
return false;
|
||||
ServerWorldKey o = (ServerWorldKey) obj;
|
||||
return Objects.equals(server, o.server)
|
||||
return obj instanceof ServerWorldKey o
|
||||
&& Objects.equals(server, o.server)
|
||||
&& Objects.equals(world, o.world);
|
||||
}
|
||||
@Override
|
||||
|
@ -20,7 +20,7 @@ import fr.pandacube.lib.core.util.Log;
|
||||
public interface IOffPlayer {
|
||||
|
||||
/** From how long the last web activity should be before considering the user offline (in ms)? */
|
||||
public static final long TIMEOUT_WEB_SESSION = 10000; // msec
|
||||
long TIMEOUT_WEB_SESSION = 10000; // msec
|
||||
|
||||
|
||||
|
||||
@ -34,7 +34,7 @@ public interface IOffPlayer {
|
||||
*
|
||||
* @return the id of the player
|
||||
*/
|
||||
public abstract UUID getUniqueId();
|
||||
UUID getUniqueId();
|
||||
|
||||
|
||||
/**
|
||||
@ -42,7 +42,7 @@ public interface IOffPlayer {
|
||||
*
|
||||
* An alt account uses a specific bit in the UUID to distinguish themselves from the original account.
|
||||
*/
|
||||
public default boolean isAltAccount() {
|
||||
default boolean isAltAccount() {
|
||||
return (getUniqueId().getMostSignificantBits() & 0x8000L) == 0x8000L;
|
||||
}
|
||||
|
||||
@ -53,14 +53,14 @@ public interface IOffPlayer {
|
||||
*
|
||||
* This method will return undetermined value if {@link #isAltAccount()} is false.
|
||||
*/
|
||||
public default int getAltIndex() {
|
||||
default int getAltIndex() {
|
||||
return (int) (getUniqueId().getMostSignificantBits() >> 8) & 0xF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the last known player name of this player, or null if this player never joined the network.
|
||||
*/
|
||||
public default String getName() {
|
||||
default String getName() {
|
||||
return PlayerFinder.getLastKnownName(getUniqueId());
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ public interface IOffPlayer {
|
||||
* Indicate if this player is connected to the current node (server or proxy, depending on interface implementation)
|
||||
* @return wether the player is online or not
|
||||
*/
|
||||
public abstract boolean isOnline();
|
||||
boolean isOnline();
|
||||
|
||||
|
||||
|
||||
@ -80,7 +80,7 @@ public interface IOffPlayer {
|
||||
* If the player is online in game, it provides the current server they are
|
||||
* connected.
|
||||
*/
|
||||
public default PlayerStatusOnServer getPlayerStatus() {
|
||||
default PlayerStatusOnServer getPlayerStatus() {
|
||||
|
||||
IOnlinePlayer op = getOnlineInstance();
|
||||
if (op != null && !op.isVanished())
|
||||
@ -103,7 +103,7 @@ public interface IOffPlayer {
|
||||
return new PlayerStatusOnServer(PlayerStatusOnServer.PlayerStatus.OFFLINE, null);
|
||||
}
|
||||
|
||||
public record PlayerStatusOnServer(PlayerStatus status, String server) {
|
||||
record PlayerStatusOnServer(PlayerStatus status, String server) {
|
||||
public Chat toComponent() {
|
||||
if (status == PlayerStatus.ONLINE_IG)
|
||||
return successText("En ligne, " + server);
|
||||
@ -130,12 +130,12 @@ public interface IOffPlayer {
|
||||
* Floodgate related stuff
|
||||
*/
|
||||
|
||||
public default boolean isBedrockAccount() {
|
||||
default boolean isBedrockAccount() {
|
||||
int v = getUniqueId().version();
|
||||
return v == 0 || v == 8; // also 8 if one day we supports alt accounts for floodgate players
|
||||
}
|
||||
|
||||
public default boolean isJavaAccount() {
|
||||
default boolean isJavaAccount() {
|
||||
return !isBedrockAccount();
|
||||
}
|
||||
|
||||
@ -149,13 +149,12 @@ public interface IOffPlayer {
|
||||
* Return the online instance of this player, if any exists.
|
||||
* May return itself if the current instance already represent an online player.
|
||||
*/
|
||||
public abstract IOnlinePlayer getOnlineInstance();
|
||||
IOnlinePlayer getOnlineInstance();
|
||||
|
||||
/**
|
||||
* Get the database entry of this player, or null if the player never joined the network.
|
||||
* @throws DBException
|
||||
*/
|
||||
public default SQLPlayer getDbPlayer() throws DBException {
|
||||
default SQLPlayer getDbPlayer() throws DBException {
|
||||
return SQLPlayer.getPlayerFromUUID(getUniqueId());
|
||||
}
|
||||
|
||||
@ -163,7 +162,7 @@ public interface IOffPlayer {
|
||||
* Get the permission instance of this player. This will never return null.
|
||||
* @return the permission instance of this player
|
||||
*/
|
||||
public default PermPlayer getPermissionUser() {
|
||||
default PermPlayer getPermissionUser() {
|
||||
return Permissions.getPlayer(getUniqueId());
|
||||
}
|
||||
|
||||
@ -181,15 +180,14 @@ public interface IOffPlayer {
|
||||
* (and team for bukkit implementation)
|
||||
* @return the display name of the player
|
||||
*/
|
||||
public abstract String getDisplayName();
|
||||
String getDisplayName();
|
||||
|
||||
/**
|
||||
* Get an updated display name of the user,
|
||||
* generated using eventual permission’s prefix(es) and suffix(es) of the player,
|
||||
* and with color codes translated to Minecraft’s native {@code §}.
|
||||
* @return
|
||||
*/
|
||||
public default String getDisplayNameFromPermissionSystem() {
|
||||
default String getDisplayNameFromPermissionSystem() {
|
||||
PermPlayer permU = getPermissionUser();
|
||||
return ChatColorUtil.translateAlternateColorCodes('&',
|
||||
permU.getPrefix() + getName() + permU.getSuffix());
|
||||
@ -215,7 +213,7 @@ public interface IOffPlayer {
|
||||
* @param permission the permission node to test
|
||||
* @return whether this player has the provided permission
|
||||
*/
|
||||
public default boolean hasPermission(String permission) {
|
||||
default boolean hasPermission(String permission) {
|
||||
IOnlinePlayer online = getOnlineInstance();
|
||||
|
||||
if (online != null)
|
||||
@ -233,10 +231,10 @@ public interface IOffPlayer {
|
||||
* loop.
|
||||
* If the player is offline, it just call the Pandacube
|
||||
* permission system.
|
||||
* @param permission the permission node to test
|
||||
* @param permissionExpression the permission node to test
|
||||
* @return whether this player has the provided permission
|
||||
*/
|
||||
public default boolean hasPermissionExpression(String permissionExpression) {
|
||||
default boolean hasPermissionExpression(String permissionExpression) {
|
||||
IOnlinePlayer online = getOnlineInstance();
|
||||
|
||||
if (online != null)
|
||||
@ -259,7 +257,7 @@ public interface IOffPlayer {
|
||||
* @param permissionPrefix the permission prefix to search for.
|
||||
* @return a LongStream containing all the values found for the specified permission prefix.
|
||||
*/
|
||||
public default LongStream getPermissionRangeValues(String permissionPrefix) {
|
||||
default LongStream getPermissionRangeValues(String permissionPrefix) {
|
||||
IOnlinePlayer online = getOnlineInstance();
|
||||
|
||||
if (online != null)
|
||||
@ -272,7 +270,7 @@ public interface IOffPlayer {
|
||||
/**
|
||||
* Returns the maximum value returned by {@link IOffPlayer#getPermissionRangeValues(String)}.
|
||||
*/
|
||||
public default OptionalLong getPermissionRangeMax(String permissionPrefix) {
|
||||
default OptionalLong getPermissionRangeMax(String permissionPrefix) {
|
||||
IOnlinePlayer online = getOnlineInstance();
|
||||
|
||||
if (online != null)
|
||||
@ -289,14 +287,14 @@ public interface IOffPlayer {
|
||||
* @return <i>true</i> if this player is part of the group,
|
||||
* <i>false</i> otherwise
|
||||
*/
|
||||
public default boolean isInGroup(String group) {
|
||||
default boolean isInGroup(String group) {
|
||||
return getPermissionUser().isInGroup(group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if this player is part of the staff, based on permission groups
|
||||
*/
|
||||
public default boolean isInStaff() {
|
||||
default boolean isInStaff() {
|
||||
return getPermissionUser().inheritsFromGroup("staff-base", true);
|
||||
}
|
||||
|
||||
@ -315,7 +313,7 @@ public interface IOffPlayer {
|
||||
* @param ignored the player that is potentially ignored by this player.
|
||||
* If this parameter is null, this method returns false.
|
||||
*/
|
||||
public default boolean canIgnore(IOffPlayer ignored) {
|
||||
default boolean canIgnore(IOffPlayer ignored) {
|
||||
if (ignored == null)
|
||||
return false;
|
||||
if (equals(ignored))
|
||||
@ -331,7 +329,7 @@ public interface IOffPlayer {
|
||||
* If this parameter is null, this method returns false.
|
||||
* @implNote the default implementation just calls {@link #canIgnore(IOffPlayer) ignorer.canIgnore(this)}.
|
||||
*/
|
||||
public default boolean canBeIgnoredBy(IOffPlayer ignorer) {
|
||||
default boolean canBeIgnoredBy(IOffPlayer ignorer) {
|
||||
if (ignorer == null)
|
||||
return false;
|
||||
return ignorer.canIgnore(this);
|
||||
@ -343,7 +341,7 @@ public interface IOffPlayer {
|
||||
* If this parameter is null, this method returns false.
|
||||
* @return true if this player have to right to ignore the provided player and is actually ignoring him.
|
||||
*/
|
||||
public default boolean isIgnoring(IOffPlayer ignored) {
|
||||
default boolean isIgnoring(IOffPlayer ignored) {
|
||||
if (!canIgnore(ignored))
|
||||
return false;
|
||||
|
||||
@ -363,7 +361,7 @@ public interface IOffPlayer {
|
||||
* @return true if the provided player have to right to ignore this player and is actually ignoring him.
|
||||
* @implNote the default implementation just calls {@link #isIgnoring(IOffPlayer) ignorer.isIgnoring(this)}.
|
||||
*/
|
||||
public default boolean isIgnoredBy(IOffPlayer ignorer) {
|
||||
default boolean isIgnoredBy(IOffPlayer ignorer) {
|
||||
return ignorer.isIgnoring(this);
|
||||
}
|
||||
|
||||
@ -379,7 +377,7 @@ public interface IOffPlayer {
|
||||
* Retrieve the time when the player will be unmuted, or null if the player is not muted.
|
||||
* @return the timestamp in millisecond of when the player will be unmuted
|
||||
*/
|
||||
public default Long getMuteTimeout() {
|
||||
default Long getMuteTimeout() {
|
||||
try {
|
||||
Long muteTimeout = getDbPlayer().get(SQLPlayer.muteTimeout);
|
||||
if (muteTimeout == null || muteTimeout <= System.currentTimeMillis())
|
||||
@ -394,9 +392,8 @@ public interface IOffPlayer {
|
||||
/**
|
||||
* Tells if the player is currently muted, meaning that they cannot communicate
|
||||
* through the chat or private messages.
|
||||
* @return
|
||||
*/
|
||||
public default boolean isMuted() {
|
||||
default boolean isMuted() {
|
||||
return getMuteTimeout() != null;
|
||||
}
|
||||
|
||||
@ -408,7 +405,7 @@ public interface IOffPlayer {
|
||||
* Birthday
|
||||
*/
|
||||
|
||||
public default void setBirthday(int day, int month, Integer year) {
|
||||
default void setBirthday(int day, int month, Integer year) {
|
||||
try {
|
||||
SQLPlayer dbPlayer = getDbPlayer();
|
||||
dbPlayer.setBirthday(day, month, year);
|
||||
@ -418,7 +415,7 @@ public interface IOffPlayer {
|
||||
}
|
||||
}
|
||||
|
||||
public default Calendar getBirthday() {
|
||||
default Calendar getBirthday() {
|
||||
try {
|
||||
return getDbPlayer().getBirthday();
|
||||
} catch (DBException e) {
|
||||
@ -434,25 +431,25 @@ public interface IOffPlayer {
|
||||
* Player config
|
||||
*/
|
||||
|
||||
public default String getConfig(String key) throws DBException {
|
||||
default String getConfig(String key) throws DBException {
|
||||
return SQLPlayerConfig.get(getUniqueId(), key);
|
||||
}
|
||||
|
||||
public default String getConfig(String key, String deflt) throws DBException {
|
||||
default String getConfig(String key, String deflt) throws DBException {
|
||||
return SQLPlayerConfig.get(getUniqueId(), key, deflt);
|
||||
}
|
||||
|
||||
public default void setConfig(String key, String value) throws DBException {
|
||||
default void setConfig(String key, String value) throws DBException {
|
||||
SQLPlayerConfig.set(getUniqueId(), key, value);
|
||||
}
|
||||
|
||||
public default void unsetConfig(String key) throws DBException {
|
||||
default void unsetConfig(String key) throws DBException {
|
||||
SQLPlayerConfig.unset(getUniqueId(), key);
|
||||
}
|
||||
|
||||
public default boolean isWelcomeQuizzDone() {
|
||||
default boolean isWelcomeQuizzDone() {
|
||||
try {
|
||||
return Boolean.valueOf(getConfig("welcome.quizz.done", "false"));
|
||||
return Boolean.parseBoolean(getConfig("welcome.quizz.done", "false"));
|
||||
} catch (DBException e) {
|
||||
Log.severe("Error knowing if player has already done the quizz. Assuming they did for now.", e);
|
||||
return true;
|
||||
|
@ -29,11 +29,11 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* @implSpec The implementation is expected to call the environment API
|
||||
* (Bukkit/Bungee) to get the name of the player.
|
||||
*/
|
||||
public abstract String getName();
|
||||
String getName();
|
||||
|
||||
public abstract String getServerName();
|
||||
String getServerName();
|
||||
|
||||
public abstract String getWorldName();
|
||||
String getWorldName();
|
||||
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* Floodgate related
|
||||
*/
|
||||
|
||||
public default boolean isBedrockClient() {
|
||||
default boolean isBedrockClient() {
|
||||
try {
|
||||
return FloodgateApi.getInstance().isFloodgatePlayer(getUniqueId());
|
||||
} catch (NoClassDefFoundError e) {
|
||||
@ -50,11 +50,11 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
}
|
||||
}
|
||||
|
||||
public default FloodgatePlayer getBedrockClient() {
|
||||
default FloodgatePlayer getBedrockClient() {
|
||||
return FloodgateApi.getInstance().getPlayer(getUniqueId());
|
||||
}
|
||||
|
||||
public default boolean isJavaClient() {
|
||||
default boolean isJavaClient() {
|
||||
return !isBedrockClient();
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* @throws DBException if a database access error occurs
|
||||
*/
|
||||
@Override
|
||||
public default SQLPlayer getDbPlayer() throws DBException {
|
||||
default SQLPlayer getDbPlayer() throws DBException {
|
||||
SQLPlayer p = SQLPlayer.getPlayerFromUUID(getUniqueId());
|
||||
if (p == null)
|
||||
throw new IllegalStateException("The player was not found in the database: " + getUniqueId());
|
||||
@ -93,7 +93,7 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* indirectly call the method {@link IOffPlayer#hasPermission(String)},
|
||||
* or it may result in a {@link StackOverflowError}.
|
||||
*/
|
||||
public abstract boolean hasPermission(String permission);
|
||||
boolean hasPermission(String permission);
|
||||
|
||||
/**
|
||||
* Tells if this online player has the permission resulted from the provided expression.
|
||||
@ -101,7 +101,7 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* indirectly call the method {@link IOffPlayer#hasPermissionExpression(String)},
|
||||
* or it may result in a {@link StackOverflowError}.
|
||||
*/
|
||||
public abstract boolean hasPermissionExpression(String permission);
|
||||
boolean hasPermissionExpression(String permission);
|
||||
|
||||
/**
|
||||
* Lists all the values for a set of permission indicating an integer in a range.
|
||||
@ -116,12 +116,12 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* @param permissionPrefix the permission prefix to search for.
|
||||
* @return a LongStream containing all the values found for the specified permission prefix.
|
||||
*/
|
||||
public abstract LongStream getPermissionRangeValues(String permissionPrefix);
|
||||
LongStream getPermissionRangeValues(String permissionPrefix);
|
||||
|
||||
/**
|
||||
* Returns the maximum value returned by {@link IOffPlayer#getPermissionRangeValues(String)}.
|
||||
*/
|
||||
public abstract OptionalLong getPermissionRangeMax(String permissionPrefix);
|
||||
OptionalLong getPermissionRangeMax(String permissionPrefix);
|
||||
|
||||
|
||||
|
||||
@ -135,9 +135,9 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* Vanish
|
||||
*/
|
||||
|
||||
public abstract boolean isVanished();
|
||||
boolean isVanished();
|
||||
|
||||
public default boolean isVanishedFor(IOffPlayer other) {
|
||||
default boolean isVanishedFor(IOffPlayer other) {
|
||||
if (!isVanished())
|
||||
return false; // can see unvanished
|
||||
|
||||
@ -168,14 +168,14 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* the chat is activated.
|
||||
* @param message the message to display.
|
||||
*/
|
||||
public abstract void sendMessage(Component message);
|
||||
void sendMessage(Component message);
|
||||
|
||||
/**
|
||||
* Display the provided message in the player’s chat, if
|
||||
* the chat is activated.
|
||||
* @param message the message to display.
|
||||
*/
|
||||
public default void sendMessage(ComponentLike message) {
|
||||
default void sendMessage(ComponentLike message) {
|
||||
sendMessage(message.asComponent());
|
||||
}
|
||||
|
||||
@ -184,7 +184,7 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* the chat is activated
|
||||
* @param message the message to display
|
||||
*/
|
||||
public default void sendMessage(Chat message) {
|
||||
default void sendMessage(Chat message) {
|
||||
sendMessage(message.getAdv());
|
||||
}
|
||||
|
||||
@ -198,7 +198,7 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* the sender. This parameter is only there to be transmitted to the client, so client side filtering can
|
||||
* be processed.
|
||||
*/
|
||||
public default void sendMessage(Component message, UUID sender) {
|
||||
default void sendMessage(Component message, UUID sender) {
|
||||
sendMessage(message, () -> sender == null ? Identity.nil() : Identity.identity(sender));
|
||||
}
|
||||
|
||||
@ -212,7 +212,7 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* the sender. This parameter is only there to be transmitted to the client, so client side filtering can
|
||||
* be processed.
|
||||
*/
|
||||
public abstract void sendMessage(Component message, Identified sender);
|
||||
void sendMessage(Component message, Identified sender);
|
||||
|
||||
/**
|
||||
* Display the provided message in the player’s chat, if
|
||||
@ -221,7 +221,7 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* @param sender the player causing the send of this message. Client side filtering may occur.
|
||||
* May be null if we don’t want client filtering, but still consider the message as CHAT message.
|
||||
*/
|
||||
public default void sendMessage(ComponentLike message, UUID sender) {
|
||||
default void sendMessage(ComponentLike message, UUID sender) {
|
||||
sendMessage(message.asComponent(), sender);
|
||||
}
|
||||
|
||||
@ -232,7 +232,7 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* @param sender the player causing the send of this message. Client side filtering may occur.
|
||||
* May be null if we don’t want client filtering, but still consider the message as CHAT message.
|
||||
*/
|
||||
public default void sendMessage(Chat message, UUID sender) {
|
||||
default void sendMessage(Chat message, UUID sender) {
|
||||
sendMessage(message.getAdv(), sender);
|
||||
}
|
||||
|
||||
@ -241,7 +241,7 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* activated, prepended with the server prefix.
|
||||
* @param message the message to display
|
||||
*/
|
||||
public default void sendPrefixedMessage(Component message) {
|
||||
default void sendPrefixedMessage(Component message) {
|
||||
sendMessage(IPlayerManager.prefixedAndColored(message));
|
||||
}
|
||||
|
||||
@ -250,7 +250,7 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* activated, prepended with the server prefix.
|
||||
* @param message the message to display
|
||||
*/
|
||||
public default void sendPrefixedMessage(Chat message) {
|
||||
default void sendPrefixedMessage(Chat message) {
|
||||
sendPrefixedMessage(message.getAdv());
|
||||
}
|
||||
|
||||
@ -262,7 +262,7 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* @param stay Stay time in tick
|
||||
* @param fadeOut Fade out time in tick
|
||||
*/
|
||||
public abstract void sendTitle(Component title, Component subtitle, int fadeIn, int stay, int fadeOut);
|
||||
void sendTitle(Component title, Component subtitle, int fadeIn, int stay, int fadeOut);
|
||||
|
||||
/**
|
||||
* Display a title in the middle of the screen.
|
||||
@ -272,7 +272,7 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* @param stay Stay time in tick
|
||||
* @param fadeOut Fade out time in tick
|
||||
*/
|
||||
public default void sendTitle(Chat title, Chat subtitle, int fadeIn, int stay, int fadeOut) {
|
||||
default void sendTitle(Chat title, Chat subtitle, int fadeIn, int stay, int fadeOut) {
|
||||
sendTitle(title.getAdv(), subtitle.getAdv(), fadeIn, stay, fadeOut);
|
||||
}
|
||||
|
||||
@ -282,7 +282,7 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* line break.
|
||||
* @param brand the server brand to send to the client.
|
||||
*/
|
||||
public abstract void sendServerBrand(String brand);
|
||||
void sendServerBrand(String brand);
|
||||
|
||||
|
||||
|
||||
@ -297,17 +297,17 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
|
||||
|
||||
|
||||
public abstract ClientOptions getClientOptions();
|
||||
ClientOptions getClientOptions();
|
||||
|
||||
public interface ClientOptions {
|
||||
interface ClientOptions {
|
||||
|
||||
public Locale getLocale();
|
||||
Locale getLocale();
|
||||
|
||||
public int getViewDistance();
|
||||
int getViewDistance();
|
||||
|
||||
|
||||
|
||||
public boolean hasChatColorEnabled();
|
||||
boolean hasChatColorEnabled();
|
||||
|
||||
/**
|
||||
* Tells if the client is configured to completely hide the chat to the
|
||||
@ -316,7 +316,7 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* @implSpec if the value is unknown, it is assumed that the chat is
|
||||
* fully visible.
|
||||
*/
|
||||
public boolean isChatHidden();
|
||||
boolean isChatHidden();
|
||||
|
||||
/**
|
||||
* Tells if the client is configured to display the chat normally.
|
||||
@ -326,7 +326,7 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* @implSpec if the value is unknown, it is assumed that the chat is
|
||||
* fully visible.
|
||||
*/
|
||||
public boolean isChatFullyVisible();
|
||||
boolean isChatFullyVisible();
|
||||
|
||||
/**
|
||||
* Tells if the client is configured to only display system messages
|
||||
@ -336,7 +336,7 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* @implSpec if the value is unknown, it is assumed that the chat is
|
||||
* fully visible.
|
||||
*/
|
||||
public boolean isChatOnlyDisplayingSystemMessages();
|
||||
boolean isChatOnlyDisplayingSystemMessages();
|
||||
|
||||
|
||||
|
||||
@ -345,44 +345,44 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* @implSpec if the value is unknown, it is assumed that the main hand
|
||||
* is on the right.
|
||||
*/
|
||||
public boolean isLeftHanded();
|
||||
boolean isLeftHanded();
|
||||
|
||||
/**
|
||||
* Tells if the client has configured the main hand on the right.
|
||||
* @implSpec if the value is unknown, it is assumed that the main hand
|
||||
* is on the right.
|
||||
*/
|
||||
public boolean isRightHanded();
|
||||
boolean isRightHanded();
|
||||
|
||||
|
||||
/**
|
||||
* Tells if the client has enabled the filtering of texts on sign and book titles.
|
||||
* Always false as of MC 1.18.
|
||||
*/
|
||||
public boolean isTextFilteringEnabled();
|
||||
boolean isTextFilteringEnabled();
|
||||
|
||||
|
||||
/**
|
||||
* Tells if the client allows the server to list their player name in the
|
||||
* multiplayer menu.
|
||||
*/
|
||||
public boolean allowsServerListing();
|
||||
boolean allowsServerListing();
|
||||
|
||||
|
||||
|
||||
public boolean hasSkinCapeEnabled();
|
||||
boolean hasSkinCapeEnabled();
|
||||
|
||||
public boolean hasSkinJacketEnabled();
|
||||
boolean hasSkinJacketEnabled();
|
||||
|
||||
public boolean hasSkinLeftSleeveEnabled();
|
||||
boolean hasSkinLeftSleeveEnabled();
|
||||
|
||||
public boolean hasSkinRightSleeveEnabled();
|
||||
boolean hasSkinRightSleeveEnabled();
|
||||
|
||||
public boolean hasSkinLeftPantsEnabled();
|
||||
boolean hasSkinLeftPantsEnabled();
|
||||
|
||||
public boolean hasSkinRightPantsEnabled();
|
||||
boolean hasSkinRightPantsEnabled();
|
||||
|
||||
public boolean hasSkinHatsEnabled();
|
||||
boolean hasSkinHatsEnabled();
|
||||
|
||||
}
|
||||
|
||||
@ -393,9 +393,8 @@ public interface IOnlinePlayer extends IOffPlayer {
|
||||
* Chat messages represent public communication between players. By default,
|
||||
* it only include actual chat message. This method may be used in commands
|
||||
* like /me, /afk or the login/logout broadcasted messages
|
||||
* @return
|
||||
*/
|
||||
public default boolean canChat() {
|
||||
default boolean canChat() {
|
||||
return getClientOptions().isChatFullyVisible();
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ import fr.pandacube.lib.core.db.DB;
|
||||
import fr.pandacube.lib.core.db.DBInitTableException;
|
||||
import fr.pandacube.lib.core.util.Log;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.ComponentLike;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
|
||||
public abstract class IPlayerManager<OP extends IOnlinePlayer, OF extends IOffPlayer> {
|
||||
@ -45,11 +46,11 @@ public abstract class IPlayerManager<OP extends IOnlinePlayer, OF extends IOffPl
|
||||
|
||||
|
||||
|
||||
private Map<UUID, OP> onlinePlayers = Collections.synchronizedMap(new HashMap<>());
|
||||
private final Map<UUID, OP> onlinePlayers = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
private LoadingCache<UUID, OF> offlinePlayers = CacheBuilder.newBuilder()
|
||||
private final LoadingCache<UUID, OF> offlinePlayers = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(10, TimeUnit.MINUTES)
|
||||
.build(CacheLoader.from(pId -> newOffPlayerInstance(pId)));
|
||||
.build(CacheLoader.from(this::newOffPlayerInstance));
|
||||
|
||||
|
||||
public IPlayerManager() throws DBInitTableException {
|
||||
@ -90,7 +91,7 @@ public abstract class IPlayerManager<OP extends IOnlinePlayer, OF extends IOffPl
|
||||
|
||||
public List<OP> getAllNotVanished() {
|
||||
List<OP> players = getAll();
|
||||
players.removeIf(op -> op.isVanished());
|
||||
players.removeIf(IOnlinePlayer::isVanished);
|
||||
return players;
|
||||
}
|
||||
|
||||
@ -183,8 +184,8 @@ public abstract class IPlayerManager<OP extends IOnlinePlayer, OF extends IOffPl
|
||||
/*
|
||||
* Message broadcasting
|
||||
*/
|
||||
|
||||
// BaseComponent/Chat/String message
|
||||
|
||||
// ComponentLike message
|
||||
// boolean prefix
|
||||
// boolean console = (permission == null)
|
||||
// String permission = null
|
||||
@ -205,13 +206,13 @@ public abstract class IPlayerManager<OP extends IOnlinePlayer, OF extends IOffPl
|
||||
*
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(Component message, boolean prefix, boolean console, String permission, UUID sourcePlayer) {
|
||||
public static void broadcast(ComponentLike message, boolean prefix, boolean console, String permission, UUID sourcePlayer) {
|
||||
Objects.requireNonNull(message, "message cannot be null");
|
||||
|
||||
IOffPlayer oSourcePlayer = getInstance().getOffline(sourcePlayer);
|
||||
|
||||
if (prefix)
|
||||
message = prefixedAndColored(message);
|
||||
message = prefixedAndColored(message.asComponent());
|
||||
|
||||
for (IOnlinePlayer op : getInstance().getAll()) {
|
||||
if (permission != null && !(op.hasPermission(permission))) continue;
|
||||
@ -231,14 +232,14 @@ public abstract class IPlayerManager<OP extends IOnlinePlayer, OF extends IOffPl
|
||||
}
|
||||
|
||||
if (console)
|
||||
getInstance().sendMessageToConsole(message);
|
||||
getInstance().sendMessageToConsole(message.asComponent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast a message to some or all players, and eventually to the console.
|
||||
* <p>
|
||||
* This method assumes this message is not caused by a specific player. To specify the source player, use
|
||||
* {@link #broadcast(BaseComponent, boolean, boolean, String, UUID)}.
|
||||
* {@link #broadcast(ComponentLike, boolean, boolean, String, UUID)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
@ -246,7 +247,7 @@ public abstract class IPlayerManager<OP extends IOnlinePlayer, OF extends IOffPl
|
||||
* @param permission if not null, the message is only sent to player with this permission.
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(Component message, boolean prefix, boolean console, String permission) {
|
||||
public static void broadcast(ComponentLike message, boolean prefix, boolean console, String permission) {
|
||||
broadcast(message, prefix, console, permission, null);
|
||||
}
|
||||
|
||||
@ -254,7 +255,7 @@ public abstract class IPlayerManager<OP extends IOnlinePlayer, OF extends IOffPl
|
||||
* Broadcast a message to all players, and eventually to the console.
|
||||
* <p>
|
||||
* This method does not restrict the reception of the message to a specific permission. If you
|
||||
* want to specify a permission, use {@link #broadcast(BaseComponent, boolean, boolean, String, UUID)}.
|
||||
* want to specify a permission, use {@link #broadcast(ComponentLike, boolean, boolean, String, UUID)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
@ -265,7 +266,7 @@ public abstract class IPlayerManager<OP extends IOnlinePlayer, OF extends IOffPl
|
||||
* to players ignoring the provided player.
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(Component message, boolean prefix, boolean console, UUID sourcePlayer) {
|
||||
public static void broadcast(ComponentLike message, boolean prefix, boolean console, UUID sourcePlayer) {
|
||||
broadcast(message, prefix, console, null, sourcePlayer);
|
||||
}
|
||||
|
||||
@ -273,36 +274,17 @@ public abstract class IPlayerManager<OP extends IOnlinePlayer, OF extends IOffPl
|
||||
* Broadcast a message to all players, and eventually to the console.
|
||||
* <p>
|
||||
* This method does not restrict the reception of the message to a specific permission. If you
|
||||
* want to specify a permission, use {@link #broadcast(BaseComponent, boolean, boolean, String)}.
|
||||
* want to specify a permission, use {@link #broadcast(ComponentLike, boolean, boolean, String)}.
|
||||
* <p>
|
||||
* This method assumes this message is not caused by a specific player. To specify the source player, use
|
||||
* {@link #broadcast(BaseComponent, boolean, boolean, UUID)}.
|
||||
* {@link #broadcast(ComponentLike, boolean, boolean, UUID)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @param console if the message must be displayed in the console.
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
@Deprecated
|
||||
public static void broadcast(BaseComponent message, boolean prefix, boolean console) {
|
||||
broadcast(Chat.toAdventure(message), prefix, console, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast a message to all players, and eventually to the console.
|
||||
* <p>
|
||||
* This method does not restrict the reception of the message to a specific permission. If you
|
||||
* want to specify a permission, use {@link #broadcast(BaseComponent, boolean, boolean, String)}.
|
||||
* <p>
|
||||
* This method assumes this message is not caused by a specific player. To specify the source player, use
|
||||
* {@link #broadcast(BaseComponent, boolean, boolean, UUID)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @param console if the message must be displayed in the console.
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(Component message, boolean prefix, boolean console) {
|
||||
public static void broadcast(ComponentLike message, boolean prefix, boolean console) {
|
||||
broadcast(message, prefix, console, null, null);
|
||||
}
|
||||
|
||||
@ -310,11 +292,11 @@ public abstract class IPlayerManager<OP extends IOnlinePlayer, OF extends IOffPl
|
||||
* Broadcast a message to some or all players, and eventually to the console.
|
||||
* <p>
|
||||
* This method assumes this message is not caused by a specific player. To specify the source player, use
|
||||
* {@link #broadcast(BaseComponent, boolean, String, UUID)}.
|
||||
* {@link #broadcast(ComponentLike, boolean, String, UUID)}.
|
||||
* <p>
|
||||
* This method decides to send the message to the console depending on whether {@code permission}
|
||||
* is null (will send to console) or not (will not send to console). To specify this behaviour, use
|
||||
* {@link #broadcast(BaseComponent, boolean, boolean, String)}.
|
||||
* {@link #broadcast(ComponentLike, boolean, boolean, String)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
@ -322,7 +304,7 @@ public abstract class IPlayerManager<OP extends IOnlinePlayer, OF extends IOffPl
|
||||
* If null, the message will be sent to all players and to console.
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(Component message, boolean prefix, String permission) {
|
||||
public static void broadcast(ComponentLike message, boolean prefix, String permission) {
|
||||
broadcast(message, prefix, (permission == null), permission, null);
|
||||
}
|
||||
|
||||
@ -330,10 +312,10 @@ public abstract class IPlayerManager<OP extends IOnlinePlayer, OF extends IOffPl
|
||||
* Broadcast a message to all players, and to the console.
|
||||
* <p>
|
||||
* This method does not restrict the reception of the message to a specific permission. If you
|
||||
* want to specify a permission, use {@link #broadcast(BaseComponent, boolean, String, UUID)}.
|
||||
* want to specify a permission, use {@link #broadcast(ComponentLike, boolean, String, UUID)}.
|
||||
* <p>
|
||||
* This method sends the message to the console. To change this behaviour, use
|
||||
* {@link #broadcast(BaseComponent, boolean, boolean, UUID)}.
|
||||
* {@link #broadcast(ComponentLike, boolean, boolean, UUID)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
@ -343,162 +325,46 @@ public abstract class IPlayerManager<OP extends IOnlinePlayer, OF extends IOffPl
|
||||
* to players ignoring the provided player.
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(Component message, boolean prefix, UUID sourcePlayer) {
|
||||
public static void broadcast(ComponentLike message, boolean prefix, UUID sourcePlayer) {
|
||||
broadcast(message, prefix, true, null, sourcePlayer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast a message to all players, and to the console.
|
||||
* <p>
|
||||
* This method assumes this message is not caused by a specific player. To specify the source player, use
|
||||
* {@link #broadcast(BaseComponent, boolean, UUID)}.
|
||||
* <p>
|
||||
* This method does not restrict the reception of the message to a specific permission. If you
|
||||
* want to specify a permission, use {@link #broadcast(BaseComponent, boolean, String)}.
|
||||
* <p>
|
||||
* This method sends the message to the console. To change this behaviour, use
|
||||
* {@link #broadcast(BaseComponent, boolean, boolean)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(Component message, boolean prefix) {
|
||||
broadcast(message, prefix, true, null, null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Broadcast a message to some or all players, and eventually to the console.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @param console if the message must be displayed in the console.
|
||||
* @param permission if not null, the message is only sent to player with this permission.
|
||||
* @param sourcePlayer specifiy the eventual player that is the source of the message.
|
||||
* If null, the message will be sent as a SYSTEM chat message.
|
||||
* If not null, the message will be sent as a CHAT message, and will not be sent
|
||||
* to players ignoring the provided player.
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(Chat message, boolean prefix, boolean console, String permission, UUID sourcePlayer) {
|
||||
Objects.requireNonNull(message, "message cannot be null");
|
||||
broadcast(message.getAdv(), prefix, console, permission, sourcePlayer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast a message to some or all players, and eventually to the console.
|
||||
* <p>
|
||||
* This method assumes this message is not caused by a specific player. To specify the source player, use
|
||||
* {@link #broadcast(BaseComponent, boolean, boolean, String, UUID)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @param console if the message must be displayed in the console.
|
||||
* @param permission if not null, the message is only sent to player with this permission.
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(Chat message, boolean prefix, boolean console, String permission) {
|
||||
broadcast(message, prefix, console, permission, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast a message to all players, and eventually to the console.
|
||||
* <p>
|
||||
* This method does not restrict the reception of the message to a specific permission. If you
|
||||
* want to specify a permission, use {@link #broadcast(BaseComponent, boolean, boolean, String, UUID)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @param console if the message must be displayed in the console.
|
||||
* @param sourcePlayer specifiy the eventual player that is the source of the message.
|
||||
* If null, the message will be sent as a SYSTEM chat message.
|
||||
* If not null, the message will be sent as a CHAT message, and will not be sent
|
||||
* to players ignoring the provided player.
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(Chat message, boolean prefix, boolean console, UUID sourcePlayer) {
|
||||
broadcast(message, prefix, console, null, sourcePlayer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast a message to all players, and eventually to the console.
|
||||
* <p>
|
||||
* This method does not restrict the reception of the message to a specific permission. If you
|
||||
* want to specify a permission, use {@link #broadcast(BaseComponent, boolean, boolean, String)}.
|
||||
* <p>
|
||||
* This method assumes this message is not caused by a specific player. To specify the source player, use
|
||||
* {@link #broadcast(BaseComponent, boolean, boolean, UUID)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @param console if the message must be displayed in the console.
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(Chat message, boolean prefix, boolean console) {
|
||||
broadcast(message, prefix, console, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast a message to some or all players, and eventually to the console.
|
||||
* <p>
|
||||
* This method assumes this message is not caused by a specific player. To specify the source player, use
|
||||
* {@link #broadcast(BaseComponent, boolean, String, UUID)}.
|
||||
* <p>
|
||||
* This method decides to send the message to the console depending on whether {@code permission}
|
||||
* is null (will send to console) or not (will not send to console). To specify this behaviour, use
|
||||
* {@link #broadcast(BaseComponent, boolean, boolean, String)}.
|
||||
* {@link #broadcast(ComponentLike, boolean, boolean, String, UUID)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @param permission if not null, the message is only sent to player with this permission (but not to console).
|
||||
* If null, the message will be sent to all players and to console.
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(Chat message, boolean prefix, String permission) {
|
||||
broadcast(message, prefix, (permission == null), permission, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast a message to all players, and to the console.
|
||||
* <p>
|
||||
* This method does not restrict the reception of the message to a specific permission. If you
|
||||
* want to specify a permission, use {@link #broadcast(BaseComponent, boolean, String, UUID)}.
|
||||
* <p>
|
||||
* This method sends the message to the console. To change this behaviour, use
|
||||
* {@link #broadcast(BaseComponent, boolean, boolean, UUID)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @param sourcePlayer specifiy the eventual player that is the source of the message.
|
||||
* If null, the message will be sent as a SYSTEM chat message.
|
||||
* If not null, the message will be sent as a CHAT message, and will not be sent
|
||||
* to players ignoring the provided player.
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(Chat message, boolean prefix, UUID sourcePlayer) {
|
||||
broadcast(message, prefix, true, null, sourcePlayer);
|
||||
public static void broadcast(ComponentLike message, boolean prefix, String permission, UUID sourcePlayer) {
|
||||
broadcast(message, prefix, true, permission, sourcePlayer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast a message to all players, and to the console.
|
||||
* <p>
|
||||
* This method assumes this message is not caused by a specific player. To specify the source player, use
|
||||
* {@link #broadcast(BaseComponent, boolean, UUID)}.
|
||||
* {@link #broadcast(ComponentLike, boolean, UUID)}.
|
||||
* <p>
|
||||
* This method does not restrict the reception of the message to a specific permission. If you
|
||||
* want to specify a permission, use {@link #broadcast(BaseComponent, boolean, String)}.
|
||||
* want to specify a permission, use {@link #broadcast(ComponentLike, boolean, String)}.
|
||||
* <p>
|
||||
* This method sends the message to the console. To change this behaviour, use
|
||||
* {@link #broadcast(BaseComponent, boolean, boolean)}.
|
||||
* {@link #broadcast(ComponentLike, boolean, boolean)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(Chat message, boolean prefix) {
|
||||
public static void broadcast(ComponentLike message, boolean prefix) {
|
||||
broadcast(message, prefix, true, null, null);
|
||||
}
|
||||
|
||||
|
@ -32,13 +32,13 @@ import fr.pandacube.lib.core.util.Log;
|
||||
*/
|
||||
public class PlayerFinder {
|
||||
|
||||
private static Cache<UUID, String> playerLastKnownName = CacheBuilder.newBuilder()
|
||||
private static final Cache<UUID, String> playerLastKnownName = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(10, TimeUnit.MINUTES)
|
||||
.maximumSize(1000)
|
||||
.build();
|
||||
|
||||
record PlayerIdCacheKey(String pName, boolean old) { }
|
||||
private static Cache<PlayerIdCacheKey, UUID> playerId = CacheBuilder.newBuilder()
|
||||
private static final Cache<PlayerIdCacheKey, UUID> playerId = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(2, TimeUnit.MINUTES)
|
||||
.maximumSize(1000)
|
||||
.build();
|
||||
@ -142,7 +142,7 @@ public class PlayerFinder {
|
||||
|
||||
public static boolean isValidPlayerName(String name) {
|
||||
if (name == null) return false;
|
||||
return name.matches("[0-9a-zA-Z_.]{2,20}");
|
||||
return name.matches("[\\da-zA-Z_.]{2,20}");
|
||||
}
|
||||
|
||||
public static SQLPlayer getDBPlayer(UUID id) throws DBException {
|
||||
@ -167,7 +167,7 @@ public class PlayerFinder {
|
||||
};
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static final <S> SuggestionsSupplier<S> TAB_PLAYER_OFFLINE() {
|
||||
public static <S> SuggestionsSupplier<S> TAB_PLAYER_OFFLINE() {
|
||||
return (SuggestionsSupplier<S>) TAB_PLAYER_OFFLINE;
|
||||
}
|
||||
|
||||
@ -188,12 +188,12 @@ public class PlayerFinder {
|
||||
public static int OLD_NICK_MULTIPLIER = 2;
|
||||
|
||||
|
||||
private static List<List<Character>> CONFUSABLE_CHARACTERS = ImmutableList.of(
|
||||
private static final List<List<Character>> CONFUSABLE_CHARACTERS = ImmutableList.of(
|
||||
ImmutableList.of('o', '0'),
|
||||
ImmutableList.of('i', '1', 'l'),
|
||||
ImmutableList.of('b', '8')
|
||||
);
|
||||
private static ToIntBiFunction<Character, Character> CHAR_DISTANCE = (c1, c2) -> {
|
||||
private static final ToIntBiFunction<Character, Character> CHAR_DISTANCE = (c1, c2) -> {
|
||||
if (c1.equals(c2))
|
||||
return 0;
|
||||
for (List<Character> charTab : CONFUSABLE_CHARACTERS) {
|
||||
@ -205,7 +205,7 @@ public class PlayerFinder {
|
||||
|
||||
record NamesCacheResult(String name, String lowercaseName, UUID id) { } // Java 16
|
||||
|
||||
private static LoadingCache<String, List<NamesCacheResult>> namesCache = CacheBuilder.newBuilder()
|
||||
private static final LoadingCache<String, List<NamesCacheResult>> namesCache = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(2, TimeUnit.MINUTES)
|
||||
.maximumSize(1)
|
||||
.build(CacheLoader.from((String k) -> {
|
||||
@ -221,7 +221,7 @@ public class PlayerFinder {
|
||||
return cached;
|
||||
}));
|
||||
|
||||
private static LoadingCache<String, SearchResponse> searchCache = CacheBuilder.newBuilder()
|
||||
private static final LoadingCache<String, SearchResponse> searchCache = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(2, TimeUnit.MINUTES)
|
||||
.maximumSize(100)
|
||||
.build(CacheLoader.from((String query) -> {
|
||||
|
@ -46,7 +46,6 @@ public class SQLPlayerIgnore extends SQLElement<SQLPlayerIgnore> {
|
||||
}
|
||||
if (el != null && !newIgnoreState) {
|
||||
el.delete();
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,9 @@
|
||||
package fr.pandacube.lib.core.search;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import fr.pandacube.lib.core.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@ -7,15 +11,9 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
||||
import fr.pandacube.lib.core.util.Log;
|
||||
|
||||
/**
|
||||
* Utility class to manage searching among a set of
|
||||
* SearchResult instances, using case insensitive
|
||||
@ -23,15 +21,15 @@ import fr.pandacube.lib.core.util.Log;
|
||||
*/
|
||||
public class SearchEngine<R extends SearchResult> {
|
||||
|
||||
Map<String, Set<R>> searchKeywordsResultMap = new HashMap<>();
|
||||
Map<R, Set<String>> resultsSearchKeywordsMap = new HashMap<>();
|
||||
private final Map<String, Set<R>> searchKeywordsResultMap = new HashMap<>();
|
||||
private final Map<R, Set<String>> resultsSearchKeywordsMap = new HashMap<>();
|
||||
|
||||
Map<String, Set<R>> suggestionsKeywordsResultMap = new HashMap<>();
|
||||
Map<R, Set<String>> resultsSuggestionsKeywordsMap = new HashMap<>();
|
||||
private final Map<String, Set<R>> suggestionsKeywordsResultMap = new HashMap<>();
|
||||
private final Map<R, Set<String>> resultsSuggestionsKeywordsMap = new HashMap<>();
|
||||
|
||||
private final Set<R> resultSet = new HashSet<>();
|
||||
|
||||
Set<R> resultSet = new HashSet<>();
|
||||
|
||||
private Cache<Set<String>, List<String>> suggestionsCache;
|
||||
private final Cache<Set<String>, List<String>> suggestionsCache;
|
||||
|
||||
public SearchEngine(int suggestionsCacheSize) {
|
||||
suggestionsCache = CacheBuilder.newBuilder()
|
||||
@ -50,7 +48,7 @@ public class SearchEngine<R extends SearchResult> {
|
||||
searchKw = result.getSearchKeywords();
|
||||
Objects.requireNonNull(searchKw, "SearchResult instance must provide a non null set of search keywords");
|
||||
searchKw = searchKw.stream()
|
||||
.filter(e -> e != null)
|
||||
.filter(Objects::nonNull)
|
||||
.map(String::toLowerCase)
|
||||
.collect(Collectors.toSet());
|
||||
} catch (Exception e) {
|
||||
@ -63,7 +61,7 @@ public class SearchEngine<R extends SearchResult> {
|
||||
suggestsKw = result.getSuggestionKeywords();
|
||||
Objects.requireNonNull(suggestsKw, "SearchResult instance must provide a non null set of suggestions keywords");
|
||||
suggestsKw = new HashSet<>(suggestsKw);
|
||||
suggestsKw.removeIf(e -> e == null);
|
||||
suggestsKw.removeIf(Objects::isNull);
|
||||
} catch (Exception e) {
|
||||
Log.severe(e);
|
||||
return;
|
||||
@ -123,7 +121,7 @@ public class SearchEngine<R extends SearchResult> {
|
||||
|
||||
public synchronized Set<R> search(Set<String> searchTerms) {
|
||||
if (searchTerms == null)
|
||||
searchTerms = new HashSet<String>();
|
||||
searchTerms = new HashSet<>();
|
||||
|
||||
Set<R> retainedResults = new HashSet<>(resultSet);
|
||||
for (String term : searchTerms) {
|
||||
@ -157,7 +155,7 @@ public class SearchEngine<R extends SearchResult> {
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
try {
|
||||
return suggestionsCache.get(lowerCaseSearchTerm, (Callable<List<String>>) () -> {
|
||||
return suggestionsCache.get(lowerCaseSearchTerm, () -> {
|
||||
Set<R> prevResults = search(lowerCaseSearchTerm);
|
||||
|
||||
Set<String> suggestions = new HashSet<>();
|
||||
|
@ -4,8 +4,8 @@ import java.util.Set;
|
||||
|
||||
public interface SearchResult {
|
||||
|
||||
public Set<String> getSearchKeywords();
|
||||
Set<String> getSearchKeywords();
|
||||
|
||||
public Set<String> getSuggestionKeywords();
|
||||
Set<String> getSuggestionKeywords();
|
||||
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ public class AmountPerTimeLimiter {
|
||||
|
||||
|
||||
|
||||
private class Entry {
|
||||
private static class Entry {
|
||||
private final long time;
|
||||
private double amount;
|
||||
public Entry(long t, double a) {
|
||||
|
@ -11,8 +11,8 @@ import java.util.function.Supplier;
|
||||
|
||||
public class BiMap<K, V> implements Iterable<Entry<K, V>> {
|
||||
|
||||
protected Map<K, V> map;
|
||||
protected Map<V, K> inversedMap;
|
||||
protected final Map<K, V> map;
|
||||
protected final Map<V, K> inversedMap;
|
||||
|
||||
private BiMap<V, K> reversedView = null;
|
||||
|
||||
|
@ -299,7 +299,7 @@ public class CronExpression {
|
||||
this.hourField = new SimpleField(CronFieldType.HOUR, parts[ix++]);
|
||||
this.dayOfMonthField = new DayOfMonthField(parts[ix++]);
|
||||
this.monthField = new SimpleField(CronFieldType.MONTH, parts[ix++]);
|
||||
this.dayOfWeekField = new DayOfWeekField(parts[ix++]);
|
||||
this.dayOfWeekField = new DayOfWeekField(parts[ix]);
|
||||
}
|
||||
|
||||
public static CronExpression create(final String expr) {
|
||||
@ -336,7 +336,7 @@ public class CronExpression {
|
||||
if (!monthField.nextMatch(nextDateTime)) {
|
||||
continue;
|
||||
}
|
||||
if (!findDay(nextDateTime, dateTimeBarrier)) {
|
||||
if (!findDay(nextDateTime)) {
|
||||
continue;
|
||||
}
|
||||
if (!hourField.nextMatch(nextDateTime)) {
|
||||
@ -361,11 +361,10 @@ public class CronExpression {
|
||||
* to handle them together in the same method.
|
||||
*
|
||||
* @param dateTime Initial {@link ZonedDateTime} instance to start from
|
||||
* @param dateTimeBarrier At which point stop searching for next execution time
|
||||
* @return {@code true} if a match was found for this field or {@code false} if the field overflowed
|
||||
* @see {@link SimpleField#nextMatch(ZonedDateTime[])}
|
||||
* @see SimpleField#nextMatch(ZonedDateTime[])
|
||||
*/
|
||||
private boolean findDay(ZonedDateTime[] dateTime, ZonedDateTime dateTimeBarrier) {
|
||||
private boolean findDay(ZonedDateTime[] dateTime) {
|
||||
int month = dateTime[0].getMonthValue();
|
||||
|
||||
while (!(dayOfMonthField.matches(dateTime[0].toLocalDate())
|
||||
@ -400,16 +399,19 @@ public class CronExpression {
|
||||
}
|
||||
|
||||
abstract static class BasicField {
|
||||
@SuppressWarnings({"RegExpRepeatedSpace", "RegExpSimplifiable", "RegExpSingleCharAlternation", "RegExpRedundantEscape"})
|
||||
private static final Pattern CRON_FIELD_REGEXP = Pattern
|
||||
.compile("(?: # start of group 1\n"
|
||||
+ " (?:(?<all>\\*)|(?<ignore>\\?)|(?<last>L)) # global flag (L, ?, *)\n"
|
||||
+ " | (?<start>[0-9]{1,2}|[a-z]{3,3}) # or start number or symbol\n"
|
||||
+ " (?: # start of group 2\n"
|
||||
+ " (?<mod>L|W) # modifier (L,W)\n"
|
||||
+ " | -(?<end>[0-9]{1,2}|[a-z]{3,3}) # or end nummer or symbol (in range)\n"
|
||||
+ " )? # end of group 2\n"
|
||||
+ ") # end of group 1\n"
|
||||
+ "(?:(?<incmod>/|\\#)(?<inc>[0-9]{1,7}))? # increment and increment modifier (/ or \\#)\n",
|
||||
.compile("""
|
||||
(?: # start of group 1
|
||||
(?:(?<all>\\*)|(?<ignore>\\?)|(?<last>L)) # global flag (L, ?, *)
|
||||
| (?<start>[0-9]{1,2}|[a-z]{3,3}) # or start number or symbol
|
||||
(?: # start of group 2
|
||||
(?<mod>L|W) # modifier (L,W)
|
||||
| -(?<end>[0-9]{1,2}|[a-z]{3,3}) # or end nummer or symbol (in range)
|
||||
)? # end of group 2
|
||||
) # end of group 1
|
||||
(?:(?<incmod>/|\\#)(?<inc>[0-9]{1,7}))? # increment and increment modifier (/ or \\#)
|
||||
""",
|
||||
Pattern.CASE_INSENSITIVE | Pattern.COMMENTS);
|
||||
|
||||
final CronFieldType fieldType;
|
||||
@ -500,10 +502,7 @@ public class CronExpression {
|
||||
}
|
||||
|
||||
protected boolean matches(int val, FieldPart part) {
|
||||
if (val >= part.from && val <= part.to && (val - part.from) % part.increment == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return val >= part.from && val <= part.to && (val - part.from) % part.increment == 0;
|
||||
}
|
||||
|
||||
protected int nextMatch(int val, FieldPart part) {
|
||||
@ -529,17 +528,6 @@ public class CronExpression {
|
||||
super(fieldType, fieldExpr);
|
||||
}
|
||||
|
||||
public boolean matches(int val) {
|
||||
if (val >= fieldType.from && val <= fieldType.to) {
|
||||
for (FieldPart part : parts) {
|
||||
if (matches(val, part)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the next match for this field. If a match cannot be found force an overflow and increase the next
|
||||
* greatest field.
|
||||
@ -602,9 +590,9 @@ public class CronExpression {
|
||||
|
||||
@Override
|
||||
protected void validatePart(FieldPart part) {
|
||||
if (part.modifier != null && Arrays.asList("L", "?").indexOf(part.modifier) == -1) {
|
||||
if (part.modifier != null && !Arrays.asList("L", "?").contains(part.modifier)) {
|
||||
throw new IllegalArgumentException(String.format("Invalid modifier [%s]", part.modifier));
|
||||
} else if (part.incrementModifier != null && Arrays.asList("/", "#").indexOf(part.incrementModifier) == -1) {
|
||||
} else if (part.incrementModifier != null && !Arrays.asList("/", "#").contains(part.incrementModifier)) {
|
||||
throw new IllegalArgumentException(String.format("Invalid increment modifier [%s]", part.incrementModifier));
|
||||
}
|
||||
}
|
||||
@ -639,7 +627,7 @@ public class CronExpression {
|
||||
|
||||
@Override
|
||||
protected void validatePart(FieldPart part) {
|
||||
if (part.modifier != null && Arrays.asList("L", "W", "?").indexOf(part.modifier) == -1) {
|
||||
if (part.modifier != null && !Arrays.asList("L", "W", "?").contains(part.modifier)) {
|
||||
throw new IllegalArgumentException(String.format("Invalid modifier [%s]", part.modifier));
|
||||
} else if (part.incrementModifier != null && !"/".equals(part.incrementModifier)) {
|
||||
throw new IllegalArgumentException(String.format("Invalid increment modifier [%s]", part.incrementModifier));
|
||||
|
@ -19,8 +19,8 @@ public class DistanceUtil {
|
||||
|
||||
String precisionFormat = "##0";
|
||||
if (precision > 0) precisionFormat += ".";
|
||||
for (int i = 0; i < precision; i++)
|
||||
precisionFormat += "0";
|
||||
precisionFormat += "0".repeat(precision);
|
||||
|
||||
DecimalFormat df = new DecimalFormat(precisionFormat);
|
||||
|
||||
double dist = meterDist / choosenUnit.multiplicator;
|
||||
@ -33,12 +33,17 @@ public class DistanceUtil {
|
||||
}
|
||||
|
||||
public enum DistanceUnit {
|
||||
NM(0.000000001, "nm"), µM(0.000001, "µm"), MM(0.001, "mm"), CM(0.01, "cm"), M(1, "m"), KM(1000, "km");
|
||||
NM(0.000000001, "nm"),
|
||||
UM(0.000001, "µm"),
|
||||
MM(0.001, "mm"),
|
||||
CM(0.01, "cm"),
|
||||
M(1, "m"),
|
||||
KM(1000, "km");
|
||||
|
||||
private final double multiplicator;
|
||||
private final String unitStr;
|
||||
|
||||
private DistanceUnit(double mult, String s) {
|
||||
DistanceUnit(double mult, String s) {
|
||||
multiplicator = mult;
|
||||
unitStr = s;
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
package fr.pandacube.lib.core.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class EnumUtil {
|
||||
|
||||
/**
|
||||
@ -10,17 +13,9 @@ public class EnumUtil {
|
||||
* @return a string representation of the enum class.
|
||||
*/
|
||||
public static <T extends Enum<T>> String enumList(Class<T> enumType, String separator) {
|
||||
T[] elements = enumType.getEnumConstants();
|
||||
|
||||
String out = "";
|
||||
boolean first = true;
|
||||
for (T el : elements) {
|
||||
if (!first) out += separator;
|
||||
first = false;
|
||||
out += el.name();
|
||||
|
||||
}
|
||||
return out;
|
||||
return Arrays.stream(enumType.getEnumConstants())
|
||||
.map(Enum::name)
|
||||
.collect(Collectors.joining(separator));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,6 +3,7 @@ package fr.pandacube.lib.core.util;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
|
||||
public class FileUtils {
|
||||
|
||||
@ -20,12 +21,17 @@ public class FileUtils {
|
||||
if (target.exists() && !target.isDirectory()) {
|
||||
throw new IllegalStateException("target file already exists: " + target);
|
||||
}
|
||||
if (source.isDirectory()) {
|
||||
target.mkdir();
|
||||
for (String child : source.list())
|
||||
copy(new File(source, child), new File(target, child));
|
||||
BasicFileAttributes sourceAttr = Files.readAttributes(source.toPath(), BasicFileAttributes.class);
|
||||
if (sourceAttr.isDirectory()) {
|
||||
if (target.mkdir()) {
|
||||
for (String child : source.list())
|
||||
copy(new File(source, child), new File(target, child));
|
||||
}
|
||||
else {
|
||||
throw new IOException("Cannot create directory " + target);
|
||||
}
|
||||
}
|
||||
else if (source.isFile()) {
|
||||
else if (sourceAttr.isRegularFile()) {
|
||||
Files.copy(source.toPath(), target.toPath());
|
||||
}
|
||||
}
|
||||
|
@ -103,13 +103,7 @@ public class GifDecoder {
|
||||
protected ArrayList<GifFrame> frames; // frames read from current file
|
||||
protected int frameCount;
|
||||
|
||||
static class GifFrame {
|
||||
public GifFrame(BufferedImage im, int del) {
|
||||
image = im;
|
||||
delay = del;
|
||||
}
|
||||
public BufferedImage image;
|
||||
public int delay;
|
||||
record GifFrame(BufferedImage image, int delay) {
|
||||
}
|
||||
|
||||
/**
|
||||
@ -184,12 +178,7 @@ public class GifDecoder {
|
||||
if (lastDispose == 2) {
|
||||
// fill last image rect area with background color
|
||||
Graphics2D g = image.createGraphics();
|
||||
Color c = null;
|
||||
if (transparency) {
|
||||
c = new Color(0, 0, 0, 0); // assume background is transparent
|
||||
} else {
|
||||
c = new Color(lastBgColor); // use given background color
|
||||
}
|
||||
Color c = transparency ? new Color(0, 0, 0, 0) : new Color(lastBgColor);
|
||||
g.setColor(c);
|
||||
g.setComposite(AlphaComposite.Src); // replace area
|
||||
g.fill(lastRect);
|
||||
@ -270,7 +259,7 @@ public class GifDecoder {
|
||||
/**
|
||||
* Reads GIF image from stream
|
||||
*
|
||||
* @param BufferedInputStream containing GIF file.
|
||||
* @param is containing GIF file.
|
||||
* @return read status code (0 = no errors)
|
||||
*/
|
||||
public int read(BufferedInputStream is) {
|
||||
@ -286,7 +275,7 @@ public class GifDecoder {
|
||||
}
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
} else {
|
||||
status = STATUS_OPEN_ERROR;
|
||||
@ -297,7 +286,7 @@ public class GifDecoder {
|
||||
/**
|
||||
* Reads GIF image from stream
|
||||
*
|
||||
* @param InputStream containing GIF file.
|
||||
* @param is containing GIF file.
|
||||
* @return read status code (0 = no errors)
|
||||
*/
|
||||
public int read(InputStream is) {
|
||||
@ -315,7 +304,7 @@ public class GifDecoder {
|
||||
}
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
} else {
|
||||
status = STATUS_OPEN_ERROR;
|
||||
@ -334,7 +323,7 @@ public class GifDecoder {
|
||||
status = STATUS_OK;
|
||||
try {
|
||||
name = name.trim().toLowerCase();
|
||||
if ((name.indexOf("file:") >= 0) ||
|
||||
if ((name.contains("file:")) ||
|
||||
(name.indexOf(":/") > 0)) {
|
||||
URL url = new URL(name);
|
||||
in = new BufferedInputStream(url.openStream());
|
||||
@ -524,14 +513,14 @@ public class GifDecoder {
|
||||
int n = 0;
|
||||
if (blockSize > 0) {
|
||||
try {
|
||||
int count = 0;
|
||||
int count;
|
||||
while (n < blockSize) {
|
||||
count = in.read(block, n, blockSize - n);
|
||||
if (count == -1)
|
||||
break;
|
||||
n += count;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
|
||||
if (n < blockSize) {
|
||||
@ -554,7 +543,7 @@ public class GifDecoder {
|
||||
int n = 0;
|
||||
try {
|
||||
n = in.read(c);
|
||||
} catch (IOException e) {
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
if (n < nbytes) {
|
||||
status = STATUS_FORMAT_ERROR;
|
||||
@ -595,11 +584,11 @@ public class GifDecoder {
|
||||
|
||||
case 0xff : // application extension
|
||||
readBlock();
|
||||
String app = "";
|
||||
StringBuilder app = new StringBuilder();
|
||||
for (int i = 0; i < 11; i++) {
|
||||
app += (char) block[i];
|
||||
app.append((char) block[i]);
|
||||
}
|
||||
if (app.equals("NETSCAPE2.0")) {
|
||||
if (app.toString().equals("NETSCAPE2.0")) {
|
||||
readNetscapeExt();
|
||||
}
|
||||
else
|
||||
@ -644,11 +633,11 @@ public class GifDecoder {
|
||||
* Reads GIF file header information.
|
||||
*/
|
||||
protected void readHeader() {
|
||||
String id = "";
|
||||
StringBuilder id = new StringBuilder();
|
||||
for (int i = 0; i < 6; i++) {
|
||||
id += (char) read();
|
||||
id.append((char) read());
|
||||
}
|
||||
if (!id.startsWith("GIF")) {
|
||||
if (!id.toString().startsWith("GIF")) {
|
||||
status = STATUS_FORMAT_ERROR;
|
||||
return;
|
||||
}
|
||||
@ -769,9 +758,6 @@ public class GifDecoder {
|
||||
lastRect = new Rectangle(ix, iy, iw, ih);
|
||||
lastImage = image;
|
||||
lastBgColor = bgColor;
|
||||
/*int dispose = 0;
|
||||
boolean transparency = false;
|
||||
int delay = 0;*/
|
||||
lct = null;
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ import java.util.NoSuchElementException;
|
||||
public class IteratorIterator<T> implements Iterator<T> {
|
||||
|
||||
public static <T> IteratorIterator<T> ofCollectionOfIterable(Collection<Iterable<T>> coll) {
|
||||
return new IteratorIterator<>(coll.stream().map(i -> i.iterator()).iterator());
|
||||
return new IteratorIterator<>(coll.stream().map(Iterable::iterator).iterator());
|
||||
}
|
||||
|
||||
public static <T> IteratorIterator<T> ofCollectionOfIterator(Collection<Iterator<T>> coll) {
|
||||
@ -18,7 +18,7 @@ public class IteratorIterator<T> implements Iterator<T> {
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> IteratorIterator<T> ofArrayOfIterable(Iterable<T>... arr) {
|
||||
return new IteratorIterator<>(Arrays.stream(arr).map(i -> i.iterator()).iterator());
|
||||
return new IteratorIterator<>(Arrays.stream(arr).map(Iterable::iterator).iterator());
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
@ -26,7 +26,7 @@ public class IteratorIterator<T> implements Iterator<T> {
|
||||
return new IteratorIterator<>(Arrays.asList(arr).iterator());
|
||||
}
|
||||
|
||||
private Iterator<Iterator<T>> iterators;
|
||||
private final Iterator<Iterator<T>> iterators;
|
||||
|
||||
private Iterator<T> currentIterator = null;
|
||||
|
||||
@ -59,5 +59,16 @@ public class IteratorIterator<T> implements Iterator<T> {
|
||||
throw new NoSuchElementException("No next value found in iterator.");
|
||||
return currentIterator.next();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @implNote The current implementation of {@link IteratorIterator} may not support
|
||||
* running this method if the current position is the last value of one of
|
||||
* the underlying iterable, and if the {@link #hasNext()} method has been called before this one.
|
||||
*/
|
||||
@Override
|
||||
public void remove() {
|
||||
// TODO change code to avoid currentIterator being null because we are about to change currentIterator
|
||||
if (currentIterator != null)
|
||||
currentIterator.remove();
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ pour les calculs (division par zero, etc...).
|
||||
|
||||
*/
|
||||
|
||||
// Classe servant <EFBFBD> palier l'absence de passage par variables ou reference
|
||||
// Classe servant à palier l'absence de passage par variables ou reference
|
||||
|
||||
class VariableInt {
|
||||
public int mValue;
|
||||
@ -65,8 +65,8 @@ public class JArithmeticInterpreter {
|
||||
|
||||
// Variables
|
||||
|
||||
int mOperator;
|
||||
double mValue;
|
||||
final int mOperator;
|
||||
final double mValue;
|
||||
JArithmeticInterpreter fg, fd;
|
||||
|
||||
// Methods
|
||||
@ -75,27 +75,21 @@ public class JArithmeticInterpreter {
|
||||
// Node
|
||||
|
||||
private JArithmeticInterpreter() {
|
||||
this(0, 0, null, null);
|
||||
this(0, 0);
|
||||
}
|
||||
|
||||
// ....................................................................................
|
||||
// Node
|
||||
|
||||
private JArithmeticInterpreter(int Operator, double Value, JArithmeticInterpreter Fg, JArithmeticInterpreter Fd) {
|
||||
private JArithmeticInterpreter(int Operator, double Value) {
|
||||
mOperator = Operator;
|
||||
mValue = Value;
|
||||
fg = Fg;
|
||||
fd = Fd;
|
||||
}
|
||||
|
||||
private JArithmeticInterpreter(int Operator, double Value) {
|
||||
this(Operator, Value, null, null);
|
||||
}
|
||||
|
||||
// ....................................................................................
|
||||
// Construct_Tree
|
||||
|
||||
private static JArithmeticInterpreter constructTree(StringBuffer string, int length, int error) {
|
||||
private static JArithmeticInterpreter constructTree(StringBuffer string, int length) {
|
||||
int imbric, Bimbric;
|
||||
int priorite, ope;
|
||||
int position, positionv, i, j;
|
||||
@ -108,7 +102,6 @@ public class JArithmeticInterpreter {
|
||||
// Initialisation des variables
|
||||
|
||||
if (length <= 0) {
|
||||
error = 3;
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -180,7 +173,6 @@ public class JArithmeticInterpreter {
|
||||
i++;
|
||||
}
|
||||
else {
|
||||
error = 2; // symbole non reconnu
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -202,7 +194,7 @@ public class JArithmeticInterpreter {
|
||||
position = i;
|
||||
caspp = 0;
|
||||
}
|
||||
else if ((imbric == Bimbric) && (priorite >= 1)) {
|
||||
else if (imbric == Bimbric) {
|
||||
priorite = 1;
|
||||
ope = 1;
|
||||
position = i;
|
||||
@ -238,7 +230,7 @@ public class JArithmeticInterpreter {
|
||||
caspp = 0;
|
||||
}
|
||||
}
|
||||
else if ((imbric == Bimbric) && (priorite >= 1)) if ((i - 1) < 0) {
|
||||
else if (imbric == Bimbric) if ((i - 1) < 0) {
|
||||
if (priorite > 5) {
|
||||
priorite = 1;
|
||||
position = i;
|
||||
@ -308,12 +300,10 @@ public class JArithmeticInterpreter {
|
||||
i++;
|
||||
break;
|
||||
default:
|
||||
error = 2; // symbole non reconnu
|
||||
return null;
|
||||
}
|
||||
|
||||
if (imbric != 0) {
|
||||
error = 1; // erreur de "parenthesage"
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -330,46 +320,42 @@ public class JArithmeticInterpreter {
|
||||
node.fd = new JArithmeticInterpreter();
|
||||
|
||||
if ((length - position - 1 - Bimbric) == 0) { // argument absent
|
||||
error = 3;
|
||||
return null;
|
||||
}
|
||||
StringBuffer temp = CopyPartialString(string, (position + 1), (length - 1 - Bimbric));
|
||||
node.fd = constructTree(temp, (length - position - 1 - Bimbric), error);
|
||||
node.fd = constructTree(temp, (length - position - 1 - Bimbric));
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
else if (priorite == 5) {
|
||||
node = new JArithmeticInterpreter(0, calc_const(string, positionv), null, null);
|
||||
node = new JArithmeticInterpreter(0, calc_const(string, positionv));
|
||||
|
||||
return node;
|
||||
}
|
||||
else if (ope > 5) {
|
||||
node = new JArithmeticInterpreter(ope, 0, null, null);
|
||||
node = new JArithmeticInterpreter(ope, 0);
|
||||
|
||||
if ((length - position - espa - Bimbric) == 0) { // argument absent
|
||||
error = 3;
|
||||
return null;
|
||||
}
|
||||
StringBuffer temp = CopyPartialString(string, (position + espa), (length - 1));
|
||||
node.fg = constructTree(temp, (length - position - espa - Bimbric), error);
|
||||
node.fg = constructTree(temp, (length - position - espa - Bimbric));
|
||||
return node;
|
||||
}
|
||||
else {
|
||||
node = new JArithmeticInterpreter(ope, 0, null, null);
|
||||
node = new JArithmeticInterpreter(ope, 0);
|
||||
|
||||
if ((position - Bimbric) == 0) { // argument absent
|
||||
error = 3;
|
||||
return null;
|
||||
}
|
||||
StringBuffer temp = CopyPartialString(string, Bimbric, (position - 1));
|
||||
node.fg = constructTree(temp, (position - Bimbric), error);
|
||||
node.fg = constructTree(temp, (position - Bimbric));
|
||||
if ((length - position - 1 - Bimbric) == 0) { // argument absent
|
||||
error = 3;
|
||||
return null;
|
||||
}
|
||||
temp = CopyPartialString(string, (position + 1), (length - 1 - Bimbric));
|
||||
node.fd = constructTree(temp, (length - position - 1 - Bimbric), error);
|
||||
node.fd = constructTree(temp, (length - position - 1 - Bimbric));
|
||||
return node;
|
||||
}
|
||||
}
|
||||
@ -378,15 +364,12 @@ public class JArithmeticInterpreter {
|
||||
|
||||
private double computeTree() {
|
||||
if (mOperator == 0) return mValue;
|
||||
int error = 0;
|
||||
|
||||
double valueL = fg.computeTree();
|
||||
|
||||
if (error != 0) return 0;
|
||||
double valueR = 0;
|
||||
|
||||
if (fd != null) valueR = fd.computeTree();
|
||||
if (error != 0) return 0;
|
||||
|
||||
switch (mOperator) {
|
||||
case 1: // +
|
||||
@ -397,7 +380,6 @@ public class JArithmeticInterpreter {
|
||||
return (valueL * valueR);
|
||||
case 4: // -
|
||||
if (valueR == 0) {
|
||||
error = 1;
|
||||
return 0;
|
||||
}
|
||||
return (valueL / valueR);
|
||||
@ -407,23 +389,16 @@ public class JArithmeticInterpreter {
|
||||
return Math.exp(valueL);
|
||||
case 7: // ln
|
||||
if (valueL <= 0) {
|
||||
if (valueL < 0) error = 2;
|
||||
else
|
||||
error = 1;
|
||||
return 0;
|
||||
}
|
||||
return (Math.log(valueL) / Math.log(2));
|
||||
case 8: // log
|
||||
if (valueL <= 0) {
|
||||
if (valueL < 0) error = 2;
|
||||
else
|
||||
error = 1;
|
||||
return 0;
|
||||
}
|
||||
return Math.log(valueL);
|
||||
case 9: // sqrt
|
||||
if (valueL < 0) {
|
||||
error = 2;
|
||||
return 0;
|
||||
}
|
||||
return Math.sqrt(valueL);
|
||||
@ -462,8 +437,7 @@ public class JArithmeticInterpreter {
|
||||
fd.writeTree(string);
|
||||
break;
|
||||
case 2:
|
||||
if ((fg.mOperator == 0) && (fg.mValue == 0)) ;
|
||||
else
|
||||
if (fg.mOperator != 0 || fg.mValue != 0)
|
||||
fg.writeTree(string);
|
||||
string.append('-');
|
||||
if ((fd.mOperator == 1) || (fd.mOperator == 2)) {
|
||||
@ -471,7 +445,7 @@ public class JArithmeticInterpreter {
|
||||
string.append('(');
|
||||
}
|
||||
fd.writeTree(string);
|
||||
if (parenthese == true) string.append(')');
|
||||
if (parenthese) string.append(')');
|
||||
break;
|
||||
case 3:
|
||||
if ((fg.mOperator == 1) || (fg.mOperator == 2)) {
|
||||
@ -479,7 +453,7 @@ public class JArithmeticInterpreter {
|
||||
string.append('(');
|
||||
}
|
||||
fg.writeTree(string);
|
||||
if (parenthese == true) string.append(')');
|
||||
if (parenthese) string.append(')');
|
||||
parenthese = false;
|
||||
string.append('*');
|
||||
if ((fd.mOperator == 1) || (fd.mOperator == 2)) {
|
||||
@ -487,7 +461,7 @@ public class JArithmeticInterpreter {
|
||||
string.append('(');
|
||||
}
|
||||
fd.writeTree(string);
|
||||
if (parenthese == true) string.append(')');
|
||||
if (parenthese) string.append(')');
|
||||
break;
|
||||
case 4:
|
||||
if ((fg.mOperator == 1) || (fg.mOperator == 2)) {
|
||||
@ -495,7 +469,7 @@ public class JArithmeticInterpreter {
|
||||
string.append('(');
|
||||
}
|
||||
fg.writeTree(string);
|
||||
if (parenthese == true) string.append(')');
|
||||
if (parenthese) string.append(')');
|
||||
parenthese = false;
|
||||
string.append('/');
|
||||
if ((fd.mOperator > 0) && (fd.mOperator < 5)) {
|
||||
@ -503,7 +477,7 @@ public class JArithmeticInterpreter {
|
||||
string.append('(');
|
||||
}
|
||||
fd.writeTree(string);
|
||||
if (parenthese == true) string.append(')');
|
||||
if (parenthese) string.append(')');
|
||||
break;
|
||||
case 5:
|
||||
if ((fg.mOperator > 0) && (fg.mOperator < 5)) {
|
||||
@ -511,7 +485,7 @@ public class JArithmeticInterpreter {
|
||||
string.append('(');
|
||||
}
|
||||
fg.writeTree(string);
|
||||
if (parenthese == true) string.append(')');
|
||||
if (parenthese) string.append(')');
|
||||
parenthese = false;
|
||||
string.append('^');
|
||||
if ((fd.mOperator > 0) && (fd.mOperator < 5)) {
|
||||
@ -519,7 +493,7 @@ public class JArithmeticInterpreter {
|
||||
string.append('(');
|
||||
}
|
||||
fd.writeTree(string);
|
||||
if (parenthese == true) string.append(')');
|
||||
if (parenthese) string.append(')');
|
||||
break;
|
||||
case 6:
|
||||
string.append("exp(");
|
||||
@ -732,8 +706,8 @@ public class JArithmeticInterpreter {
|
||||
JArithmeticInterpreter jai = null;
|
||||
|
||||
try {
|
||||
jai = JArithmeticInterpreter.constructTree(input, input.length(), 0);
|
||||
} catch (Exception e) {}
|
||||
jai = JArithmeticInterpreter.constructTree(input, input.length());
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
if (jai == null) throw new IllegalArgumentException("Le calcul passé en paramètre est invalide");
|
||||
|
||||
@ -749,7 +723,7 @@ public class JArithmeticInterpreter {
|
||||
return getResultFromExpression(expr, null);
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
public static void main(String[] args) {
|
||||
|
||||
StringBuffer b = new StringBuffer(0);
|
||||
|
||||
|
@ -18,9 +18,9 @@ import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
public class Json {
|
||||
public static final Gson gson = build(b -> b);
|
||||
public static final Gson gsonPrettyPrinting = build(b -> b.setPrettyPrinting());
|
||||
public static final Gson gsonSerializeNulls = build(b -> b.serializeNulls());
|
||||
public static final Gson gson = build(Function.identity());
|
||||
public static final Gson gsonPrettyPrinting = build(GsonBuilder::setPrettyPrinting);
|
||||
public static final Gson gsonSerializeNulls = build(GsonBuilder::serializeNulls);
|
||||
public static final Gson gsonSerializeNullsPrettyPrinting = build(b -> b.serializeNulls().setPrettyPrinting());
|
||||
|
||||
|
||||
@ -46,9 +46,9 @@ public class Json {
|
||||
}
|
||||
|
||||
private static class RecordTypeAdapter<T> extends TypeAdapter<T> {
|
||||
private Gson gson;
|
||||
private TypeAdapterFactory factory;
|
||||
private TypeToken<T> type;
|
||||
private final Gson gson;
|
||||
private final TypeAdapterFactory factory;
|
||||
private final TypeToken<T> type;
|
||||
|
||||
public RecordTypeAdapter(Gson gson, TypeAdapterFactory factory, TypeToken<T> type) {
|
||||
this.gson = gson;
|
||||
@ -72,8 +72,8 @@ public class Json {
|
||||
|
||||
RecordComponent[] recordComponents = clazz.getRecordComponents();
|
||||
Map<String, TypeToken<?>> typeMap = new HashMap<>();
|
||||
for (int i = 0; i < recordComponents.length; i++) {
|
||||
typeMap.put(recordComponents[i].getName(), TypeToken.get(recordComponents[i].getGenericType()));
|
||||
for (RecordComponent recordComponent : recordComponents) {
|
||||
typeMap.put(recordComponent.getName(), TypeToken.get(recordComponent.getGenericType()));
|
||||
}
|
||||
var argsMap = new HashMap<String, Object>();
|
||||
reader.beginObject();
|
||||
|
@ -2,6 +2,8 @@ package fr.pandacube.lib.core.util;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import fr.pandacube.lib.core.util.ThrowableUtil.SupplierException;
|
||||
|
||||
/**
|
||||
* Represents a lazy loaded value.
|
||||
*
|
||||
@ -42,11 +44,5 @@ public class LazyOrException<T> {
|
||||
cachedValue = value;
|
||||
cached = true;
|
||||
}
|
||||
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SupplierException<T> {
|
||||
public T get() throws Exception;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,12 +5,12 @@ import java.util.function.ToIntBiFunction;
|
||||
|
||||
public class LevenshteinDistance {
|
||||
|
||||
private String initialList;
|
||||
private final String initialList;
|
||||
|
||||
private int elementAdditionScore;
|
||||
private int elementDeletionScore;
|
||||
private final int elementAdditionScore;
|
||||
private final int elementDeletionScore;
|
||||
|
||||
private ToIntBiFunction<Character, Character> elementDistanceFunction;
|
||||
private final ToIntBiFunction<Character, Character> elementDistanceFunction;
|
||||
|
||||
private int[] prev, curr;
|
||||
|
||||
|
@ -7,7 +7,7 @@ import java.util.logging.Logger;
|
||||
public class Log {
|
||||
|
||||
private static Logger logger = Logger.getGlobal();
|
||||
private static AtomicBoolean logDebug = new AtomicBoolean(false);
|
||||
private static final AtomicBoolean logDebug = new AtomicBoolean(false);
|
||||
|
||||
public static void setDebug(boolean newVal) {
|
||||
logDebug.set(newVal);
|
||||
|
@ -1,12 +1,23 @@
|
||||
package fr.pandacube.lib.core.util;
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* A Wrapper list that provides a mapped view of the backend list.
|
||||
* Every modification of this list will modify the bakend list.
|
||||
* For each time a value is accessed or modified, the appropriate
|
||||
* setter or getter is used to convert the value between the source {@code S}
|
||||
* and the visible {@code T} type.
|
||||
* @param <S> the source (backend) type
|
||||
* @param <T> the visible (mapped) type
|
||||
*/
|
||||
public class MappedListView<S, T> extends AbstractList<T> {
|
||||
|
||||
private final List<S> backend;
|
||||
protected final List<S> backend;
|
||||
private final Function<S, T> getter;
|
||||
private final Function<T, S> setter;
|
||||
|
||||
@ -28,25 +39,149 @@ public class MappedListView<S, T> extends AbstractList<T> {
|
||||
|
||||
|
||||
@Override
|
||||
public int size() { return backend.size(); }
|
||||
public int size() {
|
||||
return backend.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get(int index) { return getter.apply(backend.get(index)); }
|
||||
public T get(int index) {
|
||||
return getter.apply(backend.get(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public T set(int index, T element) { return getter.apply(backend.set(index, setter.apply(element))); }
|
||||
public T set(int index, T element) {
|
||||
return getter.apply(backend.set(index, setter.apply(element)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, T element) { backend.add(index, setter.apply(element)); }
|
||||
public boolean add(T element) {
|
||||
return backend.add(setter.apply(element));
|
||||
}
|
||||
|
||||
@Override
|
||||
public T remove(int index) { return getter.apply(backend.remove(index)); }
|
||||
public void add(int index, T element) {
|
||||
backend.add(index, setter.apply(element));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() { backend.clear(); }
|
||||
public T remove(int index) {
|
||||
return getter.apply(backend.remove(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
backend.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> subList(int fromIndex, int toIndex) {
|
||||
return new MappedListView<S, T>(backend.subList(fromIndex, toIndex), getter, setter);
|
||||
return new MappedListView<>(backend.subList(fromIndex, toIndex), getter, setter);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeRange(int fromIndex, int toIndex) {
|
||||
backend.subList(fromIndex, toIndex).clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return backend.equals(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return backend.hashCode();
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public int indexOf(Object o) {
|
||||
return backend.indexOf(setter.apply((T) o));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public int lastIndexOf(Object o) {
|
||||
return backend.lastIndexOf(setter.apply((T) o));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return new Iterator<>() {
|
||||
final Iterator<S> wrappedIt = backend.iterator();
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return wrappedIt.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
return getter.apply(wrappedIt.next());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
wrappedIt.remove();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator<T> listIterator() {
|
||||
return listIterator(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator<T> listIterator(int index) {
|
||||
return new ListIterator<>() {
|
||||
final ListIterator<S> wrappedIt = backend.listIterator(index);
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return wrappedIt.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
return getter.apply(wrappedIt.next());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrevious() {
|
||||
return wrappedIt.hasPrevious();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T previous() {
|
||||
return getter.apply(wrappedIt.previous());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextIndex() {
|
||||
return wrappedIt.nextIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int previousIndex() {
|
||||
return wrappedIt.previousIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
wrappedIt.remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(T w) {
|
||||
wrappedIt.set(setter.apply(w));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(T w) {
|
||||
wrappedIt.add(setter.apply(w));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -30,7 +30,7 @@ public class MemoryUtil {
|
||||
return unitMultiplier == null ? "o" : (unitMultiplier + (si ? "o" : "io"));
|
||||
}
|
||||
|
||||
private MemoryUnit(long vTrad, long vSI, String uMult) {
|
||||
MemoryUnit(long vTrad, long vSI, String uMult) {
|
||||
valueTrad = vTrad;
|
||||
valueSI = vSI;
|
||||
unitMultiplier = uMult;
|
||||
|
@ -59,7 +59,7 @@ public enum MinecraftVersion {
|
||||
v1_19(759, "1.19");
|
||||
// IMPORTANT: don't forget to update the versionMergeDisplay value when adding a new version;
|
||||
|
||||
private static Map<EnumSet<MinecraftVersion>, List<String>> versionMergeDisplay;
|
||||
private static final Map<EnumSet<MinecraftVersion>, List<String>> versionMergeDisplay;
|
||||
|
||||
static {
|
||||
versionMergeDisplay = new HashMap<>();
|
||||
@ -157,7 +157,7 @@ public enum MinecraftVersion {
|
||||
public final int id;
|
||||
public final List<String> versionDisplay;
|
||||
|
||||
private MinecraftVersion(int v, String... d) {
|
||||
MinecraftVersion(int v, String... d) {
|
||||
id = v;
|
||||
versionDisplay = Arrays.asList(d);
|
||||
}
|
||||
@ -193,7 +193,7 @@ public enum MinecraftVersion {
|
||||
}
|
||||
|
||||
|
||||
public static final List<String> getVersionsDisplayList(List<MinecraftVersion> vList) {
|
||||
public static List<String> getVersionsDisplayList(List<MinecraftVersion> vList) {
|
||||
if (vList == null)
|
||||
return new ArrayList<>();
|
||||
Set<MinecraftVersion> vSet = EnumSet.copyOf(vList);
|
||||
|
@ -7,8 +7,6 @@ public class MinecraftWebUtil {
|
||||
|
||||
/**
|
||||
Convert a legacy Minecraft color coded String into HTML Format.
|
||||
|
||||
@param
|
||||
*/
|
||||
// TODO update to support RGB colors (Bungee and Essentials notation).
|
||||
// See JavaScript implementation at https://www.pandacube.fr/assets/js/global.js
|
||||
@ -16,7 +14,7 @@ public class MinecraftWebUtil {
|
||||
{
|
||||
String color_char = "0123456789abcdefr";
|
||||
|
||||
String builder = "";
|
||||
StringBuilder builder = new StringBuilder();
|
||||
char currentColor = 'r';
|
||||
boolean bold = false, italic = false, underlined = false, strikethrough = false;
|
||||
|
||||
@ -26,67 +24,67 @@ public class MinecraftWebUtil {
|
||||
if (c == code_prefix && (i<ligne.length()-1)) {
|
||||
i++;
|
||||
c = ligne.charAt(i);
|
||||
if (color_char.contains(new String(new char[] {Character.toLowerCase(c)}))) {
|
||||
if (color_char.contains(String.valueOf(Character.toLowerCase(c)))) {
|
||||
if (bold) {
|
||||
builder += "</span>";
|
||||
builder.append("</span>");
|
||||
bold = false;
|
||||
}
|
||||
if (italic) {
|
||||
builder += "</span>";
|
||||
builder.append("</span>");
|
||||
italic = false;
|
||||
}
|
||||
if (underlined) {
|
||||
builder += "</span>";
|
||||
builder.append("</span>");
|
||||
underlined = false;
|
||||
}
|
||||
if (strikethrough) {
|
||||
builder += "</span>";
|
||||
builder.append("</span>");
|
||||
strikethrough = false;
|
||||
}
|
||||
if (Character.toLowerCase(c) != currentColor) {
|
||||
if (currentColor != 'r')
|
||||
builder += "</span>";
|
||||
builder.append("</span>");
|
||||
if (Character.toLowerCase(c) != 'r')
|
||||
builder += "<span class=\"c" + Character.toUpperCase(c) + "\">";
|
||||
builder.append("<span class=\"c").append(Character.toUpperCase(c)).append("\">");
|
||||
currentColor = Character.toLowerCase(c);
|
||||
}
|
||||
|
||||
}
|
||||
else if (Character.toLowerCase(c) == 'l') {
|
||||
if (!bold) {
|
||||
builder += "<span class=\"cL\">";
|
||||
builder.append("<span class=\"cL\">");
|
||||
bold = true;
|
||||
}
|
||||
}
|
||||
else if (Character.toLowerCase(c) == 'm') {
|
||||
if (!strikethrough) {
|
||||
builder += "<span class=\"cM\">";
|
||||
builder.append("<span class=\"cM\">");
|
||||
strikethrough = true;
|
||||
}
|
||||
}
|
||||
else if (Character.toLowerCase(c) == 'n') {
|
||||
if (!underlined) {
|
||||
builder += "<span class=\"cN\">";
|
||||
builder.append("<span class=\"cN\">");
|
||||
underlined = true;
|
||||
}
|
||||
}
|
||||
else if (Character.toLowerCase(c) == 'o') {
|
||||
if (!italic) {
|
||||
builder += "<span class=\"cO\">";
|
||||
builder.append("<span class=\"cO\">");
|
||||
italic = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
builder += code_prefix + c;
|
||||
builder.append(code_prefix + c);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
builder += c;
|
||||
builder.append(c);
|
||||
}
|
||||
|
||||
return builder;
|
||||
return builder.toString();
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
package fr.pandacube.lib.core.util;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Objects;
|
||||
import java.util.Scanner;
|
||||
import java.util.UUID;
|
||||
@ -8,7 +8,7 @@ import java.util.UUID;
|
||||
public class OfflineUUID {
|
||||
|
||||
public static UUID getFromNickName(String nickname) {
|
||||
byte[] from_str = ("OfflinePlayer:" + nickname).getBytes(Charset.forName("UTF-8"));
|
||||
byte[] from_str = ("OfflinePlayer:" + nickname).getBytes(StandardCharsets.UTF_8);
|
||||
return UUID.nameUUIDFromBytes(from_str);
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ import java.util.Set;
|
||||
|
||||
public class RandomUtil {
|
||||
|
||||
public static Random rand = new Random();
|
||||
public static final Random rand = new Random();
|
||||
|
||||
public static int nextIntBetween(int minInclu, int maxExclu) {
|
||||
return rand.nextInt(maxExclu - minInclu) + minInclu;
|
||||
@ -32,8 +32,8 @@ public class RandomUtil {
|
||||
* Returns a random value from a set.
|
||||
*
|
||||
* May not be optimized (Actually O(n) )
|
||||
* @param arr
|
||||
* @return
|
||||
* @param set the Set from which to pick a random value
|
||||
* @return a random value from the set
|
||||
*/
|
||||
public static <T> T setElement(Set<T> set) {
|
||||
if (set.isEmpty())
|
||||
@ -51,26 +51,26 @@ public class RandomUtil {
|
||||
* Return a value between 0 and the number of parameter minus 1, using the provided frequencies.
|
||||
*
|
||||
* The probability of each value to be returned depends of the frequencies provided.
|
||||
* @param frequencies the frequencies of each entries
|
||||
* @param f the frequencies of each entries
|
||||
* @return the index of an entry, or -1 if it is unable to pick anything (all the frequencies are 0 or there is not provided frequency)
|
||||
*/
|
||||
public static int randomIndexOfFrequencies(double... frequencies) {
|
||||
if (frequencies == null)
|
||||
return -1;
|
||||
public static int randomIndexOfFrequencies(double... f) {
|
||||
if (f == null)
|
||||
throw new IllegalArgumentException("f cannot be null");
|
||||
int n = f.length;
|
||||
double[] fSums = new double[n];
|
||||
double sum = 0;
|
||||
for (double f : frequencies)
|
||||
sum += f;
|
||||
if (sum == 0)
|
||||
return -1;
|
||||
double r = rand.nextDouble() * sum;
|
||||
int i = -1;
|
||||
double limit = frequencies[++i];
|
||||
while (i < frequencies.length) {
|
||||
if (r < limit)
|
||||
return i;
|
||||
limit += frequencies[++i];
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (f[i] < 0)
|
||||
throw new IllegalArgumentException("f[" + i + "] cannot be negative.");
|
||||
fSums[i] = (sum += f[i]);
|
||||
}
|
||||
return frequencies.length - 1;
|
||||
double r = rand.nextDouble() * sum;
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (fSums[i] > r)
|
||||
return i;
|
||||
}
|
||||
return n - 1;
|
||||
}
|
||||
|
||||
|
||||
@ -81,7 +81,7 @@ public class RandomUtil {
|
||||
public static final String PASSWORD_CHARSET_LATIN_LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
|
||||
public static final String PASSWORD_CHARSET_LATIN_UPPERCASE = PASSWORD_CHARSET_LATIN_LOWERCASE.toUpperCase();
|
||||
public static final String PASSWORD_CHARSET_DIGIT = "0123456789";
|
||||
public static final String PASSWORD_CHARSET_SPECIAL = "@#+*/-;:,.?!='()[]{}&\"\\";
|
||||
public static final String PASSWORD_CHARSET_SPECIAL = "@#+*/-;:,.?!='()[]{}&";
|
||||
public static final String PASSWORD_CHARSET_NO_ANBIGUITY = "abcdefghkmnpqrstwxyzACDEFGHKLMNPQRSTWXYZ2345679";
|
||||
|
||||
public static String randomPassword(int length) {
|
||||
|
@ -4,6 +4,7 @@ import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@ -73,7 +74,7 @@ public class Reflect {
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return other != null && other instanceof MethodIdentifier o
|
||||
return other instanceof MethodIdentifier o
|
||||
&& o.methodName.equals(methodName)
|
||||
&& Arrays.equals(o.parameters, parameters);
|
||||
}
|
||||
@ -89,7 +90,7 @@ public class Reflect {
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return other != null && other instanceof ConstructorIdentifier o
|
||||
return other instanceof ConstructorIdentifier o
|
||||
&& Arrays.equals(o.parameters, parameters);
|
||||
}
|
||||
@Override
|
||||
@ -196,10 +197,10 @@ public class Reflect {
|
||||
|
||||
|
||||
public static abstract class ReflectMember<T, ID, EL, EX extends ReflectiveOperationException> {
|
||||
ReflectClass<T> reflectClass;
|
||||
protected ID identifier;
|
||||
protected final ReflectClass<T> reflectClass;
|
||||
protected final ID identifier;
|
||||
|
||||
protected EL cached;
|
||||
protected final EL cached;
|
||||
|
||||
protected ReflectMember(ReflectClass<T> c, ID id, boolean bypassFilter) throws EX {
|
||||
reflectClass = c;
|
||||
@ -210,78 +211,71 @@ public class Reflect {
|
||||
|
||||
|
||||
protected EL fetch() throws EX {
|
||||
EX ex = null;
|
||||
|
||||
// get element in current class
|
||||
try {
|
||||
EL el = fetchFromClass(reflectClass.clazz);
|
||||
setAccessible(el);
|
||||
return el;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
} catch (ReflectiveOperationException e1) {
|
||||
@SuppressWarnings("unchecked")
|
||||
EX ee = (EX) e;
|
||||
ex = ee;
|
||||
EX ex = (EX) e1;
|
||||
|
||||
// get parent class
|
||||
Class<? super T> superClass = reflectClass.clazz.getSuperclass();
|
||||
if (superClass == null)
|
||||
throw ex;
|
||||
|
||||
// get element in parent class (will do recursion)
|
||||
try {
|
||||
EL el = fetchFromReflectClass(ofClass(superClass));
|
||||
setAccessible(el);
|
||||
return el;
|
||||
} catch (ReflectiveOperationException e2) {
|
||||
ex.addSuppressed(e2);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
// get parent class
|
||||
Class<? super T> superClass = reflectClass.clazz.getSuperclass();
|
||||
if (superClass == null)
|
||||
throw ex;
|
||||
|
||||
// get element in parent class (will do recursion)
|
||||
try {
|
||||
EL el = fetchFromReflectClass(ofClass(superClass));
|
||||
setAccessible(el);
|
||||
return el;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
ex.addSuppressed(e);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected EL fetchFiltered() throws EX {
|
||||
EX ex = null;
|
||||
|
||||
// get element in current class
|
||||
try {
|
||||
EL el = fetchFromClass(reflectClass.clazz);
|
||||
setAccessible(el);
|
||||
return el;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
} catch (ReflectiveOperationException e1) {
|
||||
@SuppressWarnings("unchecked")
|
||||
EX ee = (EX) e;
|
||||
ex = ee;
|
||||
EX ex = (EX) e1;
|
||||
|
||||
// trying to bypass filtered member
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
EL[] elements = (EL[]) Reflect.ofClassOfInstance(reflectClass.clazz)
|
||||
.method(internalMethodNameElementArray(), boolean.class)
|
||||
.invoke(reflectClass.clazz, false);
|
||||
for (EL element : elements) {
|
||||
if (isEqualOurElement(element)) {
|
||||
// the values in the elements array have to be copied
|
||||
// (using special private methods in reflection api) before using it
|
||||
Object reflectionFactoryOfClazz = Reflect.ofClassOfInstance(reflectClass.clazz)
|
||||
.method("getReflectionFactory")
|
||||
.invoke(reflectClass.clazz);
|
||||
@SuppressWarnings("unchecked")
|
||||
EL copiedElement = (EL) Reflect.ofClassOfInstance(reflectionFactoryOfClazz)
|
||||
.method(internalMethodNameCopyElement(), element.getClass())
|
||||
.invoke(reflectionFactoryOfClazz, element);
|
||||
setAccessible(copiedElement);
|
||||
return copiedElement;
|
||||
}
|
||||
}
|
||||
} catch (ReflectiveOperationException e2) {
|
||||
ex.addSuppressed(e2);
|
||||
}
|
||||
|
||||
throw ex;
|
||||
}
|
||||
|
||||
// trying to bypass filtered member
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
EL[] elements = (EL[]) Reflect.ofClassOfInstance(reflectClass.clazz)
|
||||
.method(internalMethodNameElementArray(), boolean.class)
|
||||
.invoke(reflectClass.clazz, false);
|
||||
for (EL element : elements) {
|
||||
if (isEqualOurElement(element)) {
|
||||
// the values in the elements array have to be copied
|
||||
// (using special private methods in reflection api) before using it
|
||||
Object reflectionFactoryOfClazz = Reflect.ofClassOfInstance(reflectClass.clazz)
|
||||
.method("getReflectionFactory")
|
||||
.invoke(reflectClass.clazz);
|
||||
@SuppressWarnings("unchecked")
|
||||
EL copiedElement = (EL) Reflect.ofClassOfInstance(reflectionFactoryOfClazz)
|
||||
.method(internalMethodNameCopyElement(), element.getClass())
|
||||
.invoke(reflectionFactoryOfClazz, element);
|
||||
EL el = copiedElement;
|
||||
setAccessible(el);
|
||||
return el;
|
||||
}
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
ex.addSuppressed(e);
|
||||
}
|
||||
|
||||
throw ex;
|
||||
|
||||
}
|
||||
|
||||
protected abstract EL fetchFromClass(Class<T> clazz) throws EX;
|
||||
@ -311,11 +305,11 @@ public class Reflect {
|
||||
super(c, name, bypassFilter);
|
||||
}
|
||||
|
||||
@Override protected Field fetchFromClass(Class<T> clazz) throws NoSuchFieldException { return clazz.getDeclaredField(identifier); };
|
||||
@Override protected Field fetchFromReflectClass(ReflectClass<?> rc) throws NoSuchFieldException { return rc.field(identifier).get(); };
|
||||
@Override protected boolean isEqualOurElement(Field el) { return identifier.equals(el.getName()); };
|
||||
@Override protected String internalMethodNameElementArray() { return "getDeclaredFields0"; };
|
||||
@Override protected String internalMethodNameCopyElement() { return "copyField"; };
|
||||
@Override protected Field fetchFromClass(Class<T> clazz) throws NoSuchFieldException { return clazz.getDeclaredField(identifier); }
|
||||
@Override protected Field fetchFromReflectClass(ReflectClass<?> rc) throws NoSuchFieldException { return rc.field(identifier).get(); }
|
||||
@Override protected boolean isEqualOurElement(Field el) { return identifier.equals(el.getName()); }
|
||||
@Override protected String internalMethodNameElementArray() { return "getDeclaredFields0"; }
|
||||
@Override protected String internalMethodNameCopyElement() { return "copyField"; }
|
||||
@Override protected void setAccessible(Field el) { el.setAccessible(true); }
|
||||
|
||||
|
||||
@ -379,11 +373,11 @@ public class Reflect {
|
||||
super(c, methodId, bypassFilter);
|
||||
}
|
||||
|
||||
@Override protected Method fetchFromClass(Class<T> clazz) throws NoSuchMethodException { return clazz.getDeclaredMethod(identifier.methodName, identifier.parameters); };
|
||||
@Override protected Method fetchFromReflectClass(ReflectClass<?> rc) throws NoSuchMethodException { return rc.method(identifier, false).get(); };
|
||||
@Override protected boolean isEqualOurElement(Method el) { return identifier.methodName.equals(el.getName()) && Arrays.equals(identifier.parameters, el.getParameterTypes()); };
|
||||
@Override protected String internalMethodNameElementArray() { return "getDeclaredMethods0"; };
|
||||
@Override protected String internalMethodNameCopyElement() { return "copyMethod"; };
|
||||
@Override protected Method fetchFromClass(Class<T> clazz) throws NoSuchMethodException { return clazz.getDeclaredMethod(identifier.methodName, identifier.parameters); }
|
||||
@Override protected Method fetchFromReflectClass(ReflectClass<?> rc) throws NoSuchMethodException { return rc.method(identifier, false).get(); }
|
||||
@Override protected boolean isEqualOurElement(Method el) { return identifier.methodName.equals(el.getName()) && Arrays.equals(identifier.parameters, el.getParameterTypes()); }
|
||||
@Override protected String internalMethodNameElementArray() { return "getDeclaredMethods0"; }
|
||||
@Override protected String internalMethodNameCopyElement() { return "copyMethod"; }
|
||||
@Override protected void setAccessible(Method el) { el.setAccessible(true); }
|
||||
|
||||
public Object invoke(Object instance, Object... values) throws ReflectiveOperationException {
|
||||
@ -415,17 +409,16 @@ public class Reflect {
|
||||
// Override since we don't want to recursively search for a constructor
|
||||
@Override
|
||||
protected Constructor<T> fetch() throws NoSuchMethodException {
|
||||
Constructor<T> el = null;
|
||||
el = fetchFromClass(reflectClass.clazz);
|
||||
Constructor<T> el = fetchFromClass(reflectClass.clazz);
|
||||
setAccessible(el);
|
||||
return el;
|
||||
}
|
||||
|
||||
@Override protected Constructor<T> fetchFromClass(Class<T> clazz) throws NoSuchMethodException { return clazz.getDeclaredConstructor(identifier.parameters); };
|
||||
@Override protected Constructor<T> fetchFromReflectClass(ReflectClass<?> rc) throws NoSuchMethodException { throw new UnsupportedOperationException(); };
|
||||
@Override protected boolean isEqualOurElement(Constructor<T> el) { return Arrays.equals(identifier.parameters, el.getParameterTypes()); };
|
||||
@Override protected String internalMethodNameElementArray() { return "getDeclaredConstructors0"; };
|
||||
@Override protected String internalMethodNameCopyElement() { return "copyConstructor"; };
|
||||
@Override protected Constructor<T> fetchFromClass(Class<T> clazz) throws NoSuchMethodException { return clazz.getDeclaredConstructor(identifier.parameters); }
|
||||
@Override protected Constructor<T> fetchFromReflectClass(ReflectClass<?> rc) { throw new UnsupportedOperationException(); }
|
||||
@Override protected boolean isEqualOurElement(Constructor<T> el) { return Arrays.equals(identifier.parameters, el.getParameterTypes()); }
|
||||
@Override protected String internalMethodNameElementArray() { return "getDeclaredConstructors0"; }
|
||||
@Override protected String internalMethodNameCopyElement() { return "copyConstructor"; }
|
||||
@Override protected void setAccessible(Constructor<T> el) { el.setAccessible(true); }
|
||||
|
||||
public T instanciate(Object... values) throws ReflectiveOperationException {
|
||||
@ -453,7 +446,7 @@ public class Reflect {
|
||||
|
||||
|
||||
|
||||
private static Cache<Class<?>, List<Class<?>>> subClassesLists = CacheBuilder.newBuilder()
|
||||
private static final Cache<Class<?>, List<Class<?>>> subClassesLists = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(10, TimeUnit.MINUTES)
|
||||
.build();
|
||||
|
||||
@ -468,7 +461,7 @@ public class Reflect {
|
||||
return classes;
|
||||
} catch(ExecutionException e) {
|
||||
Log.severe(e);
|
||||
return null;
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,12 +6,13 @@ import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
public class ServerPropertyFile {
|
||||
|
||||
private transient File file;
|
||||
private final transient File file;
|
||||
|
||||
private String name = "default_name";
|
||||
private String memory = "512M";
|
||||
@ -22,8 +23,7 @@ public class ServerPropertyFile {
|
||||
private boolean run = true;
|
||||
|
||||
public ServerPropertyFile(File f) {
|
||||
if (f == null) throw new IllegalArgumentException("f ne doit pas être null");
|
||||
file = f;
|
||||
file = Objects.requireNonNull(f, "f");
|
||||
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ public class ServerPropertyFile {
|
||||
}
|
||||
|
||||
public void setMemory(String m) {
|
||||
if (m == null || !m.matches("^[0-9]+[mgMG]$")) throw new IllegalArgumentException();
|
||||
if (m == null || !m.matches("^\\d+[mgMG]$")) throw new IllegalArgumentException();
|
||||
memory = m;
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class ThrowableUtil {
|
||||
|
||||
@ -11,11 +12,11 @@ public class ThrowableUtil {
|
||||
public static String stacktraceToString(Throwable t) {
|
||||
if (t == null) return null;
|
||||
try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
|
||||
try (PrintStream ps = new PrintStream(os, false, "UTF-8")) {
|
||||
try (PrintStream ps = new PrintStream(os, false, StandardCharsets.UTF_8)) {
|
||||
t.printStackTrace(ps);
|
||||
ps.flush();
|
||||
}
|
||||
return os.toString("UTF-8");
|
||||
return os.toString(StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
@ -90,7 +91,7 @@ public class ThrowableUtil {
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface SupplierException<T> {
|
||||
public T get() throws Exception;
|
||||
T get() throws Exception;
|
||||
}
|
||||
|
||||
|
||||
@ -100,7 +101,7 @@ public class ThrowableUtil {
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface RunnableException {
|
||||
public void run() throws Exception;
|
||||
void run() throws Exception;
|
||||
}
|
||||
|
||||
|
||||
@ -135,10 +136,6 @@ public class ThrowableUtil {
|
||||
er = new InstantiationError();
|
||||
er.initCause(ce);
|
||||
}
|
||||
else if (t instanceof IllegalAccessException ce) {
|
||||
er = new IllegalAccessError();
|
||||
er.initCause(ce);
|
||||
}
|
||||
if (er != null)
|
||||
throw er;
|
||||
|
||||
|
@ -14,7 +14,7 @@ public class Tick {
|
||||
|
||||
/**
|
||||
* Returns the number of tick is the provided duration, in second
|
||||
* @param seconds the duration in second
|
||||
* @param minutes the duration in minutes
|
||||
* @return the same duration as provided, but in Minecraft server ticks
|
||||
*/
|
||||
public static long min(long minutes) {
|
||||
|
@ -1,5 +1,7 @@
|
||||
package fr.pandacube.lib.core.util;
|
||||
|
||||
import fr.pandacube.lib.core.commands.SuggestionsSupplier;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
@ -7,10 +9,10 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@ -19,21 +21,19 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import fr.pandacube.lib.core.commands.SuggestionsSupplier;
|
||||
|
||||
public class TimeUtil {
|
||||
|
||||
|
||||
private static DateTimeFormatter cmpDayOfWeekFormatter = DateTimeFormatter.ofPattern("EEE", Locale.getDefault());
|
||||
private static DateTimeFormatter dayOfWeekFormatter = DateTimeFormatter.ofPattern("EEEE", Locale.getDefault());
|
||||
private static DateTimeFormatter dayOfMonthFormatter = DateTimeFormatter.ofPattern("d", Locale.getDefault());
|
||||
private static DateTimeFormatter cmpMonthFormatter = DateTimeFormatter.ofPattern("MMM", Locale.getDefault());
|
||||
private static DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("MMMM", Locale.getDefault());
|
||||
private static DateTimeFormatter yearFormatter = DateTimeFormatter.ofPattern("uuuu", Locale.getDefault());
|
||||
private static final DateTimeFormatter cmpDayOfWeekFormatter = DateTimeFormatter.ofPattern("EEE", Locale.getDefault());
|
||||
private static final DateTimeFormatter dayOfWeekFormatter = DateTimeFormatter.ofPattern("EEEE", Locale.getDefault());
|
||||
private static final DateTimeFormatter dayOfMonthFormatter = DateTimeFormatter.ofPattern("d", Locale.getDefault());
|
||||
private static final DateTimeFormatter cmpMonthFormatter = DateTimeFormatter.ofPattern("MMM", Locale.getDefault());
|
||||
private static final DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("MMMM", Locale.getDefault());
|
||||
private static final DateTimeFormatter yearFormatter = DateTimeFormatter.ofPattern("uuuu", Locale.getDefault());
|
||||
|
||||
private static DateTimeFormatter HMSFormatter = DateTimeFormatter.ofPattern("HH:mm:ss", Locale.getDefault());
|
||||
private static DateTimeFormatter HMFormatter = DateTimeFormatter.ofPattern("HH:mm", Locale.getDefault());
|
||||
private static DateTimeFormatter HFormatter = DateTimeFormatter.ofPattern("H'h'", Locale.getDefault());
|
||||
private static final DateTimeFormatter HMSFormatter = DateTimeFormatter.ofPattern("HH:mm:ss", Locale.getDefault());
|
||||
private static final DateTimeFormatter HMFormatter = DateTimeFormatter.ofPattern("HH:mm", Locale.getDefault());
|
||||
private static final DateTimeFormatter HFormatter = DateTimeFormatter.ofPattern("H'h'", Locale.getDefault());
|
||||
|
||||
|
||||
public static String relativeDateFr(long displayTime, boolean showSeconds, boolean compactWords) {
|
||||
@ -67,7 +67,7 @@ public class TimeUtil {
|
||||
if (timeDiffSec > -60*2) // dans 2 min
|
||||
return compactWords ? "dans 1min" : "dans une minute";
|
||||
if (timeDiffSec > -3600) // dans moins d’1h
|
||||
return "dans " + (int)Math.floor((-timeDiffSec)/60) + (compactWords ? "min" : " minutes");
|
||||
return "dans " + (-timeDiffSec/60) + (compactWords ? "min" : " minutes");
|
||||
}
|
||||
if (relPrecision.morePreciseOrEqTo(RelativePrecision.HOURS)) {
|
||||
if (timeDiffSec > -3600) // dans moins d’1h
|
||||
@ -75,7 +75,7 @@ public class TimeUtil {
|
||||
if (timeDiffSec > -3600*2) // dans moins de 2h
|
||||
return compactWords ? "dans 1h" : "dans une heure";
|
||||
if (timeDiffSec > -3600*12) // dans moins de 12h
|
||||
return "dans " + (int)Math.floor((-timeDiffSec)/3600) + (compactWords ? "h" : " heures");
|
||||
return "dans " + (-timeDiffSec/3600) + (compactWords ? "h" : " heures");
|
||||
}
|
||||
if (relPrecision.morePreciseOrEqTo(RelativePrecision.DAYS)) {
|
||||
LocalDateTime nextMidnight = LocalDateTime.of(currentDateTime.getYear(), currentDateTime.getMonth(), currentDateTime.getDayOfMonth(), 0, 0).plusDays(1);
|
||||
@ -88,9 +88,7 @@ public class TimeUtil {
|
||||
+ dayOfMonthFormatter.format(displayDateTime) + " à "
|
||||
+ dayTimeFr(displayTime, dispPrecision);
|
||||
}
|
||||
|
||||
return fullDateFr(displayTime, dispPrecision, true, compactWords);
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
// present and past
|
||||
@ -107,7 +105,7 @@ public class TimeUtil {
|
||||
if (timeDiffSec < 60*2) // ya moins de 2 min
|
||||
return compactWords ? "il y a 1min" : "il y a une minute";
|
||||
if (timeDiffSec < 3600) // ya moins d'1h
|
||||
return "il y a " + (int)Math.floor(timeDiffSec/60) + (compactWords ? "min" : " minutes");
|
||||
return "il y a " + (timeDiffSec/60) + (compactWords ? "min" : " minutes");
|
||||
}
|
||||
if (relPrecision.morePreciseOrEqTo(RelativePrecision.HOURS)) {
|
||||
if (timeDiffSec < 3600) // ya moins d'1h
|
||||
@ -115,7 +113,7 @@ public class TimeUtil {
|
||||
if (timeDiffSec < 3600*2) // ya moins de 2h
|
||||
return "il y a une heure";
|
||||
if (timeDiffSec < 3600*12) // ya moins de 12h
|
||||
return "il y a " + (int)Math.floor(timeDiffSec/3600) + " heures";
|
||||
return "il y a " + (timeDiffSec/3600) + " heures";
|
||||
}
|
||||
if (relPrecision.morePreciseOrEqTo(RelativePrecision.DAYS)) {
|
||||
LocalDateTime lastMidnight = LocalDateTime.of(currentDateTime.getYear(), currentDateTime.getMonth(), currentDateTime.getDayOfMonth(), 0, 0);
|
||||
@ -127,11 +125,10 @@ public class TimeUtil {
|
||||
return (compactWords ? cmpDayOfWeekFormatter : dayOfWeekFormatter).format(displayDateTime) + " dernier à "
|
||||
+ dayTimeFr(displayTime, dispPrecision);
|
||||
}
|
||||
|
||||
return fullDateFr(displayTime, dispPrecision, true, compactWords);
|
||||
|
||||
|
||||
}
|
||||
|
||||
return fullDateFr(displayTime, dispPrecision, true, compactWords);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -207,7 +204,7 @@ public class TimeUtil {
|
||||
String ret = Arrays.stream(TimeUnit.values())
|
||||
.sequential()
|
||||
.filter(u -> u.compareTo(fLUnit) >= 0 && u.compareTo(fHUnit) <= 0)
|
||||
.sorted((u1, u2) -> u2.compareTo(u1))
|
||||
.sorted(Comparator.reverseOrder())
|
||||
.filter(u -> {
|
||||
if (u.convert(remainingTime.get(), TimeUnit.MILLISECONDS) == 0 && !oneDisplayed.get())
|
||||
return false;
|
||||
@ -226,40 +223,23 @@ public class TimeUtil {
|
||||
|
||||
|
||||
public static String timeUnitToSuffix(TimeUnit u, boolean fr) {
|
||||
switch (u) {
|
||||
case DAYS:
|
||||
return fr ? "j" : "d";
|
||||
case HOURS:
|
||||
return "h";
|
||||
case MINUTES:
|
||||
return "m";
|
||||
case SECONDS:
|
||||
return "s";
|
||||
case MILLISECONDS:
|
||||
return "ms";
|
||||
case MICROSECONDS:
|
||||
return "μs";
|
||||
case NANOSECONDS:
|
||||
return "ns";
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid TimeUnit: " + Objects.toString(u));
|
||||
}
|
||||
return switch (u) {
|
||||
case DAYS -> fr ? "j" : "d";
|
||||
case HOURS -> "h";
|
||||
case MINUTES -> "m";
|
||||
case SECONDS -> "s";
|
||||
case MILLISECONDS -> "ms";
|
||||
case MICROSECONDS -> "μs";
|
||||
case NANOSECONDS -> "ns";
|
||||
};
|
||||
}
|
||||
|
||||
public static int timeUnitToLeftPadLength(TimeUnit u) {
|
||||
switch (u) {
|
||||
case NANOSECONDS:
|
||||
case MICROSECONDS:
|
||||
case MILLISECONDS:
|
||||
return 3;
|
||||
case SECONDS:
|
||||
case MINUTES:
|
||||
case HOURS:
|
||||
return 2;
|
||||
case DAYS:
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
return switch (u) {
|
||||
case NANOSECONDS, MICROSECONDS, MILLISECONDS -> 3;
|
||||
case SECONDS, MINUTES, HOURS -> 2;
|
||||
case DAYS -> 1;
|
||||
};
|
||||
}
|
||||
|
||||
public static String toString(long value, int leftPad) {
|
||||
@ -279,7 +259,6 @@ public class TimeUtil {
|
||||
* Equivalent to {@link #durationToLongString(long, TimeUnit, TimeUnit, boolean, boolean, boolean) TimeUnit.durationToLongString(msDuration, TimeUnit.DAYS, milliseconds ? TimeUnit.MILLISECONDS : TimeUnit.SECONDS, true, true, false)}
|
||||
* @param msDuration the duration in ms
|
||||
* @param milliseconds if the milliseconds are displayed or not
|
||||
* @return
|
||||
*/
|
||||
public static String durationToString(long msDuration, boolean milliseconds) {
|
||||
return durationToLongString(msDuration, TimeUnit.DAYS, milliseconds ? TimeUnit.MILLISECONDS : TimeUnit.SECONDS, true, true, false);
|
||||
@ -287,8 +266,7 @@ public class TimeUtil {
|
||||
|
||||
/**
|
||||
* Equivalent to {@link #durationToLongString(long, TimeUnit, TimeUnit, boolean, boolean, boolean) TimeUnit.durationToLongString(msDuration, TimeUnit.DAYS, TimeUnit.SECONDS, true, true, false)}
|
||||
* @param msDuration
|
||||
* @return
|
||||
* @param msDuration the duration in ms
|
||||
*/
|
||||
public static String durationToString(long msDuration) {
|
||||
return durationToLongString(msDuration, TimeUnit.DAYS, TimeUnit.SECONDS, true, true, false);
|
||||
@ -296,8 +274,7 @@ public class TimeUtil {
|
||||
|
||||
/**
|
||||
* Equivalent to {@link #durationToLongString(long, TimeUnit, TimeUnit, boolean, boolean, boolean) TimeUnit.durationToLongString(msDuration, TimeUnit.DAYS, TimeUnit.SECONDS, false, false, false)}
|
||||
* @param msDuration
|
||||
* @return
|
||||
* @param msDuration the duration in ms
|
||||
*/
|
||||
public static String durationToParsableString(long msDuration) {
|
||||
return durationToLongString(msDuration, TimeUnit.DAYS, TimeUnit.SECONDS, false, false, false);
|
||||
@ -306,9 +283,10 @@ public class TimeUtil {
|
||||
|
||||
|
||||
/**
|
||||
* @see {@link com.earth2me.essentials.utils.DateUtil#parseDuration(String, boolean)}
|
||||
* @see <a href="https://github.com/EssentialsX/Essentials/blob/2.x/Essentials/src/main/java/com/earth2me/essentials/utils/DateUtil.java">Essentials DateUtil#parseDuration(String, boolean)</a>
|
||||
*/
|
||||
public static long parseDuration(String time, boolean future) throws Exception {
|
||||
@SuppressWarnings("RegExpSimplifiable")
|
||||
Pattern timePattern = Pattern.compile("(?:([0-9]+)\\s*y[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*mo[a-z]*[,\\s]*)?"
|
||||
+ "(?:([0-9]+)\\s*w[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*d[a-z]*[,\\s]*)?"
|
||||
+ "(?:([0-9]+)\\s*h[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*m[a-z]*[,\\s]*)?"
|
||||
@ -367,17 +345,13 @@ public class TimeUtil {
|
||||
List<String> remainingSuffixes = new ArrayList<>(allSuffixes);
|
||||
char[] tokenChars = token.toCharArray();
|
||||
String accSuffix = "";
|
||||
for (int i = 0; i < tokenChars.length; i++) {
|
||||
char c = tokenChars[i];
|
||||
for (char c : tokenChars) {
|
||||
if (Character.isDigit(c)) {
|
||||
scanAndRemovePastSuffixes(remainingSuffixes, accSuffix);
|
||||
accSuffix = "";
|
||||
continue;
|
||||
}
|
||||
else if (Character.isLetter(c)) {
|
||||
} else if (Character.isLetter(c)) {
|
||||
accSuffix += c;
|
||||
}
|
||||
else
|
||||
} else
|
||||
return Collections.emptyList();
|
||||
}
|
||||
String prefixToken = token.substring(0, token.length() - accSuffix.length());
|
||||
@ -388,14 +362,12 @@ public class TimeUtil {
|
||||
};
|
||||
}
|
||||
|
||||
private static List<String> allSuffixes = Arrays.asList("y", "mo", "w", "d", "h", "m", "s");
|
||||
private static List<String> emptyTokenSuggestions = allSuffixes.stream().map(p -> "1" + p).collect(Collectors.toList());
|
||||
private static final List<String> allSuffixes = Arrays.asList("y", "mo", "w", "d", "h", "m", "s");
|
||||
private static final List<String> emptyTokenSuggestions = allSuffixes.stream().map(p -> "1" + p).collect(Collectors.toList());
|
||||
private static void scanAndRemovePastSuffixes(List<String> suffixes, String foundSuffix) {
|
||||
for (int i = 0; i < suffixes.size(); i++) {
|
||||
if (foundSuffix.startsWith(suffixes.get(i))) {
|
||||
for (int j = i; j >= 0; j--) {
|
||||
suffixes.remove(j);
|
||||
}
|
||||
suffixes.subList(0, i + 1).clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -116,9 +116,7 @@ public class TypeConverter {
|
||||
* @param o the object to convert to good type
|
||||
* @param mapIntKeys if the String key representing an int should be duplicated as integer type,
|
||||
* which map to the same value as the original String key. For example, if a key is "12" and map
|
||||
* to the object <i>o</i>, an integer key 12 will be added and map to the same object
|
||||
* <i>o</i>
|
||||
* @return
|
||||
* to the object <i>o</i>, an integer key 12 will be added and map to the same object <i>o</i>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<Object, Object> toMap(Object o, boolean mapIntKeys) {
|
||||
@ -139,7 +137,7 @@ public class TypeConverter {
|
||||
try {
|
||||
int intKey = Integer.parseInt((String)entry.getKey());
|
||||
newEntries.put(intKey, entry.getValue());
|
||||
} catch (NumberFormatException e) { }
|
||||
} catch (NumberFormatException ignored) { }
|
||||
}
|
||||
}
|
||||
if (!newEntries.isEmpty()) {
|
||||
@ -150,8 +148,7 @@ public class TypeConverter {
|
||||
return currMap;
|
||||
}
|
||||
|
||||
if (o instanceof List) {
|
||||
List<?> list = (List<?>) o;
|
||||
if (o instanceof List<?> list) {
|
||||
Map<Object, Object> map = new HashMap<>();
|
||||
for(int i = 0; i < list.size(); i++) {
|
||||
map.put(Integer.toString(i), list.get(i));
|
||||
@ -200,7 +197,6 @@ public class TypeConverter {
|
||||
|
||||
|
||||
public static class ConvertionException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ConvertionException(String m) {
|
||||
super(m);
|
||||
|
@ -30,13 +30,13 @@ import fr.pandacube.lib.paper.util.BukkitEvent;
|
||||
*/
|
||||
public class GUIHotBar implements Listener {
|
||||
|
||||
private Map<ItemStack, BiConsumer<PlayerInventory, ItemStack>> itemsAndSetters = new HashMap<>();
|
||||
private final Map<ItemStack, BiConsumer<PlayerInventory, ItemStack>> itemsAndSetters = new HashMap<>();
|
||||
|
||||
private Map<ItemStack, Consumer<Player>> itemsAndRunnables = new HashMap<>();
|
||||
private final Map<ItemStack, Consumer<Player>> itemsAndRunnables = new HashMap<>();
|
||||
|
||||
private final int defltSlot;
|
||||
|
||||
private List<Player> currentPlayers = new ArrayList<>();
|
||||
private final List<Player> currentPlayers = new ArrayList<>();
|
||||
|
||||
public GUIHotBar(int defaultSlot) {
|
||||
defltSlot = Math.max(0, Math.min(8, defaultSlot));
|
||||
@ -50,7 +50,6 @@ public class GUIHotBar implements Listener {
|
||||
* @param i the item stack
|
||||
* @param setter code executed to put the item in the inventory. Additionally check for permission before doing the addition.
|
||||
* @param run the Runnable to run when the user right click on the item in the hotbar.
|
||||
* @return
|
||||
*/
|
||||
public GUIHotBar addItem(ItemStack i, BiConsumer<PlayerInventory, ItemStack> setter, Consumer<Player> run) {
|
||||
itemsAndSetters.put(i, setter);
|
||||
@ -65,8 +64,7 @@ public class GUIHotBar implements Listener {
|
||||
/**
|
||||
* Add the hotbar elements to this player.
|
||||
*
|
||||
* The players is automatically removed when it quit. You can remove it before by calling {@link #removePlayer(Player)}.
|
||||
* @param p
|
||||
* The players is automatically removed when they quit. You can remove it before by calling {@link #removePlayer(Player)}.
|
||||
*/
|
||||
public void addPlayer(Player p) {
|
||||
if (!currentPlayers.contains(p))
|
||||
@ -81,7 +79,6 @@ public class GUIHotBar implements Listener {
|
||||
|
||||
/**
|
||||
* Detach this player from this hotbar manager and removes the managed items from the players inventory.
|
||||
* @param p
|
||||
*/
|
||||
public void removePlayer(Player p) {
|
||||
if (!currentPlayers.contains(p))
|
||||
@ -134,7 +131,7 @@ public class GUIHotBar implements Listener {
|
||||
|
||||
ItemStack item = event.getItemDrop().getItemStack();
|
||||
for (ItemStack managed : itemsAndSetters.keySet()) {
|
||||
if (item != null && item.isSimilar(managed)) {
|
||||
if (item.isSimilar(managed)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
@ -173,12 +170,10 @@ public class GUIHotBar implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryClick(InventoryClickEvent event) {
|
||||
if (event.getClickedInventory() == null || !(event.getClickedInventory() instanceof PlayerInventory))
|
||||
if (event.getClickedInventory() == null || !(event.getClickedInventory() instanceof PlayerInventory inv))
|
||||
return;
|
||||
|
||||
PlayerInventory inv = (PlayerInventory) event.getClickedInventory();
|
||||
|
||||
if (!currentPlayers.contains(inv.getHolder()))
|
||||
|
||||
if (!currentPlayers.contains((Player) inv.getHolder()))
|
||||
return;
|
||||
|
||||
ItemStack item = event.getCurrentItem();
|
||||
|
@ -30,11 +30,11 @@ public class GUIInventory implements Listener {
|
||||
|
||||
public static final Map<Enchantment, Integer> FAKE_ENCHANT = ImmutableMap.of(Enchantment.DURABILITY, 1);
|
||||
|
||||
private Player player;
|
||||
private Inventory inv;
|
||||
private final Player player;
|
||||
private final Inventory inv;
|
||||
private Consumer<InventoryCloseEvent> onCloseEvent;
|
||||
private boolean isOpened = false;
|
||||
private Map<Integer, Consumer<InventoryClickEvent>> onClickEvents;
|
||||
private final Map<Integer, Consumer<InventoryClickEvent>> onClickEvents;
|
||||
|
||||
public GUIInventory(Player p, int nbLines, Chat title, Consumer<InventoryCloseEvent> closeEventAction,
|
||||
Plugin pl) {
|
||||
|
@ -139,9 +139,8 @@ public class NMSReflect {
|
||||
/**
|
||||
* @param mojName the binary name of the desired class, on the mojang mapping.
|
||||
* @throws NullPointerException if there is no mapping for the provided Mojang mapped class.
|
||||
* @throws ClassNotFoundException if there is a mapping, but the runtime class was not found.
|
||||
*/
|
||||
public static ClassMapping mojClass(String mojName) throws ClassNotFoundException {
|
||||
public static ClassMapping mojClass(String mojName) {
|
||||
return Objects.requireNonNull(CLASSES_BY_MOJ.get(mojName), "Unable to find the Mojang mapped class '" + mojName + "'");
|
||||
}
|
||||
|
||||
@ -339,7 +338,6 @@ public class NMSReflect {
|
||||
* @param mojParametersType the list of parameters of the method.
|
||||
* Each parameter type must be an instance of one of the following type:
|
||||
* {@link Type}, {@link Class}, {@link ReflectClass} or {@link ClassMapping}.
|
||||
* @return
|
||||
* @throws IllegalArgumentException if one of the parameter has an invalid type
|
||||
* @throws NullPointerException if one of the parameter is null, or if there is no mapping for the provided Mojang mapped method.
|
||||
* @throws ClassNotFoundException if there is no runtime class to represent one of the provided parametersType.
|
||||
@ -368,7 +366,6 @@ public class NMSReflect {
|
||||
/**
|
||||
*
|
||||
* @param mojName the Mojang mapped name of the field.
|
||||
* @return
|
||||
* @throws NullPointerException if there is no mapping for the provided Mojang mapped field.
|
||||
* @throws NoSuchFieldException if there is no runtime method to represent the provided method.
|
||||
*/
|
||||
@ -393,9 +390,7 @@ public class NMSReflect {
|
||||
String classToPrint = isObfClass ? obfName : mojName;
|
||||
String classSimpleName = classToPrint.substring(classToPrint.lastIndexOf('.') + 1);
|
||||
String htmlTitle = classSimpleName.equals(classToPrint) ? "" : (" title='" + classToPrint + "'");
|
||||
String typeHTML = "<a href='#c" + id + "'" + htmlTitle + " class='cl'>" + classSimpleName + "</a>";
|
||||
|
||||
return typeHTML;
|
||||
return "<a href='#c" + id + "'" + htmlTitle + " class='cl'>" + classSimpleName + "</a>";
|
||||
}
|
||||
|
||||
|
||||
@ -420,7 +415,7 @@ public class NMSReflect {
|
||||
String classToPrint = obf ? obfName : mojName;
|
||||
int packageSep = classToPrint.lastIndexOf('.');
|
||||
String classSimpleName = classToPrint.substring(packageSep + 1);
|
||||
String classPackages = classToPrint.substring(0, packageSep > 0 ? packageSep : 0);
|
||||
String classPackages = classToPrint.substring(0, Math.max(packageSep, 0));
|
||||
String classHTML = (packageSep >= 0 ? (classPackages + ".") : "") + "<b class='cl'>" + classSimpleName + "</b>";
|
||||
|
||||
Type superClass = superClass(obf);
|
||||
@ -487,7 +482,7 @@ public class NMSReflect {
|
||||
|
||||
|
||||
|
||||
private static record MethodId(String name, List<Type> parametersType) implements Comparable<MethodId> {
|
||||
private record MethodId(String name, List<Type> parametersType) implements Comparable<MethodId> {
|
||||
@Override
|
||||
public int compareTo(MethodId o) {
|
||||
int cmp = name.compareTo(o.name);
|
||||
@ -497,14 +492,13 @@ public class NMSReflect {
|
||||
}
|
||||
|
||||
private String toHTML(boolean isObfClass, boolean isStatic, boolean isFinal) {
|
||||
String paramsHTML = parametersType.stream().map(p -> p.toHTML(isObfClass)).collect(Collectors.joining(", "));
|
||||
String cl = "mtd";
|
||||
if (isStatic)
|
||||
cl += " st";
|
||||
if (isFinal)
|
||||
cl += " fn";
|
||||
String identifierHTML = "<span class='" + cl + "'>" + name + "</span>(" + paramsHTML + ")";
|
||||
return identifierHTML;
|
||||
String paramsHTML = parametersType.stream().map(p -> p.toHTML(isObfClass)).collect(Collectors.joining(", "));
|
||||
String cl = "mtd";
|
||||
if (isStatic)
|
||||
cl += " st";
|
||||
if (isFinal)
|
||||
cl += " fn";
|
||||
return "<span class='" + cl + "'>" + name + "</span>(" + paramsHTML + ")";
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
@ -516,7 +510,7 @@ public class NMSReflect {
|
||||
|
||||
|
||||
|
||||
private static record MemberDesc<I extends Comparable<I>>(I identifier, Type returnType) {
|
||||
private record MemberDesc<I extends Comparable<I>>(I identifier, Type returnType) {
|
||||
private String toHTML(boolean isObfClass, boolean isStatic, boolean isFinal) {
|
||||
String identifierHTML = "";
|
||||
if (identifier instanceof MethodId mId)
|
||||
@ -541,7 +535,7 @@ public class NMSReflect {
|
||||
|
||||
List<Type> paramsType = new ArrayList<>();
|
||||
|
||||
while ((r = (char) descReader.read()) != ')') {
|
||||
while (((char) descReader.read()) != ')') {
|
||||
descReader.skip(-1);
|
||||
paramsType.add(Type.parse(descReader));
|
||||
}
|
||||
@ -565,8 +559,8 @@ public class NMSReflect {
|
||||
|
||||
|
||||
private static abstract class MemberMapping<I extends Comparable<I>, R extends ReflectMember<?, ?, ?, ?>> {
|
||||
private String htmlTypeChar;
|
||||
/* package */ MemberDesc<I> obfDesc, mojDesc;
|
||||
private final String htmlTypeChar;
|
||||
/* package */ final MemberDesc<I> obfDesc, mojDesc;
|
||||
/* package */ ClassMapping declaringClass;
|
||||
private MemberMapping(String htmlType, MemberDesc<I> obfDesc, MemberDesc<I> mojDesc) {
|
||||
htmlTypeChar = htmlType;
|
||||
|
@ -141,14 +141,11 @@ public class Type implements Comparable<Type> {
|
||||
|
||||
/* package */ static Type parse(StringReader desc) {
|
||||
try {
|
||||
StringBuilder sbRaw = new StringBuilder();
|
||||
int arrayDepth = 0;
|
||||
char c;
|
||||
while ((c = (char) desc.read()) == '[') {
|
||||
sbRaw.append(c);
|
||||
arrayDepth++;
|
||||
}
|
||||
sbRaw.append(c);
|
||||
String type = switch(c) {
|
||||
case 'Z' -> "boolean";
|
||||
case 'B' -> "byte";
|
||||
@ -162,10 +159,8 @@ public class Type implements Comparable<Type> {
|
||||
StringBuilder sbClass = new StringBuilder();
|
||||
char r;
|
||||
while ((r = (char) desc.read()) != ';') {
|
||||
sbRaw.append(c);
|
||||
sbClass.append(r);
|
||||
}
|
||||
sbRaw.append(c);
|
||||
yield NMSReflect.binaryClassName(sbClass.toString());
|
||||
}
|
||||
default -> "void";
|
||||
|
@ -1,18 +1,13 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper;
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static fr.pandacube.lib.paper.reflect.wrapper.ReflectWrapper.unwrap;
|
||||
import fr.pandacube.lib.core.util.MappedListView;
|
||||
|
||||
public class ReflectListWrapper<W extends ReflectWrapperI> extends AbstractList<W> implements ReflectWrapperTypedI<List<Object>> {
|
||||
public class ReflectListWrapper<W extends ReflectWrapperI> extends MappedListView<Object, W> implements ReflectWrapperTypedI<List<Object>> {
|
||||
|
||||
private final List<Object> wrappedList;
|
||||
private final Class<W> expectedWrapperClass;
|
||||
|
||||
/* package */ ReflectListWrapper(Class<W> expectedWrapperClass) {
|
||||
@ -25,159 +20,23 @@ public class ReflectListWrapper<W extends ReflectWrapperI> extends AbstractList<
|
||||
this((List<Object>) (listCreator == null ? new ArrayList<>() : listCreator.get()), expectedWrapperClass);
|
||||
}
|
||||
/* package */ ReflectListWrapper(List<Object> wrappedList, Class<W> expectedWrapperClass) {
|
||||
this.wrappedList = Objects.requireNonNull(wrappedList);
|
||||
super(wrappedList, el -> ReflectWrapper.wrap(el, expectedWrapperClass), ReflectWrapper::unwrap);
|
||||
this.expectedWrapperClass = expectedWrapperClass;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Class<List<Object>> __getRuntimeClass() {
|
||||
return (Class<List<Object>>) wrappedList.getClass();
|
||||
return (Class<List<Object>>) backend.getClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> __getRuntimeInstance() {
|
||||
return wrappedList;
|
||||
}
|
||||
|
||||
private W wrap(Object el) {
|
||||
return ReflectWrapper.wrap(el, expectedWrapperClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public W get(int index) {
|
||||
return wrap(wrappedList.get(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return wrappedList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(W w) {
|
||||
return wrappedList.add(unwrap(w));
|
||||
}
|
||||
|
||||
@Override
|
||||
public W set(int index, W element) {
|
||||
return wrap(wrappedList.set(index, unwrap(element)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, W element) {
|
||||
wrappedList.add(index, unwrap(element));
|
||||
}
|
||||
|
||||
@Override
|
||||
public W remove(int index) {
|
||||
return wrap(wrappedList.remove(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object o) {
|
||||
return wrappedList.indexOf(o instanceof ReflectWrapperI w ? w.__getRuntimeInstance() : o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object o) {
|
||||
return wrappedList.lastIndexOf(o instanceof ReflectWrapperI w ? w.__getRuntimeInstance() : o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
wrappedList.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<W> iterator() {
|
||||
return new Iterator<W>() {
|
||||
final Iterator<Object> wrappedIt = wrappedList.iterator();
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return wrappedIt.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public W next() {
|
||||
return wrap(wrappedIt.next());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
wrappedIt.remove();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator<W> listIterator() {
|
||||
return listIterator(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator<W> listIterator(int index) {
|
||||
return new ListIterator<W>() {
|
||||
final ListIterator<Object> wrappedIt = wrappedList.listIterator(index);
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return wrappedIt.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public W next() {
|
||||
return wrap(wrappedIt.next());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrevious() {
|
||||
return wrappedIt.hasPrevious();
|
||||
}
|
||||
|
||||
@Override
|
||||
public W previous() {
|
||||
return wrap(wrappedIt.previous());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextIndex() {
|
||||
return wrappedIt.nextIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int previousIndex() {
|
||||
return wrappedIt.previousIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
wrappedIt.remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(W w) {
|
||||
wrappedIt.set(unwrap(w));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(W w) {
|
||||
wrappedIt.add(unwrap(w));
|
||||
}
|
||||
};
|
||||
return backend;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<W> subList(int fromIndex, int toIndex) {
|
||||
return new ReflectListWrapper<>(wrappedList.subList(fromIndex, toIndex), expectedWrapperClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return wrappedList.equals(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return wrappedList.hashCode();
|
||||
return new ReflectListWrapper<>(backend.subList(fromIndex, toIndex), expectedWrapperClass);
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,9 @@ public abstract class ReflectWrapper implements ReflectWrapperI {
|
||||
public static <W extends ReflectWrapperI> W wrap(Object runtimeObj) {
|
||||
return wrap(runtimeObj, null);
|
||||
}
|
||||
public static <T, W extends ReflectWrapperTypedI<T>> W wrapTyped(T runtimeObj, Class<W> expectedWrapperClass) {
|
||||
return wrap(runtimeObj, expectedWrapperClass);
|
||||
}
|
||||
public static <W extends ReflectWrapperI> W wrap(Object runtimeObj, Class<W> expectedWrapperClass) {
|
||||
if (runtimeObj == null)
|
||||
return null;
|
||||
|
@ -214,23 +214,10 @@ public class WrapperRegistry {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private static class RegistryEntry {
|
||||
Class<?> runtimeClass;
|
||||
Class<? extends ReflectWrapperI> wrapperClass;
|
||||
Class<? extends ReflectWrapperI> concreteWrapperClass;
|
||||
ReflectConstructor<? extends ReflectWrapperI> objectWrapperConstructor;
|
||||
|
||||
public RegistryEntry(Class<?> runtimeClass, Class<? extends ReflectWrapperI> wrapperClass, Class<? extends ReflectWrapperI> concreteWrapperClass, ReflectConstructor<? extends ReflectWrapperI> objectWrapperConstructor) {
|
||||
this.runtimeClass = runtimeClass;
|
||||
this.wrapperClass = wrapperClass;
|
||||
this.concreteWrapperClass = concreteWrapperClass;
|
||||
this.objectWrapperConstructor = objectWrapperConstructor;
|
||||
}
|
||||
private record RegistryEntry(Class<?> runtimeClass,
|
||||
Class<? extends ReflectWrapperI> wrapperClass,
|
||||
Class<? extends ReflectWrapperI> concreteWrapperClass,
|
||||
ReflectConstructor<? extends ReflectWrapperI> objectWrapperConstructor) {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.brigadier;
|
||||
|
||||
import fr.pandacube.lib.core.util.Reflect;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.ReflectWrapper;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.ReflectWrapperTyped;
|
||||
|
||||
import static fr.pandacube.lib.core.util.ThrowableUtil.wrapEx;
|
||||
|
@ -10,11 +10,11 @@ import static fr.pandacube.lib.core.util.ThrowableUtil.wrapEx;
|
||||
|
||||
@ConcreteWrapper(WorldVersion.__concrete.class)
|
||||
public interface WorldVersion extends ReflectWrapperI {
|
||||
public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.WorldVersion"));
|
||||
ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.WorldVersion"));
|
||||
|
||||
|
||||
|
||||
public static class __concrete extends ReflectWrapper implements WorldVersion {
|
||||
class __concrete extends ReflectWrapper implements WorldVersion {
|
||||
private __concrete(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
@ -12,8 +12,9 @@ public class BlockPosArgument extends ReflectWrapperTyped<ArgumentType<?>> {
|
||||
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.coordinates.BlockPosArgument"));
|
||||
private static final Reflect.ReflectMethod<?> blockPos = wrapEx(() -> MAPPING.mojMethod("blockPos"));
|
||||
|
||||
public static ArgumentType<?> blockPos() {
|
||||
return (ArgumentType<?>) wrapReflectEx(() -> blockPos.invokeStatic());
|
||||
@SuppressWarnings("unchecked")
|
||||
public static ArgumentType<Object> blockPos() {
|
||||
return (ArgumentType<Object>) wrapReflectEx(() -> blockPos.invokeStatic());
|
||||
}
|
||||
|
||||
protected BlockPosArgument(Object obj) {
|
||||
|
@ -12,8 +12,9 @@ public class ComponentArgument extends ReflectWrapperTyped<ArgumentType<?>> {
|
||||
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.ComponentArgument"));
|
||||
private static final Reflect.ReflectMethod<?> textComponent = wrapEx(() -> MAPPING.mojMethod("textComponent"));
|
||||
|
||||
public static ArgumentType<?> textComponent() {
|
||||
return (ArgumentType<?>) wrapReflectEx(() -> textComponent.invokeStatic());
|
||||
@SuppressWarnings("unchecked")
|
||||
public static ArgumentType<Object> textComponent() {
|
||||
return (ArgumentType<Object>) wrapReflectEx(() -> textComponent.invokeStatic());
|
||||
}
|
||||
|
||||
protected ComponentArgument(Object obj) {
|
||||
|
@ -15,19 +15,19 @@ import static fr.pandacube.lib.paper.reflect.wrapper.ReflectWrapper.wrap;
|
||||
|
||||
@ConcreteWrapper(Coordinates.__concrete.class)
|
||||
public interface Coordinates extends ReflectWrapperI {
|
||||
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.coordinates.Coordinates"));
|
||||
public static final Reflect.ReflectMethod<?> getPosition = wrapEx(() -> MAPPING.mojMethod("getPosition", CommandSourceStack.MAPPING));
|
||||
public static final Reflect.ReflectMethod<?> getBlockPos = wrapEx(() -> MAPPING.mojMethod("getBlockPos", CommandSourceStack.MAPPING));
|
||||
NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.coordinates.Coordinates"));
|
||||
Reflect.ReflectMethod<?> getPosition = wrapEx(() -> MAPPING.mojMethod("getPosition", CommandSourceStack.MAPPING));
|
||||
Reflect.ReflectMethod<?> getBlockPos = wrapEx(() -> MAPPING.mojMethod("getBlockPos", CommandSourceStack.MAPPING));
|
||||
|
||||
public default Vec3 getPosition(BukkitBrigadierCommandSource source) {
|
||||
default Vec3 getPosition(BukkitBrigadierCommandSource source) {
|
||||
return wrap(wrapReflectEx(() -> getPosition.invoke(__getRuntimeInstance(), source)), Vec3.class);
|
||||
}
|
||||
|
||||
public default BlockPos getBlockPos(BukkitBrigadierCommandSource source) {
|
||||
default BlockPos getBlockPos(BukkitBrigadierCommandSource source) {
|
||||
return wrap(wrapReflectEx(() -> getBlockPos.invoke(__getRuntimeInstance(), source)), BlockPos.class);
|
||||
}
|
||||
|
||||
static class __concrete extends ReflectWrapper implements Coordinates {
|
||||
class __concrete extends ReflectWrapper implements Coordinates {
|
||||
protected __concrete(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
@ -15,20 +15,24 @@ public class EntityArgument extends ReflectWrapperTyped<ArgumentType<?>> {
|
||||
private static final Reflect.ReflectMethod<?> player = wrapEx(() -> MAPPING.mojMethod("player"));
|
||||
private static final Reflect.ReflectMethod<?> players = wrapEx(() -> MAPPING.mojMethod("players"));
|
||||
|
||||
public static ArgumentType<?> entity() {
|
||||
return (ArgumentType<?>) wrapReflectEx(() -> entity.invokeStatic());
|
||||
@SuppressWarnings("unchecked")
|
||||
public static ArgumentType<Object> entity() {
|
||||
return (ArgumentType<Object>) wrapReflectEx(() -> entity.invokeStatic());
|
||||
}
|
||||
|
||||
public static ArgumentType<?> entities() {
|
||||
return (ArgumentType<?>) wrapReflectEx(() -> entities.invokeStatic());
|
||||
@SuppressWarnings("unchecked")
|
||||
public static ArgumentType<Object> entities() {
|
||||
return (ArgumentType<Object>) wrapReflectEx(() -> entities.invokeStatic());
|
||||
}
|
||||
|
||||
public static ArgumentType<?> player() {
|
||||
return (ArgumentType<?>) wrapReflectEx(() -> player.invokeStatic());
|
||||
@SuppressWarnings("unchecked")
|
||||
public static ArgumentType<Object> player() {
|
||||
return (ArgumentType<Object>) wrapReflectEx(() -> player.invokeStatic());
|
||||
}
|
||||
|
||||
public static ArgumentType<?> players() {
|
||||
return (ArgumentType<?>) wrapReflectEx(() -> players.invokeStatic());
|
||||
@SuppressWarnings("unchecked")
|
||||
public static ArgumentType<Object> players() {
|
||||
return (ArgumentType<Object>) wrapReflectEx(() -> players.invokeStatic());
|
||||
}
|
||||
|
||||
|
||||
|
@ -12,8 +12,9 @@ public class GameProfileArgument extends ReflectWrapperTyped<ArgumentType<?>> {
|
||||
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.GameProfileArgument"));
|
||||
private static final Reflect.ReflectMethod<?> gameProfile = wrapEx(() -> MAPPING.mojMethod("gameProfile"));
|
||||
|
||||
public static ArgumentType<?> gameProfile() {
|
||||
return (ArgumentType<?>) wrapReflectEx(() -> gameProfile.invokeStatic());
|
||||
@SuppressWarnings("unchecked")
|
||||
public static ArgumentType<Object> gameProfile() {
|
||||
return (ArgumentType<Object>) wrapReflectEx(() -> gameProfile.invokeStatic());
|
||||
}
|
||||
|
||||
protected GameProfileArgument(Object obj) {
|
||||
|
@ -12,8 +12,9 @@ public class ResourceLocationArgument extends ReflectWrapperTyped<ArgumentType<?
|
||||
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.ResourceLocationArgument"));
|
||||
private static final Reflect.ReflectMethod<?> id = wrapEx(() -> MAPPING.mojMethod("id"));
|
||||
|
||||
public static ArgumentType<?> id() {
|
||||
return (ArgumentType<?>) wrapReflectEx(() -> id.invokeStatic());
|
||||
@SuppressWarnings("unchecked")
|
||||
public static ArgumentType<Object> id() {
|
||||
return (ArgumentType<Object>) wrapReflectEx(() -> id.invokeStatic());
|
||||
}
|
||||
|
||||
protected ResourceLocationArgument(Object obj) {
|
||||
|
@ -12,8 +12,9 @@ public class Vec3Argument extends ReflectWrapperTyped<ArgumentType<?>> {
|
||||
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.coordinates.Vec3Argument"));
|
||||
private static final Reflect.ReflectMethod<?> vec3 = wrapEx(() -> MAPPING.mojMethod("vec3", boolean.class));
|
||||
|
||||
public static ArgumentType<?> vec3(boolean centerIntegers) {
|
||||
return (ArgumentType<?>) wrapReflectEx(() -> vec3.invokeStatic(centerIntegers));
|
||||
@SuppressWarnings("unchecked")
|
||||
public static ArgumentType<Object> vec3(boolean centerIntegers) {
|
||||
return (ArgumentType<Object>) wrapReflectEx(() -> vec3.invokeStatic(centerIntegers));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.core;
|
||||
|
||||
import fr.pandacube.lib.core.util.Reflect;
|
||||
import fr.pandacube.lib.paper.reflect.NMSReflect;
|
||||
import fr.pandacube.lib.paper.reflect.wrapper.ReflectWrapper;
|
||||
|
||||
import static fr.pandacube.lib.core.util.ThrowableUtil.wrapEx;
|
||||
|
||||
|
@ -12,17 +12,17 @@ import fr.pandacube.lib.paper.reflect.wrapper.ReflectWrapperI;
|
||||
|
||||
@ConcreteWrapper(Tag.__concrete.class)
|
||||
public interface Tag extends ReflectWrapperI {
|
||||
public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.nbt.Tag"));
|
||||
public static final ReflectMethod<?> getAsString = wrapEx(() -> MAPPING.mojMethod("getAsString"));
|
||||
ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.nbt.Tag"));
|
||||
ReflectMethod<?> getAsString = wrapEx(() -> MAPPING.mojMethod("getAsString"));
|
||||
|
||||
|
||||
public default String getAsString() {
|
||||
default String getAsString() {
|
||||
return wrapReflectEx(() -> (String) getAsString.invoke(__getRuntimeInstance()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class __concrete extends ReflectWrapper implements Tag {
|
||||
class __concrete extends ReflectWrapper implements Tag {
|
||||
private __concrete(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
@ -9,10 +9,10 @@ import static fr.pandacube.lib.core.util.ThrowableUtil.wrapEx;
|
||||
|
||||
@ConcreteWrapper(Component.__concrete.class)
|
||||
public interface Component extends ReflectWrapperI {
|
||||
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.network.chat.Component"));
|
||||
NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.network.chat.Component"));
|
||||
|
||||
|
||||
public class __concrete extends ReflectWrapper implements Component {
|
||||
class __concrete extends ReflectWrapper implements Component {
|
||||
protected __concrete(Object obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user