diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java index 27d2ddb6..e148ae02 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java @@ -69,7 +69,13 @@ import pro.gravit.launchserver.components.RegLimiterComponent; import pro.gravit.launchserver.config.LaunchServerRuntimeConfig; import pro.gravit.launchserver.dao.provider.DaoProvider; -import pro.gravit.launchserver.manangers.*; +import pro.gravit.launchserver.manangers.CertificateManager; +import pro.gravit.launchserver.manangers.LaunchServerGsonManager; +import pro.gravit.launchserver.manangers.MirrorManager; +import pro.gravit.launchserver.manangers.ModulesManager; +import pro.gravit.launchserver.manangers.ReconfigurableManager; +import pro.gravit.launchserver.manangers.ReloadManager; +import pro.gravit.launchserver.manangers.SessionManager; import pro.gravit.launchserver.manangers.hook.AuthHookManager; import pro.gravit.launchserver.manangers.hook.BuildHookManager; import pro.gravit.launchserver.socket.WebSocketService; @@ -144,11 +150,6 @@ public AuthProviderPair getAuthProviderPair() { public Map components; - // Misc options - public int threadCount; - - public int threadCoreCount; - public ExeConf launch4j; public NettyConfig netty; public GuardLicenseConf guardLicense; @@ -521,7 +522,6 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException localCommandHandler = new StdCommandHandler(true); LogHelper.warning("JLine2 isn't in classpath, using std"); } - pro.gravit.launchserver.command.handler.CommandHandler.registerCommands(localCommandHandler, this); commandHandler = localCommandHandler; // Set key pair @@ -618,6 +618,8 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException Arrays.stream(config.mirrors).forEach(mirrorManager::addMirror); + pro.gravit.launchserver.command.handler.CommandHandler.registerCommands(localCommandHandler, this); + // init modules modulesManager.initModules(); if (config.components != null) { @@ -761,9 +763,6 @@ private void generateConfigIfNotExists(boolean testEnv) throws IOException { newConfig.launcher = new LauncherConf(); newConfig.launcher.guardType = "no"; - newConfig.threadCoreCount = 0; // on your own - newConfig.threadCount = JVMHelper.OPERATING_SYSTEM_MXBEAN.getAvailableProcessors() >= 4 ? JVMHelper.OPERATING_SYSTEM_MXBEAN.getAvailableProcessors() / 2 : JVMHelper.OPERATING_SYSTEM_MXBEAN.getAvailableProcessors(); - newConfig.enabledRadon = true; newConfig.genMappings = true; newConfig.enabledProGuard = true; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/Reconfigurable.java b/LaunchServer/src/main/java/pro/gravit/launchserver/Reconfigurable.java index 45ee0193..9b784885 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/Reconfigurable.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/Reconfigurable.java @@ -1,7 +1,9 @@ package pro.gravit.launchserver; -public interface Reconfigurable { - void reconfig(String action, String[] args); +import java.util.Map; - void printConfigHelp(); +import pro.gravit.utils.command.Command; + +public interface Reconfigurable { + Map getCommands(); } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/hwid/JsonFileHWIDHandler.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/hwid/JsonFileHWIDHandler.java index b181da50..d48868e5 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/hwid/JsonFileHWIDHandler.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/hwid/JsonFileHWIDHandler.java @@ -12,8 +12,8 @@ import com.google.gson.reflect.TypeToken; -import pro.gravit.launcher.hwid.HWID; import pro.gravit.launcher.Launcher; +import pro.gravit.launcher.hwid.HWID; import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.LogHelper; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/RejectAuthProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/RejectAuthProvider.java index 4a707288..f6025060 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/RejectAuthProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/provider/RejectAuthProvider.java @@ -1,9 +1,13 @@ package pro.gravit.launchserver.auth.provider; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; import pro.gravit.launchserver.Reconfigurable; import pro.gravit.launchserver.auth.AuthException; +import pro.gravit.utils.command.Command; +import pro.gravit.utils.command.SubCommand; import pro.gravit.utils.helper.LogHelper; import pro.gravit.utils.helper.SecurityHelper; @@ -36,31 +40,15 @@ public void close() { } @Override - public void reconfig(String action, String[] args) { - switch (action) { - case "message": + public Map getCommands() { + Map commands = new HashMap<>(); + commands.put("message", new SubCommand() { + @Override + public void invoke(String... args) throws Exception { message = args[0]; LogHelper.info("New reject message: %s", message); - break; - case "whitelist.add": - if (whitelist == null) whitelist = new ArrayList<>(); - whitelist.add(args[0]); - break; - case "whitelist.remove": - if (whitelist == null) whitelist = new ArrayList<>(); - whitelist.remove(args[0]); - break; - case "whitelist.clear": - whitelist.clear(); - break; - } - } - - @Override - public void printConfigHelp() { - LogHelper.info("message [new message] - set message"); - LogHelper.info("whitelist.add [username] - add username to whitelist"); - LogHelper.info("whitelist.remove [username] - remove username into whitelist"); - LogHelper.info("whitelist.clear - clear whitelist"); + } + }); + return commands; } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/Command.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/Command.java index 83c28838..ef48ce08 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/Command.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/Command.java @@ -1,5 +1,7 @@ package pro.gravit.launchserver.command; +import java.util.Map; + import pro.gravit.launchserver.LaunchServer; public abstract class Command extends pro.gravit.utils.command.Command { @@ -9,6 +11,12 @@ public abstract class Command extends pro.gravit.utils.command.Command { protected Command(LaunchServer server) { + super(); + this.server = server; + } + + public Command(Map childCommands, LaunchServer server) { + super(childCommands); this.server = server; } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/basic/TestCommand.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/basic/TestCommand.java index 1f85bca8..6f7fd287 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/basic/TestCommand.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/basic/TestCommand.java @@ -1,14 +1,15 @@ package pro.gravit.launchserver.command.basic; +import java.nio.file.Paths; +import java.security.KeyPair; + import org.bouncycastle.cert.X509CertificateHolder; + import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.command.Command; import pro.gravit.launchserver.socket.handlers.NettyServerSocketHandler; import pro.gravit.utils.helper.CommonHelper; -import java.nio.file.Paths; -import java.security.KeyPair; - public class TestCommand extends Command { public TestCommand(LaunchServer server) { super(server); @@ -42,6 +43,10 @@ public void invoke(String... args) throws Exception { server.certificateManager.writePrivateKey(Paths.get("ca.key"), server.certificateManager.caKey); server.certificateManager.writeCertificate(Paths.get("ca.crt"), server.certificateManager.ca); } + if(args[0].equals("readCA")) { + server.certificateManager.ca = server.certificateManager.readCertificate(Paths.get("ca.crt")); + server.certificateManager.caKey = server.certificateManager.readPrivateKey(Paths.get("ca.key")); + } if(args[0].equals("genCert")) { verifyArgs(args, 2); String name = args[1]; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/dump/DumpEntryCacheCommand.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/dump/DumpEntryCacheCommand.java index 4fe70d76..fba4e1ff 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/dump/DumpEntryCacheCommand.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/dump/DumpEntryCacheCommand.java @@ -11,12 +11,59 @@ import pro.gravit.launchserver.auth.AuthProviderPair; import pro.gravit.launchserver.auth.handler.CachedAuthHandler; import pro.gravit.launchserver.command.Command; +import pro.gravit.utils.command.SubCommand; import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.LogHelper; public class DumpEntryCacheCommand extends Command { public DumpEntryCacheCommand(LaunchServer server) { super(server); + childCommands.put("load", new SubCommand() { + @Override + public void invoke(String... args) throws Exception { + verifyArgs(args, 2); + AuthProviderPair pair = server.config.getAuthProviderPair(args[0]); + if (pair == null) throw new IllegalStateException(String.format("Auth %s not found", args[0])); + if (!(pair.handler instanceof CachedAuthHandler)) + throw new UnsupportedOperationException("This command used only CachedAuthHandler"); + CachedAuthHandler authHandler = (CachedAuthHandler) pair.handler; + + LogHelper.info("CachedAuthHandler read from %s", args[0]); + int size_entry; + int size_username; + try (Reader reader = IOHelper.newReader(Paths.get(args[1]))) { + EntryAndUsername entryAndUsername = Launcher.gsonManager.configGson.fromJson(reader, EntryAndUsername.class); + size_entry = entryAndUsername.entryCache.size(); + size_username = entryAndUsername.usernameCache.size(); + authHandler.loadEntryCache(entryAndUsername.entryCache); + authHandler.loadUsernameCache(entryAndUsername.usernameCache); + + } + LogHelper.subInfo("Readed %d entryCache %d usernameCache", size_entry, size_username); + } + }); + childCommands.put("unload", new SubCommand() { + @Override + public void invoke(String... args) throws Exception { + verifyArgs(args, 2); + AuthProviderPair pair = server.config.getAuthProviderPair(args[0]); + if (pair == null) throw new IllegalStateException(String.format("Auth %s not found", args[0])); + if (!(pair.handler instanceof CachedAuthHandler)) + throw new UnsupportedOperationException("This command used only CachedAuthHandler"); + CachedAuthHandler authHandler = (CachedAuthHandler) pair.handler; + + LogHelper.info("CachedAuthHandler write to %s", args[1]); + Map entryCache = authHandler.getEntryCache(); + Map usernamesCache = authHandler.getUsernamesCache(); + EntryAndUsername serializable = new EntryAndUsername(); + serializable.entryCache = entryCache; + serializable.usernameCache = usernamesCache; + try (Writer writer = IOHelper.newWriter(Paths.get(args[1]))) { + Launcher.gsonManager.configGson.toJson(serializable, writer); + } + LogHelper.subInfo("Write %d entryCache, %d usernameCache", entryCache.size(), usernamesCache.size()); + } + }); } @Override @@ -31,37 +78,7 @@ public String getUsageDescription() { @Override public void invoke(String... args) throws Exception { - verifyArgs(args, 3); - AuthProviderPair pair = server.config.getAuthProviderPair(args[1]); - if (pair == null) throw new IllegalStateException(String.format("Auth %s not found", args[1])); - if (!(pair.handler instanceof CachedAuthHandler)) - throw new UnsupportedOperationException("This command used only CachedAuthHandler"); - CachedAuthHandler authHandler = (CachedAuthHandler) pair.handler; - if (args[0].equals("unload")) { - LogHelper.info("CachedAuthHandler write to %s", args[2]); - Map entryCache = authHandler.getEntryCache(); - Map usernamesCache = authHandler.getUsernamesCache(); - EntryAndUsername serializable = new EntryAndUsername(); - serializable.entryCache = entryCache; - serializable.usernameCache = usernamesCache; - try (Writer writer = IOHelper.newWriter(Paths.get(args[1]))) { - Launcher.gsonManager.configGson.toJson(serializable, writer); - } - LogHelper.subInfo("Write %d entryCache, %d usernameCache", entryCache.size(), usernamesCache.size()); - } else if (args[0].equals("load")) { - LogHelper.info("CachedAuthHandler read from %s", args[1]); - int size_entry; - int size_username; - try (Reader reader = IOHelper.newReader(Paths.get(args[1]))) { - EntryAndUsername entryAndUsername = Launcher.gsonManager.configGson.fromJson(reader, EntryAndUsername.class); - size_entry = entryAndUsername.entryCache.size(); - size_username = entryAndUsername.usernameCache.size(); - authHandler.loadEntryCache(entryAndUsername.entryCache); - authHandler.loadUsernameCache(entryAndUsername.usernameCache); - - } - LogHelper.subInfo("Readed %d entryCache %d usernameCache", size_entry, size_username); - } + invokeSubcommands(args); } public class EntryAndUsername { diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/dump/DumpSessionsCommand.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/dump/DumpSessionsCommand.java index 234b72d2..350e7515 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/dump/DumpSessionsCommand.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/dump/DumpSessionsCommand.java @@ -13,12 +13,41 @@ import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.command.Command; import pro.gravit.launchserver.socket.Client; +import pro.gravit.utils.command.SubCommand; import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.LogHelper; public class DumpSessionsCommand extends Command { public DumpSessionsCommand(LaunchServer server) { super(server); + childCommands.put("load", new SubCommand() { + @Override + public void invoke(String... args) throws Exception { + verifyArgs(args, 1); + LogHelper.info("Sessions read from %s", args[0]); + int size; + try (Reader reader = IOHelper.newReader(Paths.get(args[0]))) { + Type setType = new TypeToken>() { + }.getType(); + Set clientSet = Launcher.gsonManager.configGson.fromJson(reader, setType); + size = clientSet.size(); + server.sessionManager.loadSessions(clientSet); + } + LogHelper.subInfo("Readed %d sessions", size); + } + }); + childCommands.put("unload", new SubCommand() { + @Override + public void invoke(String... args) throws Exception { + verifyArgs(args, 1); + LogHelper.info("Sessions write to %s", args[0]); + Set clientSet = server.sessionManager.getSessions(); + try (Writer writer = IOHelper.newWriter(Paths.get(args[0]))) { + Launcher.gsonManager.configGson.toJson(clientSet, writer); + } + LogHelper.subInfo("Write %d sessions", clientSet.size()); + } + }); } @Override @@ -33,25 +62,6 @@ public String getUsageDescription() { @Override public void invoke(String... args) throws Exception { - verifyArgs(args, 2); - if (args[0].equals("unload")) { - LogHelper.info("Sessions write to %s", args[1]); - Set clientSet = server.sessionManager.getSessions(); - try (Writer writer = IOHelper.newWriter(Paths.get(args[1]))) { - Launcher.gsonManager.configGson.toJson(clientSet, writer); - } - LogHelper.subInfo("Write %d sessions", clientSet.size()); - } else if (args[0].equals("load")) { - LogHelper.info("Sessions read from %s", args[1]); - int size; - try (Reader reader = IOHelper.newReader(Paths.get(args[1]))) { - Type setType = new TypeToken>() { - }.getType(); - Set clientSet = Launcher.gsonManager.configGson.fromJson(reader, setType); - size = clientSet.size(); - server.sessionManager.loadSessions(clientSet); - } - LogHelper.subInfo("Readed %d sessions", size); - } + invokeSubcommands(args); } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/handler/CommandHandler.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/handler/CommandHandler.java index 69c16655..fce4adce 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/handler/CommandHandler.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/handler/CommandHandler.java @@ -32,7 +32,16 @@ import pro.gravit.launchserver.command.install.MultiCommand; import pro.gravit.launchserver.command.modules.LoadModuleCommand; import pro.gravit.launchserver.command.modules.ModulesCommand; -import pro.gravit.launchserver.command.service.*; +import pro.gravit.launchserver.command.service.ClientsCommand; +import pro.gravit.launchserver.command.service.ComponentCommand; +import pro.gravit.launchserver.command.service.ConfigCommand; +import pro.gravit.launchserver.command.service.GetModulusCommand; +import pro.gravit.launchserver.command.service.GetPermissionsCommand; +import pro.gravit.launchserver.command.service.GivePermissionsCommand; +import pro.gravit.launchserver.command.service.ReloadAllCommand; +import pro.gravit.launchserver.command.service.ReloadCommand; +import pro.gravit.launchserver.command.service.ReloadListCommand; +import pro.gravit.launchserver.command.service.ServerStatusCommand; import pro.gravit.utils.command.BaseCommandCategory; import pro.gravit.utils.command.basic.ClearCommand; import pro.gravit.utils.command.basic.DebugCommand; @@ -105,8 +114,6 @@ public static void registerCommands(pro.gravit.utils.command.CommandHandler hand service.registerCommand("reloadAll", new ReloadAllCommand(server)); service.registerCommand("reloadList", new ReloadListCommand(server)); service.registerCommand("config", new ConfigCommand(server)); - service.registerCommand("configHelp", new ConfigHelpCommand(server)); - service.registerCommand("configList", new ConfigListCommand(server)); service.registerCommand("serverStatus", new ServerStatusCommand(server)); service.registerCommand("checkInstall", new CheckInstallCommand(server)); service.registerCommand("multi", new MultiCommand(server)); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ConfigCommand.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ConfigCommand.java index 3c546609..6c069bf2 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ConfigCommand.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ConfigCommand.java @@ -2,11 +2,10 @@ import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.command.Command; -import pro.gravit.utils.helper.LogHelper; public class ConfigCommand extends Command { public ConfigCommand(LaunchServer server) { - super(server); + super(server.reconfigurableManager.getCommands(), server); } @Override @@ -21,10 +20,6 @@ public String getUsageDescription() { @Override public void invoke(String... args) throws Exception { - verifyArgs(args, 2); - LogHelper.info("Call %s module %s action", args[0], args[1]); - String[] new_args = new String[args.length - 2]; - System.arraycopy(args, 2, new_args, 0, args.length - 2); - server.reconfigurableManager.call(args[0], args[1], new_args); + invokeSubcommands(args); } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ConfigHelpCommand.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ConfigHelpCommand.java deleted file mode 100644 index b1a0b749..00000000 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ConfigHelpCommand.java +++ /dev/null @@ -1,28 +0,0 @@ -package pro.gravit.launchserver.command.service; - -import pro.gravit.launchserver.LaunchServer; -import pro.gravit.launchserver.command.Command; -import pro.gravit.utils.helper.LogHelper; - -public class ConfigHelpCommand extends Command { - public ConfigHelpCommand(LaunchServer server) { - super(server); - } - - @Override - public String getArgsDescription() { - return "[name]"; - } - - @Override - public String getUsageDescription() { - return "print help for config command"; - } - - @Override - public void invoke(String... args) throws Exception { - verifyArgs(args, 1); - LogHelper.info("Help %s module", args[0]); - server.reconfigurableManager.printHelp(args[0]); - } -} diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ConfigListCommand.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ConfigListCommand.java deleted file mode 100644 index 9af0aee9..00000000 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ConfigListCommand.java +++ /dev/null @@ -1,25 +0,0 @@ -package pro.gravit.launchserver.command.service; - -import pro.gravit.launchserver.LaunchServer; -import pro.gravit.launchserver.command.Command; - -public class ConfigListCommand extends Command { - public ConfigListCommand(LaunchServer server) { - super(server); - } - - @Override - public String getArgsDescription() { - return "[name]"; - } - - @Override - public String getUsageDescription() { - return "print help for config command"; - } - - @Override - public void invoke(String... args) { - server.reconfigurableManager.printReconfigurables(); - } -} diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/components/RegLimiterComponent.java b/LaunchServer/src/main/java/pro/gravit/launchserver/components/RegLimiterComponent.java index 2cef6770..7f9976ce 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/components/RegLimiterComponent.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/components/RegLimiterComponent.java @@ -1,15 +1,15 @@ package pro.gravit.launchserver.components; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + import pro.gravit.launcher.NeedGarbageCollection; import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.manangers.hook.AuthHookManager; import pro.gravit.utils.HookException; import pro.gravit.utils.HookSet; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - public class RegLimiterComponent extends Component implements NeedGarbageCollection, AutoCloseable { public static final long TIMEOUT = 12 * 60 * 60 * 1000; //12 часов diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/dao/User.java b/LaunchServer/src/main/java/pro/gravit/launchserver/dao/User.java index 31e42497..0573c2c3 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/dao/User.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/dao/User.java @@ -7,7 +7,16 @@ import java.util.Collection; import java.util.UUID; -import javax.persistence.*; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.Table; import pro.gravit.launcher.ClientPermissions; import pro.gravit.utils.helper.LogHelper; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/dao/UserDAO.java b/LaunchServer/src/main/java/pro/gravit/launchserver/dao/UserDAO.java index b4769a3d..c70afdbc 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/dao/UserDAO.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/dao/UserDAO.java @@ -1,10 +1,10 @@ package pro.gravit.launchserver.dao; -import pro.gravit.launcher.hwid.OshiHWID; - import java.util.List; import java.util.UUID; +import pro.gravit.launcher.hwid.OshiHWID; + public interface UserDAO { User findById(int id); User findByUsername(String username); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/dao/UserHWID.java b/LaunchServer/src/main/java/pro/gravit/launchserver/dao/UserHWID.java index 106aab2a..d81dddf3 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/dao/UserHWID.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/dao/UserHWID.java @@ -1,11 +1,16 @@ package pro.gravit.launchserver.dao; +import java.util.function.Supplier; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + import pro.gravit.launcher.hwid.HWID; import pro.gravit.launcher.hwid.OshiHWID; -import javax.persistence.*; -import java.util.function.Supplier; - @Entity @Table(name = "users_hwids") public class UserHWID implements HWID { diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/dao/provider/HibernateDaoProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/dao/provider/HibernateDaoProvider.java index 541f43ed..08dd15ec 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/dao/provider/HibernateDaoProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/dao/provider/HibernateDaoProvider.java @@ -1,6 +1,9 @@ package pro.gravit.launchserver.dao.provider; +import java.nio.file.Paths; + import org.hibernate.cfg.Configuration; + import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.dao.User; import pro.gravit.launchserver.dao.UserHWID; @@ -8,8 +11,6 @@ import pro.gravit.launchserver.dao.impl.HibernateUserDAOImpl; import pro.gravit.utils.helper.CommonHelper; -import java.nio.file.Paths; - public class HibernateDaoProvider extends DaoProvider { public String driver; public String url; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/CertificateManager.java b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/CertificateManager.java index 4b1de19e..5490077f 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/CertificateManager.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/CertificateManager.java @@ -1,5 +1,23 @@ package pro.gravit.launchserver.manangers; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.nio.file.Path; +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.ECGenParameterSpec; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.temporal.ChronoUnit; +import java.util.Date; + import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameBuilder; @@ -17,22 +35,12 @@ import org.bouncycastle.operator.bc.BcECContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.util.io.pem.PemObject; +import org.bouncycastle.util.io.pem.PemReader; import org.bouncycastle.util.io.pem.PemWriter; + import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.SecurityHelper; -import java.io.IOException; -import java.math.BigInteger; -import java.nio.file.Path; -import java.security.*; -import java.security.spec.ECGenParameterSpec; -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.time.temporal.ChronoUnit; -import java.util.Date; - public class CertificateManager { public X509CertificateHolder ca; public AsymmetricKeyParameter caKey; @@ -106,4 +114,28 @@ public void writeCertificate(Path file, X509CertificateHolder holder) throws IOE writer.writeObject(new PemObject("CERTIFICATE", holder.toASN1Structure().getEncoded())); } } + + public AsymmetricKeyParameter readPrivateKey(Path file) throws IOException { + AsymmetricKeyParameter ret; + try(PemReader reader = new PemReader(IOHelper.newReader(file))) + { + byte[] bytes = reader.readPemObject().getContent(); + try(ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes)) + { + + ret = PrivateKeyFactory.createKey(inputStream); + } + } + return ret; + } + + public X509CertificateHolder readCertificate(Path file) throws IOException { + X509CertificateHolder ret; + try(PemReader reader = new PemReader(IOHelper.newReader(file))) + { + byte[] bytes = reader.readPemObject().getContent(); + ret = new X509CertificateHolder(bytes); + } + return ret; + } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/ReconfigurableManager.java b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/ReconfigurableManager.java index 59e4d054..7d1c4b5a 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/ReconfigurableManager.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/ReconfigurableManager.java @@ -1,35 +1,63 @@ package pro.gravit.launchserver.manangers; import java.util.HashMap; -import java.util.Objects; +import java.util.Map; import pro.gravit.launchserver.Reconfigurable; -import pro.gravit.utils.helper.LogHelper; +import pro.gravit.utils.command.Command; +import pro.gravit.utils.command.CommandException; +import pro.gravit.utils.command.basic.HelpCommand; import pro.gravit.utils.helper.VerifyHelper; public class ReconfigurableManager { - private final HashMap RECONFIGURABLE = new HashMap<>(); + private class ReconfigurableVirtualCommand extends Command { + public ReconfigurableVirtualCommand(Map childs) { + super(childs); + } + + @Override + public String getArgsDescription() { + return null; + } + + @Override + public String getUsageDescription() { + return null; + } + + @Override + public void invoke(String... args) throws Exception { + invokeSubcommands(args); + } + } + private final HashMap RECONFIGURABLE = new HashMap<>(); public void registerReconfigurable(String name, Reconfigurable reconfigurable) { - VerifyHelper.putIfAbsent(RECONFIGURABLE, name.toLowerCase(), Objects.requireNonNull(reconfigurable, "adapter"), + VerifyHelper.putIfAbsent(RECONFIGURABLE, name.toLowerCase(), new ReconfigurableVirtualCommand(reconfigurable.getCommands()), String.format("Reloadable has been already registered: '%s'", name)); } - public Reconfigurable unregisterReconfigurable(String name) { - return RECONFIGURABLE.remove(name); + public void unregisterReconfigurable(String name) { + RECONFIGURABLE.remove(name); } - public void printHelp(String name) { - RECONFIGURABLE.get(name.toLowerCase()).printConfigHelp(); + public void call(String name, String action, String[] args) throws Exception + { + Command commands = RECONFIGURABLE.get(name); + if(commands == null) throw new CommandException(String.format("Reconfigurable %s not found", name)); + Command command = commands.childCommands.get(action); + if(command == null) throw new CommandException(String.format("Action %s.%s not found", name, action)); + command.invoke(args); } - public void call(String name, String action, String[] args) { - RECONFIGURABLE.get(name.toLowerCase()).reconfig(action.toLowerCase(), args); + public void printHelp(String name) throws CommandException + { + Command commands = RECONFIGURABLE.get(name); + if(commands == null) throw new CommandException(String.format("Reconfigurable %s not found", name)); + HelpCommand.printSubCommandsHelp(name, commands); } - - public void printReconfigurables() { - LogHelper.info("Print reconfigurables"); - RECONFIGURABLE.forEach((k, v) -> LogHelper.subInfo(k)); - LogHelper.info("Found %d reconfigurables", RECONFIGURABLE.size()); + public Map getCommands() + { + return RECONFIGURABLE; } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java index 06ee9636..29c96ad0 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java @@ -22,12 +22,19 @@ import pro.gravit.launcher.request.WebSocketEvent; import pro.gravit.launcher.request.admin.ProxyRequest; import pro.gravit.launchserver.LaunchServer; -import pro.gravit.launchserver.socket.response.WebSocketServerResponse; import pro.gravit.launchserver.socket.response.SimpleResponse; +import pro.gravit.launchserver.socket.response.WebSocketServerResponse; import pro.gravit.launchserver.socket.response.admin.AddLogListenerResponse; import pro.gravit.launchserver.socket.response.admin.ExecCommandResponse; import pro.gravit.launchserver.socket.response.admin.ProxyCommandResponse; -import pro.gravit.launchserver.socket.response.auth.*; +import pro.gravit.launchserver.socket.response.auth.AuthResponse; +import pro.gravit.launchserver.socket.response.auth.CheckServerResponse; +import pro.gravit.launchserver.socket.response.auth.GetAvailabilityAuthResponse; +import pro.gravit.launchserver.socket.response.auth.JoinServerResponse; +import pro.gravit.launchserver.socket.response.auth.ProfilesResponse; +import pro.gravit.launchserver.socket.response.auth.RegisterResponse; +import pro.gravit.launchserver.socket.response.auth.RestoreSessionResponse; +import pro.gravit.launchserver.socket.response.auth.SetProfileResponse; import pro.gravit.launchserver.socket.response.profile.BatchProfileByUsername; import pro.gravit.launchserver.socket.response.profile.ProfileByUUIDResponse; import pro.gravit.launchserver.socket.response.profile.ProfileByUsername; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/admin/ProxyCommandResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/admin/ProxyCommandResponse.java index 16e53c88..1301ce2a 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/admin/ProxyCommandResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/admin/ProxyCommandResponse.java @@ -2,8 +2,8 @@ import io.netty.channel.ChannelHandlerContext; import pro.gravit.launchserver.socket.Client; -import pro.gravit.launchserver.socket.response.WebSocketServerResponse; import pro.gravit.launchserver.socket.response.SimpleResponse; +import pro.gravit.launchserver.socket.response.WebSocketServerResponse; public class ProxyCommandResponse extends SimpleResponse { public WebSocketServerResponse response; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/AuthResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/AuthResponse.java index 0124074e..c7fa7a07 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/AuthResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/AuthResponse.java @@ -9,9 +9,9 @@ import javax.crypto.IllegalBlockSizeException; import io.netty.channel.ChannelHandlerContext; +import pro.gravit.launcher.events.request.AuthRequestEvent; import pro.gravit.launcher.hwid.HWID; import pro.gravit.launcher.hwid.OshiHWID; -import pro.gravit.launcher.events.request.AuthRequestEvent; import pro.gravit.launcher.profiles.ClientProfile; import pro.gravit.launchserver.auth.AuthException; import pro.gravit.launchserver.auth.AuthProviderPair; diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/RegisterResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/RegisterResponse.java index b5fae77e..c9ae5f91 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/RegisterResponse.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/RegisterResponse.java @@ -1,16 +1,16 @@ package pro.gravit.launchserver.socket.response.auth; -import io.netty.channel.ChannelHandlerContext; -import pro.gravit.launchserver.dao.User; -import pro.gravit.launchserver.socket.Client; -import pro.gravit.launchserver.socket.response.SimpleResponse; - import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.UUID; +import io.netty.channel.ChannelHandlerContext; +import pro.gravit.launchserver.dao.User; +import pro.gravit.launchserver.socket.Client; +import pro.gravit.launchserver.socket.response.SimpleResponse; + public class RegisterResponse extends SimpleResponse { public String login; public String password; diff --git a/Launcher/runtime/config.js b/Launcher/runtime/config.js index 7966e1ee..c5fa5bc1 100644 --- a/Launcher/runtime/config.js +++ b/Launcher/runtime/config.js @@ -15,6 +15,7 @@ var config = { settingsMagic: 0xC0DE5, // Magic, don't touch autoEnterDefault: false, // Should autoEnter be enabled by default? fullScreenDefault: false, // Should fullScreen be enabled by default? + featureStoreDefault: true, // Should featureStore be enabled by default? ramDefault: 1024, // Default RAM amount (0 for auto) jvm: { diff --git a/Launcher/runtime/engine/settings.js b/Launcher/runtime/engine/settings.js index 8e8b34b6..d37463cf 100644 --- a/Launcher/runtime/engine/settings.js +++ b/Launcher/runtime/engine/settings.js @@ -10,6 +10,7 @@ var settingsManagerClass = Java.extend(SettingsManagerClass.static, { new_settings.fullScreen = config.fullScreenDefault; new_settings.ram = config.ramDefault; + new_settings.featureStore = config.featureStoreDefault; new_settings.lastDigest = null; new_settings.lastProfiles.clear(); new_settings.lastHDirs.clear(); diff --git a/Launcher/src/main/java/pro/gravit/launcher/client/FunctionalBridge.java b/Launcher/src/main/java/pro/gravit/launcher/client/FunctionalBridge.java index ec1e5474..bf8d7cef 100644 --- a/Launcher/src/main/java/pro/gravit/launcher/client/FunctionalBridge.java +++ b/Launcher/src/main/java/pro/gravit/launcher/client/FunctionalBridge.java @@ -6,12 +6,12 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; -import pro.gravit.launcher.hwid.HWID; import pro.gravit.launcher.LauncherAPI; import pro.gravit.launcher.events.request.AuthRequestEvent; import pro.gravit.launcher.guard.LauncherGuardManager; import pro.gravit.launcher.hasher.FileNameMatcher; import pro.gravit.launcher.hasher.HashedDir; +import pro.gravit.launcher.hwid.HWID; import pro.gravit.launcher.hwid.OshiHWIDProvider; import pro.gravit.launcher.managers.ConsoleManager; import pro.gravit.launcher.managers.HasherManager; diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/hwid/LauncherHWIDInterface.java b/LauncherAPI/src/main/java/pro/gravit/launcher/hwid/LauncherHWIDInterface.java index 9c4c192b..fb962b11 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/hwid/LauncherHWIDInterface.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/hwid/LauncherHWIDInterface.java @@ -1,7 +1,5 @@ package pro.gravit.launcher.hwid; -import pro.gravit.launcher.hwid.HWID; - @FunctionalInterface public interface LauncherHWIDInterface { HWID getHWID(); diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/hwid/OshiHWID.java b/LauncherAPI/src/main/java/pro/gravit/launcher/hwid/OshiHWID.java index 68e8eff4..a3f36dac 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/hwid/OshiHWID.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/hwid/OshiHWID.java @@ -4,6 +4,7 @@ import java.util.StringJoiner; import com.google.gson.Gson; + import pro.gravit.launcher.LauncherAPI; public class OshiHWID implements HWID { diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/request/Request.java b/LauncherAPI/src/main/java/pro/gravit/launcher/request/Request.java index 856ed513..5c8dd4e9 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/request/Request.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/request/Request.java @@ -6,8 +6,8 @@ import pro.gravit.launcher.Launcher; import pro.gravit.launcher.LauncherAPI; import pro.gravit.launcher.LauncherNetworkAPI; -import pro.gravit.launcher.request.websockets.WebSocketRequest; import pro.gravit.launcher.request.websockets.StandartClientWebSocketService; +import pro.gravit.launcher.request.websockets.WebSocketRequest; import pro.gravit.utils.helper.SecurityHelper; public abstract class Request implements WebSocketRequest { diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/request/auth/AuthRequest.java b/LauncherAPI/src/main/java/pro/gravit/launcher/request/auth/AuthRequest.java index e3695bfb..69e94d91 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/request/auth/AuthRequest.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/request/auth/AuthRequest.java @@ -1,9 +1,9 @@ package pro.gravit.launcher.request.auth; -import pro.gravit.launcher.hwid.HWID; import pro.gravit.launcher.LauncherAPI; import pro.gravit.launcher.LauncherNetworkAPI; import pro.gravit.launcher.events.request.AuthRequestEvent; +import pro.gravit.launcher.hwid.HWID; import pro.gravit.launcher.request.Request; import pro.gravit.launcher.request.websockets.WebSocketRequest; import pro.gravit.utils.helper.VerifyHelper; diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/request/update/LauncherRequest.java b/LauncherAPI/src/main/java/pro/gravit/launcher/request/update/LauncherRequest.java index 4b7ac5ea..adefd1cc 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/request/update/LauncherRequest.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/request/update/LauncherRequest.java @@ -11,8 +11,8 @@ import pro.gravit.launcher.downloader.ListDownloader; import pro.gravit.launcher.events.request.LauncherRequestEvent; import pro.gravit.launcher.request.Request; -import pro.gravit.launcher.request.websockets.WebSocketRequest; import pro.gravit.launcher.request.websockets.StandartClientWebSocketService; +import pro.gravit.launcher.request.websockets.WebSocketRequest; import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.JVMHelper; import pro.gravit.utils.helper.LogHelper; diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/request/update/UpdateRequest.java b/LauncherAPI/src/main/java/pro/gravit/launcher/request/update/UpdateRequest.java index 99e0d743..68a91f04 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/request/update/UpdateRequest.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/request/update/UpdateRequest.java @@ -22,8 +22,8 @@ import pro.gravit.launcher.hasher.HashedFile; import pro.gravit.launcher.request.Request; import pro.gravit.launcher.request.update.UpdateRequest.State.Callback; -import pro.gravit.launcher.request.websockets.WebSocketRequest; import pro.gravit.launcher.request.websockets.StandartClientWebSocketService; +import pro.gravit.launcher.request.websockets.WebSocketRequest; import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.LogHelper; diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/ClientWebSocketService.java b/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/ClientWebSocketService.java index 2c97ebea..1ca63dc0 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/ClientWebSocketService.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/ClientWebSocketService.java @@ -12,7 +12,25 @@ import pro.gravit.launcher.Launcher; import pro.gravit.launcher.events.ExceptionEvent; -import pro.gravit.launcher.events.request.*; +import pro.gravit.launcher.events.request.AuthRequestEvent; +import pro.gravit.launcher.events.request.BatchProfileByUsernameRequestEvent; +import pro.gravit.launcher.events.request.CheckServerRequestEvent; +import pro.gravit.launcher.events.request.ErrorRequestEvent; +import pro.gravit.launcher.events.request.ExecCommandRequestEvent; +import pro.gravit.launcher.events.request.GetAvailabilityAuthRequestEvent; +import pro.gravit.launcher.events.request.GetSecureTokenRequestEvent; +import pro.gravit.launcher.events.request.JoinServerRequestEvent; +import pro.gravit.launcher.events.request.LauncherRequestEvent; +import pro.gravit.launcher.events.request.LogEvent; +import pro.gravit.launcher.events.request.ProfileByUUIDRequestEvent; +import pro.gravit.launcher.events.request.ProfileByUsernameRequestEvent; +import pro.gravit.launcher.events.request.ProfilesRequestEvent; +import pro.gravit.launcher.events.request.RegisterRequestEvent; +import pro.gravit.launcher.events.request.RestoreSessionRequestEvent; +import pro.gravit.launcher.events.request.SetProfileRequestEvent; +import pro.gravit.launcher.events.request.UpdateListRequestEvent; +import pro.gravit.launcher.events.request.UpdateRequestEvent; +import pro.gravit.launcher.events.request.VerifySecureTokenRequestEvent; import pro.gravit.launcher.hasher.HashedEntry; import pro.gravit.launcher.hasher.HashedEntryAdapter; import pro.gravit.launcher.request.WebSocketEvent; diff --git a/LauncherCore/src/main/java/pro/gravit/utils/Version.java b/LauncherCore/src/main/java/pro/gravit/utils/Version.java index be65d7db..08176b4b 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/Version.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/Version.java @@ -22,7 +22,7 @@ public final class Version { public final Type release; public static final int MAJOR = 5; public static final int MINOR = 0; - public static final int PATCH = 4; + public static final int PATCH = 5; public static final int BUILD = 1; public static final Version.Type RELEASE = Version.Type.STABLE; diff --git a/LauncherCore/src/main/java/pro/gravit/utils/command/Command.java b/LauncherCore/src/main/java/pro/gravit/utils/command/Command.java index 6deff0d9..8f2f2471 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/command/Command.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/command/Command.java @@ -1,11 +1,26 @@ package pro.gravit.utils.command; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.UUID; +import org.jline.reader.Candidate; + import pro.gravit.utils.helper.VerifyHelper; public abstract class Command { + public Map childCommands; + public Command() { + childCommands = new HashMap<>(); + } + + public Command(Map childCommands) { + this.childCommands = childCommands; + } protected static String parseUsername(String username) throws CommandException { try { @@ -29,6 +44,40 @@ protected static UUID parseUUID(String s) throws CommandException { public abstract String getUsageDescription(); + public Candidate buildCandidate(CommandHandler.Category category, String commandName) + { + return new Candidate(commandName); + } + + public List complete(List words, int wordIndex, String word) + { + if(wordIndex == 0) + { + List candidates = new ArrayList<>(); + childCommands.forEach((k,v) -> { + if(k.startsWith(word)) + { + candidates.add(new Candidate(k)); + } + }); + return candidates; + } + else + { + Command cmd = childCommands.get(words.get(0)); + if(cmd == null) return new ArrayList<>(); + return cmd.complete(words.subList(1, words.size()), wordIndex - 1, word); + } + } + + public void invokeSubcommands(String... args) throws Exception + { + verifyArgs(args, 1); + Command command = childCommands.get(args[0]); + if(command == null) throw new CommandException(String.format("Unknown sub command: '%s'", args[0])); + command.invoke(Arrays.copyOfRange(args, 1, args.length)); + } + public abstract void invoke(String... args) throws Exception; diff --git a/LauncherCore/src/main/java/pro/gravit/utils/command/JLineCommandHandler.java b/LauncherCore/src/main/java/pro/gravit/utils/command/JLineCommandHandler.java index 97566b37..e7284c9e 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/command/JLineCommandHandler.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/command/JLineCommandHandler.java @@ -36,12 +36,21 @@ public class JLineConsoleCompleter implements Completer { @Override public void complete(LineReader reader, ParsedLine line, List candidates) { String completeWord = line.word(); - if (line.wordIndex() != 0) return; - walk((category, name, command) -> { - if (name.startsWith(completeWord)) { - candidates.add(new Candidate(name)); - } - }); + if (line.wordIndex() == 0) + { + walk((category, name, command) -> { + if (name.startsWith(completeWord)) { + candidates.add(command.buildCandidate(category, name)); + } + }); + } + else + { + Command target = findCommand(line.words().get(0)); + List words = line.words(); + List candidates1 = target.complete(words.subList(1, words.size()), line.wordIndex() - 1, completeWord); + candidates.addAll(candidates1); + } } } diff --git a/LauncherCore/src/main/java/pro/gravit/utils/command/StdCommandHandler.java b/LauncherCore/src/main/java/pro/gravit/utils/command/StdCommandHandler.java index 3d817c7b..7c0a8930 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/command/StdCommandHandler.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/command/StdCommandHandler.java @@ -2,8 +2,9 @@ import java.io.BufferedReader; import java.io.IOException; -import pro.gravit.utils.helper.JVMHelper; + import pro.gravit.utils.helper.IOHelper; +import pro.gravit.utils.helper.JVMHelper; public class StdCommandHandler extends CommandHandler { private final BufferedReader reader; diff --git a/LauncherCore/src/main/java/pro/gravit/utils/command/SubCommand.java b/LauncherCore/src/main/java/pro/gravit/utils/command/SubCommand.java new file mode 100644 index 00000000..54bd51fe --- /dev/null +++ b/LauncherCore/src/main/java/pro/gravit/utils/command/SubCommand.java @@ -0,0 +1,13 @@ +package pro.gravit.utils.command; + +public abstract class SubCommand extends Command { + @Override + public String getArgsDescription() { + return null; + } + + @Override + public String getUsageDescription() { + return null; + } +} diff --git a/LauncherCore/src/main/java/pro/gravit/utils/command/basic/HelpCommand.java b/LauncherCore/src/main/java/pro/gravit/utils/command/basic/HelpCommand.java index 77c819d1..95f00723 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/command/basic/HelpCommand.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/command/basic/HelpCommand.java @@ -1,5 +1,6 @@ package pro.gravit.utils.command.basic; +import java.util.Arrays; import java.util.Map.Entry; import org.fusesource.jansi.Ansi; @@ -13,7 +14,7 @@ public final class HelpCommand extends Command { private CommandHandler handler; - private static void printCommand(String name, Command command) { + public static void printCommand(String name, Command command) { String args = command.getArgsDescription(); //LogHelper.subInfo("%s %s - %s", name, args == null ? "[nothing]" : args, command.getUsageDescription()); LogHelper.rawLog(() -> FormatHelper.rawFormat(LogHelper.Level.INFO, LogHelper.getDataTime(), true) + String.format("%s %s - %s", name, args == null ? "[nothing]" : args, command.getUsageDescription()), () -> { @@ -31,6 +32,27 @@ private static void printCommand(String name, Command command) { }, () -> LogHelper.htmlFormatLog(LogHelper.Level.INFO, LogHelper.getDataTime(), String.format("%s %s - %s", name, args == null ? "[nothing]" : args, command.getUsageDescription()), true)); } + public static void printSubCommandsHelp(String base, Command command) + { + command.childCommands.forEach((k, v) -> { + printCommand(base.concat(" ").concat(k), v); + }); + } + + public static void printSubCommandsHelp(String name, String[] args, Command command) throws CommandException + { + if(args.length == 0) + { + printSubCommandsHelp(name, command); + } + else + { + Command child = command.childCommands.get(args[0]); + if(child == null) throw new CommandException(String.format("Unknown sub command: '%s'", args[0])); + printSubCommandsHelp(name.concat(" ").concat(args[0]), Arrays.copyOfRange(args,1 , args.length), child); + } + } + private static void printCategory(String name, String description) { if (description != null) LogHelper.info("Category: %s - %s", name, description); else LogHelper.info("Category: %s", name); @@ -58,7 +80,9 @@ public void invoke(String... args) throws CommandException { } // Print command help - printCommand(args[0]); + if(args.length == 1) + printCommand(args[0]); + printSubCommandsHelp(args[0], Arrays.copyOfRange(args, 1 , args.length), handler.lookup(args[0])); } private void printCommand(String name) throws CommandException { diff --git a/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapper.java b/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapper.java index b32ac0d6..8c7bba1c 100644 --- a/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapper.java +++ b/ServerWrapper/src/main/java/pro/gravit/launcher/server/ServerWrapper.java @@ -157,21 +157,19 @@ public void run(String... args) throws Throwable { else mainClass = Class.forName(classname); MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class)); modulesManager.postInitModules(); - if (config.websocket.enabled) { - Request.service.reconnectCallback = () -> - { - LogHelper.debug("WebSocket connect closed. Try reconnect"); - try { - Request.service.open(); - LogHelper.debug("Connect to %s", config.websocket.address); - } catch (Exception e) { - LogHelper.error(e); - throw new RequestException(String.format("Connect error: %s", e.getMessage() != null ? e.getMessage() : "null")); - } - auth(); - }; - } - LogHelper.info("ServerWrapper: Project %s, LaunchServer address: %s. Title: %s", config.projectname, config.websocket.address, config.title); + Request.service.reconnectCallback = () -> + { + LogHelper.debug("WebSocket connect closed. Try reconnect"); + try { + Request.service.open(); + LogHelper.debug("Connect to %s", config.address); + } catch (Exception e) { + LogHelper.error(e); + throw new RequestException(String.format("Connect error: %s", e.getMessage() != null ? e.getMessage() : "null")); + } + auth(); + }; + LogHelper.info("ServerWrapper: Project %s, LaunchServer address: %s. Title: %s", config.projectname, config.address, config.title); LogHelper.info("Minecraft Version (for profile): %s", wrapper.profile == null ? "unknown" : wrapper.profile.getVersion().name); LogHelper.info("Start Minecraft Server"); LogHelper.debug("Invoke main method %s", mainClass.getName()); @@ -192,11 +190,9 @@ public void updateLauncherConfig() { LauncherConfig cfg = null; try { - cfg = new LauncherConfig(config.websocket.address, SecurityHelper.toPublicRSAKey(IOHelper.read(publicKeyFile)), new HashMap<>(), config.projectname); - if (config.websocket != null && config.websocket.enabled) { - cfg.isNettyEnabled = true; - cfg.address = config.websocket.address; - } + cfg = new LauncherConfig(config.address, SecurityHelper.toPublicRSAKey(IOHelper.read(publicKeyFile)), new HashMap<>(), config.projectname); + cfg.isNettyEnabled = true; + cfg.address = config.address; } catch (InvalidKeySpecException | IOException e) { LogHelper.error(e); } @@ -228,8 +224,7 @@ public Config getDefaultConfig() { newConfig.reconnectCount = 10; newConfig.reconnectSleep = 1000; newConfig.websocket = new WebSocketConf(); - newConfig.websocket.address = "ws://localhost:9274/api"; - newConfig.websocket.enabled = false; + newConfig.address = "ws://localhost:9274/api"; newConfig.env = LauncherConfig.LauncherEnvironment.STD; return newConfig; } @@ -242,6 +237,7 @@ public void setConfig(Config config) { public static final class Config { public String title; public String projectname; + public String address; public WebSocketConf websocket; public int reconnectCount; public int reconnectSleep; @@ -261,8 +257,6 @@ public static final class Config { } public static final class WebSocketConf { - public boolean enabled; - public String address; } public ClientProfile profile; diff --git a/ServerWrapper/src/main/java/pro/gravit/launcher/server/setup/ServerWrapperSetup.java b/ServerWrapper/src/main/java/pro/gravit/launcher/server/setup/ServerWrapperSetup.java index ad6c0174..6a63ffae 100644 --- a/ServerWrapper/src/main/java/pro/gravit/launcher/server/setup/ServerWrapperSetup.java +++ b/ServerWrapper/src/main/java/pro/gravit/launcher/server/setup/ServerWrapperSetup.java @@ -41,10 +41,10 @@ public void run() throws IOException { } } LogHelper.info("Found MainClass %s", mainClassName); - System.out.println("Print launchserver websocket host:"); + System.out.println("Print launchserver websocket host( ws://host:port/api ):"); String address = commands.commandHandler.readLine(); wrapper.config.mainclass = mainClassName; - wrapper.config.websocket.address = address; + wrapper.config.address = address; if (!Files.exists(ServerWrapper.publicKeyFile)) { LogHelper.error("public.key not found"); for (int i = 0; i < 10; ++i) { diff --git a/modules b/modules index dba4f013..f7cf0576 160000 --- a/modules +++ b/modules @@ -1 +1 @@ -Subproject commit dba4f0132cdb49cbc6cb7356fb6a54a063aba8b5 +Subproject commit f7cf0576033cd413b99e8180610d586e370c9351