[FIX][FEATURE] Исправления Recunfigurable и перенос туда части команд. Исправление reload Лаунчсервера

This commit is contained in:
Gravit 2019-08-25 13:07:09 +07:00
parent 36350cb661
commit a30c1db986
No known key found for this signature in database
GPG key ID: 061981E1E85D3216
13 changed files with 191 additions and 246 deletions

View file

@ -82,16 +82,14 @@
import pro.gravit.launchserver.socket.WebSocketService; import pro.gravit.launchserver.socket.WebSocketService;
import pro.gravit.launchserver.socket.handlers.NettyServerSocketHandler; import pro.gravit.launchserver.socket.handlers.NettyServerSocketHandler;
import pro.gravit.utils.Version; import pro.gravit.utils.Version;
import pro.gravit.utils.command.CommandHandler; import pro.gravit.utils.command.*;
import pro.gravit.utils.command.JLineCommandHandler;
import pro.gravit.utils.command.StdCommandHandler;
import pro.gravit.utils.helper.CommonHelper; import pro.gravit.utils.helper.CommonHelper;
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;
import pro.gravit.utils.helper.SecurityHelper; import pro.gravit.utils.helper.SecurityHelper;
public final class LaunchServer implements Runnable, AutoCloseable { public final class LaunchServer implements Runnable, AutoCloseable, Reconfigurable {
public void reload() throws Exception { public void reload() throws Exception {
config.close(); config.close();
@ -102,6 +100,35 @@ public void reload() throws Exception {
config.server = this; config.server = this;
config.verify(); config.verify();
config.init(); config.init();
if (config.components != null) {
LogHelper.debug("Init components");
config.components.forEach((k, v) -> {
LogHelper.subDebug("Init component %s", k);
registerObject("component.".concat(k), v);
v.init(this);
});
LogHelper.debug("Init components successful");
LogHelper.debug("PostInit components");
config.components.forEach((k, v) -> {
LogHelper.subDebug("PostInit component %s", k);
v.postInit(this);
});
LogHelper.debug("PostInit components successful");
}
}
@Override
public Map<String, Command> getCommands() {
Map<String, Command> commands = new HashMap<>();
SubCommand reload = new SubCommand() {
@Override
public void invoke(String... args) throws Exception {
reload();
}
};
commands.put("reload", reload);
return commands;
} }
public static final class Config { public static final class Config {
@ -209,13 +236,23 @@ public void init() {
} }
permissionsHandler.init(server); permissionsHandler.init(server);
hwidHandler.init(); hwidHandler.init();
if(dao != null)
dao.init(server); dao.init(server);
if (protectHandler != null) { if (protectHandler != null) {
protectHandler.checkLaunchServerLicense(); protectHandler.checkLaunchServerLicense();
} }
if (components != null) {
LogHelper.debug("PreInit components");
components.forEach((k, v) -> {
LogHelper.subDebug("PreInit component %s", k);
v.preInit(server);
});
LogHelper.debug("PreInit components successful");
}
server.registerObject("permissionsHandler", permissionsHandler); server.registerObject("permissionsHandler", permissionsHandler);
server.registerObject("daoProvider", dao); server.registerObject("hwidHandler", hwidHandler);
for (AuthProviderPair pair : auth) { for (int i = 0; i < auth.length; ++i) {
AuthProviderPair pair = auth[i];
server.registerObject("auth.".concat(pair.name).concat(".provider"), pair.provider); server.registerObject("auth.".concat(pair.name).concat(".provider"), pair.provider);
server.registerObject("auth.".concat(pair.name).concat(".handler"), pair.handler); server.registerObject("auth.".concat(pair.name).concat(".handler"), pair.handler);
server.registerObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider); server.registerObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider);
@ -227,6 +264,7 @@ public void init() {
public void close() { public void close() {
try { try {
server.unregisterObject("permissionsHandler", permissionsHandler); server.unregisterObject("permissionsHandler", permissionsHandler);
server.unregisterObject("hwidHandler", hwidHandler);
for (AuthProviderPair pair : auth) { for (AuthProviderPair pair : auth) {
server.unregisterObject("auth.".concat(pair.name).concat(".provider"), pair.provider); server.unregisterObject("auth.".concat(pair.name).concat(".provider"), pair.provider);
server.unregisterObject("auth.".concat(pair.name).concat(".handler"), pair.handler); server.unregisterObject("auth.".concat(pair.name).concat(".handler"), pair.handler);
@ -580,25 +618,6 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException
} }
runtime.verify(); runtime.verify();
config.verify(); config.verify();
Launcher.applyLauncherEnv(config.env);
for (AuthProviderPair provider : config.auth) {
provider.init(this);
}
config.permissionsHandler.init(this);
config.hwidHandler.init();
if(config.dao != null)
config.dao.init(this);
if (config.protectHandler != null) {
config.protectHandler.checkLaunchServerLicense();
}
if (config.components != null) {
LogHelper.debug("PreInit components");
config.components.forEach((k, v) -> {
LogHelper.subDebug("PreInit component %s", k);
v.preInit(this);
});
LogHelper.debug("PreInit components successful");
}
// build hooks, anti-brutforce and other // build hooks, anti-brutforce and other
buildHookManager = new BuildHookManager(); buildHookManager = new BuildHookManager();
@ -646,16 +665,9 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException
} }
} }
} }
config.init();
registerObject("launchServer", this);
GarbageManager.registerNeedGC(sessionManager); GarbageManager.registerNeedGC(sessionManager);
registerObject("permissionsHandler", config.permissionsHandler);
for (int i = 0; i < config.auth.length; ++i) {
AuthProviderPair pair = config.auth[i];
registerObject("auth.".concat(pair.name).concat(".provider"), pair.provider);
registerObject("auth.".concat(pair.name).concat(".handler"), pair.handler);
registerObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider);
}
Arrays.stream(config.mirrors).forEach(mirrorManager::addMirror);
pro.gravit.launchserver.command.handler.CommandHandler.registerCommands(localCommandHandler, this); pro.gravit.launchserver.command.handler.CommandHandler.registerCommands(localCommandHandler, this);

View file

@ -1,7 +0,0 @@
package pro.gravit.launchserver;
@FunctionalInterface
@Deprecated
public interface Reloadable {
void reload() throws Exception;
}

View file

@ -1,18 +1,23 @@
package pro.gravit.launchserver.auth.handler; package pro.gravit.launchserver.auth.handler;
import java.io.IOException; import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.nio.file.Paths;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
import pro.gravit.launcher.Launcher;
import pro.gravit.launcher.NeedGarbageCollection; import pro.gravit.launcher.NeedGarbageCollection;
import pro.gravit.launchserver.Reconfigurable;
import pro.gravit.launchserver.auth.provider.AuthProviderResult; import pro.gravit.launchserver.auth.provider.AuthProviderResult;
import pro.gravit.utils.helper.CommonHelper; import pro.gravit.utils.command.Command;
import pro.gravit.utils.helper.SecurityHelper; import pro.gravit.utils.command.SubCommand;
import pro.gravit.utils.helper.VerifyHelper; import pro.gravit.utils.helper.*;
public abstract class CachedAuthHandler extends AuthHandler implements NeedGarbageCollection { public abstract class CachedAuthHandler extends AuthHandler implements NeedGarbageCollection, Reconfigurable {
public static final class Entry { public static final class Entry {
public final UUID uuid; public final UUID uuid;
@ -29,6 +34,63 @@ public Entry(UUID uuid, String username, String accessToken, String serverID) {
} }
} }
protected class EntryAndUsername {
public Map<UUID, CachedAuthHandler.Entry> entryCache;
public Map<String, UUID> usernameCache;
}
@Override
public Map<String, Command> getCommands() {
Map<String, Command> commands = new HashMap<>();
commands.put("clear", new SubCommand() {
@Override
public void invoke(String... args) throws Exception {
long entryCacheSize = entryCache.size();
long usernamesCacheSize = usernamesCache.size();
entryCache.clear();
usernamesCache.clear();
LogHelper.info("Cleared cache: %d Entry %d Usernames", entryCacheSize, usernamesCacheSize);
}
});
commands.put("load", new SubCommand() {
@Override
public void invoke(String... args) throws Exception {
verifyArgs(args, 2);
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();
loadEntryCache(entryAndUsername.entryCache);
loadUsernameCache(entryAndUsername.usernameCache);
}
LogHelper.subInfo("Readed %d entryCache %d usernameCache", size_entry, size_username);
}
});
commands.put("unload", new SubCommand() {
@Override
public void invoke(String... args) throws Exception {
verifyArgs(args, 2);
LogHelper.info("CachedAuthHandler write to %s", args[1]);
Map<UUID, CachedAuthHandler.Entry> entryCache = getEntryCache();
Map<String, UUID> usernamesCache = 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());
}
});
return commands;
}
private transient final Map<UUID, Entry> entryCache = new HashMap<>(1024); private transient final Map<UUID, Entry> entryCache = new HashMap<>(1024);
private transient final Map<String, UUID> usernamesCache = new HashMap<>(1024); private transient final Map<String, UUID> usernamesCache = new HashMap<>(1024);

View file

@ -1,11 +1,17 @@
package pro.gravit.launchserver.auth.hwid; package pro.gravit.launchserver.auth.hwid;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import pro.gravit.launcher.hwid.HWID; import pro.gravit.launcher.hwid.HWID;
import pro.gravit.launchserver.Reconfigurable;
import pro.gravit.utils.ProviderMap; import pro.gravit.utils.ProviderMap;
import pro.gravit.utils.command.Command;
import pro.gravit.utils.command.SubCommand;
import pro.gravit.utils.helper.LogHelper;
public abstract class HWIDHandler implements AutoCloseable { public abstract class HWIDHandler implements AutoCloseable, Reconfigurable {
public static ProviderMap<HWIDHandler> providers = new ProviderMap<>("HWIDHandler"); public static ProviderMap<HWIDHandler> providers = new ProviderMap<>("HWIDHandler");
private static boolean registredHandl = false; private static boolean registredHandl = false;
@ -21,6 +27,40 @@ public static void registerHandlers() {
} }
} }
@Override
public Map<String, Command> getCommands() {
Map<String, Command> commands = new HashMap<>();
commands.put("ban", new SubCommand() {
@Override
public void invoke(String... args) throws Exception {
List<HWID> target = getHwid(args[0]);
ban(target);
}
});
commands.put("unban", new SubCommand() {
@Override
public void invoke(String... args) throws Exception {
List<HWID> target = getHwid(args[0]);
unban(target);
}
});
commands.put("gethwid", new SubCommand() {
@Override
public void invoke(String... args) throws Exception {
List<HWID> target = getHwid(args[0]);
for(HWID hwid : target)
{
if (hwid == null) {
LogHelper.error("[%s] HWID: null", args[0]);
continue;
}
LogHelper.info("[%s] HWID: %s", args[0], hwid.toString());
}
}
});
return commands;
}
public abstract void ban(List<HWID> hwid) throws HWIDException; public abstract void ban(List<HWID> hwid) throws HWIDException;
public void check(HWID hwid, String username) throws HWIDException { public void check(HWID hwid, String username) throws HWIDException {

View file

@ -14,10 +14,13 @@
import pro.gravit.launcher.ClientPermissions; import pro.gravit.launcher.ClientPermissions;
import pro.gravit.launcher.Launcher; import pro.gravit.launcher.Launcher;
import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.Reconfigurable;
import pro.gravit.utils.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 JsonFilePermissionsHandler extends PermissionsHandler { public class JsonFilePermissionsHandler extends PermissionsHandler implements Reconfigurable {
public String filename = "permissions.json"; public String filename = "permissions.json";
public static Map<String, ClientPermissions> map; public static Map<String, ClientPermissions> map;
@ -39,6 +42,19 @@ public void close() {
} }
@Override
public Map<String, Command> getCommands() {
Map<String, Command> commands = new HashMap<>();
SubCommand reload = new SubCommand() {
@Override
public void invoke(String... args) throws Exception {
reload();
}
};
commands.put("reload", reload);
return commands;
}
public static class Enity { public static class Enity {
public String username; public String username;
public ClientPermissions permissions; public ClientPermissions permissions;

View file

@ -14,10 +14,13 @@
import pro.gravit.launcher.ClientPermissions; import pro.gravit.launcher.ClientPermissions;
import pro.gravit.launcher.Launcher; import pro.gravit.launcher.Launcher;
import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.Reconfigurable;
import pro.gravit.utils.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 JsonLongFilePermissionsHandler extends PermissionsHandler { public class JsonLongFilePermissionsHandler extends PermissionsHandler implements Reconfigurable {
public String filename = "permissions.json"; public String filename = "permissions.json";
public long defaultPerms = 0L; public long defaultPerms = 0L;
public static Map<String, Long> map; public static Map<String, Long> map;
@ -40,6 +43,19 @@ public void close() {
} }
@Override
public Map<String, Command> getCommands() {
Map<String, Command> commands = new HashMap<>();
SubCommand reload = new SubCommand() {
@Override
public void invoke(String... args) throws Exception {
reload();
}
};
commands.put("reload", reload);
return commands;
}
public static class Enity { public static class Enity {
public String username; public String username;
public ClientPermissions permissions; public ClientPermissions permissions;

View file

@ -1,30 +0,0 @@
package pro.gravit.launchserver.command.auth;
import java.util.List;
import pro.gravit.launcher.hwid.HWID;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.command.Command;
public class BanCommand extends Command {
public BanCommand(LaunchServer server) {
super(server);
}
@Override
public String getArgsDescription() {
return "[username]";
}
@Override
public String getUsageDescription() {
return "Ban username for HWID";
}
@Override
public void invoke(String... args) throws Exception {
verifyArgs(args, 1);
List<HWID> target = server.config.hwidHandler.getHwid(args[0]);
server.config.hwidHandler.ban(target);
}
}

View file

@ -1,38 +0,0 @@
package pro.gravit.launchserver.command.auth;
import java.util.List;
import pro.gravit.launcher.hwid.HWID;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.command.Command;
import pro.gravit.utils.helper.LogHelper;
public class GetHWIDCommand extends Command {
public GetHWIDCommand(LaunchServer server) {
super(server);
}
@Override
public String getArgsDescription() {
return "[username]";
}
@Override
public String getUsageDescription() {
return "get HWID from username";
}
@Override
public void invoke(String... args) throws Exception {
verifyArgs(args, 1);
List<HWID> target = server.config.hwidHandler.getHwid(args[0]);
for (HWID hwid : target) {
if (hwid == null) {
LogHelper.error("HWID %s: null", args[0]);
continue;
}
LogHelper.info("HWID %s: %s", args[0], hwid.toString());
}
LogHelper.info("Found %d HWID", target.size());
}
}

View file

@ -1,30 +0,0 @@
package pro.gravit.launchserver.command.auth;
import java.util.List;
import pro.gravit.launcher.hwid.HWID;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.command.Command;
public class UnbanCommand extends Command {
public UnbanCommand(LaunchServer server) {
super(server);
}
@Override
public String getArgsDescription() {
return "[username]";
}
@Override
public String getUsageDescription() {
return "Unban username for HWID";
}
@Override
public void invoke(String... args) throws Exception {
verifyArgs(args, 1);
List<HWID> target = server.config.hwidHandler.getHwid(args[0]);
server.config.hwidHandler.unban(target);
}
}

View file

@ -1,88 +0,0 @@
package pro.gravit.launchserver.command.dump;
import java.io.Reader;
import java.io.Writer;
import java.nio.file.Paths;
import java.util.Map;
import java.util.UUID;
import pro.gravit.launcher.Launcher;
import pro.gravit.launchserver.LaunchServer;
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<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
public String getArgsDescription() {
return "[load/unload] [auth_id] [filename]";
}
@Override
public String getUsageDescription() {
return "Load or unload AuthHandler Entry cache";
}
@Override
public void invoke(String... args) throws Exception {
invokeSubcommands(args);
}
public class EntryAndUsername {
public Map<UUID, CachedAuthHandler.Entry> entryCache;
public Map<String, UUID> usernameCache;
}
}

View file

@ -2,10 +2,7 @@
import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.command.auth.AuthCommand; import pro.gravit.launchserver.command.auth.AuthCommand;
import pro.gravit.launchserver.command.auth.BanCommand;
import pro.gravit.launchserver.command.auth.GetHWIDCommand;
import pro.gravit.launchserver.command.auth.UUIDToUsernameCommand; import pro.gravit.launchserver.command.auth.UUIDToUsernameCommand;
import pro.gravit.launchserver.command.auth.UnbanCommand;
import pro.gravit.launchserver.command.auth.UsernameToUUIDCommand; import pro.gravit.launchserver.command.auth.UsernameToUUIDCommand;
import pro.gravit.launchserver.command.basic.BuildCommand; import pro.gravit.launchserver.command.basic.BuildCommand;
import pro.gravit.launchserver.command.basic.ProguardCleanCommand; import pro.gravit.launchserver.command.basic.ProguardCleanCommand;
@ -19,7 +16,6 @@
import pro.gravit.launchserver.command.dao.GetUserCommand; import pro.gravit.launchserver.command.dao.GetUserCommand;
import pro.gravit.launchserver.command.dao.RegisterCommand; import pro.gravit.launchserver.command.dao.RegisterCommand;
import pro.gravit.launchserver.command.dao.SetUserPasswordCommand; import pro.gravit.launchserver.command.dao.SetUserPasswordCommand;
import pro.gravit.launchserver.command.dump.DumpEntryCacheCommand;
import pro.gravit.launchserver.command.dump.DumpSessionsCommand; import pro.gravit.launchserver.command.dump.DumpSessionsCommand;
import pro.gravit.launchserver.command.hash.DownloadAssetCommand; import pro.gravit.launchserver.command.hash.DownloadAssetCommand;
import pro.gravit.launchserver.command.hash.DownloadClientCommand; import pro.gravit.launchserver.command.hash.DownloadClientCommand;
@ -86,16 +82,12 @@ public static void registerCommands(pro.gravit.utils.command.CommandHandler hand
auth.registerCommand("auth", new AuthCommand(server)); auth.registerCommand("auth", new AuthCommand(server));
auth.registerCommand("usernameToUUID", new UsernameToUUIDCommand(server)); auth.registerCommand("usernameToUUID", new UsernameToUUIDCommand(server));
auth.registerCommand("uuidToUsername", new UUIDToUsernameCommand(server)); auth.registerCommand("uuidToUsername", new UUIDToUsernameCommand(server));
auth.registerCommand("ban", new BanCommand(server));
auth.registerCommand("unban", new UnbanCommand(server));
auth.registerCommand("getHWID", new GetHWIDCommand(server));
Category authCategory = new Category(auth, "auth", "User Management"); Category authCategory = new Category(auth, "auth", "User Management");
handler.registerCategory(authCategory); handler.registerCategory(authCategory);
//Register dump commands //Register dump commands
BaseCommandCategory dump = new BaseCommandCategory(); BaseCommandCategory dump = new BaseCommandCategory();
dump.registerCommand("dumpSessions", new DumpSessionsCommand(server)); dump.registerCommand("dumpSessions", new DumpSessionsCommand(server));
dump.registerCommand("dumpEntryCache", new DumpEntryCacheCommand(server));
Category dumpCategory = new Category(dump, "dump", "Dump runtime data"); Category dumpCategory = new Category(dump, "dump", "Dump runtime data");
handler.registerCategory(dumpCategory); handler.registerCategory(dumpCategory);

View file

@ -34,11 +34,11 @@ public void invoke(String... args) throws Exception {
public void registerReconfigurable(String name, Reconfigurable reconfigurable) { public void registerReconfigurable(String name, Reconfigurable reconfigurable) {
VerifyHelper.putIfAbsent(RECONFIGURABLE, name.toLowerCase(), new ReconfigurableVirtualCommand(reconfigurable.getCommands()), VerifyHelper.putIfAbsent(RECONFIGURABLE, name.toLowerCase(), new ReconfigurableVirtualCommand(reconfigurable.getCommands()),
String.format("Reloadable has been already registered: '%s'", name)); String.format("Reconfigurable has been already registered: '%s'", name));
} }
public void unregisterReconfigurable(String name) { public void unregisterReconfigurable(String name) {
RECONFIGURABLE.remove(name); RECONFIGURABLE.remove(name.toLowerCase());
} }
public void call(String name, String action, String[] args) throws Exception public void call(String name, String action, String[] args) throws Exception

@ -1 +1 @@
Subproject commit 4b7ffbbdda9f6d0e1a5f68f9568e574b8ba551a7 Subproject commit 95154a369e166a3aaaf3e06f015eef270b93cd75