[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.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

View file

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

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

View file

@ -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) {

View file

@ -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<JsonResponseInterface> 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<String, Class> 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) {

View file

@ -23,15 +23,13 @@
public class WebSocketFrameHandler extends SimpleChannelInboundHandler<WebSocketFrame> {
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()));

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