[ANY] Слияние dev с feature/autoZip

This commit is contained in:
Zaxar163 2019-07-11 10:45:02 +03:00
commit 9dd454c7ec
42 changed files with 417 additions and 248 deletions

View file

@ -69,7 +69,13 @@
import pro.gravit.launchserver.components.RegLimiterComponent; import pro.gravit.launchserver.components.RegLimiterComponent;
import pro.gravit.launchserver.config.LaunchServerRuntimeConfig; import pro.gravit.launchserver.config.LaunchServerRuntimeConfig;
import pro.gravit.launchserver.dao.provider.DaoProvider; 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.AuthHookManager;
import pro.gravit.launchserver.manangers.hook.BuildHookManager; import pro.gravit.launchserver.manangers.hook.BuildHookManager;
import pro.gravit.launchserver.socket.WebSocketService; import pro.gravit.launchserver.socket.WebSocketService;
@ -144,11 +150,6 @@ public AuthProviderPair getAuthProviderPair() {
public Map<String, Component> components; public Map<String, Component> components;
// Misc options
public int threadCount;
public int threadCoreCount;
public ExeConf launch4j; public ExeConf launch4j;
public NettyConfig netty; public NettyConfig netty;
public GuardLicenseConf guardLicense; public GuardLicenseConf guardLicense;
@ -521,7 +522,6 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException
localCommandHandler = new StdCommandHandler(true); localCommandHandler = new StdCommandHandler(true);
LogHelper.warning("JLine2 isn't in classpath, using std"); LogHelper.warning("JLine2 isn't in classpath, using std");
} }
pro.gravit.launchserver.command.handler.CommandHandler.registerCommands(localCommandHandler, this);
commandHandler = localCommandHandler; commandHandler = localCommandHandler;
// Set key pair // Set key pair
@ -618,6 +618,8 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException
Arrays.stream(config.mirrors).forEach(mirrorManager::addMirror); Arrays.stream(config.mirrors).forEach(mirrorManager::addMirror);
pro.gravit.launchserver.command.handler.CommandHandler.registerCommands(localCommandHandler, this);
// init modules // init modules
modulesManager.initModules(); modulesManager.initModules();
if (config.components != null) { if (config.components != null) {
@ -761,9 +763,6 @@ private void generateConfigIfNotExists(boolean testEnv) throws IOException {
newConfig.launcher = new LauncherConf(); newConfig.launcher = new LauncherConf();
newConfig.launcher.guardType = "no"; 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.enabledRadon = true;
newConfig.genMappings = true; newConfig.genMappings = true;
newConfig.enabledProGuard = true; newConfig.enabledProGuard = true;

View file

@ -1,7 +1,9 @@
package pro.gravit.launchserver; package pro.gravit.launchserver;
public interface Reconfigurable { import java.util.Map;
void reconfig(String action, String[] args);
void printConfigHelp(); import pro.gravit.utils.command.Command;
public interface Reconfigurable {
Map<String, Command> getCommands();
} }

View file

@ -12,8 +12,8 @@
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import pro.gravit.launcher.hwid.HWID;
import pro.gravit.launcher.Launcher; import pro.gravit.launcher.Launcher;
import pro.gravit.launcher.hwid.HWID;
import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.IOHelper;
import pro.gravit.utils.helper.LogHelper; import pro.gravit.utils.helper.LogHelper;

View file

@ -1,9 +1,13 @@
package pro.gravit.launchserver.auth.provider; package pro.gravit.launchserver.auth.provider;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import pro.gravit.launchserver.Reconfigurable; import pro.gravit.launchserver.Reconfigurable;
import pro.gravit.launchserver.auth.AuthException; 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.LogHelper;
import pro.gravit.utils.helper.SecurityHelper; import pro.gravit.utils.helper.SecurityHelper;
@ -36,31 +40,15 @@ public void close() {
} }
@Override @Override
public void reconfig(String action, String[] args) { public Map<String, Command> getCommands() {
switch (action) { Map<String, Command> commands = new HashMap<>();
case "message": commands.put("message", new SubCommand() {
@Override
public void invoke(String... args) throws Exception {
message = args[0]; message = args[0];
LogHelper.info("New reject message: %s", message); LogHelper.info("New reject message: %s", message);
break; }
case "whitelist.add": });
if (whitelist == null) whitelist = new ArrayList<>(); return commands;
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");
} }
} }

View file

@ -1,5 +1,7 @@
package pro.gravit.launchserver.command; package pro.gravit.launchserver.command;
import java.util.Map;
import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.LaunchServer;
public abstract class Command extends pro.gravit.utils.command.Command { 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) { protected Command(LaunchServer server) {
super();
this.server = server;
}
public Command(Map<String, pro.gravit.utils.command.Command> childCommands, LaunchServer server) {
super(childCommands);
this.server = server; this.server = server;
} }
} }

