From 437da3de5910ca4a02764a05f46250c3e072382a Mon Sep 17 00:00:00 2001 From: Gravit Date: Sun, 1 Mar 2020 13:58:38 +0700 Subject: [PATCH] =?UTF-8?q?[FEATURE]=20=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20Exit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../manangers/SessionManager.java | 5 ++ .../launchserver/socket/WebSocketService.java | 1 + .../socket/response/auth/ExitResponse.java | 89 +++++++++++++++++++ .../events/request/ExitRequestEvent.java | 20 +++++ .../launcher/request/auth/ExitRequest.java | 29 ++++++ .../websockets/ClientWebSocketService.java | 1 + 6 files changed, 145 insertions(+) create mode 100644 LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/ExitResponse.java create mode 100644 LauncherAPI/src/main/java/pro/gravit/launcher/events/request/ExitRequestEvent.java create mode 100644 LauncherAPI/src/main/java/pro/gravit/launcher/request/auth/ExitRequest.java diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java index 991a87ea..db19f4f5 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/manangers/SessionManager.java @@ -40,6 +40,11 @@ public Client getOrNewClient(long session) { return clientSet.computeIfAbsent(session, Client::new); } + public Client removeClient(long session) + { + return clientSet.remove(session); + } + public void updateClient(long session) { Client c = clientSet.get(session); 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 e717dcb0..0eb2ff09 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/WebSocketService.java @@ -123,6 +123,7 @@ public static void registerResponses() { providers.register("getAvailabilityAuth", GetAvailabilityAuthResponse.class); providers.register("register", RegisterResponse.class); providers.register("setPassword", SetPasswordResponse.class); + providers.register("exit", ExitResponse.class); } public void sendObject(ChannelHandlerContext ctx, Object obj) { diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/ExitResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/ExitResponse.java new file mode 100644 index 00000000..6f66e93d --- /dev/null +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/auth/ExitResponse.java @@ -0,0 +1,89 @@ +package pro.gravit.launchserver.socket.response.auth; + +import io.netty.channel.ChannelHandlerContext; +import pro.gravit.launcher.events.RequestEvent; +import pro.gravit.launcher.events.request.ExitRequestEvent; +import pro.gravit.launchserver.socket.Client; +import pro.gravit.launchserver.socket.handlers.WebSocketFrameHandler; +import pro.gravit.launchserver.socket.response.SimpleResponse; + +public class ExitResponse extends SimpleResponse { + public boolean exitAll; + public String username; + @Override + public String getType() { + return "exit"; + } + + @Override + public void execute(ChannelHandlerContext ctx, Client client) throws Exception { + if(username != null && ( !client.isAuth || client.permissions == null || !client.permissions.canAdmin )) + { + sendError("Permissions denied"); + return; + } + if(username == null) + { + if(client.session == 0 && exitAll) + { + sendError("Session invalid"); + return; + } + WebSocketFrameHandler handler = ctx.pipeline().get(WebSocketFrameHandler.class); + if(handler == null) + { + sendError("Exit internal error"); + return; + } + Client newClient = new Client(0); + newClient.isSecure = client.isSecure; + newClient.checkSign = client.checkSign; + handler.setClient(newClient); + if(exitAll) + { + service.channels.forEach((channel) -> { + if(channel == null || channel.pipeline() == null) return; + WebSocketFrameHandler wsHandler = channel.pipeline().get(WebSocketFrameHandler.class); + if(wsHandler == null || wsHandler == handler) return; + Client chClient = wsHandler.getClient(); + if(client.isAuth && client.username != null) + { + if(!chClient.isAuth || !client.username.equals(chClient.username)) return; + } + else + { + if(chClient.session != client.session) return; + } + Client newCusClient = new Client(0); + newCusClient.isSecure = chClient.isSecure; + newCusClient.checkSign = chClient.checkSign; + wsHandler.setClient(newCusClient); + if(chClient.session != 0) server.sessionManager.removeClient(chClient.session); + ExitRequestEvent event = new ExitRequestEvent(ExitRequestEvent.ExitReason.SERVER); + event.requestUUID = RequestEvent.eventUUID; + wsHandler.service.sendObject(channel, event); + }); + } + sendResult(new ExitRequestEvent(ExitRequestEvent.ExitReason.CLIENT)); + } + else + { + service.channels.forEach((channel -> { + if(channel == null || channel.pipeline() == null) return; + WebSocketFrameHandler wsHandler = channel.pipeline().get(WebSocketFrameHandler.class); + if(wsHandler == null) return; + Client chClient = wsHandler.getClient(); + if(!chClient.isAuth || !username.equals(chClient.username)) return; + Client newCusClient = new Client(0); + newCusClient.isSecure = chClient.isSecure; + newCusClient.checkSign = chClient.checkSign; + wsHandler.setClient(newCusClient); + if(chClient.session != 0) server.sessionManager.removeClient(chClient.session); + ExitRequestEvent event = new ExitRequestEvent(ExitRequestEvent.ExitReason.SERVER); + event.requestUUID = RequestEvent.eventUUID; + wsHandler.service.sendObject(channel, event); + })); + sendResult(new ExitRequestEvent(ExitRequestEvent.ExitReason.NO_EXIT)); + } + } +} diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/events/request/ExitRequestEvent.java b/LauncherAPI/src/main/java/pro/gravit/launcher/events/request/ExitRequestEvent.java new file mode 100644 index 00000000..8916cf79 --- /dev/null +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/events/request/ExitRequestEvent.java @@ -0,0 +1,20 @@ +package pro.gravit.launcher.events.request; + +import pro.gravit.launcher.events.RequestEvent; + +public class ExitRequestEvent extends RequestEvent { + public enum ExitReason + { + SERVER, CLIENT, TIMEOUT, NO_EXIT + } + public final ExitReason reason; + + public ExitRequestEvent(ExitReason reason) { + this.reason = reason; + } + + @Override + public String getType() { + return "exit"; + } +} diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/request/auth/ExitRequest.java b/LauncherAPI/src/main/java/pro/gravit/launcher/request/auth/ExitRequest.java new file mode 100644 index 00000000..240c27a3 --- /dev/null +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/request/auth/ExitRequest.java @@ -0,0 +1,29 @@ +package pro.gravit.launcher.request.auth; + +import pro.gravit.launcher.events.request.ExitRequestEvent; +import pro.gravit.launcher.request.Request; + +public class ExitRequest extends Request { + public final boolean exitAll; + public final String username; + + public ExitRequest() { + this.exitAll = false; + this.username = null; + } + + public ExitRequest(boolean exitAll) { + this.exitAll = exitAll; + this.username = null; + } + + public ExitRequest(boolean exitAll, String username) { + this.exitAll = exitAll; + this.username = username; + } + + @Override + public String getType() { + return "exit"; + } +} diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/ClientWebSocketService.java b/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/ClientWebSocketService.java index 5b896a35..c6604048 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/ClientWebSocketService.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/request/websockets/ClientWebSocketService.java @@ -107,6 +107,7 @@ public void registerResults() { results.register("setpassword", SetPasswordRequestEvent.class); results.register("notification", NotificationEvent.class); results.register("signal", SignalEvent.class); + results.register("exit", ExitRequestEvent.class); } public void waitIfNotConnected() {