diff --git a/src/main/java/com/sekwah/advancedportals/core/AdvancedPortalsCore.java b/src/main/java/com/sekwah/advancedportals/core/AdvancedPortalsCore.java index 38af4d4f..d211dab8 100644 --- a/src/main/java/com/sekwah/advancedportals/core/AdvancedPortalsCore.java +++ b/src/main/java/com/sekwah/advancedportals/core/AdvancedPortalsCore.java @@ -5,17 +5,19 @@ import com.google.inject.Injector; import com.sekwah.advancedportals.core.api.commands.SubCommand; import com.sekwah.advancedportals.core.api.destination.Destination; import com.sekwah.advancedportals.core.api.portal.AdvancedPortal; -import com.sekwah.advancedportals.core.api.registry.TagRegistry; -import com.sekwah.advancedportals.core.api.registry.WarpEffectRegistry; -import com.sekwah.advancedportals.core.api.services.DestinationServices; -import com.sekwah.advancedportals.core.api.services.PortalServices; -import com.sekwah.advancedportals.core.api.services.PortalTempDataServices; +import com.sekwah.advancedportals.core.registry.TagRegistry; +import com.sekwah.advancedportals.core.registry.WarpEffectRegistry; +import com.sekwah.advancedportals.core.services.DestinationServices; +import com.sekwah.advancedportals.core.services.PortalServices; +import com.sekwah.advancedportals.core.services.PortalTempDataServices; import com.sekwah.advancedportals.core.commands.CommandWithSubCommands; import com.sekwah.advancedportals.core.commands.subcommands.desti.CreateDestiSubCommand; import com.sekwah.advancedportals.core.commands.subcommands.portal.*; import com.sekwah.advancedportals.core.config.RepositoryModule; import com.sekwah.advancedportals.core.data.DataStorage; import com.sekwah.advancedportals.ConfigRepository; +import com.sekwah.advancedportals.core.registry.RegisterBuilder; +import com.sekwah.advancedportals.core.registry.Registrar; import com.sekwah.advancedportals.core.util.InfoLogger; import com.sekwah.advancedportals.core.util.Lang; import com.sekwah.advancedportals.core.connector.command.CommandRegister; @@ -69,6 +71,12 @@ public class AdvancedPortalsCore { this.onEnable(); } + public void test() { + Registrar registrar = RegisterBuilder.newBuilder() + .inheritPermissions(true) + .build(); + } + private int checkMcVer(int[] mcVer) { int maxSupportedVer = 13; int minSupportedVer = 13; diff --git a/src/main/java/com/sekwah/advancedportals/core/CoreListeners.java b/src/main/java/com/sekwah/advancedportals/core/CoreListeners.java index 174d6348..ccb9e0c2 100644 --- a/src/main/java/com/sekwah/advancedportals/core/CoreListeners.java +++ b/src/main/java/com/sekwah/advancedportals/core/CoreListeners.java @@ -1,8 +1,8 @@ package com.sekwah.advancedportals.core; import com.google.inject.Inject; -import com.sekwah.advancedportals.core.api.services.PortalServices; -import com.sekwah.advancedportals.core.api.services.PortalTempDataServices; +import com.sekwah.advancedportals.core.services.PortalServices; +import com.sekwah.advancedportals.core.services.PortalTempDataServices; import com.sekwah.advancedportals.core.data.PlayerLocation; import com.sekwah.advancedportals.core.data.PortalLocation; import com.sekwah.advancedportals.core.util.Lang; diff --git a/src/main/java/com/sekwah/advancedportals/core/api/destination/Destination.java b/src/main/java/com/sekwah/advancedportals/core/api/destination/Destination.java index 7fbf44b0..a72c182c 100644 --- a/src/main/java/com/sekwah/advancedportals/core/api/destination/Destination.java +++ b/src/main/java/com/sekwah/advancedportals/core/api/destination/Destination.java @@ -2,7 +2,7 @@ package com.sekwah.advancedportals.core.api.destination; import com.google.gson.annotations.SerializedName; import com.sekwah.advancedportals.core.AdvancedPortalsCore; -import com.sekwah.advancedportals.core.api.registry.TagRegistry; +import com.sekwah.advancedportals.core.registry.TagRegistry; import com.sekwah.advancedportals.core.api.warphandler.ActivationData; import com.sekwah.advancedportals.core.api.warphandler.TagHandler; import com.sekwah.advancedportals.core.data.DataTag; diff --git a/src/main/java/com/sekwah/advancedportals/core/api/portal/AdvancedPortal.java b/src/main/java/com/sekwah/advancedportals/core/api/portal/AdvancedPortal.java index 001287a2..aaf5e6b1 100644 --- a/src/main/java/com/sekwah/advancedportals/core/api/portal/AdvancedPortal.java +++ b/src/main/java/com/sekwah/advancedportals/core/api/portal/AdvancedPortal.java @@ -2,7 +2,7 @@ package com.sekwah.advancedportals.core.api.portal; import com.google.gson.annotations.SerializedName; import com.sekwah.advancedportals.core.AdvancedPortalsCore; -import com.sekwah.advancedportals.core.api.registry.TagRegistry; +import com.sekwah.advancedportals.core.registry.TagRegistry; import com.sekwah.advancedportals.core.api.warphandler.ActivationData; import com.sekwah.advancedportals.core.api.warphandler.TagHandler; import com.sekwah.advancedportals.core.data.DataTag; diff --git a/src/main/java/com/sekwah/advancedportals/core/commands/CommandWithSubCommands.java b/src/main/java/com/sekwah/advancedportals/core/commands/CommandWithSubCommands.java index a000b14a..c0530ad5 100644 --- a/src/main/java/com/sekwah/advancedportals/core/commands/CommandWithSubCommands.java +++ b/src/main/java/com/sekwah/advancedportals/core/commands/CommandWithSubCommands.java @@ -1,7 +1,7 @@ package com.sekwah.advancedportals.core.commands; import com.sekwah.advancedportals.core.api.commands.SubCommand; -import com.sekwah.advancedportals.core.api.registry.SubCommandRegistry; +import com.sekwah.advancedportals.core.registry.SubCommandRegistry; import com.sekwah.advancedportals.core.util.Lang; import com.sekwah.advancedportals.core.connector.container.CommandSenderContainer; diff --git a/src/main/java/com/sekwah/advancedportals/core/registry/Cmd.java b/src/main/java/com/sekwah/advancedportals/core/registry/Cmd.java new file mode 100644 index 00000000..ee1dbefc --- /dev/null +++ b/src/main/java/com/sekwah/advancedportals/core/registry/Cmd.java @@ -0,0 +1,16 @@ +package com.sekwah.advancedportals.core.registry; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + + +@Retention(RetentionPolicy.RUNTIME) +public @interface Cmd { + String name(); + //TODO Convert to enum + String parentCommand() default ""; + boolean isEnabled() default true; + int minArgs() default 0; + String description() default ""; + String[] permissions() default {}; +} diff --git a/src/main/java/com/sekwah/advancedportals/core/registry/CommandDemo.java b/src/main/java/com/sekwah/advancedportals/core/registry/CommandDemo.java new file mode 100644 index 00000000..b78a4478 --- /dev/null +++ b/src/main/java/com/sekwah/advancedportals/core/registry/CommandDemo.java @@ -0,0 +1,18 @@ +package com.sekwah.advancedportals.core.registry; + +import com.google.common.collect.ImmutableList; +import com.sekwah.advancedportals.core.connector.container.CommandSenderContainer; + +public class CommandDemo implements CommandHandler { + + + @Override + public void onExecute(String commandName, String parentCommand, CommandSenderContainer sender, ImmutableList args) { + + } + + @Override + public void onCommandFailure(String[] command, CommandSenderContainer sender, CommandException exception) { + + } +} diff --git a/src/main/java/com/sekwah/advancedportals/core/registry/CommandErrorException.java b/src/main/java/com/sekwah/advancedportals/core/registry/CommandErrorException.java new file mode 100644 index 00000000..0b6070d6 --- /dev/null +++ b/src/main/java/com/sekwah/advancedportals/core/registry/CommandErrorException.java @@ -0,0 +1,6 @@ +package com.sekwah.advancedportals.core.registry; + +//TODO +public class CommandErrorException extends Exception { + private String reason; +} diff --git a/src/main/java/com/sekwah/advancedportals/core/registry/CommandException.java b/src/main/java/com/sekwah/advancedportals/core/registry/CommandException.java new file mode 100644 index 00000000..d0eb2f8f --- /dev/null +++ b/src/main/java/com/sekwah/advancedportals/core/registry/CommandException.java @@ -0,0 +1,19 @@ +package com.sekwah.advancedportals.core.registry; + +public class CommandException { + private ErrorCode errorCode; + private String message; + + public CommandException(ErrorCode errorCode, String message) { + this.errorCode = errorCode; + this.message = message; + } + + public ErrorCode getErrorCode() { + return errorCode; + } + + public String getMessage() { + return message; + } +} diff --git a/src/main/java/com/sekwah/advancedportals/core/registry/CommandHandler.java b/src/main/java/com/sekwah/advancedportals/core/registry/CommandHandler.java new file mode 100644 index 00000000..deb8ab75 --- /dev/null +++ b/src/main/java/com/sekwah/advancedportals/core/registry/CommandHandler.java @@ -0,0 +1,12 @@ +package com.sekwah.advancedportals.core.registry; + +import com.google.common.collect.ImmutableList; +import com.sekwah.advancedportals.core.connector.container.CommandSenderContainer; + +public interface CommandHandler { + void onExecute(String commandName, String parentCommand, CommandSenderContainer sender, ImmutableList args); + + default void onCommandFailure(String[] command, CommandSenderContainer sender, CommandException exception, ImmutableList args) { + sender.sendMessage(exception.getMessage()); + } +} diff --git a/src/main/java/com/sekwah/advancedportals/core/registry/ErrorCode.java b/src/main/java/com/sekwah/advancedportals/core/registry/ErrorCode.java new file mode 100644 index 00000000..30821278 --- /dev/null +++ b/src/main/java/com/sekwah/advancedportals/core/registry/ErrorCode.java @@ -0,0 +1,12 @@ +package com.sekwah.advancedportals.core.registry; + +public enum ErrorCode { + INSUFFICIENT_ARGUMENTS(""), + NO_PERMISSION(""); + ; + + + ErrorCode(String message) { + + } +} diff --git a/src/main/java/com/sekwah/advancedportals/core/registry/RegisterBuilder.java b/src/main/java/com/sekwah/advancedportals/core/registry/RegisterBuilder.java new file mode 100644 index 00000000..57e6adfb --- /dev/null +++ b/src/main/java/com/sekwah/advancedportals/core/registry/RegisterBuilder.java @@ -0,0 +1,90 @@ +package com.sekwah.advancedportals.core.registry; + +import com.google.common.collect.ImmutableSet; +import com.google.common.reflect.ClassPath; + +import java.io.IOException; +import java.lang.reflect.ParameterizedType; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class RegisterBuilder { + public static RegisterBuilder newBuilder() { + return new RegisterBuilder(); + } + + private RegisterBuilder() { + } + + private boolean allowPermissionInheritance; + private String scanDirectory; + private final Class genericType = (Class) ((ParameterizedType) getClass() + .getGenericSuperclass()).getActualTypeArguments()[0]; + + + public RegisterBuilder inheritPermissions(boolean allowInheritance) { + allowPermissionInheritance = allowInheritance; + return this; + } + + public RegisterBuilder scanDirectory(String directoryName) { + this.scanDirectory = directoryName; + return this; + } + + //TODO I don't know if we want to use this as it is marked as Unstable. + public Registrar build() { + // Table commandMap = HashBasedTable.create(); + Map commandMap = new HashMap<>(); + ImmutableSet classInfo; + final ClassLoader loader = Thread.currentThread().getContextClassLoader(); + + ClassPath classPath = null; + try { + classPath = ClassPath.from(loader); + } catch (IOException e) { + e.printStackTrace(); + } + if (null == scanDirectory || scanDirectory.isEmpty()) { + classInfo = classPath.getTopLevelClasses(scanDirectory); + } else { + classInfo = classPath.getTopLevelClasses(); + } + + //TODO implement blackout of already registered commands. + //TODO If there are duplicates ignore them and throw a warning in console. + Map> commandClasses = classInfo.stream().map(ClassPath.ClassInfo::load) + .filter(t -> t.isAnnotationPresent(Cmd.class)) + .filter(t -> t.isAssignableFrom(genericType)) + .collect(Collectors.toMap(k -> k.getAnnotation(Cmd.class), k -> k)); + + Stream>> result = commandClasses.entrySet().stream(); + + result.filter(c -> c.getKey().parentCommand().equals("")) + .forEach(c -> { + try { + commandMap.put(c.getKey(), (T) c.getValue().newInstance()); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + }); + + result.filter(c -> c.getKey().parentCommand() != "") + .forEach(c -> { + try { + commandMap.put(c.getKey(), (T) c.getValue().newInstance()); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + }); + return new Registrar<>(allowPermissionInheritance, commandMap); + } + + +} diff --git a/src/main/java/com/sekwah/advancedportals/core/registry/Registrar.java b/src/main/java/com/sekwah/advancedportals/core/registry/Registrar.java new file mode 100644 index 00000000..fe164e8f --- /dev/null +++ b/src/main/java/com/sekwah/advancedportals/core/registry/Registrar.java @@ -0,0 +1,71 @@ +package com.sekwah.advancedportals.core.registry; + +import com.google.common.collect.ImmutableList; +import com.google.inject.Singleton; +import com.sekwah.advancedportals.core.connector.container.CommandSenderContainer; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; + +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Singleton +public class Registrar implements CommandExecutor, TabCompleter { + //Parent Command, Sub Command, Object + private boolean allowPermissionInheritance; + private Map commandMap = new HashMap<>(); + + protected Registrar(boolean allowPermissionInheritance, Map commandMap) { + this.commandMap = commandMap; + } + + public boolean isAllowPermissionInheritance() { + return allowPermissionInheritance; + } + + public Map getCommandMap() { + return commandMap; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + Stream> topLevelCommands = commandMap.entrySet().stream() + .filter(c->c.getKey().name().equals(args[0]) || c.getKey().parentCommand().equals(args[0])); + + Optional> results = topLevelCommands.filter(c->c.getKey().name().equals(args[1])).findFirst(); + String[] commands = null; + Map.Entry key = null; + + + if (results.isPresent()) { + args[0] = null; + args[1] = null; + commands = new String[]{args[0], args[1]}; + + key = results.get(); + } else { + commands = new String[]{args[0]}; + key = topLevelCommands + .filter(c->c.getKey().name().equals(args[0]) && c.getKey().parentCommand().equals("")) + .findFirst().get(); + } + + if (args[0].length() >= key.getKey().minArgs()) { + + } else { + commands = new String[]{args[0], args[1]}; + //TODO ???? + key.getValue().onCommandFailure(commands, (CommandSenderContainer) sender, new CommandException(ErrorCode.INSUFFICIENT_ARGUMENTS, ""), + ImmutableList.copyOf(Arrays.asList(args))); + } + return false; + } + + @Override + public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { + return null; + } +} diff --git a/src/main/java/com/sekwah/advancedportals/core/registry/SubCmd.java b/src/main/java/com/sekwah/advancedportals/core/registry/SubCmd.java index 0d7b4297..49986c76 100644 --- a/src/main/java/com/sekwah/advancedportals/core/registry/SubCmd.java +++ b/src/main/java/com/sekwah/advancedportals/core/registry/SubCmd.java @@ -1,5 +1,11 @@ package com.sekwah.advancedportals.core.registry; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +//There is no reason to run a double class file when we can just make the main command default out. +@Deprecated() +@Retention(RetentionPolicy.RUNTIME) public @interface SubCmd { TYPE parent(); diff --git a/src/main/java/com/sekwah/advancedportals/core/api/registry/SubCommandRegistry.java b/src/main/java/com/sekwah/advancedportals/core/registry/SubCommandRegistry.java similarity index 97% rename from src/main/java/com/sekwah/advancedportals/core/api/registry/SubCommandRegistry.java rename to src/main/java/com/sekwah/advancedportals/core/registry/SubCommandRegistry.java index deacfe44..444ec718 100644 --- a/src/main/java/com/sekwah/advancedportals/core/api/registry/SubCommandRegistry.java +++ b/src/main/java/com/sekwah/advancedportals/core/registry/SubCommandRegistry.java @@ -1,4 +1,4 @@ -package com.sekwah.advancedportals.core.api.registry; +package com.sekwah.advancedportals.core.registry; import com.sekwah.advancedportals.core.AdvancedPortalsCore; import com.sekwah.advancedportals.core.api.commands.SubCommand; diff --git a/src/main/java/com/sekwah/advancedportals/core/api/registry/TagRegistry.java b/src/main/java/com/sekwah/advancedportals/core/registry/TagRegistry.java similarity index 98% rename from src/main/java/com/sekwah/advancedportals/core/api/registry/TagRegistry.java rename to src/main/java/com/sekwah/advancedportals/core/registry/TagRegistry.java index 35a0228d..78bc1d82 100644 --- a/src/main/java/com/sekwah/advancedportals/core/api/registry/TagRegistry.java +++ b/src/main/java/com/sekwah/advancedportals/core/registry/TagRegistry.java @@ -1,4 +1,4 @@ -package com.sekwah.advancedportals.core.api.registry; +package com.sekwah.advancedportals.core.registry; import com.google.inject.Inject; import com.sekwah.advancedportals.core.AdvancedPortalsCore; diff --git a/src/main/java/com/sekwah/advancedportals/core/api/registry/WarpEffectRegistry.java b/src/main/java/com/sekwah/advancedportals/core/registry/WarpEffectRegistry.java similarity index 97% rename from src/main/java/com/sekwah/advancedportals/core/api/registry/WarpEffectRegistry.java rename to src/main/java/com/sekwah/advancedportals/core/registry/WarpEffectRegistry.java index f1adf750..dc735a8d 100644 --- a/src/main/java/com/sekwah/advancedportals/core/api/registry/WarpEffectRegistry.java +++ b/src/main/java/com/sekwah/advancedportals/core/registry/WarpEffectRegistry.java @@ -1,4 +1,4 @@ -package com.sekwah.advancedportals.core.api.registry; +package com.sekwah.advancedportals.core.registry; import com.google.inject.Inject; import com.sekwah.advancedportals.core.AdvancedPortalsCore; diff --git a/src/main/java/com/sekwah/advancedportals/core/api/services/DestinationServices.java b/src/main/java/com/sekwah/advancedportals/core/services/DestinationServices.java similarity index 94% rename from src/main/java/com/sekwah/advancedportals/core/api/services/DestinationServices.java rename to src/main/java/com/sekwah/advancedportals/core/services/DestinationServices.java index 51d97c18..d151f6a4 100644 --- a/src/main/java/com/sekwah/advancedportals/core/api/services/DestinationServices.java +++ b/src/main/java/com/sekwah/advancedportals/core/services/DestinationServices.java @@ -1,4 +1,4 @@ -package com.sekwah.advancedportals.core.api.services; +package com.sekwah.advancedportals.core.services; import com.sekwah.advancedportals.core.api.destination.Destination; import com.sekwah.advancedportals.core.data.DataTag; diff --git a/src/main/java/com/sekwah/advancedportals/core/api/services/PortalServices.java b/src/main/java/com/sekwah/advancedportals/core/services/PortalServices.java similarity index 96% rename from src/main/java/com/sekwah/advancedportals/core/api/services/PortalServices.java rename to src/main/java/com/sekwah/advancedportals/core/services/PortalServices.java index b2be6a2a..f43cad80 100644 --- a/src/main/java/com/sekwah/advancedportals/core/api/services/PortalServices.java +++ b/src/main/java/com/sekwah/advancedportals/core/services/PortalServices.java @@ -1,4 +1,4 @@ -package com.sekwah.advancedportals.core.api.services; +package com.sekwah.advancedportals.core.services; import com.google.common.collect.ImmutableList; import com.sekwah.advancedportals.repository.IPortalRepository; diff --git a/src/main/java/com/sekwah/advancedportals/core/api/services/PortalTempDataServices.java b/src/main/java/com/sekwah/advancedportals/core/services/PortalTempDataServices.java similarity index 92% rename from src/main/java/com/sekwah/advancedportals/core/api/services/PortalTempDataServices.java rename to src/main/java/com/sekwah/advancedportals/core/services/PortalTempDataServices.java index 34379850..5ce795bf 100644 --- a/src/main/java/com/sekwah/advancedportals/core/api/services/PortalTempDataServices.java +++ b/src/main/java/com/sekwah/advancedportals/core/services/PortalTempDataServices.java @@ -1,4 +1,4 @@ -package com.sekwah.advancedportals.core.api.services; +package com.sekwah.advancedportals.core.services; import com.sekwah.advancedportals.core.data.PlayerTempData; import com.sekwah.advancedportals.core.data.PortalLocation; diff --git a/src/main/java/com/sekwah/advancedportals/repository/DestinationRepository.java b/src/main/java/com/sekwah/advancedportals/repository/DestinationRepository.java index 0355f58a..c4db9b74 100644 --- a/src/main/java/com/sekwah/advancedportals/repository/DestinationRepository.java +++ b/src/main/java/com/sekwah/advancedportals/repository/DestinationRepository.java @@ -1,5 +1,7 @@ package com.sekwah.advancedportals.repository; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableMap; import com.sekwah.advancedportals.core.api.destination.Destination; @@ -10,11 +12,13 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.TimeUnit; @Singleton public class DestinationRepository implements IDestinationRepository { private final String fileLocation = ""; + private Map destinationCache = new HashMap(); /*Is there any reason to load it into the array if it's not been used or connected? Q for Sekwah*/