diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java index ca37d17e..1fe39c8f 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java @@ -74,6 +74,7 @@ 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; import pro.gravit.launchserver.socket.handlers.NettyServerSocketHandler; import pro.gravit.utils.Version; import pro.gravit.utils.command.CommandHandler; @@ -495,6 +496,7 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException PermissionsHandler.registerHandlers(); Component.registerComponents(); ProtectHandler.registerHandlers(); + WebSocketService.registerResponses(); //LaunchServer.server = this; // Set command handler 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 88171bca..69c16655 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,17 +32,7 @@ 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.ComponentCommand; -import pro.gravit.launchserver.command.service.ConfigCommand; -import pro.gravit.launchserver.command.service.ConfigHelpCommand; -import pro.gravit.launchserver.command.service.ConfigListCommand; -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.launchserver.command.service.*; import pro.gravit.utils.command.BaseCommandCategory; import pro.gravit.utils.command.basic.ClearCommand; import pro.gravit.utils.command.basic.DebugCommand; @@ -124,6 +114,7 @@ public static void registerCommands(pro.gravit.utils.command.CommandHandler hand service.registerCommand("component", new ComponentCommand(server)); service.registerCommand("givePermission", new GivePermissionsCommand(server)); service.registerCommand("getPermissions", new GetPermissionsCommand(server)); + service.registerCommand("clients", new ClientsCommand(server)); Category serviceCategory = new Category(service, "service", "Managing LaunchServer Components"); handler.registerCategory(serviceCategory); } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ClientsCommand.java b/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ClientsCommand.java new file mode 100644 index 00000000..afb52e6d --- /dev/null +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/command/service/ClientsCommand.java @@ -0,0 +1,44 @@ +package pro.gravit.launchserver.command.service; + +import pro.gravit.launchserver.LaunchServer; +import pro.gravit.launchserver.command.Command; +import pro.gravit.launchserver.socket.Client; +import pro.gravit.launchserver.socket.WebSocketService; +import pro.gravit.launchserver.socket.handlers.WebSocketFrameHandler; +import pro.gravit.utils.helper.IOHelper; +import pro.gravit.utils.helper.LogHelper; + +public class ClientsCommand extends Command { + public ClientsCommand(LaunchServer server) { + super(server); + } + + @Override + public String getArgsDescription() { + return null; + } + + @Override + public String getUsageDescription() { + return "Show all connected clients"; + } + + @Override + public void invoke(String... args) throws Exception { + WebSocketService service = server.nettyServerSocketHandler.nettyServer.service; + service.channels.forEach((channel -> { + WebSocketFrameHandler frameHandler = channel.pipeline().get(WebSocketFrameHandler.class); + Client client = frameHandler.getClient(); + String ip = IOHelper.getIP(channel.remoteAddress()); + if(!client.isAuth) + LogHelper.info("Channel %s | checkSign %s", ip, client.checkSign ? "true" : "false"); + else + { + LogHelper.info("Client name %s | ip %s", client.username == null ? "null" : client.username, ip); + LogHelper.info("Data: checkSign %s | isSecure %s | auth_id %s", client.checkSign ? "true" : "false", client.isSecure ? "true" : "false", + client.auth_id); + LogHelper.info("Permissions: %s (long %d)", client.permissions == null ? "null" : client.permissions.toString(), client.permissions == null ? 0 : client.permissions.toString()); + } + })); + } +} diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/LaunchServerGsonManager.java b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/LaunchServerGsonManager.java index cc07d782..3769e19b 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/LaunchServerGsonManager.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/LaunchServerGsonManager.java @@ -2,7 +2,11 @@ import com.google.gson.GsonBuilder; +import pro.gravit.launcher.hasher.HashedEntry; +import pro.gravit.launcher.hasher.HashedEntryAdapter; import pro.gravit.launcher.managers.GsonManager; +import pro.gravit.launcher.request.JsonResultSerializeAdapter; +import pro.gravit.launcher.request.ResultInterface; import pro.gravit.launchserver.auth.handler.AuthHandler; import pro.gravit.launchserver.auth.hwid.HWIDHandler; import pro.gravit.launchserver.auth.permissions.PermissionsHandler; @@ -11,6 +15,8 @@ import pro.gravit.launchserver.auth.texture.TextureProvider; import pro.gravit.launchserver.components.Component; import pro.gravit.launchserver.dao.provider.DaoProvider; +import pro.gravit.launchserver.socket.WebSocketService; +import pro.gravit.launchserver.socket.response.JsonResponseInterface; import pro.gravit.utils.UniversalJsonAdapter; public class LaunchServerGsonManager extends GsonManager { @@ -25,5 +31,8 @@ public void registerAdapters(GsonBuilder builder) { builder.registerTypeAdapter(Component.class, new UniversalJsonAdapter<>(Component.providers)); builder.registerTypeAdapter(ProtectHandler.class, new UniversalJsonAdapter<>(ProtectHandler.providers)); builder.registerTypeAdapter(DaoProvider.class, new UniversalJsonAdapter<>(DaoProvider.providers)); + builder.registerTypeAdapter(JsonResponseInterface.class, new UniversalJsonAdapter<>(WebSocketService.providers)); + builder.registerTypeAdapter(HashedEntry.class, new HashedEntryAdapter()); + builder.registerTypeAdapter(ResultInterface.class, new JsonResultSerializeAdapter()); } } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/LauncherNettyServer.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/LauncherNettyServer.java index 0c24db50..87c456dc 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/LauncherNettyServer.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/LauncherNettyServer.java @@ -7,6 +7,7 @@ import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.EventLoopGroup; +import io.netty.channel.group.DefaultChannelGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; @@ -15,6 +16,7 @@ import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler; import io.netty.handler.logging.LoggingHandler; +import io.netty.util.concurrent.GlobalEventExecutor; import pro.gravit.launcher.request.Request; import pro.gravit.launcher.request.auth.AuthRequest; import pro.gravit.launcher.request.websockets.StandartClientWebSocketService; @@ -22,13 +24,14 @@ import pro.gravit.launchserver.socket.handlers.NettyIpForwardHandler; import pro.gravit.launchserver.socket.handlers.WebSocketFrameHandler; import pro.gravit.launchserver.socket.handlers.fileserver.FileServerHandler; +import pro.gravit.utils.helper.CommonHelper; import pro.gravit.utils.helper.LogHelper; public class LauncherNettyServer implements AutoCloseable { public final ServerBootstrap serverBootstrap; public final EventLoopGroup bossGroup; public final EventLoopGroup workerGroup; - public WebSocketFrameHandler frameHandler = null; + public final WebSocketService service; private static final String WEBSOCKET_PATH = "/api"; public LauncherNettyServer(LaunchServer server) { @@ -36,6 +39,7 @@ public LauncherNettyServer(LaunchServer server) { bossGroup = new NioEventLoopGroup(config.performance.bossThread); workerGroup = new NioEventLoopGroup(config.performance.workerThread); serverBootstrap = new ServerBootstrap(); + service = new WebSocketService(new DefaultChannelGroup(GlobalEventExecutor.INSTANCE), server); serverBootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .handler(new LoggingHandler(config.logLevel)) @@ -53,8 +57,7 @@ public void initChannel(NioSocketChannel ch) { pipeline.addLast(new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true)); if (server.config.netty.fileServerEnabled) pipeline.addLast(new FileServerHandler(server.updatesDir, true)); - frameHandler = new WebSocketFrameHandler(context, server); - pipeline.addLast(frameHandler); + pipeline.addLast(new WebSocketFrameHandler(context, server, service)); } }); if (config.proxy != null && config.proxy.enabled) { 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 8d149f62..a94b870f 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java @@ -13,19 +13,16 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.group.ChannelGroup; import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; +import pro.gravit.launcher.Launcher; import pro.gravit.launcher.events.ExceptionEvent; import pro.gravit.launcher.events.RequestEvent; import pro.gravit.launcher.events.request.AuthRequestEvent; import pro.gravit.launcher.events.request.ErrorRequestEvent; -import pro.gravit.launcher.hasher.HashedEntry; -import pro.gravit.launcher.hasher.HashedEntryAdapter; -import pro.gravit.launcher.request.JsonResultSerializeAdapter; import pro.gravit.launcher.request.Request; import pro.gravit.launcher.request.RequestException; import pro.gravit.launcher.request.ResultInterface; import pro.gravit.launcher.request.admin.ProxyRequest; import pro.gravit.launchserver.LaunchServer; -import pro.gravit.launchserver.socket.response.JsonResponseAdapter; import pro.gravit.launchserver.socket.response.JsonResponseInterface; import pro.gravit.launchserver.socket.response.SimpleResponse; import pro.gravit.launchserver.socket.response.admin.AddLogListenerResponse; @@ -40,27 +37,27 @@ import pro.gravit.launchserver.socket.response.update.LauncherResponse; import pro.gravit.launchserver.socket.response.update.UpdateListResponse; import pro.gravit.launchserver.socket.response.update.UpdateResponse; +import pro.gravit.utils.ProviderMap; import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.LogHelper; @SuppressWarnings("rawtypes") public class WebSocketService { public final ChannelGroup channels; + public static ProviderMap providers; - public WebSocketService(ChannelGroup channels, LaunchServer server, GsonBuilder gson) { + public WebSocketService(ChannelGroup channels, LaunchServer server) { this.channels = channels; this.server = server; - this.gsonBuiler = gson; - this.gsonBuiler.registerTypeAdapter(JsonResponseInterface.class, new JsonResponseAdapter(this)); - this.gsonBuiler.registerTypeAdapter(ResultInterface.class, new JsonResultSerializeAdapter()); - this.gsonBuiler.registerTypeAdapter(HashedEntry.class, new HashedEntryAdapter()); - this.gson = gsonBuiler.create(); + //this.gsonBuiler.registerTypeAdapter(JsonResponseInterface.class, new JsonResponseAdapter(this)); + //this.gsonBuiler.registerTypeAdapter(ResultInterface.class, new JsonResultSerializeAdapter()); + //this.gsonBuiler.registerTypeAdapter(HashedEntry.class, new HashedEntryAdapter()); + this.gson = Launcher.gsonManager.gson; } private final LaunchServer server; private static final HashMap responses = new HashMap<>(); private final Gson gson; - private final GsonBuilder gsonBuiler; public void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client client, String ip) { String request = frame.text(); @@ -150,34 +147,30 @@ public Class getResponseClass(String type) { return responses.get(type); } - public void registerResponse(String key, Class responseInterfaceClass) { - responses.put(key, responseInterfaceClass); - } - public void registerClient(Channel channel) { channels.add(channel); } - public void registerResponses() { - registerResponse("auth", AuthResponse.class); - registerResponse("checkServer", CheckServerResponse.class); - registerResponse("joinServer", JoinServerResponse.class); - registerResponse("profiles", ProfilesResponse.class); - registerResponse("launcher", LauncherResponse.class); - registerResponse("updateList", UpdateListResponse.class); - registerResponse("cmdExec", ExecCommandResponse.class); - registerResponse("setProfile", SetProfileResponse.class); - registerResponse("addLogListener", AddLogListenerResponse.class); - registerResponse("update", UpdateResponse.class); - registerResponse("restoreSession", RestoreSessionResponse.class); - registerResponse("batchProfileByUsername", BatchProfileByUsername.class); - registerResponse("profileByUsername", ProfileByUsername.class); - registerResponse("profileByUUID", ProfileByUUIDResponse.class); - registerResponse("getSecureToken", GetSecureTokenResponse.class); - registerResponse("verifySecureToken", VerifySecureTokenResponse.class); - registerResponse("getAvailabilityAuth", GetAvailabilityAuthResponse.class); - registerResponse("proxy", ProxyCommandResponse.class); - registerResponse("register", RegisterResponse.class); + public static void registerResponses() { + providers.register("auth", AuthResponse.class); + providers.register("checkServer", CheckServerResponse.class); + providers.register("joinServer", JoinServerResponse.class); + providers.register("profiles", ProfilesResponse.class); + providers.register("launcher", LauncherResponse.class); + providers.register("updateList", UpdateListResponse.class); + providers.register("cmdExec", ExecCommandResponse.class); + providers.register("setProfile", SetProfileResponse.class); + providers.register("addLogListener", AddLogListenerResponse.class); + providers.register("update", UpdateResponse.class); + providers.register("restoreSession", RestoreSessionResponse.class); + providers.register("batchProfileByUsername", BatchProfileByUsername.class); + providers.register("profileByUsername", ProfileByUsername.class); + providers.register("profileByUUID", ProfileByUUIDResponse.class); + providers.register("getSecureToken", GetSecureTokenResponse.class); + providers.register("verifySecureToken", VerifySecureTokenResponse.class); + providers.register("getAvailabilityAuth", GetAvailabilityAuthResponse.class); + providers.register("proxy", ProxyCommandResponse.class); + providers.register("register", RegisterResponse.class); } public void sendObject(ChannelHandlerContext ctx, Object obj) { diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/WebSocketFrameHandler.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/WebSocketFrameHandler.java index b27c9280..2e5e1ed6 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/WebSocketFrameHandler.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/WebSocketFrameHandler.java @@ -23,15 +23,13 @@ public class WebSocketFrameHandler extends SimpleChannelInboundHandler { public final LaunchServer srv; - public static GsonBuilder builder = CommonHelper.newBuilder(); public final WebSocketService service; public NettyConnectContext context; - public WebSocketFrameHandler(NettyConnectContext context, LaunchServer srv) { + public WebSocketFrameHandler(NettyConnectContext context, LaunchServer srv, WebSocketService service) { this.context = context; this.srv = srv; - service = new WebSocketService(new DefaultChannelGroup(GlobalEventExecutor.INSTANCE), srv, builder); - service.registerResponses(); + this.service = service; } private Client client; @@ -43,6 +41,8 @@ public void setClient(Client client) { this.client = client; } + public Client getClient() { return client; } + @Override public void channelActive(ChannelHandlerContext ctx) { LogHelper.dev("New client %s", IOHelper.getIP(ctx.channel().remoteAddress())); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/JsonResponseAdapter.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/JsonResponseAdapter.java deleted file mode 100644 index 0ebc0327..00000000 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/JsonResponseAdapter.java +++ /dev/null @@ -1,44 +0,0 @@ -package pro.gravit.launchserver.socket.response; - -import java.lang.reflect.Type; - -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.JsonPrimitive; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; - -import pro.gravit.launchserver.socket.WebSocketService; - -public class JsonResponseAdapter implements JsonSerializer, JsonDeserializer { - private final WebSocketService service; - private static final String PROP_NAME = "type"; - - public JsonResponseAdapter(WebSocketService service) { - this.service = service; - } - - @SuppressWarnings("unchecked") - @Override - public JsonResponseInterface deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - String typename = json.getAsJsonObject().getAsJsonPrimitive(PROP_NAME).getAsString(); - Class cls = service.getResponseClass(typename); - - - return (JsonResponseInterface) context.deserialize(json, cls); - } - - @Override - public JsonElement serialize(JsonResponseInterface src, Type typeOfSrc, JsonSerializationContext context) { - // note : won't work, you must delegate this - JsonObject jo = context.serialize(src).getAsJsonObject(); - - String classPath = src.getType(); - jo.add(PROP_NAME, new JsonPrimitive(classPath)); - - return jo; - } -}