Fixing a shit ton of warning / code style and stuff (code inspector from IDEA)

This commit is contained in:
Marc Baloup 2022-07-10 00:55:56 +02:00
parent 276b1d323a
commit b6104a76c1
118 changed files with 1116 additions and 1574 deletions

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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]));
}
}

View File

@ -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)

View File

@ -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();
}

View File

@ -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) {

View File

@ -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;
}
}

View File

@ -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>

View File

@ -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)

View File

@ -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));

View File

@ -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()));
// }
// }
}

View File

@ -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) {

View File

@ -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));
}

View File

@ -11,7 +11,6 @@ import java.util.logging.Logger;
*
*/
public class BadCommandUsage extends RuntimeException {
private static final long serialVersionUID = 1L;
public BadCommandUsage() {
super();

View File

@ -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);

View File

@ -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));
}

View File

@ -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;

View File

@ -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) {

View File

@ -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) {}
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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) {
}

View File

@ -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);
}

View File

@ -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));
}
/**

View File

@ -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

View File

@ -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
}

View File

@ -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() {

View File

@ -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);
}
}

View File

@ -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<>());
}
}

View File

@ -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;

View File

@ -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) {

View File

@ -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.

View File

@ -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.

View File

@ -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);
}

View File

@ -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() {

View File

@ -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) {}
}

View File

@ -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);
}

View File

@ -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) {

View File

@ -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();

View File

@ -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() {

View File

@ -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) {}
}
}

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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() {

View File

@ -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);
}
}

View File

@ -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")) {

View File

@ -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 cant 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;
}

View File

@ -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

View File

@ -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 permissions prefix(es) and suffix(es) of the player,
* and with color codes translated to Minecrafts 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;

View File

@ -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 players 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 players 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 dont 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 dont 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();
}

View File

@ -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);
}

View File

@ -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) -> {

View File

@ -46,7 +46,6 @@ public class SQLPlayerIgnore extends SQLElement<SQLPlayerIgnore> {
}
if (el != null && !newIgnoreState) {
el.delete();
return;
}
}

View File

@ -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<>();

View File

@ -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();
}

View File

@ -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) {

View File

@ -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;

View File

@ -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));

View File

@ -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;
}

View File

@ -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));
}
/**

View File

@ -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());
}
}

View File

@ -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;
}

View File

@ -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();
}
}

View File

@ -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);

View File

@ -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();

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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);

View File

@ -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));
}
};
}

View File

@ -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;

View File

@ -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);

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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) {

View File

@ -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<>();
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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) {

View File

@ -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 d1h
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 d1h
@ -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;
}
}

View File

@ -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);

View File

@ -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();

View File

@ -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) {

View File

@ -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;

View File

@ -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";

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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) {
}
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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);
}

View File

@ -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());
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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));
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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