Merge branch 'release/5.0.0b5'

This commit is contained in:
Gravit 2019-05-04 16:15:25 +07:00
commit 7904b0db31
No known key found for this signature in database
GPG key ID: 061981E1E85D3216
98 changed files with 471 additions and 142 deletions

View file

@ -42,6 +42,7 @@
dependencies {
pack project(':libLauncher')
pack project(':LauncherAPI')
bundle project(':Radon')
bundle 'mysql:mysql-connector-java:8.0.13'
bundle 'jline:jline:2.14.6'
@ -50,7 +51,7 @@ bundle project(':Radon')
bundle 'commons-io:commons-io:2.6'
bundle 'commons-codec:commons-codec:1.11'
bundle 'org.javassist:javassist:3.24.1-GA'
bundle 'io.netty:netty-all:4.1.32.Final'
bundle 'io.netty:netty-all:4.1.36.Final'
bundle 'org.slf4j:slf4j-simple:1.7.25'
bundle 'org.slf4j:slf4j-api:1.7.25'

View file

@ -34,10 +34,11 @@
import ru.gravit.launchserver.manangers.hook.SocketHookManager;
import ru.gravit.launchserver.socket.ServerSocketHandler;
import ru.gravit.launchserver.websocket.NettyServerSocketHandler;
import ru.gravit.utils.Version;
import ru.gravit.utils.command.CommandHandler;
import ru.gravit.utils.command.JLineCommandHandler;
import ru.gravit.utils.command.StdCommandHandler;
import ru.gravit.utils.config.JsonConfigurable;
import ru.gravit.launcher.config.JsonConfigurable;
import ru.gravit.utils.helper.*;
import java.io.*;
@ -282,12 +283,22 @@ public class NettyConfig {
public NettyPerformanceConfig performance;
public NettyBindAddress[] binds;
public LogLevel logLevel = LogLevel.DEBUG;
public NettyProxyConfig proxy = new NettyProxyConfig();
}
public class NettyPerformanceConfig
{
public int bossThread;
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 String address;
@ -688,8 +699,8 @@ private void generateConfigIfNotExists(boolean testEnv) throws IOException {
newConfig.launch4j = new ExeConf();
newConfig.launch4j.enabled = true;
newConfig.launch4j.copyright = "© GravitLauncher Team";
newConfig.launch4j.fileDesc = "GravitLauncher ".concat(Launcher.getVersion().getVersionString());
newConfig.launch4j.fileVer = Launcher.getVersion().getVersionString().concat(".").concat(String.valueOf(Launcher.getVersion().patch));
newConfig.launch4j.fileDesc = "GravitLauncher ".concat(Version.getVersion().getVersionString());
newConfig.launch4j.fileVer = Version.getVersion().getVersionString().concat(".").concat(String.valueOf(Version.getVersion().patch));
newConfig.launch4j.internalName = "Launcher";
newConfig.launch4j.trademarks = "This product is licensed under GPLv3";
newConfig.launch4j.txtFileVersion = "%s, build %d";

View file

@ -3,8 +3,8 @@
import net.sf.launch4j.Builder;
import net.sf.launch4j.Log;
import net.sf.launch4j.config.*;
import ru.gravit.launcher.Launcher;
import ru.gravit.launchserver.LaunchServer;
import ru.gravit.utils.Version;
import ru.gravit.utils.helper.IOHelper;
import ru.gravit.utils.helper.LogHelper;
@ -108,8 +108,8 @@ private void setConfig() {
ConfigPersister.getInstance().setAntConfig(config, null);
}
private static String VERSION = Launcher.getVersion().getVersionString();
private static int BUILD = Launcher.getVersion().build;
private static String VERSION = Version.getVersion().getVersionString();
private static int BUILD = Version.getVersion().build;
public static String formatVars(String mask) {
return String.format(mask, VERSION, BUILD);

View file

@ -1,8 +1,10 @@
package ru.gravit.launchserver.command.basic;
import ru.gravit.launcher.events.PingEvent;
import ru.gravit.launchserver.LaunchServer;
import ru.gravit.launchserver.command.Command;
import ru.gravit.launchserver.websocket.NettyServerSocketHandler;
import ru.gravit.launchserver.websocket.WebSocketFrameHandler;
import ru.gravit.utils.helper.CommonHelper;
public class TestCommand extends Command {
@ -33,5 +35,9 @@ public void invoke(String... args) throws Exception {
if (args[0].equals("stop")) {
handler.close();
}
if (args[0].equals("eventAll"))
{
WebSocketFrameHandler.service.sendObjectAll(new PingEvent());
}
}
}

View file

@ -1,8 +1,8 @@
package ru.gravit.launchserver.command.basic;
import ru.gravit.launcher.Launcher;
import ru.gravit.launchserver.LaunchServer;
import ru.gravit.launchserver.command.Command;
import ru.gravit.utils.Version;
import ru.gravit.utils.helper.LogHelper;
public final class VersionCommand extends Command {
@ -22,6 +22,6 @@ public String getUsageDescription() {
@Override
public void invoke(String... args) {
LogHelper.subInfo("LaunchServer version: %d.%d.%d (build #%d)", Launcher.MAJOR, Launcher.MINOR, Launcher.PATCH, Launcher.BUILD);
LogHelper.subInfo("LaunchServer version: %d.%d.%d (build #%d)", Version.MAJOR, Version.MINOR, Version.PATCH, Version.BUILD);
}
}

View file

@ -2,10 +2,9 @@
import ru.gravit.launcher.NeedGarbageCollection;
import ru.gravit.launchserver.LaunchServer;
import ru.gravit.launchserver.auth.AuthException;
import ru.gravit.launchserver.auth.provider.AuthProvider;
import ru.gravit.launchserver.socket.Client;
import ru.gravit.launchserver.websocket.json.auth.AuthResponse;
import ru.gravit.utils.HookException;
import java.util.ArrayList;
import java.util.HashMap;
@ -18,7 +17,7 @@ public void preInit(LaunchServer launchServer) {
@Override
public void init(LaunchServer launchServer) {
launchServer.authHookManager.registerPreHook(this::preAuthHook);
launchServer.authHookManager.preHook.registerHook(this::preAuthHook);
}
@Override
@ -26,10 +25,11 @@ public void postInit(LaunchServer launchServer) {
}
public void preAuthHook(AuthResponse.AuthContext context, Client client) throws AuthException {
public boolean preAuthHook(AuthResponse.AuthContext context, Client client) {
if (isLimit(context.ip)) {
AuthProvider.authError(message);
throw new HookException(message);
}
return false;
}
static class AuthEntry {

View file

@ -1,75 +1,16 @@
package ru.gravit.launchserver.manangers.hook;
import ru.gravit.launchserver.auth.AuthException;
import ru.gravit.launchserver.socket.Client;
import ru.gravit.launchserver.websocket.json.auth.AuthResponse;
import java.util.HashSet;
import java.util.Set;
import ru.gravit.launchserver.websocket.json.auth.CheckServerResponse;
import ru.gravit.launchserver.websocket.json.auth.JoinServerResponse;
import ru.gravit.launchserver.websocket.json.auth.SetProfileResponse;
import ru.gravit.utils.BiHookSet;
public class AuthHookManager {
private Set<AuthPreHook> PRE_HOOKS = new HashSet<>();
private Set<AuthPostHook> POST_HOOKS = new HashSet<>();
private Set<CheckServerHook> CHECKSERVER_HOOKS = new HashSet<>();
private Set<JoinServerHook> JOINSERVER_HOOKS = new HashSet<>();
@FunctionalInterface
public interface AuthPreHook {
void preAuthHook(AuthResponse.AuthContext context, Client client) throws AuthException;
}
@FunctionalInterface
public interface AuthPostHook {
void postAuthHook(AuthResponse.AuthContext context, Client client) throws AuthException;
}
@FunctionalInterface
public interface CheckServerHook {
void checkServerHook(String username, String serverID) throws AuthException;
}
@FunctionalInterface
public interface JoinServerHook {
void joinServerHook(String username, String accessToken, String serverID) throws AuthException;
}
public void registerPostHook(AuthPostHook hook) {
POST_HOOKS.add(hook);
}
public void registerJoinServerHook(JoinServerHook hook) {
JOINSERVER_HOOKS.add(hook);
}
public void registerCheckServerHook(CheckServerHook hook) {
CHECKSERVER_HOOKS.add(hook);
}
public void registerPreHook(AuthPreHook hook) {
PRE_HOOKS.add(hook);
}
public void preHook(AuthResponse.AuthContext context, Client client) throws AuthException {
for (AuthPreHook preHook : PRE_HOOKS) {
preHook.preAuthHook(context, client);
}
}
public void checkServerHook(String username, String serverID) throws AuthException {
for (CheckServerHook hook : CHECKSERVER_HOOKS) {
hook.checkServerHook(username, serverID);
}
}
public void joinServerHook(String username, String accessToken, String serverID) throws AuthException {
for (JoinServerHook hook : JOINSERVER_HOOKS) {
hook.joinServerHook(username, accessToken, serverID);
}
}
public void postHook(AuthResponse.AuthContext context, Client client) throws AuthException {
for (AuthPostHook postHook : POST_HOOKS) {
postHook.postAuthHook(context, client);
}
}
public BiHookSet<AuthResponse.AuthContext, Client> preHook = new BiHookSet<>();
public BiHookSet<AuthResponse.AuthContext, Client> postHook = new BiHookSet<>();
public BiHookSet<CheckServerResponse, Client> checkServerHook = new BiHookSet<>();
public BiHookSet<JoinServerResponse, Client> joinServerHook = new BiHookSet<>();
public BiHookSet<SetProfileResponse, Client> setProfileHook = new BiHookSet<>();
}

View file

@ -1,6 +1,5 @@
package ru.gravit.launchserver.modules;
import ru.gravit.launcher.Launcher;
import ru.gravit.launcher.modules.Module;
import ru.gravit.launcher.modules.ModuleContext;
import ru.gravit.utils.Version;
@ -18,7 +17,7 @@ public String getName() {
@Override
public Version getVersion() {
return Launcher.getVersion();
return Version.getVersion();
}
@Override

View file

@ -8,6 +8,7 @@
public class Client {
public long session;
public boolean proxy;
public String auth_id;
public long timestamp;
public Type type;
@ -18,7 +19,7 @@ public class Client {
public ClientPermissions permissions;
public String username;
public String verifyToken;
public LogHelper.OutputEnity logOutput;
public transient LogHelper.OutputEnity logOutput;
public transient AuthProviderPair auth;

View file

@ -13,8 +13,12 @@
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 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.websocket.fileserver.FileServerHandler;
import ru.gravit.utils.helper.LogHelper;
import java.net.InetSocketAddress;
@ -45,6 +49,18 @@ public void initChannel(NioSocketChannel ch) {
pipeline.addLast(new WebSocketFrameHandler());
}
});
if(config.proxy != null && 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)
{

View file

@ -9,11 +9,15 @@
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import ru.gravit.launcher.events.ExceptionEvent;
import ru.gravit.launcher.events.RequestEvent;
import ru.gravit.launcher.events.request.AuthRequestEvent;
import ru.gravit.launcher.events.request.ErrorRequestEvent;
import ru.gravit.launcher.hasher.HashedEntry;
import ru.gravit.launcher.hasher.HashedEntryAdapter;
import ru.gravit.launcher.request.JsonResultSerializeAdapter;
import ru.gravit.launcher.request.Request;
import ru.gravit.launcher.request.RequestException;
import ru.gravit.launcher.request.ResultInterface;
import ru.gravit.launcher.request.admin.ProxyRequest;
import ru.gravit.launchserver.LaunchServer;
import ru.gravit.launchserver.socket.Client;
import ru.gravit.launchserver.websocket.json.JsonResponseAdapter;
@ -21,6 +25,7 @@
import ru.gravit.launchserver.websocket.json.SimpleResponse;
import ru.gravit.launchserver.websocket.json.admin.AddLogListenerResponse;
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.profile.BatchProfileByUsername;
import ru.gravit.launchserver.websocket.json.profile.ProfileByUUIDResponse;
@ -34,6 +39,8 @@
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Random;
import java.util.UUID;
@SuppressWarnings("rawtypes")
public class WebSocketService {
@ -54,9 +61,73 @@ public WebSocketService(ChannelGroup channels, LaunchServer server, GsonBuilder
private final Gson gson;
private final GsonBuilder gsonBuiler;
@SuppressWarnings("unchecked")
void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client client) {
String request = frame.text();
JsonResponseInterface response = gson.fromJson(request, JsonResponseInterface.class);
if(server.config.netty.proxy.enabled)
{
if(server.config.netty.proxy.requests.contains(response.getType()))
{
UUID origRequestUUID = null;
if(response instanceof SimpleResponse)
{
SimpleResponse simpleResponse = (SimpleResponse) response;
simpleResponse.server = server;
simpleResponse.service = this;
simpleResponse.ctx = ctx;
origRequestUUID = simpleResponse.requestUUID;
}
LogHelper.debug("Proxy %s request", response.getType());
if(client.session == 0) client.session = new Random().nextLong();
ProxyRequest proxyRequest = new ProxyRequest(response, client.session);
if(response instanceof SimpleResponse)
{
((SimpleResponse) response).requestUUID = proxyRequest.requestUUID;
}
proxyRequest.isCheckSign = client.checkSign;
try {
ResultInterface result = proxyRequest.request();
if(result instanceof AuthRequestEvent)
{
LogHelper.debug("Client auth params get successful");
AuthRequestEvent authRequestEvent = (AuthRequestEvent) result;
client.isAuth = true;
client.session = authRequestEvent.session;
if(authRequestEvent.playerProfile != null) client.username = authRequestEvent.playerProfile.username;
}
if(result instanceof Request && response instanceof SimpleResponse)
{
((Request) result).requestUUID = origRequestUUID;
}
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)
{
SimpleResponse simpleResponse = (SimpleResponse) response;
@ -115,6 +186,7 @@ public void registerResponses() {
registerResponse("getSecureToken", GetSecureTokenResponse.class);
registerResponse("verifySecureToken", VerifySecureTokenResponse.class);
registerResponse("getAvailabilityAuth", GetAvailabilityAuthResponse.class);
registerResponse("proxy", ProxyCommandResponse.class);
}
public void sendObject(ChannelHandlerContext ctx, Object obj) {
@ -125,6 +197,20 @@ public void sendObject(ChannelHandlerContext ctx, Object obj, Type type) {
ctx.channel().writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, type)));
}
public void sendObjectAll(Object obj) {
for(Channel ch : channels)
{
ch.writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, ResultInterface.class)));
}
}
public void sendObjectAll(Object obj, Type type) {
for(Channel ch : channels)
{
ch.writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, type)));
}
}
public void sendObjectAndClose(ChannelHandlerContext ctx, Object obj) {
ctx.channel().writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, ResultInterface.class))).addListener(ChannelFutureListener.CLOSE);
}

View file

@ -1,9 +1,10 @@
package ru.gravit.launchserver.websocket.json;
import io.netty.channel.ChannelHandlerContext;
import ru.gravit.launcher.request.websockets.RequestInterface;
import ru.gravit.launchserver.socket.Client;
public interface JsonResponseInterface {
public interface JsonResponseInterface extends RequestInterface {
String getType();
void execute(ChannelHandlerContext ctx, Client client) throws Exception;

View file

@ -0,0 +1,27 @@
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;
public boolean isCheckSign;
@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);
real_client.checkSign = isCheckSign;
response.execute(ctx, real_client);
}
@Override
public String getType() {
return "proxy";
}
}

View file

@ -13,6 +13,7 @@
import ru.gravit.launchserver.socket.Client;
import ru.gravit.launchserver.websocket.json.SimpleResponse;
import ru.gravit.launchserver.websocket.json.profile.ProfileByUUIDResponse;
import ru.gravit.utils.HookException;
import ru.gravit.utils.helper.IOHelper;
import ru.gravit.utils.helper.LogHelper;
import ru.gravit.utils.helper.SecurityHelper;
@ -43,6 +44,7 @@ public AuthResponse(String login, String password, String auth_id, OshiHWID hwid
}
public String auth_id;
public boolean initProxy;
public ConnectTypes authType;
public OshiHWID hwid;
@ -84,7 +86,7 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
else pair = LaunchServer.server.config.getAuthProviderPair(auth_id);
AuthContext context = new AuthContext(0, login, password.length(), customText, client, ip, null, false);
AuthProvider provider = pair.provider;
LaunchServer.server.authHookManager.preHook(context, clientData);
LaunchServer.server.authHookManager.preHook.hook(context, clientData);
provider.preAuth(login, password, customText, ip);
AuthProviderResult aresult = provider.auth(login, password, ip);
if (!VerifyHelper.isValidUsername(aresult.username)) {
@ -105,7 +107,7 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
//}
if (authType == ConnectTypes.CLIENT)
LaunchServer.server.config.hwidHandler.check(hwid, aresult.username);
LaunchServer.server.authHookManager.postHook(context, clientData);
LaunchServer.server.authHookManager.postHook.hook(context, clientData);
clientData.isAuth = true;
clientData.permissions = aresult.permissions;
clientData.auth_id = auth_id;
@ -114,10 +116,17 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
result.permissions = clientData.permissions;
if(getSession)
{
if(clientData.session == 0) {
clientData.session = random.nextLong();
LaunchServer.server.sessionManager.addClient(clientData);
}
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))
{
UUID uuid = pair.handler.auth(aresult);
@ -125,7 +134,7 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
LogHelper.debug("Auth: %s accessToken %s uuid: %s", login, result.accessToken, uuid.toString());
}
sendResult(result);
} catch (AuthException | HWIDException e) {
} catch (AuthException | HWIDException | HookException e) {
sendError(e.getMessage());
}
}

View file

@ -7,6 +7,7 @@
import ru.gravit.launchserver.socket.Client;
import ru.gravit.launchserver.websocket.json.SimpleResponse;
import ru.gravit.launchserver.websocket.json.profile.ProfileByUUIDResponse;
import ru.gravit.utils.HookException;
import ru.gravit.utils.helper.LogHelper;
public class CheckServerResponse extends SimpleResponse {
@ -23,11 +24,12 @@ public String getType() {
public void execute(ChannelHandlerContext ctx, Client pClient) {
CheckServerRequestEvent result = new CheckServerRequestEvent();
try {
server.authHookManager.checkServerHook.hook(this, pClient);
result.uuid = pClient.auth.handler.checkServer(username, serverID);
if (result.uuid != null)
result.playerProfile = ProfileByUUIDResponse.getProfile(LaunchServer.server, result.uuid, username, client, pClient.auth.textureProvider);
LogHelper.debug("checkServer: %s uuid: %s serverID: %s", result.playerProfile.username, result.uuid.toString(), serverID);
} catch (AuthException e) {
} catch (AuthException | HookException e) {
sendError(e.getMessage());
return;
} catch (Exception e) {

View file

@ -6,6 +6,7 @@
import ru.gravit.launchserver.auth.AuthException;
import ru.gravit.launchserver.socket.Client;
import ru.gravit.launchserver.websocket.json.SimpleResponse;
import ru.gravit.utils.HookException;
import ru.gravit.utils.helper.LogHelper;
public class JoinServerResponse extends SimpleResponse {
@ -17,11 +18,11 @@ public class JoinServerResponse extends SimpleResponse {
public String getType() {
return "joinServer";
}
@Override
public void execute(ChannelHandlerContext ctx, Client client) {
boolean success;
try {
server.authHookManager.joinServerHook.hook(this, client);
if(client.auth == null)
{
LogHelper.warning("Client auth is null. Using default.");
@ -29,7 +30,7 @@ public void execute(ChannelHandlerContext ctx, Client client) {
}
else success = client.auth.handler.joinServer(username, accessToken, serverID);
LogHelper.debug("joinServer: %s accessToken: %s serverID: %s", username, accessToken, serverID);
} catch (AuthException e) {
} catch (AuthException | HookException e) {
sendError(e.getMessage());
return;
} catch (Exception e) {

View file

@ -6,6 +6,7 @@
import ru.gravit.launchserver.LaunchServer;
import ru.gravit.launchserver.socket.Client;
import ru.gravit.launchserver.websocket.json.SimpleResponse;
import ru.gravit.utils.HookException;
import java.util.Collection;
@ -23,6 +24,12 @@ public void execute(ChannelHandlerContext ctx, Client client) {
sendError("Access denied");
return;
}
try {
server.authHookManager.setProfileHook.hook(this, client);
} catch (HookException e)
{
sendError(e.getMessage());
}
Collection<ClientProfile> profiles = LaunchServer.server.getProfiles();
for (ClientProfile p : profiles) {
if (p.getTitle().equals(this.client)) {

View file

@ -36,12 +36,12 @@
}
dependencies {
pack project(':LauncherAPI')
pack project(':LauncherAuthlib')
bundle 'com.github.oshi:oshi-core:3.13.0'
bundle 'com.jfoenix:jfoenix:8.0.8'
bundle 'de.jensd:fontawesomefx:8.9'
bundle 'org.apache.httpcomponents:httpclient:4.5.7'
pack 'io.netty:netty-all:4.1.32.Final'
pack 'io.netty:netty-all:4.1.36.Final'
pack 'org.ow2.asm:asm-tree:7.1'
}

View file

@ -240,6 +240,18 @@ function verifyLauncher(e) {
//result.list весь список
//result.list[0].name имя авторизации(не видно)
//result.list[0].displayName имя авторизации(видно)
result.list.forEach(function(auth_type, i, arr) {
(function() {
//profilesList[serverBtn] = profile;
//var hold = serverBtn;
//var hIndex = index;
//serverBtn.setOnAction(function(event) {
// serverHolder.set(hold);
// settings.profile = hIndex;
//});
authOptions.getItems().add(auth_type.displayName);
})();
});
overlay.swap(0, processing.overlay, function(event) makeProfilesRequest(function(result) {
settings.lastProfiles = result.profiles;
updateProfilesList(result.profiles);

View file

@ -16,6 +16,7 @@
import ru.gravit.launcher.serialize.stream.StreamObject;
import ru.gravit.launcher.utils.DirWatcher;
import ru.gravit.utils.PublicURLClassLoader;
import ru.gravit.utils.Version;
import ru.gravit.utils.helper.*;
import ru.gravit.utils.helper.JVMHelper.OS;
@ -201,7 +202,7 @@ private static void addClientArgs(Collection<String> args, ClientProfile profile
Collections.addAll(args, "--assetsDir", params.assetDir.toString());
Collections.addAll(args, "--resourcePackDir", params.clientDir.resolve(RESOURCEPACKS_DIR).toString());
if (version.compareTo(ClientProfile.Version.MC194) >= 0)
Collections.addAll(args, "--versionType", "Launcher v" + Launcher.getVersion().getVersionString());
Collections.addAll(args, "--versionType", "Launcher v" + Version.getVersion().getVersionString());
// Add server args
if (params.autoEnter) {
@ -335,6 +336,7 @@ public static Process launch(
context.args.add(JVMHelper.jvmProperty(LogHelper.DEBUG_PROPERTY, Boolean.toString(LogHelper.isDebugEnabled())));
context.args.add(JVMHelper.jvmProperty(LogHelper.STACKTRACE_PROPERTY, Boolean.toString(LogHelper.isStacktraceEnabled())));
context.args.add(JVMHelper.jvmProperty(LogHelper.DEV_PROPERTY, Boolean.toString(LogHelper.isDevEnabled())));
context.args.add(JVMHelper.jvmProperty(LogHelper.NO_JANSI_PROPERTY, "true")); // Отключаем JAnsi для нормального вывода в DEBUG окно
JVMHelper.addSystemPropertyToArgs(context.args, DirBridge.CUSTOMDIR_PROPERTY);
JVMHelper.addSystemPropertyToArgs(context.args, DirBridge.USE_CUSTOMDIR_PROPERTY);
JVMHelper.addSystemPropertyToArgs(context.args, DirBridge.USE_OPTDIR_PROPERTY);

View file

@ -0,0 +1,24 @@
package ru.gravit.launcher.console.admin;
import ru.gravit.launcher.events.request.ExecCommandRequestEvent;
import ru.gravit.launcher.request.admin.ExecCommandRequest;
import ru.gravit.utils.command.Command;
import ru.gravit.utils.helper.LogHelper;
public class ExecCommand extends Command {
@Override
public String getArgsDescription() {
return null;
}
@Override
public String getUsageDescription() {
return null;
}
@Override
public void invoke(String... args) throws Exception {
ExecCommandRequestEvent request = new ExecCommandRequest(String.join(" ", args)).request();
if(!request.success) LogHelper.error("Error executing command");
}
}

View file

@ -0,0 +1,53 @@
package ru.gravit.launcher.console.admin;
import ru.gravit.launcher.LauncherNetworkAPI;
import ru.gravit.launcher.events.request.LogEvent;
import ru.gravit.launcher.request.Request;
import ru.gravit.launcher.request.websockets.RequestInterface;
import ru.gravit.utils.command.Command;
import ru.gravit.utils.helper.LogHelper;
public class LogListenerCommand extends Command {
public class LogListenerRequest implements RequestInterface
{
@LauncherNetworkAPI
public LogHelper.OutputTypes outputType;
public LogListenerRequest(LogHelper.OutputTypes outputType) {
this.outputType = outputType;
}
@Override
public String getType() {
return "addLogListener";
}
}
@Override
public String getArgsDescription() {
return null;
}
@Override
public String getUsageDescription() {
return null;
}
@Override
public void invoke(String... args) throws Exception {
LogHelper.info("Send log listener request");
Request.service.sendObject(new LogListenerRequest(LogHelper.JANSI ? LogHelper.OutputTypes.JANSI : LogHelper.OutputTypes.PLAIN));
LogHelper.info("Add log handler");
Request.service.registerHandler((result) -> {
if(result instanceof LogEvent)
{
LogHelper.rawLog(() -> {
return ((LogEvent) result).string;
}, () -> {
return ((LogEvent) result).string;
}, () -> {
return ((LogEvent) result).string;
});
}
});
}
}

View file

@ -1,5 +1,8 @@
package ru.gravit.launcher.managers;
import ru.gravit.launcher.console.admin.ExecCommand;
import ru.gravit.launcher.console.admin.LogListenerCommand;
import ru.gravit.utils.command.BaseCommandCategory;
import ru.gravit.utils.command.basic.ClearCommand;
import ru.gravit.utils.command.basic.DebugCommand;
import ru.gravit.utils.command.basic.GCCommand;
@ -48,5 +51,9 @@ public static boolean checkUnlockKey(String key)
public static void unlock()
{
handler.registerCommand("debug", new DebugCommand());
BaseCommandCategory admin = new BaseCommandCategory();
admin.registerCommand("exec", new ExecCommand());
admin.registerCommand("logListen", new LogListenerCommand());
handler.registerCategory(new CommandHandler.Category(admin, "admin", "Server admin commands"));
}
}

View file

@ -6,7 +6,7 @@
import ru.gravit.launcher.hasher.HashedDir;
import ru.gravit.launcher.serialize.HInput;
import ru.gravit.launcher.serialize.HOutput;
import ru.gravit.utils.config.JsonConfigurable;
import ru.gravit.launcher.config.JsonConfigurable;
import ru.gravit.utils.helper.IOHelper;
import java.io.IOException;

View file

@ -3,8 +3,6 @@
dependencies {
compile project(':libLauncher')
compileOnly 'io.netty:netty-all:4.1.32.Final'
compileOnly 'org.apache.httpcomponents:httpclient:4.5.7'
compileOnly 'com.google.guava:guava:26.0-jre'
compile files('../compat/authlib/authlib-clean.jar')
compileOnly 'io.netty:netty-all:4.1.36.Final'
}

View file

@ -20,6 +20,8 @@ public class ClientPermissions {
public boolean canUSR3;
@LauncherAPI
public boolean canBot;
@LauncherAPI
public boolean canProxy;
public ClientPermissions(HInput input) throws IOException {
this(input.readLong());

View file

@ -4,7 +4,6 @@
import ru.gravit.launcher.modules.ModulesManager;
import ru.gravit.launcher.profiles.ClientProfile;
import ru.gravit.launcher.serialize.HInput;
import ru.gravit.utils.Version;
import ru.gravit.utils.helper.IOHelper;
import ru.gravit.utils.helper.LogHelper;
import ru.gravit.utils.helper.SecurityHelper;
@ -57,11 +56,6 @@ public final class Launcher {
public static final String CONFIG_SCRIPT_FILE = "config.js";
private static final Pattern UUID_PATTERN = Pattern.compile("-", Pattern.LITERAL);
public static final int MAJOR = 5;
public static final int MINOR = 0;
public static final int PATCH = 0;
public static final int BUILD = 4;
public static final Version.Type RELEASE = Version.Type.BETA;
public static GsonManager gsonManager;
@LauncherAPI
@ -119,10 +113,6 @@ public static String toHash(UUID uuid) {
return UUID_PATTERN.matcher(uuid.toString()).replaceAll("");
}
public static Version getVersion() {
return new Version(MAJOR, MINOR, PATCH, BUILD, RELEASE);
}
public static void applyLauncherEnv(LauncherConfig.LauncherEnvironment env) {
switch (env) {
case DEV:

View file

@ -1,4 +1,4 @@
package ru.gravit.utils.config;
package ru.gravit.launcher.config;
import ru.gravit.launcher.Launcher;
import ru.gravit.launcher.LauncherAPI;

View file

@ -1,6 +1,6 @@
package ru.gravit.launcher.managers;
import ru.gravit.utils.config.JsonConfigurable;
import ru.gravit.launcher.config.JsonConfigurable;
import ru.gravit.utils.helper.LogHelper;
import ru.gravit.utils.helper.VerifyHelper;

View file

@ -1,9 +1,11 @@
package ru.gravit.launcher.request;
import ru.gravit.launcher.request.websockets.StandartClientWebSocketService;
public final class PingRequest extends Request<ResultInterface> {
@Override
protected ResultInterface requestDo() throws Exception {
protected ResultInterface requestDo(StandartClientWebSocketService service) throws Exception {
return null;
}

View file

@ -36,11 +36,17 @@ public R request() throws Exception {
if (!started.compareAndSet(false, true))
throw new IllegalStateException("Request already started");
if(service == null) service = StandartClientWebSocketService.initWebSockets(Launcher.getConfig().address, false);
return requestDo();
return requestDo(service);
}
@LauncherAPI
public R request(StandartClientWebSocketService service) throws Exception {
if (!started.compareAndSet(false, true))
throw new IllegalStateException("Request already started");
return requestDo(service);
}
@SuppressWarnings("unchecked")
protected R requestDo() throws Exception
protected R requestDo(StandartClientWebSocketService service) throws Exception
{
return (R) service.sendRequest(this);
}

View file

@ -15,6 +15,6 @@ public ExecCommandRequest(String cmd) {
@Override
public String getType() {
return "execCmd";
return "cmdExec";
}
}

View file

@ -0,0 +1,21 @@
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 boolean isCheckSign;
public ProxyRequest(RequestInterface response, long session) {
this.response = response;
this.session = session;
}
@Override
public String getType() {
return "proxy";
}
}

View file

@ -23,6 +23,10 @@ public final class AuthRequest extends Request<AuthRequestEvent> implements Requ
private final boolean getSession;
@LauncherNetworkAPI
private final ConnectTypes authType;
@LauncherNetworkAPI
public boolean initProxy;
@LauncherNetworkAPI
public String password;
public enum ConnectTypes {
@LauncherNetworkAPI
@ -30,7 +34,9 @@ public enum ConnectTypes {
@LauncherNetworkAPI
CLIENT,
@LauncherNetworkAPI
BOT
BOT,
@LauncherNetworkAPI
PROXY
}
@LauncherAPI
@ -75,6 +81,16 @@ public AuthRequest(String login, byte[] encryptedPassword, String auth_id, Conne
this.customText = "";
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
public String getType() {

View file

@ -7,6 +7,7 @@
import ru.gravit.launcher.events.request.LauncherRequestEvent;
import ru.gravit.launcher.request.Request;
import ru.gravit.launcher.request.websockets.RequestInterface;
import ru.gravit.launcher.request.websockets.StandartClientWebSocketService;
import ru.gravit.utils.helper.IOHelper;
import ru.gravit.utils.helper.JVMHelper;
import ru.gravit.utils.helper.LogHelper;
@ -65,7 +66,7 @@ public static void update(LauncherRequestEvent result) throws IOException {
}
@Override
public LauncherRequestEvent requestDo() throws Exception {
public LauncherRequestEvent requestDo(StandartClientWebSocketService service) throws Exception {
LauncherRequestEvent result = (LauncherRequestEvent) service.sendRequest(this);
if (result.needUpdate) update(result);
return result;

View file

@ -12,6 +12,7 @@
import ru.gravit.launcher.request.Request;
import ru.gravit.launcher.request.update.UpdateRequest.State.Callback;
import ru.gravit.launcher.request.websockets.RequestInterface;
import ru.gravit.launcher.request.websockets.StandartClientWebSocketService;
import ru.gravit.utils.helper.IOHelper;
import ru.gravit.utils.helper.LogHelper;
@ -166,7 +167,7 @@ public double getTotalSizeMiB() {
}
@Override
public UpdateRequestEvent requestDo() throws Exception {
public UpdateRequestEvent requestDo(StandartClientWebSocketService service) throws Exception {
LogHelper.debug("Start update request");
UpdateRequestEvent e = (UpdateRequestEvent) service.sendRequest(this);
LogHelper.debug("Start update");

View file

@ -118,7 +118,7 @@ public void registerResults() {
registerResult("getSecureToken", GetSecureTokenRequestEvent.class);
registerResult("verifySecureToken", VerifySecureTokenRequestEvent.class);
registerResult("log", LogEvent.class);
registerResult("execCmd", ExecCommandRequestEvent.class);
registerResult("cmdExec", ExecCommandRequestEvent.class);
registerResult("getAvailabilityAuth", GetAvailabilityAuthRequestEvent.class);
registerResult("exception", ExceptionEvent.class);
}

View file

@ -0,0 +1,9 @@
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
dependencies {
compile project(':LauncherAPI')
compileOnly 'org.apache.httpcomponents:httpclient:4.5.7'
compileOnly 'com.google.guava:guava:26.0-jre'
compile files('../compat/authlib/authlib-clean.jar')
}

View file

@ -27,9 +27,9 @@
}
dependencies {
pack project(':LauncherAPI')
pack project(':LauncherAuthlib')
pack 'org.apache.httpcomponents:httpclient:4.5.7'
pack 'io.netty:netty-all:4.1.32.Final'
pack 'io.netty:netty-all:4.1.36.Final'
}
shadowJar {

View file

@ -11,7 +11,7 @@
import ru.gravit.launcher.request.update.ProfilesRequest;
import ru.gravit.launcher.server.setup.ServerWrapperSetup;
import ru.gravit.utils.PublicURLClassLoader;
import ru.gravit.utils.config.JsonConfigurable;
import ru.gravit.launcher.config.JsonConfigurable;
import ru.gravit.utils.helper.CommonHelper;
import ru.gravit.utils.helper.IOHelper;
import ru.gravit.utils.helper.LogHelper;
@ -172,7 +172,7 @@ public void run(String... args) throws Throwable {
auth();
};
}
LogHelper.info("ServerWrapper: LaunchServer address: %s. Title: %s", config.websocket.address, config.title);
LogHelper.info("ServerWrapper: Project %s, LaunchServer address: %s. Title: %s", config.projectname, config.websocket.address, config.title);
LogHelper.info("Minecraft Version (for profile): %s", wrapper.profile == null ? "unknown" : wrapper.profile.getVersion().name);
LogHelper.info("Start Minecraft Server");
LogHelper.debug("Invoke main method %s", mainClass.getName());
@ -193,7 +193,7 @@ public void updateLauncherConfig() {
LauncherConfig cfg = null;
try {
cfg = new LauncherConfig(config.websocket.address, SecurityHelper.toPublicRSAKey(IOHelper.read(publicKeyFile)), new HashMap<>());
cfg = new LauncherConfig(config.websocket.address, SecurityHelper.toPublicRSAKey(IOHelper.read(publicKeyFile)), new HashMap<>(), config.projectname);
if(config.websocket != null && config.websocket.enabled)
{
cfg.isNettyEnabled = true;
@ -221,6 +221,7 @@ public Config getConfig() {
public Config getDefaultConfig() {
Config newConfig = new Config();
newConfig.title = "Your profile title";
newConfig.projectname = "MineCraft";
newConfig.login = "login";
newConfig.password = "password";
newConfig.mainclass = "";
@ -242,6 +243,7 @@ public void setConfig(Config config) {
public static final class Config {
public String title;
public String projectname;
public WebSocketConf websocket;
public int reconnectCount;
public int reconnectSleep;

View file

@ -7,6 +7,8 @@
apply plugin: 'eclipse'
apply plugin: 'java'
group = 'ru.gravit'
repositories {
mavenCentral()
maven { url 'http://oss.sonatype.org/content/groups/public' }
@ -30,6 +32,12 @@
}
}
subprojects {
tasks.withType(JavaCompile) {
options.incremental = true // one flag, and things will get MUCH faster
}
}
wrapper {
distributionType = Wrapper.DistributionType.ALL
}

View file

@ -2,4 +2,5 @@
git clone https://github.com/GravitLauncher/Launcher.git
cd Launcher
sed -i 's/git@github.com:/https:\/\/github.com\//' .gitmodules
git submodule sync
git submodule update --init --recursive

View file

@ -18,7 +18,5 @@ public interface Module extends AutoCloseable {
default void finish(ModuleContext context) {
// NOP
}
;
};
}

View file

@ -0,0 +1,29 @@
package ru.gravit.utils;
import java.util.HashSet;
import java.util.Set;
public class BiHookSet<V,R> {
public Set<Hook<V,R>> list = new HashSet<>();
@FunctionalInterface
public interface Hook<V, R>
{
boolean hook(V object, R context) throws HookException;
}
public void registerHook(Hook<V, R> hook)
{
list.add(hook);
}
public boolean unregisterHook(Hook<V, R> hook)
{
return list.remove(hook);
}
public boolean hook(V context, R object) throws HookException
{
for(Hook<V, R> hook : list)
{
if(hook.hook(context, object)) return true;
}
return false;
}
}

View file

@ -0,0 +1,21 @@
package ru.gravit.utils;
public class HookException extends RuntimeException {
private static final long serialVersionUID = -529141998961943161L;
public HookException(String message) {
super(message);
}
public HookException(String message, Throwable cause) {
super(message, cause);
}
public HookException(Throwable cause) {
super(cause);
}
public HookException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View file

@ -8,7 +8,7 @@ public class HookSet<R> {
@FunctionalInterface
public interface Hook<R>
{
boolean hook(R context);
boolean hook(R context) throws HookException;
}
public void registerHook(Hook<R> hook)
{
@ -18,7 +18,7 @@ public boolean unregisterHook(Hook<R> hook)
{
return list.remove(hook);
}
public boolean hook(R context)
public boolean hook(R context) throws HookException
{
for(Hook<R> hook : list)
{

View file

@ -15,6 +15,11 @@ public final class Version {
public final int build;
@LauncherAPI
public final Type release;
public static final int MAJOR = 5;
public static final int MINOR = 0;
public static final int PATCH = 0;
public static final int BUILD = 5;
public static final Version.Type RELEASE = Version.Type.BETA;
@LauncherAPI
public Version(int major, int minor, int patch) {
@ -43,6 +48,10 @@ public Version(int major, int minor, int patch, int build, Type release) {
this.release = release;
}
public static Version getVersion() {
return new Version(MAJOR, MINOR, PATCH, BUILD, RELEASE);
}
@Override
@LauncherAPI
public boolean equals(Object o) {

View file

@ -1,7 +1,7 @@
package ru.gravit.utils.helper;
import org.fusesource.jansi.Ansi;
import ru.gravit.launcher.Launcher;
import ru.gravit.utils.Version;
/*
* Nashorn при инициализации LogHelper пытается инициализировтаь все доступные в нем методы.
@ -59,8 +59,8 @@ static String ansiFormatVersion(String product) {
fgBright(Ansi.Color.MAGENTA).a("GravitLauncher "). // sashok724's
fgBright(Ansi.Color.BLUE).a("(fork sashok724's Launcher) ").
fgBright(Ansi.Color.CYAN).a(product). // Product
fgBright(Ansi.Color.WHITE).a(" v").fgBright(Ansi.Color.BLUE).a(Launcher.getVersion().toString()). // Version
fgBright(Ansi.Color.WHITE).a(" (build #").fgBright(Ansi.Color.RED).a(Launcher.getVersion().build).fgBright(Ansi.Color.WHITE).a(')'). // Build#
fgBright(Ansi.Color.WHITE).a(" v").fgBright(Ansi.Color.BLUE).a(Version.getVersion().toString()). // Version
fgBright(Ansi.Color.WHITE).a(" (build #").fgBright(Ansi.Color.RED).a(Version.getVersion().build).fgBright(Ansi.Color.WHITE).a(')'). // Build#
reset().toString(); // To file
}
@ -79,7 +79,7 @@ public static String rawFormat(LogHelper.Level level, String dateTime, boolean s
}
static String formatVersion(String product) {
return String.format("GravitLauncher (fork sashok724's Launcher) %s v%s", product, Launcher.getVersion().toString());
return String.format("GravitLauncher (fork sashok724's Launcher) %s v%s", product, Version.getVersion().toString());
}
static String formatLicense(String product) {

View file

@ -1,6 +1,5 @@
package ru.gravit.utils.helper;
import ru.gravit.launcher.Launcher;
import ru.gravit.launcher.LauncherAPI;
import javax.imageio.ImageIO;
@ -10,8 +9,8 @@
import java.net.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.nio.file.FileSystem;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Collections;
import java.util.Set;
@ -229,7 +228,7 @@ public static byte[] getResourceBytes(String name) throws IOException {
@LauncherAPI
public static URL getResourceURL(String name) throws NoSuchFileException {
URL url = Launcher.class.getResource('/' + name);
URL url = IOHelper.class.getResource('/' + name);
if (url == null)
throw new NoSuchFileException(name);
return url;

View file

@ -4,6 +4,7 @@
import org.fusesource.jansi.AnsiConsole;
import org.fusesource.jansi.AnsiOutputStream;
import ru.gravit.launcher.LauncherAPI;
import ru.gravit.launcher.LauncherNetworkAPI;
import java.io.*;
import java.nio.file.Path;
@ -47,7 +48,12 @@ public OutputEnity(Output output, OutputTypes type) {
}
public enum OutputTypes {
PLAIN, JANSI, HTML
@LauncherNetworkAPI
PLAIN,
@LauncherNetworkAPI
JANSI,
@LauncherNetworkAPI
HTML
}
private static final Set<OutputEnity> OUTPUTS = Collections.newSetFromMap(new ConcurrentHashMap<>(2));
@ -107,7 +113,7 @@ public static void debug(String format, Object... args) {
@LauncherAPI
public static void dev(String format, Object... args) {
debug(String.format(format, args));
dev(String.format(format, args));
}
@LauncherAPI
@ -378,6 +384,9 @@ public static String htmlFormatLog(Level level, String dateTime, String message,
case DEBUG:
levelColor = "gravitlauncher-log-debug";
break;
case DEV:
levelColor = "gravitlauncher-log-dev";
break;
default:
levelColor = "gravitlauncher-log-unknown";
break;

@ -1 +1 @@
Subproject commit c338164496249a17eea2079ed560b09132831f35
Subproject commit 3f7cf22f4270dcdf6baa5c74dd00673b2b4ffc9e

View file

@ -4,6 +4,7 @@
include 'Radon'
include 'libLauncher'
include 'LauncherAPI'
include 'LauncherAuthlib'
include 'ServerWrapper'
include 'LaunchServer'
include 'LaunchServerConsole'