From bb6ae7d37037180f4cb29a084b1e2ab1a86c747a Mon Sep 17 00:00:00 2001 From: Dico Date: Fri, 28 Sep 2018 05:47:32 +0100 Subject: Add /p global list, tweaks/fixes --- build.gradle.kts | 6 + .../main/java/io/dico/dicore/command/Command.java | 4 +- .../io/dico/dicore/command/CommandBuilder.java | 14 +-- .../io/dico/dicore/command/ExecutionContext.java | 8 +- .../io/dico/dicore/command/ICommandAddress.java | 6 +- .../dicore/command/ModifiableCommandAddress.java | 40 +++---- .../io/dico/dicore/command/RootCommandAddress.java | 3 +- .../command/chat/AbstractChatController.java | 112 ------------------- .../dicore/command/chat/AbstractChatHandler.java | 94 ++++++++++++++++ .../dico/dicore/command/chat/ChatControllers.java | 20 ---- .../io/dico/dicore/command/chat/ChatHandlers.java | 20 ++++ .../dico/dicore/command/chat/IChatController.java | 31 ------ .../io/dico/dicore/command/chat/IChatHandler.java | 60 ++++++++++ .../chat/help/defaults/DefaultPageLayout.java | 4 +- .../chat/help/defaults/SubcommandsHelpTopic.java | 3 +- .../dicore/command/predef/DefaultGroupCommand.java | 2 +- .../io/dico/dicore/command/predef/HelpCommand.java | 2 +- .../dico/dicore/command/predef/SyntaxCommand.java | 2 +- .../reflect/KotlinReflectiveRegistration.kt | 2 +- .../src/main/java/io/dico/dicore/Formatting.java | 5 +- src/main/kotlin/io/dico/parcels2/PlayerProfile.kt | 8 +- src/main/kotlin/io/dico/parcels2/Privilege.kt | 24 +++- .../command/CommandsAdminPrivilegesGlobal.kt | 28 ++++- .../parcels2/command/CommandsPrivilegesGlobal.kt | 9 ++ .../dico/parcels2/command/ParcelCommandBuilder.kt | 2 +- .../command/ParcelOptionsInteractCommand.kt | 7 +- .../dico/parcels2/command/ParcelParameterTypes.kt | 6 +- .../dico/parcels2/command/ParcelsChatController.kt | 11 -- .../io/dico/parcels2/command/ParcelsChatHandler.kt | 24 ++++ .../parcels2/defaultimpl/DefaultParcelContainer.kt | 1 + .../io/dico/parcels2/defaultimpl/InfoBuilder.kt | 88 +++++++++++++++ .../io/dico/parcels2/defaultimpl/ParcelImpl.kt | 124 +++------------------ .../parcels2/defaultimpl/ParcelProviderImpl.kt | 7 +- .../io/dico/parcels2/listener/ParcelListeners.kt | 2 +- .../io/dico/parcels2/storage/exposed/ListTables.kt | 24 ++-- 35 files changed, 453 insertions(+), 350 deletions(-) delete mode 100644 dicore3/command/src/main/java/io/dico/dicore/command/chat/AbstractChatController.java create mode 100644 dicore3/command/src/main/java/io/dico/dicore/command/chat/AbstractChatHandler.java delete mode 100644 dicore3/command/src/main/java/io/dico/dicore/command/chat/ChatControllers.java create mode 100644 dicore3/command/src/main/java/io/dico/dicore/command/chat/ChatHandlers.java delete mode 100644 dicore3/command/src/main/java/io/dico/dicore/command/chat/IChatController.java create mode 100644 dicore3/command/src/main/java/io/dico/dicore/command/chat/IChatHandler.java delete mode 100644 src/main/kotlin/io/dico/parcels2/command/ParcelsChatController.kt create mode 100644 src/main/kotlin/io/dico/parcels2/command/ParcelsChatHandler.kt create mode 100644 src/main/kotlin/io/dico/parcels2/defaultimpl/InfoBuilder.kt diff --git a/build.gradle.kts b/build.gradle.kts index c745ca5..bd94b3f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -46,6 +46,12 @@ allprojects { } } +project(":dicore3:dicore3-core") { + dependencies { + compile("org.jetbrains:annotations:16.0.3") + } +} + project(":dicore3:dicore3-command") { apply() diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/Command.java b/dicore3/command/src/main/java/io/dico/dicore/command/Command.java index e423529..53e5821 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/Command.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/Command.java @@ -139,7 +139,7 @@ public abstract class Command { try { executeWithContext(executionContext); } catch (Throwable t) { - caller.getChatController().handleException(sender, executionContext, t); + caller.getChatHandler().handleException(sender, executionContext, t); } } @@ -159,7 +159,7 @@ public abstract class Command { //System.out.println("Post-contextfilters"); String message = execute(context.getSender(), context); - context.getAddress().getChatController().sendMessage(context.getSender(), EMessageType.RESULT, message); + context.sendMessage(EMessageType.RESULT, message); } public abstract String execute(CommandSender sender, ExecutionContext context) throws CommandException; diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/CommandBuilder.java b/dicore3/command/src/main/java/io/dico/dicore/command/CommandBuilder.java index 76211c2..63628d3 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/CommandBuilder.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/CommandBuilder.java @@ -1,6 +1,6 @@ package io.dico.dicore.command; -import io.dico.dicore.command.chat.IChatController; +import io.dico.dicore.command.chat.IChatHandler; import io.dico.dicore.command.parameter.type.IParameterTypeSelector; import io.dico.dicore.command.parameter.type.MapBasedParameterTypeSelector; import io.dico.dicore.command.parameter.type.ParameterType; @@ -340,16 +340,16 @@ public final class CommandBuilder { } /** - * Configure the chat controller at this address. The chat controller + * Configure the chat handler at this address. The chat handler * is used for all children down the tree if they don't explicitly have - * their own chat controller configured. If this isn't configured, - * {@code ChatControllers.defaultChat()} is used. + * their own chat handler configured. If this isn't configured, + * {@code ChatHandlers.defaultChat()} is used. * - * @param chatController the chat controller + * @param chatHandler the chat handler * @return this */ - public CommandBuilder setChatController(IChatController chatController) { - cur.setChatController(chatController); + public CommandBuilder setChatHandler(IChatHandler chatHandler) { + cur.setChatHandler(chatHandler); return this; } diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/ExecutionContext.java b/dicore3/command/src/main/java/io/dico/dicore/command/ExecutionContext.java index c473166..2a074e1 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/ExecutionContext.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/ExecutionContext.java @@ -229,7 +229,7 @@ public class ExecutionContext { } public Formatting getFormat(EMessageType type) { - return address.getChatController().getChatFormatForType(type); + return address.getChatHandler().getChatFormatForType(type); } /** @@ -345,7 +345,7 @@ public class ExecutionContext { if (translateColours) { message = Formatting.translateChars('&', message); } - address.getChatController().sendMessage(this, messageType, message); + address.getChatHandler().sendMessage(this, messageType, message); } } @@ -367,13 +367,13 @@ public class ExecutionContext { public void sendHelpMessage(int page) { if (!muted) { - address.getChatController().sendHelpMessage(sender, this, address, page); + address.getChatHandler().sendHelpMessage(sender, this, address, page); } } public void sendSyntaxMessage() { if (!muted) { - address.getChatController().sendSyntaxMessage(sender, this, address); + address.getChatHandler().sendSyntaxMessage(sender, this, address); } } diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/ICommandAddress.java b/dicore3/command/src/main/java/io/dico/dicore/command/ICommandAddress.java index fb0d7b4..bef20e4 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/ICommandAddress.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/ICommandAddress.java @@ -1,6 +1,6 @@ package io.dico.dicore.command; -import io.dico.dicore.command.chat.IChatController; +import io.dico.dicore.command.chat.IChatHandler; import io.dico.dicore.command.parameter.ArgumentBuffer; import io.dico.dicore.command.predef.PredefinedCommand; import org.bukkit.command.CommandSender; @@ -161,9 +161,9 @@ public interface ICommandAddress { ICommandDispatcher getDispatcherForTree(); /** - * @return The desired chatcontroller for use by commands at this address and any sub-addresses, if they define no explicit chat controller. + * @return The desired chathandler for use by commands at this address and any sub-addresses, if they define no explicit chat handler. */ - IChatController getChatController(); + IChatHandler getChatHandler(); static ICommandAddress newChild() { return new ChildCommandAddress(); diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/ModifiableCommandAddress.java b/dicore3/command/src/main/java/io/dico/dicore/command/ModifiableCommandAddress.java index 6871462..0c4c476 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/ModifiableCommandAddress.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/ModifiableCommandAddress.java @@ -1,7 +1,7 @@ package io.dico.dicore.command; -import io.dico.dicore.command.chat.ChatControllers; -import io.dico.dicore.command.chat.IChatController; +import io.dico.dicore.command.chat.ChatHandlers; +import io.dico.dicore.command.chat.IChatHandler; import io.dico.dicore.command.predef.DefaultGroupCommand; import io.dico.dicore.command.predef.HelpCommand; import io.dico.dicore.command.predef.PredefinedCommand; @@ -12,10 +12,10 @@ public abstract class ModifiableCommandAddress implements ICommandAddress { Map children; Collection childrenMainKeys = Collections.emptyList(); - // the chat controller as configured by the programmer - IChatController chatController; - // cache for the algorithm that finds the first chat controller going up the tree - transient IChatController chatControllerCache; + // the chat handler as configured by the programmer + IChatHandler chatHandler; + // cache for the algorithm that finds the first chat handler going up the tree + transient IChatHandler cachedChatHandlerFallback; ModifiableCommandAddress helpChild; @@ -230,30 +230,30 @@ public abstract class ModifiableCommandAddress implements ICommandAddress { } @Override - public IChatController getChatController() { - if (chatControllerCache == null) { - if (chatController != null) { - chatControllerCache = chatController; + public IChatHandler getChatHandler() { + if (cachedChatHandlerFallback == null) { + if (chatHandler != null) { + cachedChatHandlerFallback = chatHandler; } else if (!hasParent()) { - chatControllerCache = ChatControllers.defaultChat(); + cachedChatHandlerFallback = ChatHandlers.defaultChat(); } else { - chatControllerCache = getParent().getChatController(); + cachedChatHandlerFallback = getParent().getChatHandler(); } } - return chatControllerCache; + return cachedChatHandlerFallback; } - public void setChatController(IChatController chatController) { - this.chatController = chatController; - resetChatControllerCache(new HashSet<>()); + public void setChatHandler(IChatHandler chatHandler) { + this.chatHandler = chatHandler; + resetChatHandlerCache(new HashSet<>()); } - void resetChatControllerCache(Set dejaVu) { + void resetChatHandlerCache(Set dejaVu) { if (dejaVu.add(this)) { - chatControllerCache = chatController; + cachedChatHandlerFallback = chatHandler; for (ChildCommandAddress address : children.values()) { - if (address.chatController == null) { - address.resetChatControllerCache(dejaVu); + if (address.chatHandler == null) { + address.resetChatHandlerCache(dejaVu); } } } diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/RootCommandAddress.java b/dicore3/command/src/main/java/io/dico/dicore/command/RootCommandAddress.java index aa84b67..10dade5 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/RootCommandAddress.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/RootCommandAddress.java @@ -1,7 +1,6 @@ package io.dico.dicore.command; import io.dico.dicore.command.parameter.ArgumentBuffer; -import io.dico.dicore.command.predef.DefaultGroupCommand; import io.dico.dicore.command.registration.BukkitCommand; import org.bukkit.Location; import org.bukkit.command.CommandSender; @@ -197,7 +196,7 @@ public class RootCommandAddress extends ModifiableCommandAddress implements ICom if (targetAddress == null) { targetAddress = this; } - targetAddress.getChatController().handleException(sender, context, t); + targetAddress.getChatHandler().handleException(sender, context, t); } return true; diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/chat/AbstractChatController.java b/dicore3/command/src/main/java/io/dico/dicore/command/chat/AbstractChatController.java deleted file mode 100644 index 000c094..0000000 --- a/dicore3/command/src/main/java/io/dico/dicore/command/chat/AbstractChatController.java +++ /dev/null @@ -1,112 +0,0 @@ -package io.dico.dicore.command.chat; - -import io.dico.dicore.Formatting; -import io.dico.dicore.command.CommandException; -import io.dico.dicore.command.EMessageType; -import io.dico.dicore.command.ExecutionContext; -import io.dico.dicore.command.ICommandAddress; -import io.dico.dicore.command.chat.help.HelpPages; -import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; - -public class AbstractChatController implements IChatController { - private @NotNull HelpPages helpPages; - - public AbstractChatController(@NotNull HelpPages helpPages) { - this.helpPages = helpPages; - } - - public AbstractChatController() { - this(HelpPages.newDefaultHelpPages()); - } - - @NotNull - public HelpPages getHelpPages() { - return helpPages; - } - - public void setHelpPages(@NotNull HelpPages helpPages) { - this.helpPages = helpPages; - } - - @Override - public void sendMessage(ExecutionContext context, EMessageType type, String message) { - sendMessage(context.getSender(), type, message); - } - - @Override - public void sendMessage(CommandSender sender, EMessageType type, String message) { - if (message != null && !message.isEmpty()) { - sender.sendMessage(filterMessage(getMessagePrefixForType(type) + getChatFormatForType(type) + message)); - } - } - - @Override - public void handleCommandException(CommandSender sender, ExecutionContext context, CommandException exception) { - sendMessage(sender, EMessageType.EXCEPTION, exception.getMessage()); - } - - @Override - public void handleException(CommandSender sender, ExecutionContext context, Throwable exception) { - if (exception instanceof CommandException) { - handleCommandException(sender, context, (CommandException) exception); - } else { - sendMessage(sender, EMessageType.EXCEPTION, "An internal error occurred whilst executing this command"); - exception.printStackTrace(); - } - } - - @Override - public void sendHelpMessage(CommandSender sender, ExecutionContext context, ICommandAddress address, int page) { - sender.sendMessage(helpPages.getHelpPage(sender, context, address, page)); - } - - @Override - public void sendSyntaxMessage(CommandSender sender, ExecutionContext context, ICommandAddress address) { - sender.sendMessage(helpPages.getSyntax(sender, context, address)); - } - - @Override - public Formatting getChatFormatForType(EMessageType type) { - switch (type) { - case EXCEPTION: - case BAD_NEWS: - return Formatting.RED; - case INSTRUCTION: - case NEUTRAL: - return Formatting.GRAY; - case CUSTOM: - return Formatting.WHITE; - case INFORMATIVE: - return Formatting.AQUA; - case RESULT: - default: - case GOOD_NEWS: - return Formatting.GREEN; - case WARNING: - return Formatting.YELLOW; - - case DESCRIPTION: - return Formatting.GREEN; - case SYNTAX: - return Formatting.AQUA; - case HIGHLIGHT: - return Formatting.RED; - case SUBCOMMAND: - return Formatting.GRAY; - case NUMBER: - return Formatting.YELLOW; - } - } - - @Override - public String getMessagePrefixForType(EMessageType type) { - return ""; - } - - @Override - public String filterMessage(String message) { - return message; - } - -} diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/chat/AbstractChatHandler.java b/dicore3/command/src/main/java/io/dico/dicore/command/chat/AbstractChatHandler.java new file mode 100644 index 0000000..c0d23ee --- /dev/null +++ b/dicore3/command/src/main/java/io/dico/dicore/command/chat/AbstractChatHandler.java @@ -0,0 +1,94 @@ +package io.dico.dicore.command.chat; + +import io.dico.dicore.Formatting; +import io.dico.dicore.command.EMessageType; +import io.dico.dicore.command.ExecutionContext; +import io.dico.dicore.command.ICommandAddress; +import io.dico.dicore.command.chat.help.HelpPages; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +public class AbstractChatHandler implements IChatHandler { + private @NotNull HelpPages helpPages; + + public AbstractChatHandler(@NotNull HelpPages helpPages) { + this.helpPages = helpPages; + } + + public AbstractChatHandler() { + this(HelpPages.newDefaultHelpPages()); + } + + @NotNull + public HelpPages getHelpPages() { + return helpPages; + } + + public void setHelpPages(@NotNull HelpPages helpPages) { + this.helpPages = helpPages; + } + + @Override + public Formatting getChatFormatForType(EMessageType type) { + switch (type) { + case EXCEPTION: + case BAD_NEWS: + return Formatting.RED; + case INSTRUCTION: + case NEUTRAL: + return Formatting.GRAY; + case CUSTOM: + return Formatting.WHITE; + case INFORMATIVE: + return Formatting.AQUA; + case RESULT: + default: + case GOOD_NEWS: + return Formatting.GREEN; + case WARNING: + return Formatting.YELLOW; + + case DESCRIPTION: + return Formatting.GREEN; + case SYNTAX: + return Formatting.AQUA; + case HIGHLIGHT: + return Formatting.RED; + case SUBCOMMAND: + return Formatting.GRAY; + case NUMBER: + return Formatting.YELLOW; + } + } + + @Override + public String getMessagePrefixForType(EMessageType type) { + return ""; + } + + protected String createMessage(EMessageType type, String message) { + if (message == null || message.isEmpty()) return null; + return getMessagePrefixForType(type) + getChatFormatForType(type) + message; + } + + @Override + public String createMessage(ExecutionContext context, EMessageType type, String message) { + return createMessage(type, message); + } + + @Override + public String createMessage(CommandSender sender, EMessageType type, String message) { + return createMessage(type, message); + } + + @Override + public String createHelpMessage(CommandSender sender, ExecutionContext context, ICommandAddress address, int page) { + return helpPages.getHelpPage(sender, context, address, page); + } + + @Override + public String createSyntaxMessage(CommandSender sender, ExecutionContext context, ICommandAddress address) { + return helpPages.getSyntax(sender, context, address); + } + +} diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/chat/ChatControllers.java b/dicore3/command/src/main/java/io/dico/dicore/command/chat/ChatControllers.java deleted file mode 100644 index 723edda..0000000 --- a/dicore3/command/src/main/java/io/dico/dicore/command/chat/ChatControllers.java +++ /dev/null @@ -1,20 +0,0 @@ -package io.dico.dicore.command.chat; - -/** - * Static factory methods for {@link IChatController} - */ -public class ChatControllers { - private static final IChatController defaultChat; - - private ChatControllers() { - - } - - public static IChatController defaultChat() { - return defaultChat; - } - - static { - defaultChat = new AbstractChatController(); - } -} diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/chat/ChatHandlers.java b/dicore3/command/src/main/java/io/dico/dicore/command/chat/ChatHandlers.java new file mode 100644 index 0000000..232d5cf --- /dev/null +++ b/dicore3/command/src/main/java/io/dico/dicore/command/chat/ChatHandlers.java @@ -0,0 +1,20 @@ +package io.dico.dicore.command.chat; + +/** + * Static factory methods for {@link IChatHandler} + */ +public class ChatHandlers { + private static final IChatHandler defaultChat; + + private ChatHandlers() { + + } + + public static IChatHandler defaultChat() { + return defaultChat; + } + + static { + defaultChat = new AbstractChatHandler(); + } +} diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/chat/IChatController.java b/dicore3/command/src/main/java/io/dico/dicore/command/chat/IChatController.java deleted file mode 100644 index a514499..0000000 --- a/dicore3/command/src/main/java/io/dico/dicore/command/chat/IChatController.java +++ /dev/null @@ -1,31 +0,0 @@ -package io.dico.dicore.command.chat; - -import io.dico.dicore.Formatting; -import io.dico.dicore.command.CommandException; -import io.dico.dicore.command.EMessageType; -import io.dico.dicore.command.ExecutionContext; -import io.dico.dicore.command.ICommandAddress; -import org.bukkit.command.CommandSender; - -//TODO add methods to send JSON messages -public interface IChatController { - - void sendMessage(ExecutionContext context, EMessageType type, String message); - - void sendMessage(CommandSender sender, EMessageType type, String message); - - void handleCommandException(CommandSender sender, ExecutionContext context, CommandException exception); - - void handleException(CommandSender sender, ExecutionContext context, Throwable exception); - - void sendHelpMessage(CommandSender sender, ExecutionContext context, ICommandAddress address, int page); - - void sendSyntaxMessage(CommandSender sender, ExecutionContext context, ICommandAddress address); - - Formatting getChatFormatForType(EMessageType type); - - String getMessagePrefixForType(EMessageType type); - - String filterMessage(String message); - -} diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/chat/IChatHandler.java b/dicore3/command/src/main/java/io/dico/dicore/command/chat/IChatHandler.java new file mode 100644 index 0000000..98283ef --- /dev/null +++ b/dicore3/command/src/main/java/io/dico/dicore/command/chat/IChatHandler.java @@ -0,0 +1,60 @@ +package io.dico.dicore.command.chat; + +import io.dico.dicore.Formatting; +import io.dico.dicore.command.CommandException; +import io.dico.dicore.command.EMessageType; +import io.dico.dicore.command.ExecutionContext; +import io.dico.dicore.command.ICommandAddress; +import org.bukkit.command.CommandSender; + +//TODO add methods to send JSON messages +public interface IChatHandler { + + default void sendMessage(ExecutionContext context, EMessageType type, String message) { + message = createMessage(context, type, message); + if (message != null) { + context.getSender().sendMessage(message); + } + } + + default void sendMessage(CommandSender sender, EMessageType type, String message) { + message = createMessage(sender, type, message); + if (message != null) { + sender.sendMessage(message); + } + } + + default void handleCommandException(CommandSender sender, ExecutionContext context, CommandException exception) { + sendMessage(context, EMessageType.EXCEPTION, exception.getMessage()); + } + + default void handleException(CommandSender sender, ExecutionContext context, Throwable exception) { + if (exception instanceof CommandException) { + handleCommandException(sender, context, (CommandException) exception); + } else { + sendMessage(sender, EMessageType.EXCEPTION, "An internal error occurred whilst executing this command"); + exception.printStackTrace(); + } + } + + default void sendHelpMessage(CommandSender sender, ExecutionContext context, ICommandAddress address, int page) { + sender.sendMessage(createHelpMessage(sender, context, address, page)); + } + + default void sendSyntaxMessage(CommandSender sender, ExecutionContext context, ICommandAddress address) { + sender.sendMessage(createSyntaxMessage(sender, context, address)); + } + + Formatting getChatFormatForType(EMessageType type); + + String getMessagePrefixForType(EMessageType type); + + String createMessage(ExecutionContext context, EMessageType type, String message); + + String createMessage(CommandSender sender, EMessageType type, String message); + + String createHelpMessage(CommandSender sender, ExecutionContext context, ICommandAddress address, int page); + + String createSyntaxMessage(CommandSender sender, ExecutionContext context, ICommandAddress address); + +} diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/chat/help/defaults/DefaultPageLayout.java b/dicore3/command/src/main/java/io/dico/dicore/command/chat/help/defaults/DefaultPageLayout.java index 886b7b1..8d3d004 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/chat/help/defaults/DefaultPageLayout.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/chat/help/defaults/DefaultPageLayout.java @@ -5,7 +5,7 @@ import io.dico.dicore.command.ExecutionContext; import io.dico.dicore.command.ICommandAddress; import io.dico.dicore.command.ModifiableCommandAddress; import io.dico.dicore.Formatting; -import io.dico.dicore.command.chat.IChatController; +import io.dico.dicore.command.chat.IChatHandler; import io.dico.dicore.command.chat.help.IPageBorder; import io.dico.dicore.command.chat.help.IPageLayout; import io.dico.dicore.command.chat.help.PageBorders; @@ -15,7 +15,7 @@ public class DefaultPageLayout implements IPageLayout { @Override public PageBorders getPageBorders(ICommandAddress target, Permissible viewer, ExecutionContext context, int pageNum) { - IChatController c = context.getAddress().getChatController(); + IChatHandler c = context.getAddress().getChatHandler(); String prefix = c.getMessagePrefixForType(EMessageType.INFORMATIVE); Formatting informative = c.getChatFormatForType(EMessageType.INFORMATIVE); Formatting number = c.getChatFormatForType(EMessageType.NEUTRAL); diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/chat/help/defaults/SubcommandsHelpTopic.java b/dicore3/command/src/main/java/io/dico/dicore/command/chat/help/defaults/SubcommandsHelpTopic.java index cfa3bb1..0e680ae 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/chat/help/defaults/SubcommandsHelpTopic.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/chat/help/defaults/SubcommandsHelpTopic.java @@ -7,7 +7,6 @@ import io.dico.dicore.Formatting; import io.dico.dicore.command.chat.help.IHelpComponent; import io.dico.dicore.command.chat.help.IHelpTopic; import io.dico.dicore.command.chat.help.SimpleHelpComponent; -import io.dico.dicore.command.predef.PredefinedCommand; import org.bukkit.command.CommandSender; import org.bukkit.permissions.Permissible; @@ -54,7 +53,7 @@ public class SubcommandsHelpTopic implements IHelpTopic { } private static Formatting colorOf(ExecutionContext context, EMessageType type) { - return context.getAddress().getChatController().getChatFormatForType(type); + return context.getAddress().getChatHandler().getChatFormatForType(type); } } diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/predef/DefaultGroupCommand.java b/dicore3/command/src/main/java/io/dico/dicore/command/predef/DefaultGroupCommand.java index 12483cc..3988da2 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/predef/DefaultGroupCommand.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/predef/DefaultGroupCommand.java @@ -30,7 +30,7 @@ public class DefaultGroupCommand extends PredefinedCommand @Override public String execute(CommandSender sender, ExecutionContext context) throws CommandException { - context.getAddress().getChatController().sendHelpMessage(sender, context, context.getAddress(), 1); + context.getAddress().getChatHandler().sendHelpMessage(sender, context, context.getAddress(), 1); return null; } diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/predef/HelpCommand.java b/dicore3/command/src/main/java/io/dico/dicore/command/predef/HelpCommand.java index cadf4ae..def0db1 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/predef/HelpCommand.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/predef/HelpCommand.java @@ -33,7 +33,7 @@ public class HelpCommand extends PredefinedCommand { target = target.getParent(); } - context.getAddress().getChatController().sendHelpMessage(sender, context, target, context.get("page") - 1); + context.getAddress().getChatHandler().sendHelpMessage(sender, context, target, context.get("page") - 1); return null; } diff --git a/dicore3/command/src/main/java/io/dico/dicore/command/predef/SyntaxCommand.java b/dicore3/command/src/main/java/io/dico/dicore/command/predef/SyntaxCommand.java index 4f26a7b..7ae8638 100644 --- a/dicore3/command/src/main/java/io/dico/dicore/command/predef/SyntaxCommand.java +++ b/dicore3/command/src/main/java/io/dico/dicore/command/predef/SyntaxCommand.java @@ -21,7 +21,7 @@ public class SyntaxCommand extends PredefinedCommand { @Override public String execute(CommandSender sender, ExecutionContext context) throws CommandException { - context.getAddress().getChatController().sendSyntaxMessage(sender, context, context.getAddress().getParent()); + context.getAddress().getChatHandler().sendSyntaxMessage(sender, context, context.getAddress().getParent()); return null; } diff --git a/dicore3/command/src/main/kotlin/io/dico/dicore/command/registration/reflect/KotlinReflectiveRegistration.kt b/dicore3/command/src/main/kotlin/io/dico/dicore/command/registration/reflect/KotlinReflectiveRegistration.kt index 6fac845..c4aa134 100644 --- a/dicore3/command/src/main/kotlin/io/dico/dicore/command/registration/reflect/KotlinReflectiveRegistration.kt +++ b/dicore3/command/src/main/kotlin/io/dico/dicore/command/registration/reflect/KotlinReflectiveRegistration.kt @@ -41,7 +41,7 @@ fun callAsCoroutine( } job.invokeOnCompletion { - val cc = context.address.chatController + val cc = context.address.chatHandler try { val result = job.getResult() cc.sendMessage(context.sender, EMessageType.RESULT, result) diff --git a/dicore3/core/src/main/java/io/dico/dicore/Formatting.java b/dicore3/core/src/main/java/io/dico/dicore/Formatting.java index eac6ac5..9fdfe0e 100644 --- a/dicore3/core/src/main/java/io/dico/dicore/Formatting.java +++ b/dicore3/core/src/main/java/io/dico/dicore/Formatting.java @@ -9,11 +9,14 @@ package io.dico.dicore; +import org.jetbrains.annotations.NotNull; + public final class Formatting implements CharSequence { public static final char FORMAT_CHAR = '\u00a7'; private static final String CACHED_CHARS = "0123456789abcdefklmnor"; private static final Formatting[] singleCharInstances = new Formatting[CACHED_CHARS.length()]; - + + @NotNull public static final Formatting BLACK = from('0'), DARK_BLUE = from('1'), diff --git a/src/main/kotlin/io/dico/parcels2/PlayerProfile.kt b/src/main/kotlin/io/dico/parcels2/PlayerProfile.kt index 99b2b5f..e3e0f55 100644 --- a/src/main/kotlin/io/dico/parcels2/PlayerProfile.kt +++ b/src/main/kotlin/io/dico/parcels2/PlayerProfile.kt @@ -121,6 +121,8 @@ interface PlayerProfile { override fun matches(player: OfflinePlayer, allowNameMatch: Boolean): Boolean { return true } + + override fun toString() = "Star" } abstract class NameOnly(override val name: String) : BaseImpl() { @@ -130,6 +132,8 @@ interface PlayerProfile { override fun matches(player: OfflinePlayer, allowNameMatch: Boolean): Boolean { return allowNameMatch && player.name == name } + + override fun toString() = "${javaClass.simpleName}($name)" } class Fake(name: String) : NameOnly(name) { @@ -166,7 +170,9 @@ interface PlayerProfile { } } - private class RealImpl(override val uuid: UUID, override val name: String?) : BaseImpl(), Real + private class RealImpl(override val uuid: UUID, override val name: String?) : BaseImpl(), Real { + override fun toString() = "Real($notNullName)" + } } diff --git a/src/main/kotlin/io/dico/parcels2/Privilege.kt b/src/main/kotlin/io/dico/parcels2/Privilege.kt index 7949dbc..135d7c1 100644 --- a/src/main/kotlin/io/dico/parcels2/Privilege.kt +++ b/src/main/kotlin/io/dico/parcels2/Privilege.kt @@ -25,7 +25,7 @@ enum class Privilege( OWNER(-1, transient = true), ADMIN(-1, transient = true); - fun isDistanceGrEq(other: Privilege): Boolean = + fun implies(other: Privilege): Boolean = when { other > DEFAULT -> this >= other other == DEFAULT -> this == other @@ -61,6 +61,7 @@ interface RawPrivileges { fun getRawStoredPrivilege(key: PrivilegeKey): Privilege fun setRawStoredPrivilege(key: PrivilegeKey, privilege: Privilege): Boolean + fun hasAnyDeclaredPrivileges(): Boolean } open class PrivilegesHolder(override var privilegeMap: MutablePrivilegeMap = EmptyPrivilegeMap) : RawPrivileges { @@ -95,9 +96,30 @@ open class PrivilegesHolder(override var privilegeMap: MutablePrivilegeMap = Emp else privilegeMap.put(key, privilege) != privilege } + override fun hasAnyDeclaredPrivileges(): Boolean { + return privilegeMap.isNotEmpty() || privilegeOfStar != DEFAULT + } + fun copyPrivilegesFrom(other: PrivilegesHolder) { privilegeMap = other.privilegeMap privilegeOfStar = other.privilegeOfStar } + +} + +private fun MutableMap.put(key: K, value: V, override: Boolean) { + if (override) this[key] = value + else putIfAbsent(key, value) } +fun RawPrivileges.filterProfilesWithPrivilegeTo(map: MutableMap, privilege: Privilege) { + if (privilegeOfStar.implies(privilege)) { + map.putIfAbsent(PlayerProfile.Star, privilegeOfStar) + } + + for ((profile, declaredPrivilege) in privilegeMap) { + if (declaredPrivilege.implies(privilege)) { + map.putIfAbsent(profile, declaredPrivilege) + } + } +} diff --git a/src/main/kotlin/io/dico/parcels2/command/CommandsAdminPrivilegesGlobal.kt b/src/main/kotlin/io/dico/parcels2/command/CommandsAdminPrivilegesGlobal.kt index 541ea87..cee3e62 100644 --- a/src/main/kotlin/io/dico/parcels2/command/CommandsAdminPrivilegesGlobal.kt +++ b/src/main/kotlin/io/dico/parcels2/command/CommandsAdminPrivilegesGlobal.kt @@ -7,7 +7,10 @@ import io.dico.dicore.command.Validate import io.dico.dicore.command.annotation.Cmd import io.dico.dicore.command.annotation.Desc import io.dico.parcels2.* +import io.dico.parcels2.Privilege.BANNED +import io.dico.parcels2.Privilege.CAN_BUILD import io.dico.parcels2.PrivilegeChangeResult.* +import io.dico.parcels2.defaultimpl.InfoBuilder import io.dico.parcels2.util.ext.PERM_ADMIN_MANAGE import org.bukkit.OfflinePlayer @@ -15,8 +18,10 @@ class CommandsAdminPrivilegesGlobal(plugin: ParcelsPlugin) : AbstractParcelComma private val data inline get() = plugin.globalPrivileges - private fun checkContext(context: ExecutionContext, owner: OfflinePlayer): OfflinePlayer { - checkConnected("have privileges changed") + private fun checkContext(context: ExecutionContext, owner: OfflinePlayer, changing: Boolean = true): OfflinePlayer { + if (changing) { + checkConnected("have privileges changed") + } val sender = context.sender if (sender !== owner) { Validate.isAuthorized(sender, PERM_ADMIN_MANAGE) @@ -24,6 +29,25 @@ class CommandsAdminPrivilegesGlobal(plugin: ParcelsPlugin) : AbstractParcelComma return owner } + @Cmd("list", aliases = ["l"]) + @Desc( + "List globally declared privileges, players you", + "allowed to build on or banned from all your parcels", + shortVersion = "lists globally declared privileges" + ) + fun cmdList(context: ExecutionContext, owner: OfflinePlayer): Any? { + checkContext(context, owner, changing = false) + val map = plugin.globalPrivileges[owner] + Validate.isTrue(map.hasAnyDeclaredPrivileges(), "This user has not declared any global privileges") + + return StringBuilder().apply { + with(InfoBuilder) { + appendProfilesWithPrivilege("Globally Allowed", map, null, CAN_BUILD) + appendProfilesWithPrivilege("Globally Banned", map, null, BANNED) + } + }.toString() + } + @Cmd("entrust") @Desc( "Allows a player to manage globally", diff --git a/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesGlobal.kt b/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesGlobal.kt index 9e3ac23..3b4234c 100644 --- a/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesGlobal.kt +++ b/src/main/kotlin/io/dico/parcels2/command/CommandsPrivilegesGlobal.kt @@ -9,6 +9,15 @@ import org.bukkit.entity.Player class CommandsPrivilegesGlobal(plugin: ParcelsPlugin, val adminVersion: CommandsAdminPrivilegesGlobal) : AbstractParcelCommands(plugin) { + @Cmd("list", aliases = ["l"]) + @Desc( + "List globally declared privileges, players you", + "allowed to build on or banned from all your parcels", + shortVersion = "lists globally declared privileges" + ) + fun cmdList(sender: Player, context: ExecutionContext) = + adminVersion.cmdList(context, sender) + @Cmd("entrust") @Desc( "Allows a player to manage globally", diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt index 6a604c3..2777b7f 100644 --- a/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt +++ b/src/main/kotlin/io/dico/parcels2/command/ParcelCommandBuilder.kt @@ -15,7 +15,7 @@ import java.util.Queue fun getParcelCommands(plugin: ParcelsPlugin): ICommandDispatcher = CommandBuilder().apply { val parcelsAddress = SpecialCommandAddress() - setChatController(ParcelsChatController()) + setChatHandler(ParcelsChatHandler()) addParameterType(false, ParcelParameterType(plugin.parcelProvider)) addParameterType(false, ProfileParameterType()) addParameterType(true, ParcelTarget.PType(plugin.parcelProvider, parcelsAddress)) diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt index 1b61660..23087dc 100644 --- a/src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt +++ b/src/main/kotlin/io/dico/parcels2/command/ParcelOptionsInteractCommand.kt @@ -3,7 +3,6 @@ package io.dico.parcels2.command import io.dico.dicore.command.* import io.dico.dicore.command.parameter.type.ParameterTypes import io.dico.parcels2.Interactables -import io.dico.parcels2.ParcelProvider import io.dico.parcels2.ParcelsPlugin import io.dico.parcels2.Privilege import org.bukkit.command.CommandSender @@ -33,9 +32,9 @@ class ParcelOptionsInteractCommand(val plugin: ParcelsPlugin) : Command() { val setting = parcel.interactableConfig.isInteractable(interactableClass) val default = setting == interactableClass.interactableByDefault - val canColor = context.address.chatController.getChatFormatForType(EMessageType.BAD_NEWS) - val cannotColor = context.address.chatController.getChatFormatForType(EMessageType.GOOD_NEWS) - val resetColor = context.address.chatController.getChatFormatForType(EMessageType.RESULT) + val canColor = context.address.chatHandler.getChatFormatForType(EMessageType.BAD_NEWS) + val cannotColor = context.address.chatHandler.getChatFormatForType(EMessageType.GOOD_NEWS) + val resetColor = context.address.chatHandler.getChatFormatForType(EMessageType.RESULT) val settingString = (if (setting) "${canColor}can" else "${cannotColor}cannot") + resetColor val defaultString = if (default) " (default)" else "" diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt index ae58f94..736e568 100644 --- a/src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt +++ b/src/main/kotlin/io/dico/parcels2/command/ParcelParameterTypes.kt @@ -51,7 +51,7 @@ annotation class ProfileKind(val kind: Int) { companion object : ParameterConfig(ProfileKind::class.java) { const val REAL = 1 const val FAKE = 2 - const val ANY = 4 + const val ANY = REAL or FAKE override fun toParameterInfo(annotation: ProfileKind): Int { return annotation.kind @@ -63,8 +63,8 @@ class ProfileParameterType : ParameterType(PlayerProfile::cl override fun parse(parameter: Parameter, sender: CommandSender, buffer: ArgumentBuffer): PlayerProfile { val info = parameter.paramInfo ?: REAL - val allowReal = info and REAL != 0 - val allowFake = info and FAKE != 0 + val allowReal = (info and REAL) != 0 + val allowFake = (info and FAKE) != 0 val input = buffer.next() return PlayerProfile.byName(input, allowReal, allowFake) diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelsChatController.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelsChatController.kt deleted file mode 100644 index fe9ca0d..0000000 --- a/src/main/kotlin/io/dico/parcels2/command/ParcelsChatController.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.dico.parcels2.command - -import io.dico.dicore.command.chat.AbstractChatController - -class ParcelsChatController : AbstractChatController() { - - override fun filterMessage(message: String?): String { - return "[Parcels] $message" - } - -} \ No newline at end of file diff --git a/src/main/kotlin/io/dico/parcels2/command/ParcelsChatHandler.kt b/src/main/kotlin/io/dico/parcels2/command/ParcelsChatHandler.kt new file mode 100644 index 0000000..b616f77 --- /dev/null +++ b/src/main/kotlin/io/dico/parcels2/command/ParcelsChatHandler.kt @@ -0,0 +1,24 @@ +package io.dico.parcels2.command + +import io.dico.dicore.Formatting +import io.dico.dicore.command.EMessageType +import io.dico.dicore.command.ExecutionContext +import io.dico.dicore.command.chat.AbstractChatHandler +import io.dico.parcels2.util.ext.plus + +class ParcelsChatHandler : AbstractChatHandler() { + + override fun getMessagePrefixForType(type: EMessageType?): String { + return Formatting.RED + "[Parcels] " + } + + override fun createMessage(context: ExecutionContext, type: EMessageType, message: String?): String? { + if (message.isNullOrEmpty()) return null + var result = getChatFormatForType(type) + message + if (context.address.mainKey != "info") { + result = getMessagePrefixForType(type) + result + } + return result + } + +} \ No newline at end of file diff --git a/src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelContainer.kt b/src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelContainer.kt index e6d29f4..24db275 100644 --- a/src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelContainer.kt +++ b/src/main/kotlin/io/dico/parcels2/defaultimpl/DefaultParcelContainer.kt @@ -52,6 +52,7 @@ class DefaultParcelContainer(val world: ParcelWorld) : ParcelContainer { private fun walkInCircle(): Iterable = Iterable { iterator { val center = world.options.axisLimit + yield(parcels[center][center]) for (radius in 0..center) { var x = center - radius; var z = center - radius diff --git a/src/main/kotlin/io/dico/parcels2/defaultimpl/InfoBuilder.kt b/src/main/kotlin/io/dico/parcels2/defaultimpl/InfoBuilder.kt new file mode 100644 index 0000000..a3704c7 --- /dev/null +++ b/src/main/kotlin/io/dico/parcels2/defaultimpl/InfoBuilder.kt @@ -0,0 +1,88 @@ +package io.dico.parcels2.defaultimpl + +import io.dico.dicore.Formatting +import io.dico.parcels2.Privilege +import io.dico.parcels2.PrivilegeKey +import io.dico.parcels2.RawPrivileges +import io.dico.parcels2.filterProfilesWithPrivilegeTo + +object InfoBuilder { + val infoStringColor1 = Formatting.GREEN + val infoStringColor2 = Formatting.AQUA + + inline fun StringBuilder.appendField(field: StringBuilder.() -> Unit, value: StringBuilder.() -> Unit) { + append(infoStringColor1) + field() + append(": ") + append(infoStringColor2) + value() + append(' ') + } + + inline fun StringBuilder.appendField(name: String, value: StringBuilder.() -> Unit) { + appendField({ append(name) }, value) + } + + inline fun StringBuilder.appendFieldWithCount(name: String, count: Int, value: StringBuilder.() -> Unit) { + appendField({ + append(name) + append('(') + append(infoStringColor2) + append(count) + append(infoStringColor1) + append(')') + }, value) + } + + fun StringBuilder.appendProfilesWithPrivilege(fieldName: String, local: RawPrivileges, global: RawPrivileges?, privilege: Privilege) { + val map = linkedMapOf() + local.filterProfilesWithPrivilegeTo(map, privilege) + val localCount = map.size + global?.filterProfilesWithPrivilegeTo(map, privilege) + appendPrivilegeProfiles(fieldName, map, localCount) + } + + fun StringBuilder.appendPrivilegeProfiles(fieldName: String, map: LinkedHashMap, localCount: Int) { + if (map.isEmpty()) return + + appendFieldWithCount(fieldName, map.size) { + // first [localCount] entries are local + val separator = "$infoStringColor1, $infoStringColor2" + val iterator = map.iterator() + + if (localCount != 0) { + appendPrivilegeEntry(false, iterator.next().toPair()) + repeat(localCount - 1) { + append(separator) + appendPrivilegeEntry(false, iterator.next().toPair()) + } + + } else if (iterator.hasNext()) { + // ensure there is never a leading or trailing separator + appendPrivilegeEntry(true, iterator.next().toPair()) + } + + iterator.forEach { next -> + append(separator) + appendPrivilegeEntry(true, next.toPair()) + } + } + } + + fun StringBuilder.appendPrivilegeEntry(global: Boolean, pair: Pair) { + val (key, priv) = pair + + append(key.notNullName) + + // suffix. Maybe T should be M for mod or something. T means they have CAN_MANAGE privilege. + append( + when { + global && priv == Privilege.CAN_MANAGE -> " (G) (T)" + global -> " (G)" + priv == Privilege.CAN_MANAGE -> " (T)" + else -> "" + } + ) + } + +} \ No newline at end of file diff --git a/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt b/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt index 65378bf..16136e9 100644 --- a/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt +++ b/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelImpl.kt @@ -1,10 +1,9 @@ package io.dico.parcels2.defaultimpl -import io.dico.dicore.Formatting import io.dico.parcels2.* import io.dico.parcels2.Privilege.* -import io.dico.parcels2.util.math.Vec2i import io.dico.parcels2.util.ext.alsoIfTrue +import io.dico.parcels2.util.math.Vec2i import org.bukkit.Material import org.joda.time.DateTime import java.util.concurrent.atomic.AtomicInteger @@ -17,7 +16,6 @@ class ParcelImpl( override val id: ParcelId = this override val pos get() = Vec2i(x, z) override var data: ParcelDataHolder = ParcelDataHolder(); private set - override val infoString get() = ParcelInfoStringComputer.getInfoString(this) override val hasBlockVisitors get() = blockVisitors.get() > 0 override val worldId: ParcelWorldId get() = world.id @@ -77,6 +75,7 @@ class ParcelImpl( ?: globalPrivileges?.getStoredPrivilege(key) ?: DEFAULT + override fun hasAnyDeclaredPrivileges() = data.hasAnyDeclaredPrivileges() private var _interactableConfig: InteractableConfiguration? = null @@ -120,108 +119,20 @@ class ParcelImpl( } override fun toString() = toStringExt() -} - -private object ParcelInfoStringComputer { - val infoStringColor1 = Formatting.GREEN - val infoStringColor2 = Formatting.AQUA - - private inline fun StringBuilder.appendField(field: StringBuilder.() -> Unit, value: StringBuilder.() -> Unit) { - append(infoStringColor1) - field() - append(": ") - append(infoStringColor2) - value() - append(' ') - } - - private inline fun StringBuilder.appendField(name: String, value: StringBuilder.() -> Unit) { - appendField({ append(name) }, value) - } - - private inline fun StringBuilder.appendFieldWithCount(name: String, count: Int, value: StringBuilder.() -> Unit) { - appendField({ - append(name) - append('(') - append(infoStringColor2) - append(count) - append(infoStringColor1) - append(')') - }, value) - } - - private fun processPrivileges(local: RawPrivileges, global: RawPrivileges?, - privilege: Privilege): Pair, Int> { - val map = linkedMapOf() - local.privilegeOfStar.takeIf { it != DEFAULT }?.let { map[PlayerProfile.Star] = it } - map.values.retainAll { it.isDistanceGrEq(privilege) } - val localCount = map.size - - if (global != null) { - global.privilegeMap.forEach { - if (it.value.isDistanceGrEq(privilege)) - map.putIfAbsent(it.key, it.value) - } - - global.privilegeOfStar.takeIf { it != DEFAULT && it.isDistanceGrEq(privilege) } - ?.let { map.putIfAbsent(PlayerProfile.Star, it) } - } - - return map to localCount - } - - private fun StringBuilder.appendAddedList(local: RawPrivileges, global: RawPrivileges?, privilege: Privilege, fieldName: String) { - val (map, localCount) = processPrivileges(local, global, privilege) - if (map.isEmpty()) return - appendFieldWithCount(fieldName, map.size) { - // first [localCount] entries are local - val separator = "$infoStringColor1, $infoStringColor2" - val iterator = map.iterator() - - if (localCount != 0) { - appendPrivilegeEntry(false, iterator.next().toPair()) - repeat(localCount - 1) { - append(separator) - appendPrivilegeEntry(false, iterator.next().toPair()) - } - - } else if (iterator.hasNext()) { - // ensure there is never a leading or trailing separator - appendPrivilegeEntry(true, iterator.next().toPair()) - } - - iterator.forEach { next -> - append(separator) - appendPrivilegeEntry(true, next.toPair()) - } - } - } - - private fun StringBuilder.appendPrivilegeEntry(global: Boolean, pair: Pair) { - val (key, priv) = pair - - append(key.notNullName) - - // suffix. Maybe T should be M for mod or something. T means they have CAN_MANAGE privilege. - append( - when { - global && priv == CAN_MANAGE -> " (G) (T)" - global -> " (G)" - priv == CAN_MANAGE -> " (T)" - else -> "" - } - ) - } + override val infoString: String + get() = getInfoString() +} - fun getInfoString(parcel: Parcel): String = buildString { +private fun Parcel.getInfoString() = StringBuilder().apply { + with(InfoBuilder) { appendField("ID") { - append(parcel.x) + append(x) append(',') - append(parcel.z) + append(z) } - val owner = parcel.owner + val owner = owner appendField("Owner") { if (owner == null) { append(infoStringColor1) @@ -235,18 +146,17 @@ private object ParcelInfoStringComputer { append('\n') - val local: RawPrivileges = parcel.data - val global = parcel.globalPrivileges - appendAddedList(local, global, CAN_BUILD, "Allowed") // includes CAN_MANAGE privilege + val local: RawPrivileges = data + val global = globalPrivileges + appendProfilesWithPrivilege("Allowed", local, global, CAN_BUILD) // includes CAN_MANAGE privilege append('\n') - appendAddedList(local, global, BANNED, "Banned") + appendProfilesWithPrivilege("Banned", local, global, BANNED) - if (!parcel.interactableConfig.isDefault()) { - val interactables = parcel.interactableConfig.interactableClasses + if (!interactableConfig.isDefault()) { + val interactables = interactableConfig.interactableClasses appendFieldWithCount("Interactables", interactables.size) { interactables.asSequence().map { it.name }.joinTo(this) } } - } -} \ No newline at end of file +}.toString() diff --git a/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelProviderImpl.kt b/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelProviderImpl.kt index 1edf849..7a2534f 100644 --- a/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelProviderImpl.kt +++ b/src/main/kotlin/io/dico/parcels2/defaultimpl/ParcelProviderImpl.kt @@ -106,8 +106,11 @@ class ParcelProviderImpl(val plugin: ParcelsPlugin) : ParcelProvider { val channel2 = plugin.storage.transmitAllGlobalPrivileges() while (true) { val (profile, data) = channel2.receiveOrNull() ?: break - val key = profile as? PrivilegeKey ?: continue - (plugin.globalPrivileges[key] as PrivilegesHolder).copyPrivilegesFrom(data) + if (profile !is PrivilegeKey) { + logger.error("Received profile that is not a privilege key: ${profile.javaClass}, $profile") + continue + } + (plugin.globalPrivileges[profile] as PrivilegesHolder).copyPrivilegesFrom(data) } logger.info("Loading data completed") diff --git a/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt b/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt index 94fca4b..6c3b355 100644 --- a/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt +++ b/src/main/kotlin/io/dico/parcels2/listener/ParcelListeners.kt @@ -237,7 +237,7 @@ class ParcelListeners( if (bedTypes.contains(type)) { val bed = clickedBlock.blockData as Bed - val head = if (bed == Bed.Part.FOOT) clickedBlock.getRelative(bed.facing) else clickedBlock + val head = if (bed.part == Bed.Part.FOOT) clickedBlock.getRelative(bed.facing) else clickedBlock when (head.biome) { Biome.NETHER, Biome.THE_END -> { if (world.options.disableExplosions) { diff --git a/src/main/kotlin/io/dico/parcels2/storage/exposed/ListTables.kt b/src/main/kotlin/io/dico/parcels2/storage/exposed/ListTables.kt index 6a0a41b..b9d16fc 100644 --- a/src/main/kotlin/io/dico/parcels2/storage/exposed/ListTables.kt +++ b/src/main/kotlin/io/dico/parcels2/storage/exposed/ListTables.kt @@ -4,13 +4,14 @@ package io.dico.parcels2.storage.exposed import io.dico.parcels2.* import io.dico.parcels2.Privilege.DEFAULT +import io.dico.parcels2.util.ext.alsoIfTrue import kotlinx.coroutines.channels.SendChannel import org.jetbrains.exposed.sql.* object PrivilegesLocalT : PrivilegesTable("parcels_privilege_local", ParcelsT) object PrivilegesGlobalT : PrivilegesTable("parcels_privilege_global", ProfilesT) -object ParcelOptionsT : Table("parcel_options") { +object ParcelOptionsT : Table("parcels_options") { val parcel_id = integer("parcel_id").primaryKey().references(ParcelsT.id, ReferenceOption.CASCADE) val interact_bitmask = binary("interact_bitmask", 4) } @@ -57,8 +58,8 @@ sealed class PrivilegesTable(name: String, val idTable: IdTransactionsT val iterator = selectAll().orderBy(attach_id).iterator() if (iterator.hasNext()) { - val firstRow = iterator.next() - var id: Int = firstRow[attach_id] + var row = iterator.next() + var id: Int = row[attach_id] var attach: AttachT? = null var map: PrivilegesHolder? = null @@ -77,7 +78,7 @@ sealed class PrivilegesTable(name: String, val idTable: IdTransactionsT initAttachAndMap() - for (row in iterator) { + do { val rowId = row[attach_id] if (rowId != id) { sendIfPresent() @@ -89,10 +90,19 @@ sealed class PrivilegesTable(name: String, val idTable: IdTransactionsT continue // owner not found for this owner id } - val profile = ProfilesT.getRealItem(row[profile_id]) ?: continue - val privilege = Privilege.getByNumber(row[privilege]) ?: continue + val profile = ProfilesT.getRealItem(row[profile_id]) + if (profile == null) { + logger.error("Privilege from database is null, id ${row[profile_id]}") + continue + } + val privilege = Privilege.getByNumber(row[privilege]) + if (privilege == null) { + logger.error("Privilege from database is null, number ${row[this.privilege]}") + continue + } map!!.setRawStoredPrivilege(profile, privilege) - } + + } while (iterator.hasNext().alsoIfTrue { row = iterator.next() }) sendIfPresent() } -- cgit v1.2.3