View file

@ -1,14 +1,15 @@
package pro.gravit.launchserver.command.basic; package pro.gravit.launchserver.command.basic;
import java.nio.file.Paths;
import java.security.KeyPair;
import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509CertificateHolder;
import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.command.Command; import pro.gravit.launchserver.command.Command;
import pro.gravit.launchserver.socket.handlers.NettyServerSocketHandler; import pro.gravit.launchserver.socket.handlers.NettyServerSocketHandler;
import pro.gravit.utils.helper.CommonHelper; import pro.gravit.utils.helper.CommonHelper;
import java.nio.file.Paths;
import java.security.KeyPair;
public class TestCommand extends Command { public class TestCommand extends Command {
public TestCommand(LaunchServer server) { public TestCommand(LaunchServer server) {
super(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.writePrivateKey(Paths.get("ca.key"), server.certificateManager.caKey);
server.certificateManager.writeCertificate(Paths.get("ca.crt"), server.certificateManager.ca); 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")) { if(args[0].equals("genCert")) {
verifyArgs(args, 2); verifyArgs(args, 2);
String name = args[1]; String name = args[1];

View file

@ -11,12 +11,59 @@
import pro.gravit.launchserver.auth.AuthProviderPair; import pro.gravit.launchserver.auth.AuthProviderPair;
import pro.gravit.launchserver.auth.handler.CachedAuthHandler; import pro.gravit.launchserver.auth.handler.CachedAuthHandler;
import pro.gravit.launchserver.command.Command; import pro.gravit.launchserver.command.Command;
import pro.gravit.utils.command.SubCommand;
import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.IOHelper;
import pro.gravit.utils.helper.LogHelper; import pro.gravit.utils.helper.LogHelper;
public class DumpEntryCacheCommand extends Command { public class DumpEntryCacheCommand extends Command {
public DumpEntryCacheCommand(LaunchServer server) { public DumpEntryCacheCommand(LaunchServer server) {
super(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<UUID, CachedAuthHandler.Entry> entryCache = authHandler.getEntryCache();
Map<String, UUID> 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 @Override
@ -31,37 +78,7 @@ public String getUsageDescription() {
@Override @Override
public void invoke(String... args) throws Exception { public void invoke(String... args) throws Exception {
verifyArgs(args, 3); invokeSubcommands(args);
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<UUID, CachedAuthHandler.Entry> entryCache = authHandler.getEntryCache();
Map<String, UUID> 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);
}
} }
public class EntryAndUsername { public class EntryAndUsername {

View file

@ -13,12 +13,41 @@
import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.command.Command; import pro.gravit.launchserver.command.Command;
import pro.gravit.launchserver.socket.Client; import pro.gravit.launchserver.socket.Client;
import pro.gravit.utils.command.SubCommand;
import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.IOHelper;
import pro.gravit.utils.helper.LogHelper; import pro.gravit.utils.helper.LogHelper;
public class DumpSessionsCommand extends Command { public class DumpSessionsCommand extends Command {
public DumpSessionsCommand(LaunchServer server) { public DumpSessionsCommand(LaunchServer server) {
super(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<HashSet<Client>>() {
}.getType();
Set<Client> 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<Client> 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 @Override
@ -33,25 +62,6 @@ public String getUsageDescription() {
@Override @Override
public void invoke(String... args) throws Exception { public void invoke(String... args) throws Exception {
verifyArgs(args, 2); invokeSubcommands(args);
if (args[0].equals("unload")) {
LogHelper.info("Sessions write to %s", args[1]);
Set<Client> 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<HashSet<Client>>() {
}.getType();
Set<Client> clientSet = Launcher.gsonManager.configGson.fromJson(reader, setType);
size = clientSet.size();
server.sessionManager.loadSessions(clientSet);
}
LogHelper.subInfo("Readed %d sessions", size);
}
} }
} }

View file

@ -32,7 +32,16 @@
import pro.gravit.launchserver.command.install.MultiCommand; import pro.gravit.launchserver.command.install.MultiCommand;
import pro.gravit.launchserver.command.modules.LoadModuleCommand; import pro.gravit.launchserver.command.modules.LoadModuleCommand;
import pro.gravit.launchserver.command.modules.ModulesCommand; 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.BaseCommandCategory;
import pro.gravit.utils.command.basic.ClearCommand; import pro.gravit.utils.command.basic.ClearCommand;
import pro.gravit.utils.command.basic.DebugCommand; 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("reloadAll", new ReloadAllCommand(server));
service.registerCommand("reloadList", new ReloadListCommand(server)); service.registerCommand("reloadList", new ReloadListCommand(server));
service.registerCommand("config", new ConfigCommand(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("serverStatus", new ServerStatusCommand(server));
service.registerCommand("checkInstall", new CheckInstallCommand(server)); service.registerCommand("checkInstall", new CheckInstallCommand(server));
service.registerCommand("multi", new MultiCommand(server)); service.registerCommand("multi", new MultiCommand(server));

View file

@ -2,11 +2,10 @@
import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.command.Command; import pro.gravit.launchserver.command.Command;
import pro.gravit.utils.helper.LogHelper;
public class ConfigCommand extends Command { public class ConfigCommand extends Command {
public ConfigCommand(LaunchServer server) { public ConfigCommand(LaunchServer server) {
super(server); super(server.reconfigurableManager.getCommands(), server);
} }
@Override @Override
@ -21,10 +20,6 @@ public String getUsageDescription() {
@Override @Override
public void invoke(String... args) throws Exception { public void invoke(String... args) throws Exception {
verifyArgs(args, 2); invokeSubcommands(args);
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);
} }
} }

View file

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

View file

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

View file

@ -1,15 +1,15 @@
package pro.gravit.launchserver.components; 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.launcher.NeedGarbageCollection;
import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.manangers.hook.AuthHookManager; import pro.gravit.launchserver.manangers.hook.AuthHookManager;
import pro.gravit.utils.HookException; import pro.gravit.utils.HookException;
import pro.gravit.utils.HookSet; 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 class RegLimiterComponent extends Component implements NeedGarbageCollection, AutoCloseable {
public static final long TIMEOUT = 12 * 60 * 60 * 1000; //12 часов public static final long TIMEOUT = 12 * 60 * 60 * 1000; //12 часов

View file

@ -7,7 +7,16 @@
import java.util.Collection; import java.util.Collection;
import java.util.UUID; 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.launcher.ClientPermissions;
import pro.gravit.utils.helper.LogHelper; import pro.gravit.utils.helper.LogHelper;

View file

@ -1,10 +1,10 @@
package pro.gravit.launchserver.dao; package pro.gravit.launchserver.dao;
import pro.gravit.launcher.hwid.OshiHWID;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import pro.gravit.launcher.hwid.OshiHWID;
public interface UserDAO { public interface UserDAO {
User findById(int id); User findById(int id);
User findByUsername(String username); User findByUsername(String username);

View file

@ -1,11 +1,16 @@
package pro.gravit.launchserver.dao; 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.HWID;
import pro.gravit.launcher.hwid.OshiHWID; import pro.gravit.launcher.hwid.OshiHWID;
import javax.persistence.*;
import java.util.function.Supplier;
@Entity @Entity
@Table(name = "users_hwids") @Table(name = "users_hwids")
public class UserHWID implements HWID { public class UserHWID implements HWID {

View file

@ -1,6 +1,9 @@
package pro.gravit.launchserver.dao.provider; package pro.gravit.launchserver.dao.provider;
import java.nio.file.Paths;
import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Configuration;
import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.dao.User; import pro.gravit.launchserver.dao.User;
import pro.gravit.launchserver.dao.UserHWID; import pro.gravit.launchserver.dao.UserHWID;
@ -8,8 +11,6 @@
import pro.gravit.launchserver.dao.impl.HibernateUserDAOImpl; import pro.gravit.launchserver.dao.impl.HibernateUserDAOImpl;
import pro.gravit.utils.helper.CommonHelper; import pro.gravit.utils.helper.CommonHelper;
import java.nio.file.Paths;
public class HibernateDaoProvider extends DaoProvider { public class HibernateDaoProvider extends DaoProvider {
public String driver; public String driver;
public String url; public String url;

View file

@ -1,5 +1,23 @@
package pro.gravit.launchserver.manangers; 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.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.X500NameBuilder; import org.bouncycastle.asn1.x500.X500NameBuilder;
@ -17,22 +35,12 @@
import org.bouncycastle.operator.bc.BcECContentSignerBuilder; import org.bouncycastle.operator.bc.BcECContentSignerBuilder;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import org.bouncycastle.util.io.pem.PemWriter; import org.bouncycastle.util.io.pem.PemWriter;
import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.IOHelper;
import pro.gravit.utils.helper.SecurityHelper; 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 class CertificateManager {
public X509CertificateHolder ca; public X509CertificateHolder ca;
public AsymmetricKeyParameter caKey; public AsymmetricKeyParameter caKey;
@ -106,4 +114,28 @@ public void writeCertificate(Path file, X509CertificateHolder holder) throws IOE
writer.writeObject(new PemObject("CERTIFICATE", holder.toASN1Structure().getEncoded())); 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;
}
} }

View file

@ -1,35 +1,63 @@
package pro.gravit.launchserver.manangers; package pro.gravit.launchserver.manangers;
import java.util.HashMap; import java.util.HashMap;
import java.util.Objects; import java.util.Map;
import pro.gravit.launchserver.Reconfigurable; 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; import pro.gravit.utils.helper.VerifyHelper;
public class ReconfigurableManager { public class ReconfigurableManager {
private final HashMap<String, Reconfigurable> RECONFIGURABLE = new HashMap<>(); private class ReconfigurableVirtualCommand extends Command {
public ReconfigurableVirtualCommand(Map<String, Command> 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<String, Command> RECONFIGURABLE = new HashMap<>();
public void registerReconfigurable(String name, Reconfigurable reconfigurable) { 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)); String.format("Reloadable has been already registered: '%s'", name));
} }
public Reconfigurable unregisterReconfigurable(String name) { public void unregisterReconfigurable(String name) {
return RECONFIGURABLE.remove(name); RECONFIGURABLE.remove(name);
} }
public void printHelp(String name) { public void call(String name, String action, String[] args) throws Exception
RECONFIGURABLE.get(name.toLowerCase()).printConfigHelp(); {
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) { public void printHelp(String name) throws CommandException
RECONFIGURABLE.get(name.toLowerCase()).reconfig(action.toLowerCase(), args); {
Command commands = RECONFIGURABLE.get(name);
if(commands == null) throw new CommandException(String.format("Reconfigurable %s not found", name));
HelpCommand.printSubCommandsHelp(name, commands);
} }
public Map<String, Command> getCommands()
public void printReconfigurables() { {
LogHelper.info("Print reconfigurables"); return RECONFIGURABLE;
RECONFIGURABLE.forEach((k, v) -> LogHelper.subInfo(k));
LogHelper.info("Found %d reconfigurables", RECONFIGURABLE.size());
} }
} }

View file

@ -22,12 +22,19 @@
import pro.gravit.launcher.request.WebSocketEvent; import pro.gravit.launcher.request.WebSocketEvent;
import pro.gravit.launcher.request.admin.ProxyRequest; import pro.gravit.launcher.request.admin.ProxyRequest;
import pro.gravit.launchserver.LaunchServer; 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.SimpleResponse;
import pro.gravit.launchserver.socket.response.WebSocketServerResponse;
import pro.gravit.launchserver.socket.response.admin.AddLogListenerResponse; import pro.gravit.launchserver.socket.response.admin.AddLogListenerResponse;
import pro.gravit.launchserver.socket.response.admin.ExecCommandResponse; import pro.gravit.launchserver.socket.response.admin.ExecCommandResponse;
import pro.gravit.launchserver.socket.response.admin.ProxyCommandResponse; 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.BatchProfileByUsername;
import pro.gravit.launchserver.socket.response.profile.ProfileByUUIDResponse; import pro.gravit.launchserver.socket.response.profile.ProfileByUUIDResponse;
import pro.gravit.launchserver.socket.response.profile.ProfileByUsername; import pro.gravit.launchserver.socket.response.profile.ProfileByUsername;

View file

@ -2,8 +2,8 @@
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import pro.gravit.launchserver.socket.Client; 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.SimpleResponse;
import pro.gravit.launchserver.socket.response.WebSocketServerResponse;
public class ProxyCommandResponse extends SimpleResponse { public class ProxyCommandResponse extends SimpleResponse {
public WebSocketServerResponse response; public WebSocketServerResponse response;

View file

@ -9,9 +9,9 @@
import javax.crypto.IllegalBlockSizeException; import javax.crypto.IllegalBlockSizeException;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import pro.gravit.launcher.events.request.AuthRequestEvent;
import pro.gravit.launcher.hwid.HWID; import pro.gravit.launcher.hwid.HWID;
import pro.gravit.launcher.hwid.OshiHWID; import pro.gravit.launcher.hwid.OshiHWID;
import pro.gravit.launcher.events.request.AuthRequestEvent;
import pro.gravit.launcher.profiles.ClientProfile; import pro.gravit.launcher.profiles.ClientProfile;
import pro.gravit.launchserver.auth.AuthException; import pro.gravit.launchserver.auth.AuthException;
import pro.gravit.launchserver.auth.AuthProviderPair; import pro.gravit.launchserver.auth.AuthProviderPair;

View file

@ -1,16 +1,16 @@
package pro.gravit.launchserver.socket.response.auth; 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.nio.charset.StandardCharsets;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.Arrays; import java.util.Arrays;
import java.util.UUID; 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 class RegisterResponse extends SimpleResponse {
public String login; public String login;
public String password; public String password;

View file

@ -15,6 +15,7 @@ var config = {
settingsMagic: 0xC0DE5, // Magic, don't touch settingsMagic: 0xC0DE5, // Magic, don't touch
autoEnterDefault: false, // Should autoEnter be enabled by default? autoEnterDefault: false, // Should autoEnter be enabled by default?
fullScreenDefault: false, // Should fullScreen 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) ramDefault: 1024, // Default RAM amount (0 for auto)
jvm: { jvm: {

View file

@ -10,6 +10,7 @@ var settingsManagerClass = Java.extend(SettingsManagerClass.static, {
new_settings.fullScreen = config.fullScreenDefault; new_settings.fullScreen = config.fullScreenDefault;
new_settings.ram = config.ramDefault; new_settings.ram = config.ramDefault;
new_settings.featureStore = config.featureStoreDefault;
new_settings.lastDigest = null; new_settings.lastDigest = null;
new_settings.lastProfiles.clear(); new_settings.lastProfiles.clear();
new_settings.lastHDirs.clear(); new_settings.lastHDirs.clear();

View file

@ -6,12 +6,12 @@
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import pro.gravit.launcher.hwid.HWID;
import pro.gravit.launcher.LauncherAPI; import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.events.request.AuthRequestEvent; import pro.gravit.launcher.events.request.AuthRequestEvent;
import pro.gravit.launcher.guard.LauncherGuardManager; import pro.gravit.launcher.guard.LauncherGuardManager;
import pro.gravit.launcher.hasher.FileNameMatcher; import pro.gravit.launcher.hasher.FileNameMatcher;
import pro.gravit.launcher.hasher.HashedDir; import pro.gravit.launcher.hasher.HashedDir;
import pro.gravit.launcher.hwid.HWID;
import pro.gravit.launcher.hwid.OshiHWIDProvider; import pro.gravit.launcher.hwid.OshiHWIDProvider;
import pro.gravit.launcher.managers.ConsoleManager; import pro.gravit.launcher.managers.ConsoleManager;
import pro.gravit.launcher.managers.HasherManager; import pro.gravit.launcher.managers.HasherManager;

View file

@ -1,7 +1,5 @@
package pro.gravit.launcher.hwid; package pro.gravit.launcher.hwid;
import pro.gravit.launcher.hwid.HWID;
@FunctionalInterface @FunctionalInterface
public interface LauncherHWIDInterface { public interface LauncherHWIDInterface {
HWID getHWID(); HWID getHWID();

View file

@ -4,6 +4,7 @@
import java.util.StringJoiner; import java.util.StringJoiner;
import com.google.gson.Gson; import com.google.gson.Gson;
import pro.gravit.launcher.LauncherAPI; import pro.gravit.launcher.LauncherAPI;
public class OshiHWID implements HWID { public class OshiHWID implements HWID {

View file

@ -6,8 +6,8 @@
import pro.gravit.launcher.Launcher; import pro.gravit.launcher.Launcher;
import pro.gravit.launcher.LauncherAPI; import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.LauncherNetworkAPI; 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.StandartClientWebSocketService;
import pro.gravit.launcher.request.websockets.WebSocketRequest;
import pro.gravit.utils.helper.SecurityHelper; import pro.gravit.utils.helper.SecurityHelper;
public abstract class Request<R extends WebSocketEvent> implements WebSocketRequest { public abstract class Request<R extends WebSocketEvent> implements WebSocketRequest {

View file

@ -1,9 +1,9 @@
package pro.gravit.launcher.request.auth; package pro.gravit.launcher.request.auth;
import pro.gravit.launcher.hwid.HWID;
import pro.gravit.launcher.LauncherAPI; import pro.gravit.launcher.LauncherAPI;
import pro.gravit.launcher.LauncherNetworkAPI; import pro.gravit.launcher.LauncherNetworkAPI;
import pro.gravit.launcher.events.request.AuthRequestEvent; import pro.gravit.launcher.events.request.AuthRequestEvent;
import pro.gravit.launcher.hwid.HWID;
import pro.gravit.launcher.request.Request; import pro.gravit.launcher.request.Request;
import pro.gravit.launcher.request.websockets.WebSocketRequest; import pro.gravit.launcher.request.websockets.WebSocketRequest;
import pro.gravit.utils.helper.VerifyHelper; import pro.gravit.utils.helper.VerifyHelper;

View file

@ -11,8 +11,8 @@
import pro.gravit.launcher.downloader.ListDownloader; import pro.gravit.launcher.downloader.ListDownloader;
import pro.gravit.launcher.events.request.LauncherRequestEvent; import pro.gravit.launcher.events.request.LauncherRequestEvent;
import pro.gravit.launcher.request.Request; 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.StandartClientWebSocketService;
import pro.gravit.launcher.request.websockets.WebSocketRequest;
import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.IOHelper;
import pro.gravit.utils.helper.JVMHelper; import pro.gravit.utils.helper.JVMHelper;
import pro.gravit.utils.helper.LogHelper; import pro.gravit.utils.helper.LogHelper;

View file

@ -22,8 +22,8 @@
import pro.gravit.launcher.hasher.HashedFile; import pro.gravit.launcher.hasher.HashedFile;
import pro.gravit.launcher.request.Request; import pro.gravit.launcher.request.Request;
import pro.gravit.launcher.request.update.UpdateRequest.State.Callback; 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.StandartClientWebSocketService;
import pro.gravit.launcher.request.websockets.WebSocketRequest;
import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.IOHelper;
import pro.gravit.utils.helper.LogHelper; import pro.gravit.utils.helper.LogHelper;

View file

@ -12,7 +12,25 @@
import pro.gravit.launcher.Launcher; import pro.gravit.launcher.Launcher;
import pro.gravit.launcher.events.ExceptionEvent; 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.HashedEntry;
import pro.gravit.launcher.hasher.HashedEntryAdapter; import pro.gravit.launcher.hasher.HashedEntryAdapter;
import pro.gravit.launcher.request.WebSocketEvent; import pro.gravit.launcher.request.WebSocketEvent;

View file

@ -22,7 +22,7 @@ public final class Version {
public final Type release; public final Type release;
public static final int MAJOR = 5; public static final int MAJOR = 5;
public static final int MINOR = 0; 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 int BUILD = 1;
public static final Version.Type RELEASE = Version.Type.STABLE; public static final Version.Type RELEASE = Version.Type.STABLE;

View file

@ -1,11 +1,26 @@
package pro.gravit.utils.command; 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 java.util.UUID;
import org.jline.reader.Candidate;
import pro.gravit.utils.helper.VerifyHelper; import pro.gravit.utils.helper.VerifyHelper;
public abstract class Command { public abstract class Command {
public Map<String, Command> childCommands;
public Command() {
childCommands = new HashMap<>();
}
public Command(Map<String, Command> childCommands) {
this.childCommands = childCommands;
}
protected static String parseUsername(String username) throws CommandException { protected static String parseUsername(String username) throws CommandException {
try { try {
@ -29,6 +44,40 @@ protected static UUID parseUUID(String s) throws CommandException {
public abstract String getUsageDescription(); public abstract String getUsageDescription();
public Candidate buildCandidate(CommandHandler.Category category, String commandName)
{
return new Candidate(commandName);
}
public List<Candidate> complete(List<String> words, int wordIndex, String word)
{
if(wordIndex == 0)
{
List<Candidate> 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; public abstract void invoke(String... args) throws Exception;

View file

@ -36,13 +36,22 @@ public class JLineConsoleCompleter implements Completer {
@Override @Override
public void complete(LineReader reader, ParsedLine line, List<Candidate> candidates) { public void complete(LineReader reader, ParsedLine line, List<Candidate> candidates) {
String completeWord = line.word(); String completeWord = line.word();
if (line.wordIndex() != 0) return; if (line.wordIndex() == 0)
{
walk((category, name, command) -> { walk((category, name, command) -> {
if (name.startsWith(completeWord)) { if (name.startsWith(completeWord)) {
candidates.add(new Candidate(name)); candidates.add(command.buildCandidate(category, name));
} }
}); });
} }
else
{
Command target = findCommand(line.words().get(0));
List<String> words = line.words();
List<Candidate> candidates1 = target.complete(words.subList(1, words.size()), line.wordIndex() - 1, completeWord);
candidates.addAll(candidates1);
}
}
} }
public JLineCommandHandler() throws IOException { public JLineCommandHandler() throws IOException {

View file

@ -2,8 +2,9 @@
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import pro.gravit.utils.helper.JVMHelper;
import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.IOHelper;
import pro.gravit.utils.helper.JVMHelper;
public class StdCommandHandler extends CommandHandler { public class StdCommandHandler extends CommandHandler {
private final BufferedReader reader; private final BufferedReader reader;

View file

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

View file

@ -1,5 +1,6 @@
package pro.gravit.utils.command.basic; package pro.gravit.utils.command.basic;
import java.util.Arrays;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.fusesource.jansi.Ansi; import org.fusesource.jansi.Ansi;
@ -13,7 +14,7 @@
public final class HelpCommand extends Command { public final class HelpCommand extends Command {
private CommandHandler handler; private CommandHandler handler;
private static void printCommand(String name, Command command) { public static void printCommand(String name, Command command) {
String args = command.getArgsDescription(); String args = command.getArgsDescription();
//LogHelper.subInfo("%s %s - %s", name, args == null ? "[nothing]" : args, command.getUsageDescription()); //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()), () -> { 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("<font color=\"green\">%s</font> <font color=\"cyan\">%s</font> - <font color=\"yellow\">%s</font>", name, args == null ? "[nothing]" : args, command.getUsageDescription()), true)); }, () -> LogHelper.htmlFormatLog(LogHelper.Level.INFO, LogHelper.getDataTime(), String.format("<font color=\"green\">%s</font> <font color=\"cyan\">%s</font> - <font color=\"yellow\">%s</font>", 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) { private static void printCategory(String name, String description) {
if (description != null) LogHelper.info("Category: %s - %s", name, description); if (description != null) LogHelper.info("Category: %s - %s", name, description);
else LogHelper.info("Category: %s", name); else LogHelper.info("Category: %s", name);
@ -58,7 +80,9 @@ public void invoke(String... args) throws CommandException {
} }
// Print command help // Print command help
if(args.length == 1)
printCommand(args[0]); printCommand(args[0]);
printSubCommandsHelp(args[0], Arrays.copyOfRange(args, 1 , args.length), handler.lookup(args[0]));
} }
private void printCommand(String name) throws CommandException { private void printCommand(String name) throws CommandException {

View file

@ -157,21 +157,19 @@ public void run(String... args) throws Throwable {
else mainClass = Class.forName(classname); else mainClass = Class.forName(classname);
MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class)); MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class));
modulesManager.postInitModules(); modulesManager.postInitModules();
if (config.websocket.enabled) {
Request.service.reconnectCallback = () -> Request.service.reconnectCallback = () ->
{ {
LogHelper.debug("WebSocket connect closed. Try reconnect"); LogHelper.debug("WebSocket connect closed. Try reconnect");
try { try {
Request.service.open(); Request.service.open();
LogHelper.debug("Connect to %s", config.websocket.address); LogHelper.debug("Connect to %s", config.address);
} catch (Exception e) { } catch (Exception e) {
LogHelper.error(e); LogHelper.error(e);
throw new RequestException(String.format("Connect error: %s", e.getMessage() != null ? e.getMessage() : "null")); throw new RequestException(String.format("Connect error: %s", e.getMessage() != null ? e.getMessage() : "null"));
} }
auth(); auth();
}; };
} LogHelper.info("ServerWrapper: Project %s, LaunchServer address: %s. Title: %s", config.projectname, config.address, config.title);
LogHelper.info("ServerWrapper: Project %s, LaunchServer address: %s. Title: %s", config.projectname, config.websocket.address, config.title);
LogHelper.info("Minecraft Version (for profile): %s", wrapper.profile == null ? "unknown" : wrapper.profile.getVersion().name); LogHelper.info("Minecraft Version (for profile): %s", wrapper.profile == null ? "unknown" : wrapper.profile.getVersion().name);
LogHelper.info("Start Minecraft Server"); LogHelper.info("Start Minecraft Server");
LogHelper.debug("Invoke main method %s", mainClass.getName()); LogHelper.debug("Invoke main method %s", mainClass.getName());
@ -192,11 +190,9 @@ public void updateLauncherConfig() {
LauncherConfig cfg = null; LauncherConfig cfg = null;
try { try {
cfg = new LauncherConfig(config.websocket.address, SecurityHelper.toPublicRSAKey(IOHelper.read(publicKeyFile)), new HashMap<>(), config.projectname); cfg = new LauncherConfig(config.address, SecurityHelper.toPublicRSAKey(IOHelper.read(publicKeyFile)), new HashMap<>(), config.projectname);
if (config.websocket != null && config.websocket.enabled) {
cfg.isNettyEnabled = true; cfg.isNettyEnabled = true;
cfg.address = config.websocket.address; cfg.address = config.address;
}
} catch (InvalidKeySpecException | IOException e) { } catch (InvalidKeySpecException | IOException e) {
LogHelper.error(e); LogHelper.error(e);
} }
@ -228,8 +224,7 @@ public Config getDefaultConfig() {
newConfig.reconnectCount = 10; newConfig.reconnectCount = 10;
newConfig.reconnectSleep = 1000; newConfig.reconnectSleep = 1000;
newConfig.websocket = new WebSocketConf(); newConfig.websocket = new WebSocketConf();
newConfig.websocket.address = "ws://localhost:9274/api"; newConfig.address = "ws://localhost:9274/api";
newConfig.websocket.enabled = false;
newConfig.env = LauncherConfig.LauncherEnvironment.STD; newConfig.env = LauncherConfig.LauncherEnvironment.STD;
return newConfig; return newConfig;
} }
@ -242,6 +237,7 @@ public void setConfig(Config config) {
public static final class Config { public static final class Config {
public String title; public String title;
public String projectname; public String projectname;
public String address;
public WebSocketConf websocket; public WebSocketConf websocket;
public int reconnectCount; public int reconnectCount;
public int reconnectSleep; public int reconnectSleep;
@ -261,8 +257,6 @@ public static final class Config {
} }
public static final class WebSocketConf { public static final class WebSocketConf {
public boolean enabled;
public String address;
} }
public ClientProfile profile; public ClientProfile profile;

View file

@ -41,10 +41,10 @@ public void run() throws IOException {
} }
} }
LogHelper.info("Found MainClass %s", mainClassName); 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(); String address = commands.commandHandler.readLine();
wrapper.config.mainclass = mainClassName; wrapper.config.mainclass = mainClassName;
wrapper.config.websocket.address = address; wrapper.config.address = address;
if (!Files.exists(ServerWrapper.publicKeyFile)) { if (!Files.exists(ServerWrapper.publicKeyFile)) {
LogHelper.error("public.key not found"); LogHelper.error("public.key not found");
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {

@ -1 +1 @@
Subproject commit dba4f0132cdb49cbc6cb7356fb6a54a063aba8b5 Subproject commit f7cf0576033cd413b99e8180610d586e370c9351