[FEATURE][EXPERIMENTAL] WebSocketService стал доступным извне и привязан к глобальному GsonBuilder, команда clients

This commit is contained in:
Gravit 2019-07-01 16:59:47 +07:00
parent c11f1660ca
commit d737b8f41d
No known key found for this signature in database
GPG key ID: 061981E1E85D3216
8 changed files with 95 additions and 97 deletions

View file

@ -74,6 +74,7 @@
import pro.gravit.launchserver.manangers.SessionManager; 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.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.CommandHandler;
@ -495,6 +496,7 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException
PermissionsHandler.registerHandlers(); PermissionsHandler.registerHandlers();
Component.registerComponents(); Component.registerComponents();
ProtectHandler.registerHandlers(); ProtectHandler.registerHandlers();
WebSocketService.registerResponses();
//LaunchServer.server = this; //LaunchServer.server = this;
// Set command handler // Set command handler

View file

@ -32,17 +32,7 @@
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.ComponentCommand; import pro.gravit.launchserver.command.service.*;
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.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;
@ -124,6 +114,7 @@ public static void registerCommands(pro.gravit.utils.command.CommandHandler hand
service.registerCommand("component", new ComponentCommand(server)); service.registerCommand("component", new ComponentCommand(server));
service.registerCommand("givePermission", new GivePermissionsCommand(server)); service.registerCommand("givePermission", new GivePermissionsCommand(server));
service.registerCommand("getPermissions", new GetPermissionsCommand(server)); service.registerCommand("getPermissions", new GetPermissionsCommand(server));
service.registerCommand("clients", new ClientsCommand(server));
Category serviceCategory = new Category(service, "service", "Managing LaunchServer Components"); Category serviceCategory = new Category(service, "service", "Managing LaunchServer Components");
handler.registerCategory(serviceCategory); handler.registerCategory(serviceCategory);
} }

View file

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

View file

@ -2,7 +2,11 @@
import com.google.gson.GsonBuilder; 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.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.handler.AuthHandler;
import pro.gravit.launchserver.auth.hwid.HWIDHandler; import pro.gravit.launchserver.auth.hwid.HWIDHandler;
import pro.gravit.launchserver.auth.permissions.PermissionsHandler; import pro.gravit.launchserver.auth.permissions.PermissionsHandler;
@ -11,6 +15,8 @@
import pro.gravit.launchserver.auth.texture.TextureProvider; import pro.gravit.launchserver.auth.texture.TextureProvider;
import pro.gravit.launchserver.components.Component; import pro.gravit.launchserver.components.Component;
import pro.gravit.launchserver.dao.provider.DaoProvider; 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; import pro.gravit.utils.UniversalJsonAdapter;
public class LaunchServerGsonManager extends GsonManager { public class LaunchServerGsonManager extends GsonManager {
@ -25,5 +31,8 @@ public void registerAdapters(GsonBuilder builder) {
builder.registerTypeAdapter(Component.class, new UniversalJsonAdapter<>(Component.providers)); builder.registerTypeAdapter(Component.class, new UniversalJsonAdapter<>(Component.providers));
builder.registerTypeAdapter(ProtectHandler.class, new UniversalJsonAdapter<>(ProtectHandler.providers)); builder.registerTypeAdapter(ProtectHandler.class, new UniversalJsonAdapter<>(ProtectHandler.providers));
builder.registerTypeAdapter(DaoProvider.class, new UniversalJsonAdapter<>(DaoProvider.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());
} }
} }

View file

