mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-12-23 09:01:08 +03:00
[FEATURE][EXPERIMENTAL] LaunchServer в качестве прокси
This commit is contained in:
parent
dd596805e1
commit
f1cd39babd
10 changed files with 145 additions and 2 deletions
|
@ -283,12 +283,22 @@ public class NettyConfig {
|
||||||
public NettyPerformanceConfig performance;
|
public NettyPerformanceConfig performance;
|
||||||
public NettyBindAddress[] binds;
|
public NettyBindAddress[] binds;
|
||||||
public LogLevel logLevel = LogLevel.DEBUG;
|
public LogLevel logLevel = LogLevel.DEBUG;
|
||||||
|
public NettyProxyConfig proxy = new NettyProxyConfig();
|
||||||
}
|
}
|
||||||
public class NettyPerformanceConfig
|
public class NettyPerformanceConfig
|
||||||
{
|
{
|
||||||
public int bossThread;
|
public int bossThread;
|
||||||
public int workerThread;
|
public int workerThread;
|
||||||
}
|
}
|
||||||
|
public class NettyProxyConfig
|
||||||
|
{
|
||||||
|
public boolean enabled;
|
||||||
|
public String address = "ws://localhost:9275/api";
|
||||||
|
public String login = "login";
|
||||||
|
public String password = "password";
|
||||||
|
public String auth_id = "std";
|
||||||
|
public ArrayList<String> requests = new ArrayList<>();
|
||||||
|
}
|
||||||
public class NettyBindAddress
|
public class NettyBindAddress
|
||||||
{
|
{
|
||||||
public String address;
|
public String address;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
public class Client {
|
public class Client {
|
||||||
public long session;
|
public long session;
|
||||||
|
public boolean proxy;
|
||||||
public String auth_id;
|
public String auth_id;
|
||||||
public long timestamp;
|
public long timestamp;
|
||||||
public Type type;
|
public Type type;
|
||||||
|
|
|
@ -13,8 +13,12 @@
|
||||||
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 ru.gravit.launcher.request.Request;
|
||||||
|
import ru.gravit.launcher.request.auth.AuthRequest;
|
||||||
|
import ru.gravit.launcher.request.websockets.StandartClientWebSocketService;
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
import ru.gravit.launchserver.LaunchServer;
|
||||||
import ru.gravit.launchserver.websocket.fileserver.FileServerHandler;
|
import ru.gravit.launchserver.websocket.fileserver.FileServerHandler;
|
||||||
|
import ru.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
|
@ -45,6 +49,18 @@ public void initChannel(NioSocketChannel ch) {
|
||||||
pipeline.addLast(new WebSocketFrameHandler());
|
pipeline.addLast(new WebSocketFrameHandler());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if(config.proxy.enabled)
|
||||||
|
{
|
||||||
|
LogHelper.info("Connect to main server %s");
|
||||||
|
Request.service = StandartClientWebSocketService.initWebSockets(config.proxy.address, false);
|
||||||
|
AuthRequest authRequest = new AuthRequest(config.proxy.login, config.proxy.password, config.proxy.auth_id, AuthRequest.ConnectTypes.PROXY);
|
||||||
|
authRequest.initProxy = true;
|
||||||
|
try {
|
||||||
|
authRequest.request();
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogHelper.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public ChannelFuture bind(InetSocketAddress address)
|
public ChannelFuture bind(InetSocketAddress address)
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,7 +13,9 @@
|
||||||
import ru.gravit.launcher.hasher.HashedEntry;
|
import ru.gravit.launcher.hasher.HashedEntry;
|
||||||
import ru.gravit.launcher.hasher.HashedEntryAdapter;
|
import ru.gravit.launcher.hasher.HashedEntryAdapter;
|
||||||
import ru.gravit.launcher.request.JsonResultSerializeAdapter;
|
import ru.gravit.launcher.request.JsonResultSerializeAdapter;
|
||||||
|
import ru.gravit.launcher.request.RequestException;
|
||||||
import ru.gravit.launcher.request.ResultInterface;
|
import ru.gravit.launcher.request.ResultInterface;
|
||||||
|
import ru.gravit.launcher.request.admin.ProxyRequest;
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
import ru.gravit.launchserver.LaunchServer;
|
||||||
import ru.gravit.launchserver.socket.Client;
|
import ru.gravit.launchserver.socket.Client;
|
||||||
import ru.gravit.launchserver.websocket.json.JsonResponseAdapter;
|
import ru.gravit.launchserver.websocket.json.JsonResponseAdapter;
|
||||||
|
@ -21,6 +23,7 @@
|
||||||
import ru.gravit.launchserver.websocket.json.SimpleResponse;
|
import ru.gravit.launchserver.websocket.json.SimpleResponse;
|
||||||
import ru.gravit.launchserver.websocket.json.admin.AddLogListenerResponse;
|
import ru.gravit.launchserver.websocket.json.admin.AddLogListenerResponse;
|
||||||
import ru.gravit.launchserver.websocket.json.admin.ExecCommandResponse;
|
import ru.gravit.launchserver.websocket.json.admin.ExecCommandResponse;
|
||||||
|
import ru.gravit.launchserver.websocket.json.admin.ProxyCommandResponse;
|
||||||
import ru.gravit.launchserver.websocket.json.auth.*;
|
import ru.gravit.launchserver.websocket.json.auth.*;
|
||||||
import ru.gravit.launchserver.websocket.json.profile.BatchProfileByUsername;
|
import ru.gravit.launchserver.websocket.json.profile.BatchProfileByUsername;
|
||||||
import ru.gravit.launchserver.websocket.json.profile.ProfileByUUIDResponse;
|
import ru.gravit.launchserver.websocket.json.profile.ProfileByUUIDResponse;
|
||||||
|
@ -57,6 +60,48 @@ public WebSocketService(ChannelGroup channels, LaunchServer server, GsonBuilder
|
||||||
void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client client) {
|
void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client client) {
|
||||||
String request = frame.text();
|
String request = frame.text();
|
||||||
JsonResponseInterface response = gson.fromJson(request, JsonResponseInterface.class);
|
JsonResponseInterface response = gson.fromJson(request, JsonResponseInterface.class);
|
||||||
|
if(server.config.netty.proxy.enabled)
|
||||||
|
{
|
||||||
|
if(server.config.netty.proxy.requests.contains(response.getType()))
|
||||||
|
{
|
||||||
|
if(response instanceof SimpleResponse)
|
||||||
|
{
|
||||||
|
SimpleResponse simpleResponse = (SimpleResponse) response;
|
||||||
|
simpleResponse.server = server;
|
||||||
|
simpleResponse.service = this;
|
||||||
|
simpleResponse.ctx = ctx;
|
||||||
|
}
|
||||||
|
LogHelper.debug("Proxy %s request", response.getType());
|
||||||
|
ProxyRequest proxyRequest = new ProxyRequest(response, 0);
|
||||||
|
try {
|
||||||
|
ResultInterface result = proxyRequest.request();
|
||||||
|
sendObject(ctx, result);
|
||||||
|
} catch (RequestException e)
|
||||||
|
{
|
||||||
|
sendObject(ctx, new ErrorRequestEvent(e.getMessage()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogHelper.error(e);
|
||||||
|
RequestEvent event;
|
||||||
|
if(server.config.netty.sendExceptionEnabled)
|
||||||
|
{
|
||||||
|
event = new ExceptionEvent(e);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
event = new ErrorRequestEvent("Fatal server error. Contact administrator");
|
||||||
|
}
|
||||||
|
if(response instanceof SimpleResponse)
|
||||||
|
{
|
||||||
|
event.requestUUID = ((SimpleResponse) response).requestUUID;
|
||||||
|
}
|
||||||
|
sendObject(ctx, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
process(ctx,response, client);
|
||||||
|
}
|
||||||
|
void process(ChannelHandlerContext ctx, JsonResponseInterface response, Client client)
|
||||||
|
{
|
||||||
if(response instanceof SimpleResponse)
|
if(response instanceof SimpleResponse)
|
||||||
{
|
{
|
||||||
SimpleResponse simpleResponse = (SimpleResponse) response;
|
SimpleResponse simpleResponse = (SimpleResponse) response;
|
||||||
|
@ -115,6 +160,7 @@ public void registerResponses() {
|
||||||
registerResponse("getSecureToken", GetSecureTokenResponse.class);
|
registerResponse("getSecureToken", GetSecureTokenResponse.class);
|
||||||
registerResponse("verifySecureToken", VerifySecureTokenResponse.class);
|
registerResponse("verifySecureToken", VerifySecureTokenResponse.class);
|
||||||
registerResponse("getAvailabilityAuth", GetAvailabilityAuthResponse.class);
|
registerResponse("getAvailabilityAuth", GetAvailabilityAuthResponse.class);
|
||||||
|
registerResponse("proxy", ProxyCommandResponse.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendObject(ChannelHandlerContext ctx, Object obj) {
|
public void sendObject(ChannelHandlerContext ctx, Object obj) {
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
package ru.gravit.launchserver.websocket.json;
|
package ru.gravit.launchserver.websocket.json;
|
||||||
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import ru.gravit.launcher.request.websockets.RequestInterface;
|
||||||
import ru.gravit.launchserver.socket.Client;
|
import ru.gravit.launchserver.socket.Client;
|
||||||
|
|
||||||
public interface JsonResponseInterface {
|
public interface JsonResponseInterface extends RequestInterface {
|
||||||
String getType();
|
String getType();
|
||||||
|
|
||||||
void execute(ChannelHandlerContext ctx, Client client) throws Exception;
|
void execute(ChannelHandlerContext ctx, Client client) throws Exception;
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package ru.gravit.launchserver.websocket.json.admin;
|
||||||
|
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import ru.gravit.launchserver.socket.Client;
|
||||||
|
import ru.gravit.launchserver.websocket.json.JsonResponseInterface;
|
||||||
|
import ru.gravit.launchserver.websocket.json.SimpleResponse;
|
||||||
|
|
||||||
|
public class ProxyCommandResponse extends SimpleResponse {
|
||||||
|
public JsonResponseInterface response;
|
||||||
|
public long session;
|
||||||
|
@Override
|
||||||
|
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
|
if(!client.proxy) {
|
||||||
|
sendError("Proxy server error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Client real_client = server.sessionManager.getOrNewClient(session);
|
||||||
|
response.execute(ctx, real_client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return "proxy";
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,6 +45,7 @@ public AuthResponse(String login, String password, String auth_id, OshiHWID hwid
|
||||||
}
|
}
|
||||||
|
|
||||||
public String auth_id;
|
public String auth_id;
|
||||||
|
public boolean initProxy;
|
||||||
public ConnectTypes authType;
|
public ConnectTypes authType;
|
||||||
public OshiHWID hwid;
|
public OshiHWID hwid;
|
||||||
|
|
||||||
|
@ -120,6 +121,11 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
|
||||||
LaunchServer.server.sessionManager.addClient(clientData);
|
LaunchServer.server.sessionManager.addClient(clientData);
|
||||||
result.session = clientData.session;
|
result.session = clientData.session;
|
||||||
}
|
}
|
||||||
|
if(initProxy)
|
||||||
|
{
|
||||||
|
if(!clientData.permissions.canProxy) throw new AuthException("initProxy not allow");
|
||||||
|
clientData.proxy = true;
|
||||||
|
}
|
||||||
if(LaunchServer.server.config.protectHandler.allowGetAccessToken(context))
|
if(LaunchServer.server.config.protectHandler.allowGetAccessToken(context))
|
||||||
{
|
{
|
||||||
UUID uuid = pair.handler.auth(aresult);
|
UUID uuid = pair.handler.auth(aresult);
|
||||||
|
|
|
@ -20,6 +20,8 @@ public class ClientPermissions {
|
||||||
public boolean canUSR3;
|
public boolean canUSR3;
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public boolean canBot;
|
public boolean canBot;
|
||||||
|
@LauncherAPI
|
||||||
|
public boolean canProxy;
|
||||||
|
|
||||||
public ClientPermissions(HInput input) throws IOException {
|
public ClientPermissions(HInput input) throws IOException {
|
||||||
this(input.readLong());
|
this(input.readLong());
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package ru.gravit.launcher.request.admin;
|
||||||
|
|
||||||
|
import ru.gravit.launcher.request.Request;
|
||||||
|
import ru.gravit.launcher.request.ResultInterface;
|
||||||
|
import ru.gravit.launcher.request.websockets.RequestInterface;
|
||||||
|
|
||||||
|
public class ProxyRequest extends Request<ResultInterface> implements RequestInterface {
|
||||||
|
public RequestInterface response;
|
||||||
|
public long session;
|
||||||
|
|
||||||
|
public ProxyRequest(RequestInterface response, long session) {
|
||||||
|
this.response = response;
|
||||||
|
this.session = session;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return "proxy";
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,10 @@ public final class AuthRequest extends Request<AuthRequestEvent> implements Requ
|
||||||
private final boolean getSession;
|
private final boolean getSession;
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
private final ConnectTypes authType;
|
private final ConnectTypes authType;
|
||||||
|
@LauncherNetworkAPI
|
||||||
|
public boolean initProxy;
|
||||||
|
@LauncherNetworkAPI
|
||||||
|
public String password;
|
||||||
|
|
||||||
public enum ConnectTypes {
|
public enum ConnectTypes {
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
|
@ -30,7 +34,9 @@ public enum ConnectTypes {
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
CLIENT,
|
CLIENT,
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
BOT
|
BOT,
|
||||||
|
@LauncherNetworkAPI
|
||||||
|
PROXY
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
|
@ -75,6 +81,16 @@ public AuthRequest(String login, byte[] encryptedPassword, String auth_id, Conne
|
||||||
this.customText = "";
|
this.customText = "";
|
||||||
this.getSession = false;
|
this.getSession = false;
|
||||||
}
|
}
|
||||||
|
public AuthRequest(String login, String password, String auth_id, ConnectTypes authType) {
|
||||||
|
this.login = login;
|
||||||
|
this.password = password;
|
||||||
|
this.encryptedPassword = null;
|
||||||
|
this.auth_id = auth_id;
|
||||||
|
this.authType = authType;
|
||||||
|
this.hwid = null;
|
||||||
|
this.customText = "";
|
||||||
|
this.getSession = false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
|
|
Loading…
Reference in a new issue