@ -7,6 +7,7 @@
import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup; import io.netty.channel.EventLoopGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel; 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.WebSocketServerProtocolHandler;
import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler; import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler;
import io.netty.handler.logging.LoggingHandler; import io.netty.handler.logging.LoggingHandler;
import io.netty.util.concurrent.GlobalEventExecutor;
import pro.gravit.launcher.request.Request; import pro.gravit.launcher.request.Request;
import pro.gravit.launcher.request.auth.AuthRequest; import pro.gravit.launcher.request.auth.AuthRequest;
import pro.gravit.launcher.request.websockets.StandartClientWebSocketService; import pro.gravit.launcher.request.websockets.StandartClientWebSocketService;
@ -22,13 +24,14 @@
import pro.gravit.launchserver.socket.handlers.NettyIpForwardHandler; import pro.gravit.launchserver.socket.handlers.NettyIpForwardHandler;
import pro.gravit.launchserver.socket.handlers.WebSocketFrameHandler; import pro.gravit.launchserver.socket.handlers.WebSocketFrameHandler;
import pro.gravit.launchserver.socket.handlers.fileserver.FileServerHandler; import pro.gravit.launchserver.socket.handlers.fileserver.FileServerHandler;
import pro.gravit.utils.helper.CommonHelper;
import pro.gravit.utils.helper.LogHelper; import pro.gravit.utils.helper.LogHelper;
public class LauncherNettyServer implements AutoCloseable { public class LauncherNettyServer implements AutoCloseable {
public final ServerBootstrap serverBootstrap; public final ServerBootstrap serverBootstrap;
public final EventLoopGroup bossGroup; public final EventLoopGroup bossGroup;
public final EventLoopGroup workerGroup; public final EventLoopGroup workerGroup;
public WebSocketFrameHandler frameHandler = null; public final WebSocketService service;
private static final String WEBSOCKET_PATH = "/api"; private static final String WEBSOCKET_PATH = "/api";
public LauncherNettyServer(LaunchServer server) { public LauncherNettyServer(LaunchServer server) {
@ -36,6 +39,7 @@ public LauncherNettyServer(LaunchServer server) {
bossGroup = new NioEventLoopGroup(config.performance.bossThread); bossGroup = new NioEventLoopGroup(config.performance.bossThread);
workerGroup = new NioEventLoopGroup(config.performance.workerThread); workerGroup = new NioEventLoopGroup(config.performance.workerThread);
serverBootstrap = new ServerBootstrap(); serverBootstrap = new ServerBootstrap();
service = new WebSocketService(new DefaultChannelGroup(GlobalEventExecutor.INSTANCE), server);
serverBootstrap.group(bossGroup, workerGroup) serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class) .channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(config.logLevel)) .handler(new LoggingHandler(config.logLevel))
@ -53,8 +57,7 @@ public void initChannel(NioSocketChannel ch) {
pipeline.addLast(new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true)); pipeline.addLast(new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true));
if (server.config.netty.fileServerEnabled) if (server.config.netty.fileServerEnabled)
pipeline.addLast(new FileServerHandler(server.updatesDir, true)); pipeline.addLast(new FileServerHandler(server.updatesDir, true));
frameHandler = new WebSocketFrameHandler(context, server); pipeline.addLast(new WebSocketFrameHandler(context, server, service));
pipeline.addLast(frameHandler);
} }
}); });
if (config.proxy != null && config.proxy.enabled) { if (config.proxy != null && config.proxy.enabled) {

View file

@ -13,19 +13,16 @@
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.group.ChannelGroup; import io.netty.channel.group.ChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import pro.gravit.launcher.Launcher;
import pro.gravit.launcher.events.ExceptionEvent; import pro.gravit.launcher.events.ExceptionEvent;
import pro.gravit.launcher.events.RequestEvent; import pro.gravit.launcher.events.RequestEvent;
import pro.gravit.launcher.events.request.AuthRequestEvent; import pro.gravit.launcher.events.request.AuthRequestEvent;
import pro.gravit.launcher.events.request.ErrorRequestEvent; 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.Request;
import pro.gravit.launcher.request.RequestException; import pro.gravit.launcher.request.RequestException;
import pro.gravit.launcher.request.ResultInterface; import pro.gravit.launcher.request.ResultInterface;
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.JsonResponseAdapter;
import pro.gravit.launchserver.socket.response.JsonResponseInterface; import pro.gravit.launchserver.socket.response.JsonResponseInterface;
import pro.gravit.launchserver.socket.response.SimpleResponse; import pro.gravit.launchserver.socket.response.SimpleResponse;
import pro.gravit.launchserver.socket.response.admin.AddLogListenerResponse; 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.LauncherResponse;
import pro.gravit.launchserver.socket.response.update.UpdateListResponse; import pro.gravit.launchserver.socket.response.update.UpdateListResponse;
import pro.gravit.launchserver.socket.response.update.UpdateResponse; import pro.gravit.launchserver.socket.response.update.UpdateResponse;
import pro.gravit.utils.ProviderMap;
import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.IOHelper;
import pro.gravit.utils.helper.LogHelper; import pro.gravit.utils.helper.LogHelper;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public class WebSocketService { public class WebSocketService {
public final ChannelGroup channels; public final ChannelGroup channels;
public static ProviderMap<JsonResponseInterface> providers;
public WebSocketService(ChannelGroup channels, LaunchServer server, GsonBuilder gson) { public WebSocketService(ChannelGroup channels, LaunchServer server) {
this.channels = channels; this.channels = channels;
this.server = server; this.server = server;
this.gsonBuiler = gson; //this.gsonBuiler.registerTypeAdapter(JsonResponseInterface.class, new JsonResponseAdapter(this));
this.gsonBuiler.registerTypeAdapter(JsonResponseInterface.class, new JsonResponseAdapter(this)); //this.gsonBuiler.registerTypeAdapter(ResultInterface.class, new JsonResultSerializeAdapter());
this.gsonBuiler.registerTypeAdapter(ResultInterface.class, new JsonResultSerializeAdapter()); //this.gsonBuiler.registerTypeAdapter(HashedEntry.class, new HashedEntryAdapter());
this.gsonBuiler.registerTypeAdapter(HashedEntry.class, new HashedEntryAdapter()); this.gson = Launcher.gsonManager.gson;
this.gson = gsonBuiler.create();
} }
private final LaunchServer server; private final LaunchServer server;
private static final HashMap<String, Class> responses = new HashMap<>(); private static final HashMap<String, Class> responses = new HashMap<>();
private final Gson gson; private final Gson gson;
private final GsonBuilder gsonBuiler;
public void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client client, String ip) { public void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client client, String ip) {
String request = frame.text(); String request = frame.text();
@ -150,34 +147,30 @@ public Class getResponseClass(String type) {
return responses.get(type); return responses.get(type);
} }
public void registerResponse(String key, Class responseInterfaceClass) {
responses.put(key, responseInterfaceClass);
}
public void registerClient(Channel channel) { public void registerClient(Channel channel) {
channels.add(channel); channels.add(channel);
} }
public void registerResponses() { public static void registerResponses() {
registerResponse("auth", AuthResponse.class); providers.register("auth", AuthResponse.class);
registerResponse("checkServer", CheckServerResponse.class); providers.register("checkServer", CheckServerResponse.class);
registerResponse("joinServer", JoinServerResponse.class); providers.register("joinServer", JoinServerResponse.class);
registerResponse("profiles", ProfilesResponse.class); providers.register("profiles", ProfilesResponse.class);
registerResponse("launcher", LauncherResponse.class); providers.register("launcher", LauncherResponse.class);
registerResponse("updateList", UpdateListResponse.class); providers.register("updateList", UpdateListResponse.class);
registerResponse("cmdExec", ExecCommandResponse.class); providers.register("cmdExec", ExecCommandResponse.class);
registerResponse("setProfile", SetProfileResponse.class); providers.register("setProfile", SetProfileResponse.class);
registerResponse("addLogListener", AddLogListenerResponse.class); providers.register("addLogListener", AddLogListenerResponse.class);
registerResponse("update", UpdateResponse.class); providers.register("update", UpdateResponse.class);
registerResponse("restoreSession", RestoreSessionResponse.class); providers.register("restoreSession", RestoreSessionResponse.class);
registerResponse("batchProfileByUsername", BatchProfileByUsername.class); providers.register("batchProfileByUsername", BatchProfileByUsername.class);
registerResponse("profileByUsername", ProfileByUsername.class); providers.register("profileByUsername", ProfileByUsername.class);
registerResponse("profileByUUID", ProfileByUUIDResponse.class); providers.register("profileByUUID", ProfileByUUIDResponse.class);
registerResponse("getSecureToken", GetSecureTokenResponse.class); providers.register("getSecureToken", GetSecureTokenResponse.class);
registerResponse("verifySecureToken", VerifySecureTokenResponse.class); providers.register("verifySecureToken", VerifySecureTokenResponse.class);
registerResponse("getAvailabilityAuth", GetAvailabilityAuthResponse.class); providers.register("getAvailabilityAuth", GetAvailabilityAuthResponse.class);
registerResponse("proxy", ProxyCommandResponse.class); providers.register("proxy", ProxyCommandResponse.class);
registerResponse("register", RegisterResponse.class); providers.register("register", RegisterResponse.class);
} }
public void sendObject(ChannelHandlerContext ctx, Object obj) { public void sendObject(ChannelHandlerContext ctx, Object obj) {

View file

@ -23,15 +23,13 @@
public class WebSocketFrameHandler extends SimpleChannelInboundHandler<WebSocketFrame> { public class WebSocketFrameHandler extends SimpleChannelInboundHandler<WebSocketFrame> {
public final LaunchServer srv; public final LaunchServer srv;
public static GsonBuilder builder = CommonHelper.newBuilder();
public final WebSocketService service; public final WebSocketService service;
public NettyConnectContext context; public NettyConnectContext context;
public WebSocketFrameHandler(NettyConnectContext context, LaunchServer srv) { public WebSocketFrameHandler(NettyConnectContext context, LaunchServer srv, WebSocketService service) {
this.context = context; this.context = context;
this.srv = srv; this.srv = srv;
service = new WebSocketService(new DefaultChannelGroup(GlobalEventExecutor.INSTANCE), srv, builder); this.service = service;
service.registerResponses();
} }
private Client client; private Client client;
@ -43,6 +41,8 @@ public void setClient(Client client) {
this.client = client; this.client = client;
} }
public Client getClient() { return client; }
@Override @Override
public void channelActive(ChannelHandlerContext ctx) { public void channelActive(ChannelHandlerContext ctx) {
LogHelper.dev("New client %s", IOHelper.getIP(ctx.channel().remoteAddress())); LogHelper.dev("New client %s", IOHelper.getIP(ctx.channel().remoteAddress()));

View file

@ -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<JsonResponseInterface>, JsonDeserializer<JsonResponseInterface> {
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<JsonResponseInterface> 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;
}
}