diff --git a/CODEOFCONDUCT.md b/CODE_OF_CONDUCT.md similarity index 100% rename from CODEOFCONDUCT.md rename to CODE_OF_CONDUCT.md diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/LaunchServer.java b/LaunchServer/src/main/java/ru/gravit/launchserver/LaunchServer.java index ffd0034f..df4cb8c7 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/LaunchServer.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/LaunchServer.java @@ -185,6 +185,8 @@ public class NettyConfig { public String bindAddress; public int port; + public String launcherURL; + public String launcherEXEURL; } public class GuardLicenseConf { @@ -574,9 +576,9 @@ private void generateConfigIfNotExists() throws IOException { newConfig.isWarningMissArchJava = true; // Set server address - LogHelper.println("LaunchServer address: "); + System.out.println("LaunchServer address: "); newConfig.setAddress(commandHandler.readLine()); - LogHelper.println("LaunchServer projectName: "); + System.out.println("LaunchServer projectName: "); newConfig.setProjectName(commandHandler.readLine()); // Write LaunchServer config diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/auth/handler/AuthHandler.java b/LaunchServer/src/main/java/ru/gravit/launchserver/auth/handler/AuthHandler.java index 1f3e9dba..5f30924f 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/auth/handler/AuthHandler.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/auth/handler/AuthHandler.java @@ -41,9 +41,6 @@ public static void registerHandlers() { if (!registredHandl) { registerHandler("null", NullAuthHandler.class); registerHandler("memory", MemoryAuthHandler.class); - - // Auth handler that doesn't do nothing :D - registerHandler("binaryFile", BinaryFileAuthHandler.class); registerHandler("mysql", MySQLAuthHandler.class); registredHandl = true; } diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/auth/handler/BinaryFileAuthHandler.java b/LaunchServer/src/main/java/ru/gravit/launchserver/auth/handler/BinaryFileAuthHandler.java deleted file mode 100644 index 820bfd0c..00000000 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/auth/handler/BinaryFileAuthHandler.java +++ /dev/null @@ -1,37 +0,0 @@ -package ru.gravit.launchserver.auth.handler; - -import ru.gravit.launcher.serialize.HInput; -import ru.gravit.launcher.serialize.HOutput; -import ru.gravit.utils.helper.IOHelper; - -import java.io.IOException; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -public final class BinaryFileAuthHandler extends FileAuthHandler { - - @Override - protected void readAuthFile() throws IOException { - try (HInput input = new HInput(IOHelper.newInput(file))) { - int count = input.readLength(0); - for (int i = 0; i < count; i++) { - UUID uuid = input.readUUID(); - Entry entry = new Entry(input); - addAuth(uuid, entry); - } - } - } - - @Override - protected void writeAuthFileTmp() throws IOException { - Set> entrySet = entrySet(); - try (HOutput output = new HOutput(IOHelper.newOutput(fileTmp))) { - output.writeLength(entrySet.size(), 0); - for (Map.Entry entry : entrySet) { - output.writeUUID(entry.getKey()); - entry.getValue().write(output); - } - } - } -} diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/auth/handler/FileAuthHandler.java b/LaunchServer/src/main/java/ru/gravit/launchserver/auth/handler/FileAuthHandler.java deleted file mode 100644 index 90dd12bf..00000000 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/auth/handler/FileAuthHandler.java +++ /dev/null @@ -1,233 +0,0 @@ -package ru.gravit.launchserver.auth.handler; - -import ru.gravit.launcher.profiles.PlayerProfile; -import ru.gravit.launcher.serialize.HInput; -import ru.gravit.launcher.serialize.HOutput; -import ru.gravit.launcher.serialize.stream.StreamObject; -import ru.gravit.launchserver.auth.provider.AuthProviderResult; -import ru.gravit.utils.helper.*; - -import java.io.IOException; -import java.nio.file.Path; -import java.security.SecureRandom; -import java.util.*; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -public abstract class FileAuthHandler extends AuthHandler { - public static final class Entry extends StreamObject { - private String username; - private String accessToken; - private String serverID; - - - public Entry(HInput input) throws IOException { - username = VerifyHelper.verifyUsername(input.readString(64)); - if (input.readBoolean()) { - accessToken = SecurityHelper.verifyToken(input.readASCII(-SecurityHelper.TOKEN_STRING_LENGTH)); - if (input.readBoolean()) - serverID = VerifyHelper.verifyServerID(input.readASCII(41)); - } - } - - - public Entry(String username) { - this.username = VerifyHelper.verifyUsername(username); - } - - - public Entry(String username, String accessToken, String serverID) { - this(username); - if (accessToken == null && serverID != null) - throw new IllegalArgumentException("Can't set access token while server ID is null"); - - // Set and verify access token - this.accessToken = accessToken == null ? null : SecurityHelper.verifyToken(accessToken); - this.serverID = serverID == null ? null : VerifyHelper.verifyServerID(serverID); - } - - private void auth(String username, String accessToken) { - this.username = username; // Update username case - this.accessToken = accessToken; - serverID = null; - } - - private boolean checkServer(String username, String serverID) { - return username.equals(this.username) && serverID.equals(this.serverID); - } - - - public String getAccessToken() { - return accessToken; - } - - - public String getServerID() { - return serverID; - } - - - public String getUsername() { - return username; - } - - private boolean joinServer(String username, String accessToken, String serverID) { - if (!username.equals(this.username) || !accessToken.equals(this.accessToken)) - return false; // Username or access token mismatch - - // Update server ID - this.serverID = serverID; - return true; - } - - @Override - public void write(HOutput output) throws IOException { - output.writeString(username, 64); - output.writeBoolean(accessToken != null); - if (accessToken != null) { - output.writeASCII(accessToken, -SecurityHelper.TOKEN_STRING_LENGTH); - output.writeBoolean(serverID != null); - if (serverID != null) - output.writeASCII(serverID, 41); - } - } - } - - - public Path file; - - public Path fileTmp; - - - public boolean offlineUUIDs; - // Instance - private final SecureRandom random = SecurityHelper.newRandom(); - - private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); - // Storage - private final Map entryMap = new HashMap<>(256); - - private final Map usernamesMap = new HashMap<>(256); - - - protected final void addAuth(UUID uuid, Entry entry) { - lock.writeLock().lock(); - try { - Entry previous = entryMap.put(uuid, entry); - if (previous != null) - usernamesMap.remove(CommonHelper.low(previous.username)); - usernamesMap.put(CommonHelper.low(entry.username), uuid); - } finally { - lock.writeLock().unlock(); - } - } - - @Override - public final UUID auth(AuthProviderResult authResult) { - lock.writeLock().lock(); - try { - UUID uuid = usernameToUUID(authResult.username); - Entry entry = entryMap.get(uuid); - - // Not registered? Fix it! - if (entry == null) { - entry = new Entry(authResult.username); - - // Generate UUID - uuid = genUUIDFor(authResult.username); - entryMap.put(uuid, entry); - usernamesMap.put(CommonHelper.low(authResult.username), uuid); - } - - // Authenticate - entry.auth(authResult.username, authResult.accessToken); - return uuid; - } finally { - lock.writeLock().unlock(); - } - } - - @Override - public final UUID checkServer(String username, String serverID) { - lock.readLock().lock(); - try { - UUID uuid = usernameToUUID(username); - Entry entry = entryMap.get(uuid); - - // Check server (if has such account of course) - return entry != null && entry.checkServer(username, serverID) ? uuid : null; - } finally { - lock.readLock().unlock(); - } - } - - @Override - public final void close() throws IOException { - lock.readLock().lock(); - try { - LogHelper.info("Writing auth handler file (%d entries)", entryMap.size()); - writeAuthFileTmp(); - IOHelper.move(fileTmp, file); - } finally { - lock.readLock().unlock(); - } - } - - - protected final Set> entrySet() { - return Collections.unmodifiableMap(entryMap).entrySet(); - } - - private UUID genUUIDFor(String username) { - if (offlineUUIDs) { - UUID md5UUID = PlayerProfile.offlineUUID(username); - if (!entryMap.containsKey(md5UUID)) - return md5UUID; - LogHelper.warning("Offline UUID collision, using random: '%s'", username); - } - - // Pick random UUID - UUID uuid; - do - uuid = new UUID(random.nextLong(), random.nextLong()); - while (entryMap.containsKey(uuid)); - return uuid; - } - - @Override - public final boolean joinServer(String username, String accessToken, String serverID) { - lock.writeLock().lock(); - try { - Entry entry = entryMap.get(usernameToUUID(username)); - return entry != null && entry.joinServer(username, accessToken, serverID); - } finally { - lock.writeLock().unlock(); - } - } - - - protected abstract void readAuthFile() throws IOException; - - @Override - public final UUID usernameToUUID(String username) { - lock.readLock().lock(); - try { - return usernamesMap.get(CommonHelper.low(username)); - } finally { - lock.readLock().unlock(); - } - } - - @Override - public final String uuidToUsername(UUID uuid) { - lock.readLock().lock(); - try { - Entry entry = entryMap.get(uuid); - return entry == null ? null : entry.username; - } finally { - lock.readLock().unlock(); - } - } - - - protected abstract void writeAuthFileTmp() throws IOException; -} diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/auth/provider/AuthProvider.java b/LaunchServer/src/main/java/ru/gravit/launchserver/auth/provider/AuthProvider.java index b797b7ad..6883f636 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/auth/provider/AuthProvider.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/auth/provider/AuthProvider.java @@ -29,9 +29,6 @@ public static void registerProviders() { registerProvider("null", NullAuthProvider.class); registerProvider("accept", AcceptAuthProvider.class); registerProvider("reject", RejectAuthProvider.class); - - // Auth providers that doesn't do nothing :D - registerProvider("mojang", MojangAuthProvider.class); registerProvider("mysql", MySQLAuthProvider.class); registerProvider("request", RequestAuthProvider.class); registerProvider("json", JsonAuthProvider.class); diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/auth/provider/MojangAuthProvider.java b/LaunchServer/src/main/java/ru/gravit/launchserver/auth/provider/MojangAuthProvider.java deleted file mode 100644 index 5305c26f..00000000 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/auth/provider/MojangAuthProvider.java +++ /dev/null @@ -1,69 +0,0 @@ -package ru.gravit.launchserver.auth.provider; - -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import ru.gravit.utils.HTTPRequest; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.UUID; -import java.util.regex.Pattern; - -public final class MojangAuthProvider extends AuthProvider { - private static final Pattern UUID_REGEX = Pattern.compile("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})"); - private static final URL URL; - private static final Gson gson = new Gson(); - - static { - try { - URL = new URL("https://authserver.com.mojang.com/authenticate"); - } catch (MalformedURLException e) { - throw new InternalError(e); - } - } - - public class mojangAuth { - public mojangAuth(String username, String password) { - this.username = username; - this.password = password; - name = "Minecraft"; - version = 1; - } - - String name; - int version; - String username; - String password; - - } - - @Override - public AuthProviderResult auth(String login, String password, String ip) throws Exception { - mojangAuth mojangAuth = new mojangAuth(login, password); - JsonElement request = gson.toJsonTree(mojangAuth); - - // Verify there's no error - JsonObject response = HTTPRequest.jsonRequest(request, URL).getAsJsonObject(); - if (response == null) - authError("Empty com.mojang response"); - JsonElement errorMessage = response.get("errorMessage"); - if (errorMessage != null) - authError(errorMessage.getAsString()); - - // Parse JSON data - JsonObject selectedProfile = response.get("selectedProfile").getAsJsonObject(); - String username = selectedProfile.get("name").getAsString(); - String accessToken = response.get("clientToken").getAsString(); - UUID uuid = UUID.fromString(UUID_REGEX.matcher(selectedProfile.get("id").getAsString()).replaceFirst("$1-$2-$3-$4-$5")); - String launcherToken = response.get("accessToken").getAsString(); - - // We're done - return new MojangAuthProviderResult(username, accessToken, uuid, launcherToken); - } - - @Override - public void close() { - // Do nothing - } -} diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/auth/provider/MojangAuthProviderResult.java b/LaunchServer/src/main/java/ru/gravit/launchserver/auth/provider/MojangAuthProviderResult.java deleted file mode 100644 index 123dbe05..00000000 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/auth/provider/MojangAuthProviderResult.java +++ /dev/null @@ -1,14 +0,0 @@ -package ru.gravit.launchserver.auth.provider; - -import java.util.UUID; - -public final class MojangAuthProviderResult extends AuthProviderResult { - public final UUID uuid; - public final String launcherToken; - - public MojangAuthProviderResult(String username, String accessToken, UUID uuid, String launcherToken) { - super(username, accessToken); - this.uuid = uuid; - this.launcherToken = launcherToken; - } -} diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/command/handler/JLineCommandHandler.java b/LaunchServer/src/main/java/ru/gravit/launchserver/command/handler/JLineCommandHandler.java index 7455b026..039afe3d 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/command/handler/JLineCommandHandler.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/command/handler/JLineCommandHandler.java @@ -32,7 +32,7 @@ public JLineCommandHandler(LaunchServer server) throws IOException { // Replace writer LogHelper.removeStdOutput(); - LogHelper.addOutput(new JLineOutput()); + LogHelper.addOutput(new JLineOutput(), LogHelper.OutputTypes.JANSI); } @Override diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/response/admin/ExecCommandResponse.java b/LaunchServer/src/main/java/ru/gravit/launchserver/response/admin/ExecCommandResponse.java index 2e633828..e47be8ba 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/response/admin/ExecCommandResponse.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/response/admin/ExecCommandResponse.java @@ -30,7 +30,7 @@ public void reply() throws Exception { LogHelper.error(e); } }; - LogHelper.addOutput(loutput); + LogHelper.addOutput(loutput, LogHelper.OutputTypes.PLAIN); try { server.commandHandler.eval(cmd, false); output.writeBoolean(false); diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/Client.java b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/Client.java index 40346ddc..74deb416 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/Client.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/Client.java @@ -2,6 +2,7 @@ import ru.gravit.launcher.ClientPermissions; import ru.gravit.launcher.profiles.ClientProfile; +import ru.gravit.utils.helper.LogHelper; public class Client { public long session; @@ -13,6 +14,7 @@ public class Client { public boolean checkSign; public ClientPermissions permissions; public String username; + public LogHelper.Output logOutput; public Client(long session) { this.session = session; diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/WebSocketService.java b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/WebSocketService.java index 42fae12e..ffebe4cc 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/WebSocketService.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/WebSocketService.java @@ -16,14 +16,14 @@ import ru.gravit.launchserver.socket.websocket.json.EchoResponse; import ru.gravit.launchserver.socket.websocket.json.JsonResponseAdapter; import ru.gravit.launchserver.socket.websocket.json.JsonResponseInterface; -import ru.gravit.launchserver.socket.websocket.json.auth.AuthResponse; -import ru.gravit.launchserver.socket.websocket.json.auth.CheckServerResponse; -import ru.gravit.launchserver.socket.websocket.json.auth.JoinServerResponse; -import ru.gravit.launchserver.socket.websocket.json.auth.ProfilesResponse; +import ru.gravit.launchserver.socket.websocket.json.admin.AddLogListenerResponse; +import ru.gravit.launchserver.socket.websocket.json.admin.ExecCommandResponse; +import ru.gravit.launchserver.socket.websocket.json.auth.*; import ru.gravit.launchserver.socket.websocket.json.update.LauncherResponse; import ru.gravit.launchserver.socket.websocket.json.update.UpdateListResponse; import ru.gravit.utils.helper.LogHelper; +import java.lang.reflect.Type; import java.util.HashMap; @SuppressWarnings({"unused", "rawtypes"}) @@ -74,52 +74,44 @@ public void registerResponses() { registerResponse("checkServer", CheckServerResponse.class); registerResponse("joinServer", JoinServerResponse.class); registerResponse("profiles", ProfilesResponse.class); - registerResponse("launcherUpdate", LauncherResponse.class); + registerResponse("launcher", LauncherResponse.class); registerResponse("updateList", UpdateListResponse.class); - registerResponse("cmdExec", UpdateListResponse.class); + registerResponse("cmdExec", ExecCommandResponse.class); + registerResponse("setProfile", SetProfileResponse.class); + registerResponse("addLogListener", AddLogListenerResponse.class); } public void sendObject(ChannelHandlerContext ctx, Object obj) { - ctx.channel().writeAndFlush(new TextWebSocketFrame(gson.toJson(obj))); + ctx.channel().writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, ResultInterface.class))); + } + public void sendObject(ChannelHandlerContext ctx, Object obj, Type type) { + ctx.channel().writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, type))); } public void sendObjectAndClose(ChannelHandlerContext ctx, Object obj) { - ctx.channel().writeAndFlush(new TextWebSocketFrame(gson.toJson(obj))).addListener(ChannelFutureListener.CLOSE); + ctx.channel().writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, ResultInterface.class))).addListener(ChannelFutureListener.CLOSE); + } + + public void sendObjectAndClose(ChannelHandlerContext ctx, Object obj, Type type) { + ctx.channel().writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, type))).addListener(ChannelFutureListener.CLOSE); } public void sendEvent(EventResult obj) { channels.writeAndFlush(new TextWebSocketFrame(gson.toJson(obj))); } - public static class ErrorResult { - public ErrorResult(String error) { - this.error = error; - this.type = "requestError"; - } - - public final String error; - public final String type; - } - - public static class SuccessResult { - public SuccessResult(String requesttype) { - this.requesttype = requesttype; - this.type = "success"; - } - - public final String requesttype; - public final String type; - } - - public static class EventResult { + public static class EventResult implements ResultInterface { public EventResult() { - this.type = "event"; + } - public final String type; + @Override + public String getType() { + return "event"; + } } - public static class ExceptionResult { + public static class ExceptionResult implements ResultInterface { public ExceptionResult(Exception e) { this.message = e.getMessage(); this.clazz = e.getClass().getName(); @@ -129,5 +121,10 @@ public ExceptionResult(Exception e) { public final String message; public final String clazz; public final String type; + + @Override + public String getType() { + return "exception"; + } } } diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/EchoResponse.java b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/EchoResponse.java index 8fba54b4..eb91724c 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/EchoResponse.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/EchoResponse.java @@ -1,6 +1,7 @@ package ru.gravit.launchserver.socket.websocket.json; import io.netty.channel.ChannelHandlerContext; +import ru.gravit.launcher.events.request.EchoRequestEvent; import ru.gravit.launchserver.socket.Client; import ru.gravit.launchserver.socket.websocket.WebSocketService; import ru.gravit.utils.helper.LogHelper; @@ -20,14 +21,7 @@ public String getType() { @Override public void execute(WebSocketService service, ChannelHandlerContext ctx, Client client) { LogHelper.info("Echo: %s, isAuth %s", echo, client.isAuth ? "true" : "false"); - service.sendObject(ctx, new Result(echo)); + service.sendObject(ctx, new EchoRequestEvent(echo)); } - public class Result { - String echo; - - public Result(String echo) { - this.echo = echo; - } - } } diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/admin/AddLogListenerResponse.java b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/admin/AddLogListenerResponse.java new file mode 100644 index 00000000..f507a7e8 --- /dev/null +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/admin/AddLogListenerResponse.java @@ -0,0 +1,50 @@ +package ru.gravit.launchserver.socket.websocket.json.admin; + +import io.netty.channel.ChannelHandlerContext; +import ru.gravit.launcher.events.request.ErrorRequestEvent; +import ru.gravit.launcher.events.request.LogEvent; +import ru.gravit.launchserver.socket.Client; +import ru.gravit.launchserver.socket.websocket.WebSocketService; +import ru.gravit.launchserver.socket.websocket.json.JsonResponseInterface; +import ru.gravit.utils.helper.LogHelper; + +public class AddLogListenerResponse implements JsonResponseInterface { + public LogHelper.OutputTypes outputType = LogHelper.OutputTypes.PLAIN; + @Override + public String getType() { + return "addLogListener"; + } + + @Override + public void execute(WebSocketService service, ChannelHandlerContext ctx, Client client) throws Exception { + if (!client.isAuth) { + service.sendObject(ctx, new ErrorRequestEvent("Access denied")); + return; + } + if (!client.permissions.canAdmin) { + service.sendObject(ctx, new ErrorRequestEvent("Access denied")); + return; + } + if(client.logOutput != null) + { + LogHelper.info("Client %s remove log listener", client.username); + LogHelper.removeOutput(client.logOutput); + } + else + { + LogHelper.info("Client %s add log listener", client.username); + LogHelper.Output output = (str) -> { + if(!ctx.isRemoved()) + { + service.sendObject(ctx,new LogEvent(str)); + } + else { + LogHelper.removeOutput(client.logOutput); + LogHelper.info("Client %s remove log listener", client.username); + } + }; + client.logOutput = output; + LogHelper.addOutput(output, outputType); + } + } +} diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/admin/ExecCommandResponse.java b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/admin/ExecCommandResponse.java index 3ecd04d9..c7c0fd9d 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/admin/ExecCommandResponse.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/admin/ExecCommandResponse.java @@ -1,6 +1,8 @@ package ru.gravit.launchserver.socket.websocket.json.admin; import io.netty.channel.ChannelHandlerContext; +import ru.gravit.launcher.events.request.ErrorRequestEvent; +import ru.gravit.launcher.events.request.ExecCommandRequestEvent; import ru.gravit.launchserver.LaunchServer; import ru.gravit.launchserver.socket.Client; import ru.gravit.launchserver.socket.websocket.WebSocketService; @@ -17,14 +19,14 @@ public String getType() { @Override public void execute(WebSocketService service, ChannelHandlerContext ctx, Client client) { if (!client.isAuth) { - service.sendObject(ctx, new WebSocketService.ErrorResult("Access denied")); + service.sendObject(ctx, new ErrorRequestEvent("Access denied")); return; } if (!client.permissions.canAdmin) { - service.sendObject(ctx, new WebSocketService.ErrorResult("Access denied")); + service.sendObject(ctx, new ErrorRequestEvent("Access denied")); return; } LaunchServer.server.commandHandler.eval(cmd, false); - service.sendObject(ctx, new WebSocketService.SuccessResult("cmdExec")); + service.sendObject(ctx, new ExecCommandRequestEvent(true)); } } diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/auth/AuthResponse.java b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/auth/AuthResponse.java index f824bbe6..65aae7e9 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/auth/AuthResponse.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/auth/AuthResponse.java @@ -3,6 +3,7 @@ import io.netty.channel.ChannelHandlerContext; import ru.gravit.launcher.OshiHWID; import ru.gravit.launcher.events.request.AuthRequestEvent; +import ru.gravit.launcher.events.request.ErrorRequestEvent; import ru.gravit.launcher.profiles.ClientProfile; import ru.gravit.launchserver.LaunchServer; import ru.gravit.launchserver.auth.AuthException; @@ -14,8 +15,11 @@ import ru.gravit.launchserver.socket.websocket.WebSocketService; import ru.gravit.launchserver.socket.websocket.json.JsonResponseInterface; import ru.gravit.utils.helper.IOHelper; +import ru.gravit.utils.helper.SecurityHelper; import ru.gravit.utils.helper.VerifyHelper; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; import java.util.Collection; import java.util.UUID; @@ -25,6 +29,7 @@ public class AuthResponse implements JsonResponseInterface { public String customText; public String password; + public byte[] encryptedPassword; public AuthResponse(String login, String password, int authid, OshiHWID hwid) { this.login = login; @@ -55,10 +60,19 @@ public void execute(WebSocketService service, ChannelHandlerContext ctx, Client AuthProvider.authError(LaunchServer.server.config.authRejectString); return; } - if (authType != ConnectTypes.CLIENT &&!clientData.checkSign) { + if ((authType == null || authType == ConnectTypes.CLIENT) &&!clientData.checkSign) { AuthProvider.authError("Don't skip Launcher Update"); return; } + if(password == null) + { + try { + password = IOHelper.decode(SecurityHelper.newRSADecryptCipher(LaunchServer.server.privateKey). + doFinal(encryptedPassword)); + } catch (IllegalBlockSizeException | BadPaddingException ignored) { + throw new AuthException("Password decryption error"); + } + } clientData.permissions = LaunchServer.server.config.permissionsHandler.getPermissions(login); if(authType == ConnectTypes.BOT && !clientData.permissions.canBot) { @@ -86,9 +100,9 @@ public void execute(WebSocketService service, ChannelHandlerContext ctx, Client clientData.profile = p; } } - if (clientData.profile == null) { - throw new AuthException("You profile not found"); - } + //if (clientData.profile == null) { + // throw new AuthException("You profile not found"); + //} UUID uuid = LaunchServer.server.config.authHandler.auth(aresult); if(authType == ConnectTypes.CLIENT) LaunchServer.server.config.hwidHandler.check(hwid, aresult.username); @@ -100,7 +114,7 @@ public void execute(WebSocketService service, ChannelHandlerContext ctx, Client result.playerProfile = ProfileByUUIDResponse.getProfile(LaunchServer.server,uuid,aresult.username,client); service.sendObject(ctx, result); } catch (AuthException | HWIDException e) { - service.sendObject(ctx, new WebSocketService.ErrorResult(e.getMessage())); + service.sendObject(ctx, new ErrorRequestEvent(e.getMessage())); } } diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/auth/CheckServerResponse.java b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/auth/CheckServerResponse.java index c615542d..80a13120 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/auth/CheckServerResponse.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/auth/CheckServerResponse.java @@ -1,7 +1,8 @@ package ru.gravit.launchserver.socket.websocket.json.auth; import io.netty.channel.ChannelHandlerContext; -import ru.gravit.launcher.events.request.CheckServerEvent; +import ru.gravit.launcher.events.request.CheckServerRequestEvent; +import ru.gravit.launcher.events.request.ErrorRequestEvent; import ru.gravit.launchserver.LaunchServer; import ru.gravit.launchserver.auth.AuthException; import ru.gravit.launchserver.response.profile.ProfileByUUIDResponse; @@ -22,20 +23,20 @@ public String getType() { @Override public void execute(WebSocketService service, ChannelHandlerContext ctx, Client pClient) { - CheckServerEvent result = new CheckServerEvent(); + CheckServerRequestEvent result = new CheckServerRequestEvent(); try { result.uuid = LaunchServer.server.config.authHandler.checkServer(username, serverID); if(result.uuid != null) result.playerProfile = ProfileByUUIDResponse.getProfile(LaunchServer.server,result.uuid,username,client); } catch (AuthException e) { - service.sendObject(ctx, new WebSocketService.ErrorResult(e.getMessage())); + service.sendObject(ctx, new ErrorRequestEvent(e.getMessage())); return; } catch (Exception e) { LogHelper.error(e); - service.sendObject(ctx, new WebSocketService.ErrorResult("Internal authHandler error")); + service.sendObject(ctx, new ErrorRequestEvent("Internal authHandler error")); return; } - service.sendObject(ctx, new CheckServerEvent()); + service.sendObject(ctx, new CheckServerRequestEvent()); } } diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/auth/JoinServerResponse.java b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/auth/JoinServerResponse.java index 56eeb0d2..85aa3dd7 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/auth/JoinServerResponse.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/auth/JoinServerResponse.java @@ -1,6 +1,7 @@ package ru.gravit.launchserver.socket.websocket.json.auth; import io.netty.channel.ChannelHandlerContext; +import ru.gravit.launcher.events.request.ErrorRequestEvent; import ru.gravit.launcher.events.request.JoinServerRequestEvent; import ru.gravit.launchserver.LaunchServer; import ru.gravit.launchserver.auth.AuthException; @@ -25,11 +26,11 @@ public void execute(WebSocketService service, ChannelHandlerContext ctx, Client try { success = LaunchServer.server.config.authHandler.joinServer(username, accessToken, serverID); } catch (AuthException e) { - service.sendObject(ctx, new WebSocketService.ErrorResult(e.getMessage())); + service.sendObject(ctx, new ErrorRequestEvent(e.getMessage())); return; } catch (Exception e) { LogHelper.error(e); - service.sendObject(ctx, new WebSocketService.ErrorResult("Internal authHandler error")); + service.sendObject(ctx, new ErrorRequestEvent("Internal authHandler error")); return; } service.sendObject(ctx, new JoinServerRequestEvent(success)); diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/auth/ProfilesResponse.java b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/auth/ProfilesResponse.java index 778b1caa..e4610cc4 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/auth/ProfilesResponse.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/auth/ProfilesResponse.java @@ -1,6 +1,7 @@ package ru.gravit.launchserver.socket.websocket.json.auth; import io.netty.channel.ChannelHandlerContext; +import ru.gravit.launcher.events.request.ErrorRequestEvent; import ru.gravit.launcher.events.request.ProfilesRequestEvent; import ru.gravit.launcher.profiles.ClientProfile; import ru.gravit.launchserver.LaunchServer; @@ -18,9 +19,9 @@ public String getType() { @Override public void execute(WebSocketService service, ChannelHandlerContext ctx, Client client) throws Exception { - if(!client.isAuth) + if(!client.checkSign) { - service.sendObject(ctx, new WebSocketService.ErrorResult("Access denied")); + service.sendObject(ctx, new ErrorRequestEvent("Access denied")); return; } service.sendObject(ctx, new ProfilesRequestEvent((List) LaunchServer.server.getProfiles())); diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/auth/SetProfileResponse.java b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/auth/SetProfileResponse.java index a4490683..c12b5053 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/auth/SetProfileResponse.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/auth/SetProfileResponse.java @@ -1,6 +1,8 @@ package ru.gravit.launchserver.socket.websocket.json.auth; import io.netty.channel.ChannelHandlerContext; +import ru.gravit.launcher.events.request.ErrorRequestEvent; +import ru.gravit.launcher.events.request.SetProfileRequestEvent; import ru.gravit.launcher.profiles.ClientProfile; import ru.gravit.launchserver.LaunchServer; import ru.gravit.launchserver.socket.Client; @@ -20,21 +22,21 @@ public String getType() { public void execute(WebSocketService service, ChannelHandlerContext ctx, Client client) throws Exception { if(!client.isAuth) { - service.sendObject(ctx, new WebSocketService.ErrorResult("Access denied")); + service.sendObject(ctx, new ErrorRequestEvent("Access denied")); return; } Collection profiles = LaunchServer.server.getProfiles(); for (ClientProfile p : profiles) { if (p.getTitle().equals(this.client)) { if (!p.isWhitelistContains(client.username)) { - service.sendObject(ctx, new WebSocketService.ErrorResult(LaunchServer.server.config.whitelistRejectString)); + service.sendObject(ctx, new ErrorRequestEvent(LaunchServer.server.config.whitelistRejectString)); return; } client.profile = p; - service.sendObject(ctx, new WebSocketService.SuccessResult(getType())); - break; + service.sendObject(ctx, new SetProfileRequestEvent(p)); + return; } } - service.sendObject(ctx, new WebSocketService.ErrorResult("Profile not found")); + service.sendObject(ctx, new ErrorRequestEvent("Profile not found")); } } diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/update/LauncherResponse.java b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/update/LauncherResponse.java index 956968b5..59deb921 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/update/LauncherResponse.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/update/LauncherResponse.java @@ -1,6 +1,7 @@ package ru.gravit.launchserver.socket.websocket.json.update; import io.netty.channel.ChannelHandlerContext; +import ru.gravit.launcher.events.request.ErrorRequestEvent; import ru.gravit.launcher.events.request.LauncherRequestEvent; import ru.gravit.launchserver.LaunchServer; import ru.gravit.launchserver.socket.Client; @@ -14,19 +15,24 @@ public class LauncherResponse implements JsonResponseInterface { public Version version; public String hash; + public byte[] digest; public int launcher_type; //REPLACED TO REAL URL - public static final String JAR_URL = "http://localhost:9752/Launcher.jar"; - public static final String EXE_URL = "http://localhost:9752/Launcher.exe"; + public static final String JAR_URL = LaunchServer.server.config.netty.launcherURL; + public static final String EXE_URL = LaunchServer.server.config.netty.launcherEXEURL; @Override public String getType() { - return "launcherUpdate"; + return "launcher"; } @Override public void execute(WebSocketService service, ChannelHandlerContext ctx, Client client) { - byte[] bytes = Base64.getDecoder().decode(hash); + byte[] bytes; + if(hash != null) + bytes = Base64.getDecoder().decode(hash); + else + bytes = digest; if (launcher_type == 1) // JAR { byte[] hash = LaunchServer.server.launcherBinary.getBytes().getDigest(); @@ -47,7 +53,7 @@ public void execute(WebSocketService service, ChannelHandlerContext ctx, Client } else { service.sendObjectAndClose(ctx, new LauncherRequestEvent(true, EXE_URL)); } - } else service.sendObject(ctx, new WebSocketService.ErrorResult("Request launcher type error")); + } else service.sendObject(ctx, new ErrorRequestEvent("Request launcher type error")); } diff --git a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/update/UpdateListResponse.java b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/update/UpdateListResponse.java index aac849f6..743c71b4 100644 --- a/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/update/UpdateListResponse.java +++ b/LaunchServer/src/main/java/ru/gravit/launchserver/socket/websocket/json/update/UpdateListResponse.java @@ -1,15 +1,19 @@ package ru.gravit.launchserver.socket.websocket.json.update; import io.netty.channel.ChannelHandlerContext; +import ru.gravit.launcher.events.request.ErrorRequestEvent; import ru.gravit.launcher.events.request.UpdateListRequestEvent; import ru.gravit.launcher.hasher.HashedDir; +import ru.gravit.launcher.serialize.signed.SignedObjectHolder; import ru.gravit.launchserver.LaunchServer; import ru.gravit.launchserver.socket.Client; import ru.gravit.launchserver.socket.websocket.WebSocketService; import ru.gravit.launchserver.socket.websocket.json.JsonResponseInterface; +import java.util.HashSet; +import java.util.Map; + public class UpdateListResponse implements JsonResponseInterface { - public String dir; @Override public String getType() { @@ -19,11 +23,13 @@ public String getType() { @Override public void execute(WebSocketService service, ChannelHandlerContext ctx, Client client) { if (!client.isAuth) { - service.sendObject(ctx, new WebSocketService.ErrorResult("Access denied")); + service.sendObject(ctx, new ErrorRequestEvent("Access denied")); return; } - HashedDir hdir = LaunchServer.server.updatesDirMap.get(dir).object; - service.sendObject(ctx, new UpdateListRequestEvent(hdir)); + HashSet set = new HashSet<>(); + for(Map.Entry> entry : LaunchServer.server.updatesDirMap.entrySet()) + set.add(entry.getKey()); + service.sendObject(ctx, new UpdateListRequestEvent(set)); } } diff --git a/LaunchServer/src/main/resources/ru/gravit/launchserver/defaults/proguard.cfg b/LaunchServer/src/main/resources/ru/gravit/launchserver/defaults/proguard.cfg index 3c081430..9d82a488 100644 --- a/LaunchServer/src/main/resources/ru/gravit/launchserver/defaults/proguard.cfg +++ b/LaunchServer/src/main/resources/ru/gravit/launchserver/defaults/proguard.cfg @@ -31,6 +31,11 @@ ; } +-keepclassmembers @ru.gravit.launcher.LauncherNetworkAPI class ** { + ; + ; +} + -keepclassmembers class ** { @ru.gravit.launcher.LauncherAPI ; @@ -38,6 +43,13 @@ ; } +-keepclassmembers class ** { + @ru.gravit.launcher.LauncherNetworkAPI + ; + @ru.gravit.launcher.LauncherNetworkAPI + ; +} + -keepclassmembers public class ** { public static void main(java.lang.String[]); public static void premain(java.lang.String, java.lang.instrument.Instrumentation); diff --git a/Launcher/runtime/dialog/dialog.js b/Launcher/runtime/dialog/dialog.js index b193e69f..3007dea9 100644 --- a/Launcher/runtime/dialog/dialog.js +++ b/Launcher/runtime/dialog/dialog.js @@ -215,7 +215,7 @@ function doAuth(login, rsaPassword) { overlay.show(processing.overlay, function (event) { FunctionalBridge.getHWID.join(); makeAuthRequest(login, rsaPassword, function (result) { - loginData = { pp: result.pp , accessToken: result.accessToken, permissions: result.permissions}; + loginData = { pp: result.playerProfile , accessToken: result.accessToken, permissions: result.permissions}; overlay.hide(0, function () { setCurrentScene(menuScene); diff --git a/Launcher/runtime/dialog/overlay/settings/settings.js b/Launcher/runtime/dialog/overlay/settings/settings.js index d49d48bd..1ea44f04 100644 --- a/Launcher/runtime/dialog/overlay/settings/settings.js +++ b/Launcher/runtime/dialog/overlay/settings/settings.js @@ -29,9 +29,9 @@ var settingsClass = Java.extend(LauncherSettingsClass.static, { setRAM: function(ram) { if (ram>762&&ram<1024){ - settings.ram = java.lang.Math["min(int,int)"](ram, FunctionalBridge.getTotalMemory()); + settings.ram = java.lang.Math["min(int,int)"](ram, FunctionalBridge.getJVMTotalMemory()); }else{ - settings.ram = java.lang.Math["min(int,int)"](((ram / 256) | 0) * 256, FunctionalBridge.getTotalMemory()); + settings.ram = java.lang.Math["min(int,int)"](((ram / 256) | 0) * 256, FunctionalBridge.getJVMTotalMemory()); } }, }); diff --git a/Launcher/runtime/engine/api.js b/Launcher/runtime/engine/api.js index d7cbcae5..a1bb7b7a 100644 --- a/Launcher/runtime/engine/api.js +++ b/Launcher/runtime/engine/api.js @@ -60,20 +60,8 @@ var LauncherSettings = LauncherSettingsClass.static; // Helper JS class API imports var JSApplication = null; -var CheckComboBox = null; -var CheckModel = null; -var IndexedCheckModel = null; -var CheckComboBoxSkin = null; -var RingProgressIndicator = null; -var RingProgressIndicatorSkin = null; if (typeof JSApplicationClass !== 'undefined') { JSApplication = JSApplicationClass.static; - CheckComboBox = CheckComboBoxClass.static; - CheckModel = CheckModelClass.static; - IndexedCheckModel = IndexedCheckModelClass.static; - CheckComboBoxSkin = CheckComboBoxSkinClass.static; - RingProgressIndicator = RingProgressIndicatorClass.static; - RingProgressIndicatorSkin = RingProgressIndicatorSkinClass.static; } // API wrapper diff --git a/Launcher/src/main/java/ru/gravit/launcher/LauncherEngine.java b/Launcher/src/main/java/ru/gravit/launcher/LauncherEngine.java index 273cc5a2..37a794fa 100644 --- a/Launcher/src/main/java/ru/gravit/launcher/LauncherEngine.java +++ b/Launcher/src/main/java/ru/gravit/launcher/LauncherEngine.java @@ -71,8 +71,6 @@ public void start(String... args) throws Throwable { throw new IllegalStateException("Launcher has been already started"); Launcher.modulesManager.initModules(); runtimeProvider.preLoad(); - FunctionalBridge.worker = new RequestWorker(); - CommonHelper.newThread("Task Worker", true, FunctionalBridge.worker).start(); FunctionalBridge.getHWID = CommonHelper.newThread("GetHWID Thread", true, FunctionalBridge::getHWID); FunctionalBridge.getHWID.start(); LogHelper.debug("Dir: %s", DirBridge.dir); diff --git a/Launcher/src/main/java/ru/gravit/launcher/RequestWorker.java b/Launcher/src/main/java/ru/gravit/launcher/RequestWorker.java deleted file mode 100644 index bbb44ead..00000000 --- a/Launcher/src/main/java/ru/gravit/launcher/RequestWorker.java +++ /dev/null @@ -1,30 +0,0 @@ -package ru.gravit.launcher; - -import ru.gravit.utils.helper.LogHelper; - -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; - -public class RequestWorker implements Runnable { - public RequestWorker() { - queue = new LinkedBlockingQueue<>(64); - } - - public BlockingQueue queue; - - @Override - public void run() { - LogHelper.debug("FX Task Thread start"); - while (!Thread.interrupted()) { - try { - Runnable task; - task = queue.take(); - task.run(); - } catch (InterruptedException e) { - LogHelper.error(e); - return; - } - } - LogHelper.debug("FX Task Thread done"); - } -} diff --git a/Launcher/src/main/java/ru/gravit/launcher/client/FunctionalBridge.java b/Launcher/src/main/java/ru/gravit/launcher/client/FunctionalBridge.java index 882855e0..f055ebda 100644 --- a/Launcher/src/main/java/ru/gravit/launcher/client/FunctionalBridge.java +++ b/Launcher/src/main/java/ru/gravit/launcher/client/FunctionalBridge.java @@ -3,7 +3,7 @@ import javafx.concurrent.Task; import ru.gravit.launcher.HWID; import ru.gravit.launcher.LauncherAPI; -import ru.gravit.launcher.RequestWorker; +import ru.gravit.launcher.guard.LauncherGuardManager; import ru.gravit.launcher.hasher.FileNameMatcher; import ru.gravit.launcher.hasher.HashedDir; import ru.gravit.launcher.hwid.OshiHWIDProvider; @@ -13,17 +13,18 @@ import ru.gravit.launcher.request.update.LegacyLauncherRequest; import ru.gravit.launcher.request.websockets.RequestInterface; import ru.gravit.launcher.serialize.signed.SignedObjectHolder; -import ru.gravit.utils.helper.LogHelper; import java.io.IOException; import java.nio.file.Path; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicReference; public class FunctionalBridge { @LauncherAPI public static LauncherSettings settings; @LauncherAPI - public static RequestWorker worker; + public static ExecutorService worker = Executors.newWorkStealingPool(); @LauncherAPI public static OshiHWIDProvider hwidProvider = new OshiHWIDProvider(); @LauncherAPI @@ -64,11 +65,7 @@ public static void makeJsonRequest(RequestInterface request, Runnable callback) @LauncherAPI public static void startTask(@SuppressWarnings("rawtypes") Task task) { - try { - worker.queue.put(task); - } catch (InterruptedException e) { - LogHelper.error(e); - } + worker.execute(task); } @LauncherAPI @@ -83,6 +80,24 @@ public static long getTotalMemory() { return hwidProvider.getTotalMemory() >> 20; } + @LauncherAPI + public static int getClientJVMBits() + { + return LauncherGuardManager.guard.getClientJVMBits(); + } + @LauncherAPI + public static long getJVMTotalMemory() + { + if(getClientJVMBits() == 32) + { + return Math.min(getTotalMemory(),1536); + } + else + { + return getTotalMemory(); + } + } + @LauncherAPI public static HasherStore getDefaultHasherStore() { return HasherManager.getDefaultStore(); diff --git a/Launcher/src/main/java/ru/gravit/launcher/guard/LauncherGuardInterface.java b/Launcher/src/main/java/ru/gravit/launcher/guard/LauncherGuardInterface.java index 7e793db0..fb6e8fdd 100644 --- a/Launcher/src/main/java/ru/gravit/launcher/guard/LauncherGuardInterface.java +++ b/Launcher/src/main/java/ru/gravit/launcher/guard/LauncherGuardInterface.java @@ -3,11 +3,11 @@ import ru.gravit.launcher.client.ClientLauncherContext; import java.nio.file.Path; -import java.util.Collection; public interface LauncherGuardInterface { String getName(); Path getJavaBinPath(); + int getClientJVMBits(); void init(boolean clientInstance); void addCustomParams(ClientLauncherContext context); void addCustomEnv(ClientLauncherContext context); diff --git a/Launcher/src/main/java/ru/gravit/launcher/guard/LauncherJavaGuard.java b/Launcher/src/main/java/ru/gravit/launcher/guard/LauncherJavaGuard.java index 0e2a0d18..77c4606a 100644 --- a/Launcher/src/main/java/ru/gravit/launcher/guard/LauncherJavaGuard.java +++ b/Launcher/src/main/java/ru/gravit/launcher/guard/LauncherJavaGuard.java @@ -7,7 +7,6 @@ import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Collection; import java.util.Collections; public class LauncherJavaGuard implements LauncherGuardInterface { @@ -24,6 +23,11 @@ public Path getJavaBinPath() { return IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home"))); } + @Override + public int getClientJVMBits() { + return JVMHelper.OS_BITS; + } + @Override public void init(boolean clientInstance) { diff --git a/Launcher/src/main/java/ru/gravit/launcher/guard/LauncherNoGuard.java b/Launcher/src/main/java/ru/gravit/launcher/guard/LauncherNoGuard.java index 7ff825f2..9bd1923c 100644 --- a/Launcher/src/main/java/ru/gravit/launcher/guard/LauncherNoGuard.java +++ b/Launcher/src/main/java/ru/gravit/launcher/guard/LauncherNoGuard.java @@ -2,11 +2,11 @@ import ru.gravit.launcher.client.ClientLauncherContext; import ru.gravit.utils.helper.IOHelper; +import ru.gravit.utils.helper.JVMHelper; import ru.gravit.utils.helper.LogHelper; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Collection; import java.util.Collections; public class LauncherNoGuard implements LauncherGuardInterface { @@ -20,6 +20,11 @@ public Path getJavaBinPath() { return IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home"))); } + @Override + public int getClientJVMBits() { + return JVMHelper.JVM_BITS; + } + @Override public void init(boolean clientInstance) { LogHelper.warning("Using noGuard interface"); diff --git a/Launcher/src/main/java/ru/gravit/launcher/guard/LauncherWrapperGuard.java b/Launcher/src/main/java/ru/gravit/launcher/guard/LauncherWrapperGuard.java index 5f55acfb..bd97ebbb 100644 --- a/Launcher/src/main/java/ru/gravit/launcher/guard/LauncherWrapperGuard.java +++ b/Launcher/src/main/java/ru/gravit/launcher/guard/LauncherWrapperGuard.java @@ -9,8 +9,6 @@ import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Base64; -import java.util.Collection; import java.util.Collections; import java.util.Map; @@ -32,6 +30,11 @@ public Path getJavaBinPath() { return IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home"))); } + @Override + public int getClientJVMBits() { + return JVMHelper.JVM_BITS; + } + @Override public void init(boolean clientInstance) { try { diff --git a/Launcher/src/main/java/ru/gravit/launcher/gui/JSRuntimeProvider.java b/Launcher/src/main/java/ru/gravit/launcher/gui/JSRuntimeProvider.java index fc99a3c0..a65c9330 100644 --- a/Launcher/src/main/java/ru/gravit/launcher/gui/JSRuntimeProvider.java +++ b/Launcher/src/main/java/ru/gravit/launcher/gui/JSRuntimeProvider.java @@ -5,12 +5,6 @@ import ru.gravit.launcher.LauncherAPI; import ru.gravit.launcher.LauncherConfig; import ru.gravit.launcher.client.*; -import ru.gravit.launcher.gui.choosebox.CheckComboBox; -import ru.gravit.launcher.gui.choosebox.CheckComboBoxSkin; -import ru.gravit.launcher.gui.choosebox.CheckModel; -import ru.gravit.launcher.gui.choosebox.IndexedCheckModel; -import ru.gravit.launcher.gui.indicator.RingProgressIndicator; -import ru.gravit.launcher.gui.indicator.RingProgressIndicatorSkin; import ru.gravit.launcher.hasher.FileNameMatcher; import ru.gravit.launcher.hasher.HashedDir; import ru.gravit.launcher.hasher.HashedEntry; @@ -117,12 +111,6 @@ public static void addLauncherClassBindings(Map bindings) { try { Class.forName("javafx.application.Application"); bindings.put("JSApplicationClass", JSApplication.class); - bindings.put("RingProgressIndicatorClass", RingProgressIndicator.class); - bindings.put("RingProgressIndicatorSkinClass", RingProgressIndicatorSkin.class); - bindings.put("CheckComboBoxClass", CheckComboBox.class); - bindings.put("CheckModelClass", CheckModel.class); - bindings.put("IndexedCheckModelClass", IndexedCheckModel.class); - bindings.put("CheckComboBoxSkinClass", CheckComboBoxSkin.class); } catch (ClassNotFoundException ignored) { LogHelper.warning("JavaFX API isn't available"); } diff --git a/Launcher/src/main/java/ru/gravit/launcher/gui/choosebox/CheckBitSetModelBase.java b/Launcher/src/main/java/ru/gravit/launcher/gui/choosebox/CheckBitSetModelBase.java deleted file mode 100644 index 58203cc6..00000000 --- a/Launcher/src/main/java/ru/gravit/launcher/gui/choosebox/CheckBitSetModelBase.java +++ /dev/null @@ -1,233 +0,0 @@ -package ru.gravit.launcher.gui.choosebox; - -import com.sun.javafx.collections.MappingChange; -import com.sun.javafx.collections.NonIterableChange; -import com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList; -import javafx.beans.property.BooleanProperty; -import javafx.beans.property.SimpleBooleanProperty; -import javafx.collections.ListChangeListener; -import javafx.collections.ObservableList; - -import java.util.BitSet; -import java.util.Map; - -abstract class CheckBitSetModelBase implements IndexedCheckModel { - private final Map itemBooleanMap; - - private final BitSet checkedIndices; - private final ReadOnlyUnbackedObservableList checkedIndicesList; - private final ReadOnlyUnbackedObservableList checkedItemsList; - - CheckBitSetModelBase(final Map itemBooleanMap) { - this.itemBooleanMap = itemBooleanMap; - - this.checkedIndices = new BitSet(); - - this.checkedIndicesList = new ReadOnlyUnbackedObservableList() { - @Override - public boolean contains(Object o) { - if (o instanceof Number) { - Number n = (Number) o; - int index = n.intValue(); - - return index >= 0 && index < checkedIndices.length() && checkedIndices.get(index); - } - - return false; - } - - @Override - public Integer get(int index) { - if (index < 0 || index >= getItemCount()) - return -1; - - for (int pos = 0, val = checkedIndices.nextSetBit(0); val >= 0 - || pos == index; pos++, val = checkedIndices.nextSetBit(val + 1)) - if (pos == index) - return val; - - return -1; - } - - @Override - public int size() { - return checkedIndices.cardinality(); - } - }; - - this.checkedItemsList = new ReadOnlyUnbackedObservableList() { - @Override - public T get(int i) { - int pos = checkedIndicesList.get(i); - if (pos < 0 || pos >= getItemCount()) - return null; - return getItem(pos); - } - - @Override - public int size() { - return checkedIndices.cardinality(); - } - }; - - final MappingChange.Map map = this::getItem; - - checkedIndicesList.addListener((ListChangeListener) c -> { - boolean hasRealChangeOccurred = false; - while (c.next() && !hasRealChangeOccurred) - hasRealChangeOccurred = c.wasAdded() || c.wasRemoved(); - - if (hasRealChangeOccurred) { - c.reset(); - checkedItemsList.callObservers(new MappingChange<>(c, map, checkedItemsList)); - } - c.reset(); - }); - getCheckedItems().addListener((ListChangeListener) c -> { - while (c.next()) { - if (c.wasAdded()) - for (T item : c.getAddedSubList()) { - BooleanProperty p = getItemBooleanProperty(item); - if (p != null) - p.set(true); - } - - if (c.wasRemoved()) - for (T item : c.getRemoved()) { - BooleanProperty p = getItemBooleanProperty(item); - if (p != null) - p.set(false); - } - } - }); - } - - @Override - public void check(int index) { - if (index < 0 || index >= getItemCount()) - return; - checkedIndices.set(index); - final int changeIndex = checkedIndicesList.indexOf(index); - checkedIndicesList.callObservers( - new NonIterableChange.SimpleAddChange<>(changeIndex, changeIndex + 1, checkedIndicesList)); - } - - @Override - public void check(T item) { - int index = getItemIndex(item); - check(index); - } - - @Override - public void checkAll() { - for (int i = 0; i < getItemCount(); i++) - check(i); - } - - @Override - public void checkIndices(int... indices) { - for (int indice : indices) - check(indice); - } - - @Override - public void clearCheck(int index) { - if (index < 0 || index >= getItemCount()) - return; - checkedIndices.clear(index); - - final int changeIndex = checkedIndicesList.indexOf(index); - checkedIndicesList.callObservers( - new NonIterableChange.SimpleRemovedChange<>(changeIndex, changeIndex, index, checkedIndicesList)); - } - - @Override - public void clearCheck(T item) { - int index = getItemIndex(item); - clearCheck(index); - } - - @Override - public void clearChecks() { - for (int index = 0; index < checkedIndices.length(); index++) - clearCheck(index); - } - - @Override - public ObservableList getCheckedIndices() { - return checkedIndicesList; - } - - @Override - public ObservableList getCheckedItems() { - return checkedItemsList; - } - - @Override - public abstract T getItem(int index); - - BooleanProperty getItemBooleanProperty(T item) { - return itemBooleanMap.get(item); - } - - @Override - public abstract int getItemCount(); - - @Override - public abstract int getItemIndex(T item); - - @Override - public boolean isChecked(int index) { - return checkedIndices.get(index); - } - - @Override - public boolean isChecked(T item) { - int index = getItemIndex(item); - return isChecked(index); - } - - @Override - public boolean isEmpty() { - return checkedIndices.isEmpty(); - } - - @Override - public void toggleCheckState(int index) { - if (isChecked(index)) - clearCheck(index); - else - check(index); - } - - @Override - public void toggleCheckState(T item) { - int index = getItemIndex(item); - toggleCheckState(index); - } - - protected void updateMap() { - itemBooleanMap.clear(); - for (int i = 0; i < getItemCount(); i++) { - final int index = i; - final T item = getItem(index); - - final BooleanProperty booleanProperty = new SimpleBooleanProperty(item, "selected", false); //$NON-NLS-1$ - itemBooleanMap.put(item, booleanProperty); - - booleanProperty.addListener(o -> { - if (booleanProperty.get()) { - checkedIndices.set(index); - final int changeIndex1 = checkedIndicesList.indexOf(index); - checkedIndicesList.callObservers(new NonIterableChange.SimpleAddChange<>(changeIndex1, - changeIndex1 + 1, checkedIndicesList)); - } else { - final int changeIndex2 = checkedIndicesList.indexOf(index); - checkedIndices.clear(index); - checkedIndicesList.callObservers(new NonIterableChange.SimpleRemovedChange<>(changeIndex2, - changeIndex2, index, checkedIndicesList)); - } - }); - } - } -} \ No newline at end of file diff --git a/Launcher/src/main/java/ru/gravit/launcher/gui/choosebox/CheckComboBox.java b/Launcher/src/main/java/ru/gravit/launcher/gui/choosebox/CheckComboBox.java deleted file mode 100644 index 262d1fde..00000000 --- a/Launcher/src/main/java/ru/gravit/launcher/gui/choosebox/CheckComboBox.java +++ /dev/null @@ -1,142 +0,0 @@ -package ru.gravit.launcher.gui.choosebox; - -import javafx.beans.property.*; -import javafx.collections.FXCollections; -import javafx.collections.ListChangeListener; -import javafx.collections.ObservableList; -import javafx.scene.control.Skin; -import javafx.util.StringConverter; -import ru.gravit.launcher.LauncherAPI; - -import java.util.HashMap; -import java.util.Map; - -public class CheckComboBox extends ControlsFXControl { - private static class CheckComboBoxBitSetCheckModel extends CheckBitSetModelBase { - private final ObservableList items; - - CheckComboBoxBitSetCheckModel(final ObservableList items, final Map itemBooleanMap) { - super(itemBooleanMap); - - this.items = items; - this.items.addListener((ListChangeListener) c -> updateMap()); - - updateMap(); - } - - @Override - public T getItem(int index) { - return items.get(index); - } - - @Override - public int getItemCount() { - return items.size(); - } - - @Override - public int getItemIndex(T item) { - return items.indexOf(item); - } - } - - private final ObservableList items; - private final Map itemBooleanMap; - private CheckComboBoxSkin checkComboBoxSkin; - private ObjectProperty> checkModel = new SimpleObjectProperty<>(this, "checkModel"); - private ObjectProperty> converter = new SimpleObjectProperty<>(this, - "converter"); - private StringProperty title = new SimpleStringProperty(null); - - public CheckComboBox() { - this(null); - } - - public CheckComboBox(final ObservableList items) { - final int initialSize = items == null ? 32 : items.size(); - - this.itemBooleanMap = new HashMap<>(initialSize); - this.items = items == null ? FXCollections.observableArrayList() : items; - setCheckModel(new CheckComboBoxBitSetCheckModel<>(this.items, itemBooleanMap)); - } - - @LauncherAPI - public final ObjectProperty> checkModelProperty() { - return checkModel; - } - - @LauncherAPI - public final ObjectProperty> converterProperty() { - return converter; - } - - @Override - protected Skin createDefaultSkin() { - checkComboBoxSkin = new CheckComboBoxSkin<>(this); - return checkComboBoxSkin; - } - - @LauncherAPI - public final IndexedCheckModel getCheckModel() { - return checkModel == null ? null : checkModel.get(); - } - - @LauncherAPI - public final StringConverter getConverter() { - return converterProperty().get(); - } - - @LauncherAPI - public BooleanProperty getItemBooleanProperty(int index) { - if (index < 0 || index >= items.size()) - return null; - return getItemBooleanProperty(getItems().get(index)); - } - - @LauncherAPI - public BooleanProperty getItemBooleanProperty(T item) { - return itemBooleanMap.get(item); - } - - @LauncherAPI - public ObservableList getItems() { - return items; - } - - @LauncherAPI - public final String getTitle() { - return title.getValue(); - } - - @LauncherAPI - public void hide() { - if (checkComboBoxSkin != null) - checkComboBoxSkin.hide(); - } - - @LauncherAPI - public final void setCheckModel(IndexedCheckModel value) { - checkModelProperty().set(value); - } - - @LauncherAPI - public final void setConverter(StringConverter value) { - converterProperty().set(value); - } - - @LauncherAPI - public final void setTitle(String value) { - title.setValue(value); - } - - @LauncherAPI - public void show() { - if (checkComboBoxSkin != null) - checkComboBoxSkin.show(); - } - - @LauncherAPI - public final StringProperty titleProperty() { - return title; - } -} diff --git a/Launcher/src/main/java/ru/gravit/launcher/gui/choosebox/CheckComboBoxSkin.java b/Launcher/src/main/java/ru/gravit/launcher/gui/choosebox/CheckComboBoxSkin.java deleted file mode 100644 index 3a826a39..00000000 --- a/Launcher/src/main/java/ru/gravit/launcher/gui/choosebox/CheckComboBoxSkin.java +++ /dev/null @@ -1,172 +0,0 @@ -package ru.gravit.launcher.gui.choosebox; - -import com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList; -import com.sun.javafx.scene.control.behavior.BehaviorBase; -import com.sun.javafx.scene.control.skin.BehaviorSkinBase; -import com.sun.javafx.scene.control.skin.ComboBoxListViewSkin; -import javafx.collections.ListChangeListener; -import javafx.collections.ObservableList; -import javafx.scene.control.ComboBox; -import javafx.scene.control.ListCell; -import javafx.scene.control.ListView; -import javafx.scene.control.Skin; -import javafx.scene.control.cell.CheckBoxListCell; -import javafx.scene.input.KeyCode; -import ru.gravit.launcher.LauncherAPI; - -import java.util.Collections; - -public class CheckComboBoxSkin extends BehaviorSkinBase, BehaviorBase>> { - - private final ComboBox comboBox; - private final ListCell buttonCell; - - private final CheckComboBox control; - private final ReadOnlyUnbackedObservableList selectedItems; - - @SuppressWarnings("unchecked") - public CheckComboBoxSkin(final CheckComboBox control) { - super(control, new BehaviorBase<>(control, Collections.emptyList())); - - this.control = control; - ObservableList items = control.getItems(); - - ReadOnlyUnbackedObservableList selectedIndices = (ReadOnlyUnbackedObservableList) control.getCheckModel().getCheckedIndices(); - selectedItems = (ReadOnlyUnbackedObservableList) control.getCheckModel().getCheckedItems(); - - comboBox = new ComboBox(items) { - @Override - protected javafx.scene.control.Skin createDefaultSkin() { - return createComboBoxListViewSkin(this); - } - }; - comboBox.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE); - - comboBox.setCellFactory(listView -> { - CheckBoxListCell result = new CheckBoxListCell<>(control::getItemBooleanProperty); - result.focusedProperty().addListener((o, ov, nv) -> { - if (nv) - result.getParent().requestFocus(); - }); - result.setOnMouseClicked(e -> { - T item = result.getItem(); - if (control.getCheckModel().isChecked(item)) - control.getCheckModel().clearCheck(item); - else - control.getCheckModel().check(item); - }); - result.converterProperty().bind(control.converterProperty()); - return result; - }); - - buttonCell = new ListCell() { - @Override - protected void updateItem(T item, boolean empty) { - setText(getTextString()); - } - }; - comboBox.setButtonCell(buttonCell); - comboBox.setValue((T) getTextString()); - - selectedIndices.addListener((ListChangeListener) c -> buttonCell.updateIndex(0)); - - getChildren().add(comboBox); - } - - private String buildString() { - final StringBuilder sb = new StringBuilder(); - for (int i = 0, max = selectedItems.size(); i < max; i++) { - T item = selectedItems.get(i); - if (control.getConverter() == null) - sb.append(item); - else - sb.append(control.getConverter().toString(item)); - if (i < max - 1) - sb.append(", "); //$NON-NLS-1$ - } - return sb.toString(); - } - - @LauncherAPI - @Override - protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, - double leftInset) { - return getSkinnable().prefHeight(width); - } - - @LauncherAPI - @Override - protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, - double leftInset) { - return getSkinnable().prefWidth(height); - } - - @LauncherAPI - @Override - protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, - double leftInset) { - return comboBox.minHeight(width); - } - - @LauncherAPI - @Override - protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, - double leftInset) { - return comboBox.minWidth(height); - } - - @LauncherAPI - @Override - protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, - double leftInset) { - return comboBox.prefHeight(width); - } - - @LauncherAPI - @Override - protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, - double leftInset) { - return comboBox.prefWidth(height); - } - - private Skin createComboBoxListViewSkin(ComboBox comboBox) { - final ComboBoxListViewSkin comboBoxListViewSkin = new ComboBoxListViewSkin(comboBox) { - @Override - protected boolean isHideOnClickEnabled() { - return false; - } - }; - @SuppressWarnings("unchecked") final ListView listView = (ListView) comboBoxListViewSkin.getPopupContent(); - listView.setOnKeyPressed(e -> { - if (e.getCode() == KeyCode.SPACE) { - T item = listView.getSelectionModel().getSelectedItem(); - if (item != null) { - final IndexedCheckModel checkModel = control.getCheckModel(); - if (checkModel != null) - checkModel.toggleCheckState(item); - } - } else if (e.getCode() == KeyCode.ESCAPE) - hide(); - }); - return comboBoxListViewSkin; - } - - @LauncherAPI - protected String getTextString() { - - if (control.getTitle() != null) - return control.getTitle(); - return buildString(); - - } - - @LauncherAPI - public void hide() { - comboBox.hide(); - } - - @LauncherAPI - public void show() { - comboBox.show(); - } -} diff --git a/Launcher/src/main/java/ru/gravit/launcher/gui/choosebox/CheckModel.java b/Launcher/src/main/java/ru/gravit/launcher/gui/choosebox/CheckModel.java deleted file mode 100644 index 33a33e45..00000000 --- a/Launcher/src/main/java/ru/gravit/launcher/gui/choosebox/CheckModel.java +++ /dev/null @@ -1,33 +0,0 @@ -package ru.gravit.launcher.gui.choosebox; - -import javafx.collections.ObservableList; -import ru.gravit.launcher.LauncherAPI; - -public interface CheckModel { - @LauncherAPI - void check(T item); - - @LauncherAPI - void checkAll(); - - @LauncherAPI - void clearCheck(T item); - - @LauncherAPI - void clearChecks(); - - @LauncherAPI - ObservableList getCheckedItems(); - - @LauncherAPI - int getItemCount(); - - @LauncherAPI - boolean isChecked(T item); - - @LauncherAPI - boolean isEmpty(); - - @LauncherAPI - void toggleCheckState(T item); -} diff --git a/Launcher/src/main/java/ru/gravit/launcher/gui/choosebox/ControlsFXControl.java b/Launcher/src/main/java/ru/gravit/launcher/gui/choosebox/ControlsFXControl.java deleted file mode 100644 index 82353bba..00000000 --- a/Launcher/src/main/java/ru/gravit/launcher/gui/choosebox/ControlsFXControl.java +++ /dev/null @@ -1,20 +0,0 @@ -package ru.gravit.launcher.gui.choosebox; - -import javafx.scene.control.Control; - -abstract class ControlsFXControl extends Control { - - private String stylesheet; - - public ControlsFXControl() { - - } - - protected final String getUserAgentStylesheet(Class clazz, String fileName) { - - if (stylesheet == null) - stylesheet = clazz.getResource(fileName).toExternalForm(); - - return stylesheet; - } -} diff --git a/Launcher/src/main/java/ru/gravit/launcher/gui/choosebox/IndexedCheckModel.java b/Launcher/src/main/java/ru/gravit/launcher/gui/choosebox/IndexedCheckModel.java deleted file mode 100644 index 5d661000..00000000 --- a/Launcher/src/main/java/ru/gravit/launcher/gui/choosebox/IndexedCheckModel.java +++ /dev/null @@ -1,31 +0,0 @@ -package ru.gravit.launcher.gui.choosebox; - -import javafx.collections.ObservableList; -import ru.gravit.launcher.LauncherAPI; - -public interface IndexedCheckModel extends CheckModel { - @LauncherAPI - void check(int index); - - @LauncherAPI - void checkIndices(int... indices); - - @LauncherAPI - void clearCheck(int index); - - @LauncherAPI - ObservableList getCheckedIndices(); - - @LauncherAPI - T getItem(int index); - - @LauncherAPI - int getItemIndex(T item); - - @LauncherAPI - boolean isChecked(int index); - - @LauncherAPI - void toggleCheckState(int index); - -} \ No newline at end of file diff --git a/Launcher/src/main/java/ru/gravit/launcher/gui/indicator/ProgressCircleIndicator.java b/Launcher/src/main/java/ru/gravit/launcher/gui/indicator/ProgressCircleIndicator.java deleted file mode 100644 index bf7d4a2e..00000000 --- a/Launcher/src/main/java/ru/gravit/launcher/gui/indicator/ProgressCircleIndicator.java +++ /dev/null @@ -1,86 +0,0 @@ -package ru.gravit.launcher.gui.indicator; - -import com.sun.javafx.css.converters.SizeConverter; -import javafx.beans.property.DoubleProperty; -import javafx.css.CssMetaData; -import javafx.css.Styleable; -import javafx.css.StyleableDoubleProperty; -import javafx.css.StyleableProperty; -import javafx.scene.control.Control; -import javafx.scene.control.ProgressIndicator; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -abstract class ProgressCircleIndicator extends ProgressIndicator { - public ProgressCircleIndicator() { - this.getStylesheets().add(ProgressCircleIndicator.class.getResource("/runtime/launcher/overlay/update/circleprogress.css").toExternalForm()); - } - - public final void setInnerCircleRadius(int value) { - innerCircleRadiusProperty().set(value); - } - - public final DoubleProperty innerCircleRadiusProperty() { - return innerCircleRadius; - } - - public final double getInnerCircleRadius() { - return innerCircleRadiusProperty().get(); - } - - /** - * radius of the inner circle - */ - private DoubleProperty innerCircleRadius = new StyleableDoubleProperty(60) { - @Override - public Object getBean() { - return ProgressCircleIndicator.this; - } - - @Override - public String getName() { - return "innerCircleRadius"; - } - - @Override - public CssMetaData getCssMetaData() { - return StyleableProperties.INNER_CIRCLE_RADIUS; - } - }; - - private static class StyleableProperties { - private static final CssMetaData INNER_CIRCLE_RADIUS = new CssMetaData( - "-fx-inner-radius", SizeConverter.getInstance(), 60) { - - @Override - public boolean isSettable(ProgressCircleIndicator n) { - return n.innerCircleRadiusProperty() == null || !n.innerCircleRadiusProperty().isBound(); - } - - @SuppressWarnings("unchecked") - @Override - public StyleableProperty getStyleableProperty(ProgressCircleIndicator n) { - return (StyleableProperty) n.innerCircleRadiusProperty(); - } - }; - - public static final List> STYLEABLES; - - static { - final List> styleables = new ArrayList<>(Control.getClassCssMetaData()); - styleables.add(INNER_CIRCLE_RADIUS); - STYLEABLES = Collections.unmodifiableList(styleables); - } - } - - public static List> getClassCssMetaData() { - return StyleableProperties.STYLEABLES; - } - - @Override - public List> getControlCssMetaData() { - return StyleableProperties.STYLEABLES; - } -} diff --git a/Launcher/src/main/java/ru/gravit/launcher/gui/indicator/RingProgressIndicator.java b/Launcher/src/main/java/ru/gravit/launcher/gui/indicator/RingProgressIndicator.java deleted file mode 100644 index 11c04589..00000000 --- a/Launcher/src/main/java/ru/gravit/launcher/gui/indicator/RingProgressIndicator.java +++ /dev/null @@ -1,95 +0,0 @@ -package ru.gravit.launcher.gui.indicator; - -import com.sun.javafx.css.converters.SizeConverter; -import javafx.beans.property.DoubleProperty; -import javafx.css.CssMetaData; -import javafx.css.Styleable; -import javafx.css.StyleableDoubleProperty; -import javafx.css.StyleableProperty; -import javafx.scene.control.Control; -import javafx.scene.control.Skin; -import ru.gravit.launcher.LauncherAPI; -import ru.gravit.utils.helper.LogHelper; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class RingProgressIndicator extends ProgressCircleIndicator { - public RingProgressIndicator() { - LogHelper.debug("Setting JVM dir name"); - this.getStylesheets().add(RingProgressIndicator.class.getResource("/runtime/launcher/overlay/update/ringprogress.css").toExternalForm()); - this.getStyleClass().add("ringindicator"); - } - - @Override - protected Skin createDefaultSkin() { - return new RingProgressIndicatorSkin(this); - } - - @LauncherAPI - public final void setRingWidth(int value) { - ringWidthProperty().set(value); - } - - @LauncherAPI - public final DoubleProperty ringWidthProperty() { - return ringWidth; - } - - @LauncherAPI - public final double getRingWidth() { - return ringWidthProperty().get(); - } - - /** - * thickness of the ring indicator. - */ - private DoubleProperty ringWidth = new StyleableDoubleProperty(22) { - @Override - public Object getBean() { - return RingProgressIndicator.this; - } - - @Override - public String getName() { - return "ringWidth"; - } - - @Override - public CssMetaData getCssMetaData() { - return StyleableProperties.RING_WIDTH; - } - }; - - private static class StyleableProperties { - private static final CssMetaData RING_WIDTH = new CssMetaData( - "-fx-ring-width", SizeConverter.getInstance(), 22) { - - @Override - public boolean isSettable(RingProgressIndicator n) { - return n.ringWidth == null || !n.ringWidth.isBound(); - } - - @SuppressWarnings("unchecked") - @Override - public StyleableProperty getStyleableProperty(RingProgressIndicator n) { - return (StyleableProperty) n.ringWidth; - } - }; - - public static final List> STYLEABLES; - - static { - final List> styleables = new ArrayList<>(Control.getClassCssMetaData()); - styleables.addAll(getClassCssMetaData()); - styleables.add(RING_WIDTH); - STYLEABLES = Collections.unmodifiableList(styleables); - } - } - - @Override - public List> getControlCssMetaData() { - return StyleableProperties.STYLEABLES; - } -} diff --git a/Launcher/src/main/java/ru/gravit/launcher/gui/indicator/RingProgressIndicatorSkin.java b/Launcher/src/main/java/ru/gravit/launcher/gui/indicator/RingProgressIndicatorSkin.java deleted file mode 100644 index 3367767e..00000000 --- a/Launcher/src/main/java/ru/gravit/launcher/gui/indicator/RingProgressIndicatorSkin.java +++ /dev/null @@ -1,124 +0,0 @@ -package ru.gravit.launcher.gui.indicator; - -import javafx.animation.Animation; -import javafx.animation.Interpolator; -import javafx.animation.RotateTransition; -import javafx.scene.Node; -import javafx.scene.control.Label; -import javafx.scene.control.Skin; -import javafx.scene.layout.Region; -import javafx.scene.layout.StackPane; -import javafx.scene.shape.Arc; -import javafx.scene.shape.Circle; -import javafx.util.Duration; - -/** - * Skin of the ring progress indicator where an arc grows and by the progress value up to 100% where the arc becomes a ring. - * - * @author Andrea Vacondio - */ -public class RingProgressIndicatorSkin implements Skin { - - private final RingProgressIndicator indicator; - private final Label percentLabel = new Label(); - private final Circle innerCircle = new Circle(); - private final Circle outerCircle = new Circle(); - private final StackPane container = new StackPane(); - private final Arc fillerArc = new Arc(); - private final RotateTransition transition = new RotateTransition(Duration.millis(2000), fillerArc); - - public RingProgressIndicatorSkin(final RingProgressIndicator indicator) { - this.indicator = indicator; - initContainer(indicator); - initFillerArc(); - container.widthProperty().addListener((o, oldVal, newVal) -> fillerArc.setCenterX(newVal.intValue() / 2)); - container.heightProperty().addListener((o, oldVal, newVal) -> fillerArc.setCenterY(newVal.intValue() / 2)); - innerCircle.getStyleClass().add("ringindicator-inner-circle"); - outerCircle.getStyleClass().add("ringindicator-outer-circle-secondary"); - updateRadii(); - - this.indicator.indeterminateProperty().addListener((o, oldVal, newVal) -> initIndeterminate(newVal)); - this.indicator.progressProperty().addListener((o, oldVal, newVal) -> { - if (newVal.intValue() >= 0) { - fillerArc.setLength(newVal.doubleValue() * -360); - } - }); - this.indicator.ringWidthProperty().addListener((o, oldVal, newVal) -> updateRadii()); - innerCircle.strokeWidthProperty().addListener((e) -> updateRadii()); - innerCircle.radiusProperty().addListener((e) -> updateRadii()); - initTransition(); - initIndeterminate(indicator.isIndeterminate()); - indicator.visibleProperty().addListener((o, oldVal, newVal) -> { - if (newVal && this.indicator.isIndeterminate()) { - transition.play(); - } else { - transition.pause(); - } - }); - container.getChildren().addAll(fillerArc, outerCircle, innerCircle, percentLabel); - } - - private void initTransition() { - transition.setAutoReverse(false); - transition.setCycleCount(Animation.INDEFINITE); - transition.setDelay(Duration.ZERO); - transition.setInterpolator(Interpolator.LINEAR); - transition.setByAngle(360); - } - - private void initFillerArc() { - fillerArc.setManaged(false); - fillerArc.getStyleClass().add("ringindicator-filler"); - fillerArc.setStartAngle(90); - fillerArc.setLength(indicator.getProgress() * -360); - } - - private void initContainer(final RingProgressIndicator indicator) { - container.getStylesheets().addAll(indicator.getStylesheets()); - container.getStyleClass().addAll("circleindicator-container"); - container.setMaxHeight(Region.USE_PREF_SIZE); - container.setMaxWidth(Region.USE_PREF_SIZE); - } - - private void updateRadii() { - double ringWidth = indicator.getRingWidth(); - double innerCircleHalfStrokeWidth = innerCircle.getStrokeWidth() / 2; - double innerCircleRadius = indicator.getInnerCircleRadius(); - outerCircle.setRadius(innerCircleRadius + innerCircleHalfStrokeWidth + ringWidth); - fillerArc.setRadiusY(innerCircleRadius + innerCircleHalfStrokeWidth - 1 + (ringWidth / 2)); - fillerArc.setRadiusX(innerCircleRadius + innerCircleHalfStrokeWidth - 1 + (ringWidth / 2)); - fillerArc.setStrokeWidth(ringWidth); - innerCircle.setRadius(innerCircleRadius); - } - - private void initIndeterminate(boolean newVal) { - percentLabel.setVisible(!newVal); - if (newVal) { - fillerArc.setLength(360); - fillerArc.getStyleClass().add("indeterminate"); - if (indicator.isVisible()) { - transition.play(); - } - } else { - fillerArc.getStyleClass().remove("indeterminate"); - fillerArc.setRotate(0); - transition.stop(); - } - } - - @Override - public RingProgressIndicator getSkinnable() { - return indicator; - } - - @Override - public Node getNode() { - return container; - } - - @Override - public void dispose() { - transition.stop(); - } - -} diff --git a/LauncherAPI/src/main/java/com/mojang/authlib/yggdrasil/CompatBridge.java b/LauncherAPI/src/main/java/com/mojang/authlib/yggdrasil/CompatBridge.java index b722c10b..8daeda25 100644 --- a/LauncherAPI/src/main/java/com/mojang/authlib/yggdrasil/CompatBridge.java +++ b/LauncherAPI/src/main/java/com/mojang/authlib/yggdrasil/CompatBridge.java @@ -19,26 +19,26 @@ public final class CompatBridge { public static CompatProfile checkServer(String username, String serverID) throws Exception { LogHelper.debug("CompatBridge.checkServer, Username: '%s', Server ID: %s", username, serverID); - return CompatProfile.fromPlayerProfile(new CheckServerRequest(username, serverID).request()); + return CompatProfile.fromPlayerProfile(new CheckServerRequest(username, serverID).request().playerProfile); } public static boolean joinServer(String username, String accessToken, String serverID) throws Exception { // Join server LogHelper.debug("LegacyBridge.joinServer, Username: '%s', Access token: %s, Server ID: %s", username, accessToken, serverID); - return new JoinServerRequest(username, accessToken, serverID).request(); + return new JoinServerRequest(username, accessToken, serverID).request().allow; } public static CompatProfile profileByUsername(String username) throws Exception { - return CompatProfile.fromPlayerProfile(new ProfileByUsernameRequest(username).request()); + return CompatProfile.fromPlayerProfile(new ProfileByUsernameRequest(username).request().playerProfile); } public static CompatProfile profileByUUID(UUID uuid) throws Exception { - return CompatProfile.fromPlayerProfile(new ProfileByUUIDRequest(uuid).request()); + return CompatProfile.fromPlayerProfile(new ProfileByUUIDRequest(uuid).request().playerProfile); } public static CompatProfile[] profilesByUsername(String... usernames) throws Exception { - PlayerProfile[] profiles = new BatchProfileByUsernameRequest(usernames).request(); + PlayerProfile[] profiles = new BatchProfileByUsernameRequest(usernames).request().playerProfiles; // Convert profiles CompatProfile[] resultProfiles = new CompatProfile[profiles.length]; diff --git a/LauncherAPI/src/main/java/com/mojang/authlib/yggdrasil/LegacyBridge.java b/LauncherAPI/src/main/java/com/mojang/authlib/yggdrasil/LegacyBridge.java index 378145e6..aa79f146 100644 --- a/LauncherAPI/src/main/java/com/mojang/authlib/yggdrasil/LegacyBridge.java +++ b/LauncherAPI/src/main/java/com/mojang/authlib/yggdrasil/LegacyBridge.java @@ -32,7 +32,7 @@ public static String joinServer(String username, String accessToken, String serv // Join server LogHelper.debug("LegacyBridge.joinServer, Username: '%s', Access token: %s, Server ID: %s", username, accessToken, serverID); try { - return new JoinServerRequest(username, accessToken, serverID).request() ? "OK" : "Bad Login (Clientside)"; + return new JoinServerRequest(username, accessToken, serverID).request().allow ? "OK" : "Bad Login (Clientside)"; } catch (Exception e) { return e.toString(); } diff --git a/LauncherAPI/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilGameProfileRepository.java b/LauncherAPI/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilGameProfileRepository.java index d869426e..37f330e3 100644 --- a/LauncherAPI/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilGameProfileRepository.java +++ b/LauncherAPI/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilGameProfileRepository.java @@ -43,7 +43,7 @@ public void findProfilesByNames(String[] usernames, Agent agent, ProfileLookupCa // Batch Username-To-UUID request PlayerProfile[] sliceProfiles; try { - sliceProfiles = new BatchProfileByUsernameRequest(sliceUsernames).request(); + sliceProfiles = new BatchProfileByUsernameRequest(sliceUsernames).request().playerProfiles; } catch (Exception e) { for (String username : sliceUsernames) { LogHelper.debug("Couldn't find profile '%s': %s", username, e); diff --git a/LauncherAPI/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilMinecraftSessionService.java b/LauncherAPI/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilMinecraftSessionService.java index 3328195f..a13032ce 100644 --- a/LauncherAPI/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilMinecraftSessionService.java +++ b/LauncherAPI/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilMinecraftSessionService.java @@ -98,7 +98,7 @@ public GameProfile fillProfileProperties(GameProfile profile, boolean requireSec // Make profile request PlayerProfile pp; try { - pp = new ProfileByUUIDRequest(uuid).request(); + pp = new ProfileByUUIDRequest(uuid).request().playerProfile; } catch (Exception e) { LogHelper.debug("Couldn't fetch profile properties for '%s': %s", profile, e); return profile; @@ -155,7 +155,7 @@ public GameProfile hasJoinedServer(GameProfile profile, String serverID) throws // Make checkServer request PlayerProfile pp; try { - pp = new CheckServerRequest(username, serverID).request(); + pp = new CheckServerRequest(username, serverID).request().playerProfile; } catch (Exception e) { LogHelper.error(e); throw new AuthenticationUnavailableException(e); @@ -184,7 +184,7 @@ public void joinServer(GameProfile profile, String accessToken, String serverID) // Make joinServer request boolean success; try { - success = new JoinServerRequest(username, accessToken, serverID).request(); + success = new JoinServerRequest(username, accessToken, serverID).request().allow; } catch (Exception e) { throw new AuthenticationUnavailableException(e); } diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/CustomRequest.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/CustomRequest.java index cb886b1a..47fb20ab 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/CustomRequest.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/CustomRequest.java @@ -21,7 +21,7 @@ public CustomRequest(LauncherConfig config) { public abstract String getName(); @Override - public final Integer getType() { + public final Integer getLegacyType() { return 255; } diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/PingRequest.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/PingRequest.java index 36e529a1..c725aff6 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/PingRequest.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/PingRequest.java @@ -21,7 +21,7 @@ public PingRequest(LauncherConfig config) { } @Override - public Integer getType() { + public Integer getLegacyType() { return RequestType.PING.getNumber(); } diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/Request.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/Request.java index 496b314a..8d1dce9e 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/Request.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/Request.java @@ -29,9 +29,9 @@ public static void requestError(String message) throws RequestException { } @LauncherAPI - protected final LauncherConfig config; + protected transient final LauncherConfig config; - private final AtomicBoolean started = new AtomicBoolean(false); + private transient final AtomicBoolean started = new AtomicBoolean(false); @LauncherAPI protected Request() { @@ -44,7 +44,7 @@ protected Request(LauncherConfig config) { } @LauncherAPI - public abstract Integer getType(); + public abstract Integer getLegacyType(); @LauncherAPI protected final void readError(HInput input) throws IOException { @@ -57,7 +57,10 @@ protected final void readError(HInput input) throws IOException { public R request() throws Exception { if (!started.compareAndSet(false, true)) throw new IllegalStateException("Request already started"); - + R wsResult = null; + if(config.nettyPort != 0) + wsResult = requestWebSockets(); + if(wsResult != null) return wsResult; // Make request to LaunchServer try (Socket socket = IOHelper.newSocket()) { socket.connect(IOHelper.resolve(config.address)); @@ -68,7 +71,10 @@ public R request() throws Exception { } } } - + protected R requestWebSockets() throws Exception + { + return null; + } @LauncherAPI protected abstract R requestDo(HInput input, HOutput output) throws Exception; @@ -77,7 +83,7 @@ private void writeHandshake(HInput input, HOutput output) throws IOException { output.writeInt(Launcher.PROTOCOL_MAGIC); output.writeBigInteger(config.publicKey.getModulus(), SecurityHelper.RSA_KEY_LENGTH + 1); output.writeLong(session); - output.writeVarInt(getType()); + output.writeVarInt(getLegacyType()); output.flush(); // Verify is accepted diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/admin/ExecCommandRequest.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/admin/ExecCommandRequest.java index a929591d..bf2cd2fd 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/admin/ExecCommandRequest.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/admin/ExecCommandRequest.java @@ -17,7 +17,7 @@ public ExecCommandRequest(LogHelper.Output output, String cmd) { } @Override - public Integer getType() { + public Integer getLegacyType() { return RequestType.EXECCOMMAND.getNumber(); } diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/AuthRequest.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/AuthRequest.java index 22929b0f..f9e2e7f5 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/AuthRequest.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/AuthRequest.java @@ -1,10 +1,12 @@ package ru.gravit.launcher.request.auth; import ru.gravit.launcher.*; +import ru.gravit.launcher.events.request.AuthRequestEvent; import ru.gravit.launcher.profiles.PlayerProfile; import ru.gravit.launcher.request.Request; import ru.gravit.launcher.request.RequestType; -import ru.gravit.launcher.request.auth.AuthRequest.Result; +import ru.gravit.launcher.request.websockets.LegacyRequestBridge; +import ru.gravit.launcher.request.websockets.RequestInterface; import ru.gravit.launcher.serialize.HInput; import ru.gravit.launcher.serialize.HOutput; import ru.gravit.launcher.serialize.SerializeLimits; @@ -13,21 +15,7 @@ import java.io.IOException; -public final class AuthRequest extends Request { - public static final class Result { - @LauncherAPI - public final PlayerProfile pp; - @LauncherAPI - public final String accessToken; - @LauncherAPI - public final ClientPermissions permissions; - - private Result(PlayerProfile pp, String accessToken, ClientPermissions permissions) { - this.pp = pp; - this.accessToken = accessToken; - this.permissions = permissions; - } - } +public final class AuthRequest extends Request implements RequestInterface { private final String login; @@ -37,55 +25,59 @@ private Result(PlayerProfile pp, String accessToken, ClientPermissions permissio private final String customText; @LauncherAPI - public AuthRequest(LauncherConfig config, String login, byte[] encryptedPassword, HWID hwid) { + public AuthRequest(LauncherConfig config, String login, byte[] password, HWID hwid) { super(config); this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty"); - this.encryptedPassword = encryptedPassword.clone(); + this.encryptedPassword = password.clone(); this.hwid = hwid; customText = ""; auth_id = 0; } @LauncherAPI - public AuthRequest(LauncherConfig config, String login, byte[] encryptedPassword, HWID hwid, String customText) { + public AuthRequest(LauncherConfig config, String login, byte[] password, HWID hwid, String customText) { super(config); this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty"); - this.encryptedPassword = encryptedPassword.clone(); + this.encryptedPassword = password.clone(); this.hwid = hwid; this.customText = customText; auth_id = 0; } @LauncherAPI - public AuthRequest(LauncherConfig config, String login, byte[] encryptedPassword, HWID hwid, int auth_id) { + public AuthRequest(LauncherConfig config, String login, byte[] password, HWID hwid, int auth_id) { super(config); this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty"); - this.encryptedPassword = encryptedPassword.clone(); + this.encryptedPassword = password.clone(); this.hwid = hwid; this.auth_id = auth_id; customText = ""; } @LauncherAPI - public AuthRequest(LauncherConfig config, String login, byte[] encryptedPassword, HWID hwid, String customText, int auth_id) { + public AuthRequest(LauncherConfig config, String login, byte[] password, HWID hwid, String customText, int auth_id) { super(config); this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty"); - this.encryptedPassword = encryptedPassword.clone(); + this.encryptedPassword = password.clone(); this.hwid = hwid; this.auth_id = auth_id; this.customText = customText; } @LauncherAPI - public AuthRequest(String login, byte[] encryptedPassword, HWID hwid) { - this(null, login, encryptedPassword, hwid); + public AuthRequest(String login, byte[] password, HWID hwid) { + this(null, login, password, hwid); + } + @Override + public AuthRequestEvent requestWebSockets() throws Exception + { + return (AuthRequestEvent) LegacyRequestBridge.sendRequest(this); } - @LauncherAPI - public AuthRequest(String login, byte[] encryptedPassword, HWID hwid, int auth_id) { - this(null, login, encryptedPassword, hwid, auth_id); + public AuthRequest(String login, byte[] password, HWID hwid, int auth_id) { + this(null, login, password, hwid, auth_id); } @Override - public Integer getType() { + public Integer getLegacyType() { return RequestType.AUTH.getNumber(); } /*public class EchoRequest implements RequestInterface @@ -97,12 +89,12 @@ public EchoRequest(String echo) { } @Override - public String getType() { + public String getLegacyType() { return "echo"; } }*/ @Override - protected Result requestDo(HInput input, HOutput output) throws IOException { + protected AuthRequestEvent requestDo(HInput input, HOutput output) throws IOException { /*try { LegacyRequestBridge.sendRequest(new EchoRequest("Hello World!")); } catch (InterruptedException e) { @@ -126,6 +118,11 @@ protected Result requestDo(HInput input, HOutput output) throws IOException { PlayerProfile pp = new PlayerProfile(input); String accessToken = input.readASCII(-SecurityHelper.TOKEN_STRING_LENGTH); ClientPermissions permissions = new ClientPermissions(input); - return new Result(pp, accessToken, permissions); + return new AuthRequestEvent(pp, accessToken, permissions); + } + + @Override + public String getType() { + return "auth"; } } diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/AuthServerRequest.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/AuthServerRequest.java index 49113e5a..829fc0a3 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/AuthServerRequest.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/AuthServerRequest.java @@ -71,7 +71,7 @@ public AuthServerRequest(String login, byte[] encryptedPassword, int auth_id) { } @Override - public Integer getType() { + public Integer getLegacyType() { return RequestType.SERVERAUTH.getNumber(); } diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/ChangeServerRequest.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/ChangeServerRequest.java index 0ea7877a..ecb4399e 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/ChangeServerRequest.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/ChangeServerRequest.java @@ -10,7 +10,7 @@ public class ChangeServerRequest extends Request { @Override - public Integer getType() { + public Integer getLegacyType() { return RequestType.CHANGESERVER.getNumber(); } diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/CheckServerRequest.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/CheckServerRequest.java index fff01495..94c29a23 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/CheckServerRequest.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/CheckServerRequest.java @@ -3,6 +3,7 @@ import ru.gravit.launcher.Launcher; import ru.gravit.launcher.LauncherAPI; import ru.gravit.launcher.LauncherConfig; +import ru.gravit.launcher.events.request.CheckServerRequestEvent; import ru.gravit.launcher.profiles.PlayerProfile; import ru.gravit.launcher.request.Request; import ru.gravit.launcher.request.RequestType; @@ -14,7 +15,7 @@ import java.io.IOException; -public final class CheckServerRequest extends Request { +public final class CheckServerRequest extends Request { private final String username; private final String serverID; @@ -31,12 +32,12 @@ public CheckServerRequest(String username, String serverID) { } @Override - public Integer getType() { + public Integer getLegacyType() { return RequestType.CHECK_SERVER.getNumber(); } @Override - protected PlayerProfile requestDo(HInput input, HOutput output) throws IOException { + protected CheckServerRequestEvent requestDo(HInput input, HOutput output) throws IOException { output.writeString(username, SerializeLimits.MAX_LOGIN); output.writeASCII(serverID, SerializeLimits.MAX_SERVERID); // 1 char for minus sign if (Launcher.profile == null) { @@ -48,6 +49,6 @@ protected PlayerProfile requestDo(HInput input, HOutput output) throws IOExcepti // Read response readError(input); - return input.readBoolean() ? new PlayerProfile(input) : null; + return input.readBoolean() ? new CheckServerRequestEvent(new PlayerProfile(input)) : null; } } diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/JoinServerRequest.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/JoinServerRequest.java index 264d9819..0ff36115 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/JoinServerRequest.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/JoinServerRequest.java @@ -2,6 +2,7 @@ import ru.gravit.launcher.LauncherAPI; import ru.gravit.launcher.LauncherConfig; +import ru.gravit.launcher.events.request.JoinServerRequestEvent; import ru.gravit.launcher.request.Request; import ru.gravit.launcher.request.RequestType; import ru.gravit.launcher.serialize.HInput; @@ -12,7 +13,7 @@ import java.io.IOException; -public final class JoinServerRequest extends Request { +public final class JoinServerRequest extends Request { // Instance private final String username; @@ -33,12 +34,12 @@ public JoinServerRequest(String username, String accessToken, String serverID) { } @Override - public Integer getType() { + public Integer getLegacyType() { return RequestType.JOIN_SERVER.getNumber(); } @Override - protected Boolean requestDo(HInput input, HOutput output) throws IOException { + protected JoinServerRequestEvent requestDo(HInput input, HOutput output) throws IOException { output.writeString(username, SerializeLimits.MAX_LOGIN); output.writeASCII(accessToken, -SecurityHelper.TOKEN_STRING_LENGTH); output.writeASCII(serverID, SerializeLimits.MAX_SERVERID); // 1 char for minus sign @@ -46,7 +47,7 @@ protected Boolean requestDo(HInput input, HOutput output) throws IOException { // Read response readError(input); - return input.readBoolean(); + return new JoinServerRequestEvent(input.readBoolean()); } } diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/SetProfileRequest.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/SetProfileRequest.java index 191b77b2..a0872d82 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/SetProfileRequest.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/auth/SetProfileRequest.java @@ -1,30 +1,45 @@ package ru.gravit.launcher.request.auth; import ru.gravit.launcher.LauncherConfig; +import ru.gravit.launcher.events.request.SetProfileRequestEvent; import ru.gravit.launcher.profiles.ClientProfile; import ru.gravit.launcher.request.Request; import ru.gravit.launcher.request.RequestType; +import ru.gravit.launcher.request.websockets.LegacyRequestBridge; +import ru.gravit.launcher.request.websockets.RequestInterface; import ru.gravit.launcher.serialize.HInput; import ru.gravit.launcher.serialize.HOutput; import ru.gravit.launcher.serialize.SerializeLimits; -public class SetProfileRequest extends Request { - private ClientProfile profile; +public class SetProfileRequest extends Request implements RequestInterface { + private transient ClientProfile profile; + + public String client; public SetProfileRequest(LauncherConfig config, ClientProfile profile) { super(config); this.profile = profile; + this.client = profile.getTitle(); } - @Override - public Integer getType() { + public SetProfileRequestEvent requestWebSockets() throws Exception + { + return (SetProfileRequestEvent) LegacyRequestBridge.sendRequest(this); + } + @Override + public Integer getLegacyType() { return RequestType.SETPROFILE.getNumber(); } @Override - protected Boolean requestDo(HInput input, HOutput output) throws Exception { + protected SetProfileRequestEvent requestDo(HInput input, HOutput output) throws Exception { output.writeString(profile.getTitle(), SerializeLimits.MAX_CLIENT); readError(input); - return input.readBoolean(); + return new SetProfileRequestEvent(profile); + } + + @Override + public String getType() { + return "setProfile"; } } diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/LauncherRequest.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/LauncherRequest.java index f8ed16ff..11777930 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/LauncherRequest.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/LauncherRequest.java @@ -3,8 +3,12 @@ import ru.gravit.launcher.Launcher; import ru.gravit.launcher.LauncherAPI; import ru.gravit.launcher.LauncherConfig; +import ru.gravit.launcher.LauncherNetworkAPI; +import ru.gravit.launcher.events.request.LauncherRequestEvent; import ru.gravit.launcher.request.Request; import ru.gravit.launcher.request.RequestType; +import ru.gravit.launcher.request.websockets.LegacyRequestBridge; +import ru.gravit.launcher.request.websockets.RequestInterface; import ru.gravit.launcher.serialize.HInput; import ru.gravit.launcher.serialize.HOutput; import ru.gravit.utils.helper.IOHelper; @@ -13,31 +17,18 @@ import ru.gravit.utils.helper.SecurityHelper; import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.net.URLConnection; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; -public final class LauncherRequest extends Request { - public static final class Result { - private final byte[] binary; - private final byte[] digest; - - public Result(byte[] binary, byte[] sign) { - this.binary = binary == null ? null : binary.clone(); - this.digest = sign.clone(); - } - - @LauncherAPI - public byte[] getBinary() { - return binary == null ? null : binary.clone(); - } - - @LauncherAPI - public byte[] getDigest() { - return digest.clone(); - } - } - +public final class LauncherRequest extends Request implements RequestInterface { + @LauncherNetworkAPI + public byte[] digest; + @LauncherNetworkAPI + public int launcher_type = EXE_BINARY ? 2 : 1; @LauncherAPI public static final Path BINARY_PATH = IOHelper.getCodeSource(Launcher.class); @@ -45,7 +36,7 @@ public byte[] getDigest() { public static final boolean EXE_BINARY = IOHelper.hasExtension(BINARY_PATH, "exe"); @LauncherAPI - public static void update(LauncherConfig config, Result result) throws IOException { + public static void update(LauncherConfig config, LauncherRequestEvent result) throws IOException { List args = new ArrayList<>(8); args.add(IOHelper.resolveJavaBin(null).toString()); if (LogHelper.isDebugEnabled()) @@ -58,7 +49,16 @@ public static void update(LauncherConfig config, Result result) throws IOExcepti builder.inheritIO(); // Rewrite and start new instance - IOHelper.write(BINARY_PATH, result.binary); + if(result.binary != null) + IOHelper.write(BINARY_PATH, result.binary); + else + { + URLConnection connection = IOHelper.newConnection(new URL(result.url)); + connection.connect(); + try(OutputStream stream = connection.getOutputStream()) { + IOHelper.transfer(BINARY_PATH, stream); + } + } builder.start(); // Kill current instance @@ -71,20 +71,32 @@ public LauncherRequest() { this(null); } + @Override + public LauncherRequestEvent requestWebSockets() throws Exception + { + LauncherRequestEvent result = (LauncherRequestEvent) LegacyRequestBridge.sendRequest(this); + if(result.needUpdate) update(config, result); + return result; + } + @LauncherAPI public LauncherRequest(LauncherConfig config) { super(config); + Path launcherPath = IOHelper.getCodeSource(LauncherRequest.class); + try { + digest = SecurityHelper.digest(SecurityHelper.DigestAlgorithm.SHA512, launcherPath); + } catch (IOException e) { + LogHelper.error(e); + } } @Override - public Integer getType() { + public Integer getLegacyType() { return RequestType.LAUNCHER.getNumber(); } @Override - protected Result requestDo(HInput input, HOutput output) throws Exception { - Path launcherPath = IOHelper.getCodeSource(LauncherRequest.class); - byte[] digest = SecurityHelper.digest(SecurityHelper.DigestAlgorithm.SHA512, launcherPath); + protected LauncherRequestEvent requestDo(HInput input, HOutput output) throws Exception { output.writeBoolean(EXE_BINARY); output.writeByteArray(digest, 0); output.flush(); @@ -94,11 +106,16 @@ protected Result requestDo(HInput input, HOutput output) throws Exception { boolean shouldUpdate = input.readBoolean(); if (shouldUpdate) { byte[] binary = input.readByteArray(0); - Result result = new Result(binary, digest); + LauncherRequestEvent result = new LauncherRequestEvent(binary, digest); update(Launcher.getConfig(), result); } // Return request result - return new Result(null, digest); + return new LauncherRequestEvent(null, digest); + } + + @Override + public String getType() { + return "launcher"; } } diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/LegacyLauncherRequest.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/LegacyLauncherRequest.java index 7fd08e96..30d643b1 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/LegacyLauncherRequest.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/LegacyLauncherRequest.java @@ -88,7 +88,7 @@ public LegacyLauncherRequest(LauncherConfig config) { } @Override - public Integer getType() { + public Integer getLegacyType() { return RequestType.LEGACYLAUNCHER.getNumber(); } diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/ProfilesRequest.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/ProfilesRequest.java index 9c0d079d..c13eb7ec 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/ProfilesRequest.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/ProfilesRequest.java @@ -3,26 +3,19 @@ import ru.gravit.launcher.Launcher; import ru.gravit.launcher.LauncherAPI; import ru.gravit.launcher.LauncherConfig; +import ru.gravit.launcher.events.request.ProfilesRequestEvent; import ru.gravit.launcher.profiles.ClientProfile; import ru.gravit.launcher.request.Request; import ru.gravit.launcher.request.RequestType; +import ru.gravit.launcher.request.websockets.LegacyRequestBridge; +import ru.gravit.launcher.request.websockets.RequestInterface; import ru.gravit.launcher.serialize.HInput; import ru.gravit.launcher.serialize.HOutput; import java.util.ArrayList; -import java.util.Collections; import java.util.List; -public final class ProfilesRequest extends Request { - - public static final class Result { - @LauncherAPI - public final List profiles; - - private Result(List profiles) { - this.profiles = Collections.unmodifiableList(profiles); - } - } +public final class ProfilesRequest extends Request implements RequestInterface { @LauncherAPI public ProfilesRequest() { @@ -35,12 +28,18 @@ public ProfilesRequest(LauncherConfig config) { } @Override - public Integer getType() { + public Integer getLegacyType() { return RequestType.PROFILES.getNumber(); } @Override - protected Result requestDo(HInput input, HOutput output) throws Exception { + public ProfilesRequestEvent requestWebSockets() throws Exception + { + return (ProfilesRequestEvent) LegacyRequestBridge.sendRequest(this); + } + + @Override + protected ProfilesRequestEvent requestDo(HInput input, HOutput output) throws Exception { output.writeBoolean(true); output.flush(); readError(input); @@ -52,6 +51,11 @@ protected Result requestDo(HInput input, HOutput output) throws Exception { profiles.add(Launcher.gson.fromJson(prof, ClientProfile.class)); } // Return request result - return new Result(profiles); + return new ProfilesRequestEvent(profiles); + } + + @Override + public String getType() { + return "profiles"; } } diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/UpdateListRequest.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/UpdateListRequest.java index fb9c67d2..dfe9c1c1 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/UpdateListRequest.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/UpdateListRequest.java @@ -2,18 +2,19 @@ import ru.gravit.launcher.LauncherAPI; import ru.gravit.launcher.LauncherConfig; +import ru.gravit.launcher.events.request.UpdateListRequestEvent; import ru.gravit.launcher.request.Request; import ru.gravit.launcher.request.RequestType; +import ru.gravit.launcher.request.websockets.LegacyRequestBridge; +import ru.gravit.launcher.request.websockets.RequestInterface; import ru.gravit.launcher.serialize.HInput; import ru.gravit.launcher.serialize.HOutput; import ru.gravit.utils.helper.IOHelper; import java.io.IOException; -import java.util.Collections; import java.util.HashSet; -import java.util.Set; -public final class UpdateListRequest extends Request> { +public final class UpdateListRequest extends Request implements RequestInterface { @LauncherAPI public UpdateListRequest() { this(null); @@ -25,20 +26,31 @@ public UpdateListRequest(LauncherConfig config) { } @Override - public Integer getType() { + public UpdateListRequestEvent requestWebSockets() throws Exception + { + return (UpdateListRequestEvent) LegacyRequestBridge.sendRequest(this); + } + + @Override + public Integer getLegacyType() { return RequestType.UPDATE_LIST.getNumber(); } @Override - protected Set requestDo(HInput input, HOutput output) throws IOException { + protected UpdateListRequestEvent requestDo(HInput input, HOutput output) throws IOException { int count = input.readLength(0); // Read all update dirs names - Set result = new HashSet<>(count); + HashSet result = new HashSet<>(count); for (int i = 0; i < count; i++) result.add(IOHelper.verifyFileName(input.readString(255))); // We're done. Make it unmodifiable and return - return Collections.unmodifiableSet(result); + return new UpdateListRequestEvent(result); + } + + @Override + public String getType() { + return "updateList"; } } diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/UpdateRequest.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/UpdateRequest.java index 5d065966..687c656a 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/UpdateRequest.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/update/UpdateRequest.java @@ -285,7 +285,7 @@ private void downloadFile(Path file, HashedFile hFile, InputStream input) throws } @Override - public Integer getType() { + public Integer getLegacyType() { return RequestType.UPDATE.getNumber(); } diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/uuid/BatchProfileByUsernameRequest.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/uuid/BatchProfileByUsernameRequest.java index 282489b9..471b184f 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/uuid/BatchProfileByUsernameRequest.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/uuid/BatchProfileByUsernameRequest.java @@ -2,6 +2,7 @@ import ru.gravit.launcher.LauncherAPI; import ru.gravit.launcher.LauncherConfig; +import ru.gravit.launcher.events.request.BatchProfileByUsernameRequestEvent; import ru.gravit.launcher.profiles.PlayerProfile; import ru.gravit.launcher.request.Request; import ru.gravit.launcher.request.RequestType; @@ -13,7 +14,7 @@ import java.io.IOException; -public final class BatchProfileByUsernameRequest extends Request { +public final class BatchProfileByUsernameRequest extends Request { private final String[] usernames; @LauncherAPI @@ -31,12 +32,12 @@ public BatchProfileByUsernameRequest(String... usernames) throws IOException { } @Override - public Integer getType() { + public Integer getLegacyType() { return RequestType.BATCH_PROFILE_BY_USERNAME.getNumber(); } @Override - protected PlayerProfile[] requestDo(HInput input, HOutput output) throws IOException { + protected BatchProfileByUsernameRequestEvent requestDo(HInput input, HOutput output) throws IOException { output.writeLength(usernames.length, SerializeLimits.MAX_BATCH_SIZE); for (String username : usernames) { output.writeString(username, SerializeLimits.MAX_LOGIN); @@ -50,6 +51,6 @@ protected PlayerProfile[] requestDo(HInput input, HOutput output) throws IOExcep profiles[i] = input.readBoolean() ? new PlayerProfile(input) : null; // Return result - return profiles; + return new BatchProfileByUsernameRequestEvent(profiles); } } diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/uuid/ProfileByUUIDRequest.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/uuid/ProfileByUUIDRequest.java index 2199890f..d7c0cab4 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/uuid/ProfileByUUIDRequest.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/uuid/ProfileByUUIDRequest.java @@ -3,6 +3,7 @@ import ru.gravit.launcher.Launcher; import ru.gravit.launcher.LauncherAPI; import ru.gravit.launcher.LauncherConfig; +import ru.gravit.launcher.events.request.ProfileByUUIDRequestEvent; import ru.gravit.launcher.profiles.PlayerProfile; import ru.gravit.launcher.request.Request; import ru.gravit.launcher.request.RequestType; @@ -14,7 +15,7 @@ import java.util.Objects; import java.util.UUID; -public final class ProfileByUUIDRequest extends Request { +public final class ProfileByUUIDRequest extends Request { private final UUID uuid; @LauncherAPI @@ -29,17 +30,17 @@ public ProfileByUUIDRequest(UUID uuid) { } @Override - public Integer getType() { + public Integer getLegacyType() { return RequestType.PROFILE_BY_UUID.getNumber(); } @Override - protected PlayerProfile requestDo(HInput input, HOutput output) throws IOException { + protected ProfileByUUIDRequestEvent requestDo(HInput input, HOutput output) throws IOException { output.writeUUID(uuid); output.writeString(Launcher.profile.getTitle(), SerializeLimits.MAX_CLIENT); output.flush(); // Return profile - return input.readBoolean() ? new PlayerProfile(input) : null; + return input.readBoolean() ? new ProfileByUUIDRequestEvent(new PlayerProfile(input)) : null; } } diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/uuid/ProfileByUsernameRequest.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/uuid/ProfileByUsernameRequest.java index 2136ef19..a256b2ef 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/uuid/ProfileByUsernameRequest.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/uuid/ProfileByUsernameRequest.java @@ -3,6 +3,7 @@ import ru.gravit.launcher.Launcher; import ru.gravit.launcher.LauncherAPI; import ru.gravit.launcher.LauncherConfig; +import ru.gravit.launcher.events.request.ProfileByUsernameRequestEvent; import ru.gravit.launcher.profiles.PlayerProfile; import ru.gravit.launcher.request.Request; import ru.gravit.launcher.request.RequestType; @@ -13,7 +14,7 @@ import java.io.IOException; -public final class ProfileByUsernameRequest extends Request { +public final class ProfileByUsernameRequest extends Request { private final String username; @LauncherAPI @@ -28,16 +29,16 @@ public ProfileByUsernameRequest(String username) { } @Override - public Integer getType() { + public Integer getLegacyType() { return RequestType.PROFILE_BY_USERNAME.getNumber(); } @Override - protected PlayerProfile requestDo(HInput input, HOutput output) throws IOException { + protected ProfileByUsernameRequestEvent requestDo(HInput input, HOutput output) throws IOException { output.writeString(username, SerializeLimits.MAX_LOGIN); output.writeString(Launcher.profile.getTitle(), SerializeLimits.MAX_CLIENT); output.flush(); // Return profile - return input.readBoolean() ? new PlayerProfile(input) : null; + return input.readBoolean() ? new ProfileByUsernameRequestEvent(new PlayerProfile(input)) : null; } } diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/websockets/ClientWebSocketService.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/websockets/ClientWebSocketService.java index 73f7473a..98629b59 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/websockets/ClientWebSocketService.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/websockets/ClientWebSocketService.java @@ -2,14 +2,15 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import ru.gravit.launcher.events.request.*; import ru.gravit.launcher.hasher.HashedEntry; import ru.gravit.launcher.hasher.HashedEntryAdapter; import ru.gravit.launcher.request.ResultInterface; import ru.gravit.utils.helper.LogHelper; import java.io.IOException; +import java.lang.reflect.Type; import java.net.URI; -import java.net.URL; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -27,14 +28,15 @@ public ClientWebSocketService(GsonBuilder gsonBuilder, String address, int port, results = new HashMap<>(); handlers = new HashSet<>(); this.gsonBuilder = gsonBuilder; - gsonBuilder.registerTypeAdapter(RequestInterface.class, new JsonRequestAdapter(this)); - gsonBuilder.registerTypeAdapter(HashedEntry.class, new HashedEntryAdapter()); + this.gsonBuilder.registerTypeAdapter(RequestInterface.class, new JsonRequestAdapter(this)); + this.gsonBuilder.registerTypeAdapter(ResultInterface.class, new JsonResultAdapter(this)); + this.gsonBuilder.registerTypeAdapter(HashedEntry.class, new HashedEntryAdapter()); this.gson = gsonBuilder.create(); } private static URI createURL(String address, int port) { try { - URL u = new URL(address); - return new URL(u.getProtocol(), u.getHost(), port, u.getFile()).toURI(); + URI u = new URI("ws://".concat(address).concat(":").concat(String.valueOf(port)).concat("/api")); + return u; } catch (Throwable e) { LogHelper.error(e); return null; @@ -48,6 +50,11 @@ public void onMessage(String message) { handler.process(result); } } + @Override + public void onError(Exception e) + { + LogHelper.error(e); + } public Class getRequestClass(String key) { return requests.get(key); @@ -69,7 +76,18 @@ public void registerResult(String key, Class clazz) { } public void registerResults() { - + registerResult("echo", EchoRequestEvent.class); + registerResult("auth", AuthRequestEvent.class); + registerResult("checkServer", CheckServerRequestEvent.class); + registerResult("joinServer", JoinServerRequestEvent.class); + registerResult("launcher", LauncherRequestEvent.class); + registerResult("profileByUsername", ProfileByUsernameRequestEvent.class); + registerResult("profileByUUID", ProfileByUUIDRequestEvent.class); + registerResult("batchProfileByUsername", BatchProfileByUsernameRequestEvent.class); + registerResult("profiles", ProfilesRequestEvent.class); + registerResult("setProfile", SetProfileRequestEvent.class); + registerResult("updateList", UpdateListRequestEvent.class); + registerResult("error", ErrorRequestEvent.class); } public void registerHandler(EventHandler eventHandler) @@ -78,7 +96,10 @@ public void registerHandler(EventHandler eventHandler) } public void sendObject(Object obj) throws IOException { - send(gson.toJson(obj)); + send(gson.toJson(obj, RequestInterface.class)); + } + public void sendObject(Object obj, Type type) throws IOException { + send(gson.toJson(obj, type)); } @FunctionalInterface public interface EventHandler diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/websockets/LegacyRequestBridge.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/websockets/LegacyRequestBridge.java index c39b3c0c..72728fcb 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/websockets/LegacyRequestBridge.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/websockets/LegacyRequestBridge.java @@ -2,7 +2,10 @@ import com.google.gson.GsonBuilder; import ru.gravit.launcher.Launcher; +import ru.gravit.launcher.events.request.ErrorRequestEvent; +import ru.gravit.launcher.request.RequestException; import ru.gravit.launcher.request.ResultInterface; +import ru.gravit.utils.helper.LogHelper; import java.io.IOException; public class LegacyRequestBridge { @@ -18,15 +21,30 @@ public static ResultInterface sendRequest(RequestInterface request) throws IOExc synchronized(e) { e.wait(); + LogHelper.debug("WAIT OK"); } } ResultInterface result = e.result; waitEventHandler.requests.remove(e); + if(e.result.getType().equals("error")) + { + ErrorRequestEvent errorRequestEvent = (ErrorRequestEvent) e.result; + throw new RequestException(errorRequestEvent.error); + } return result; } public static void initWebSockets(String address, int port) { service = new ClientWebSocketService(new GsonBuilder(), address, port, 5000); + service.registerResults(); + service.registerRequests(); + service.registerHandler(waitEventHandler); + try { + if(!service.connectBlocking()) LogHelper.error("Error connecting"); + LogHelper.debug("Connect to %s:%d",address,port); + } catch (InterruptedException e) { + e.printStackTrace(); + } } static { if(Launcher.getConfig().nettyPort != 0) diff --git a/LauncherAPI/src/main/java/ru/gravit/launcher/request/websockets/WaitEventHandler.java b/LauncherAPI/src/main/java/ru/gravit/launcher/request/websockets/WaitEventHandler.java index 45aa9f78..cc1352b0 100644 --- a/LauncherAPI/src/main/java/ru/gravit/launcher/request/websockets/WaitEventHandler.java +++ b/LauncherAPI/src/main/java/ru/gravit/launcher/request/websockets/WaitEventHandler.java @@ -1,17 +1,21 @@ package ru.gravit.launcher.request.websockets; import ru.gravit.launcher.request.ResultInterface; +import ru.gravit.utils.helper.LogHelper; import java.util.HashSet; public class WaitEventHandler implements ClientWebSocketService.EventHandler { - public HashSet requests; + public HashSet requests = new HashSet<>(); @Override public void process(ResultInterface result) { + LogHelper.debug("Processing event %s type", result.getType()); for(ResultEvent r : requests) { - if(r.type.equals(result.getType())) + LogHelper.subDebug("Processing %s", r.type); + if(r.type.equals(result.getType()) || result.getType().equals("error")) { + LogHelper.debug("Event %s type", r.type); synchronized (r) { r.result = result; diff --git a/ServerWrapper/src/main/java/ru/gravit/launcher/server/ServerWrapper.java b/ServerWrapper/src/main/java/ru/gravit/launcher/server/ServerWrapper.java index 8d8f25e4..74bf4a53 100644 --- a/ServerWrapper/src/main/java/ru/gravit/launcher/server/ServerWrapper.java +++ b/ServerWrapper/src/main/java/ru/gravit/launcher/server/ServerWrapper.java @@ -5,6 +5,7 @@ import ru.gravit.launcher.ClientPermissions; import ru.gravit.launcher.Launcher; import ru.gravit.launcher.LauncherConfig; +import ru.gravit.launcher.events.request.ProfilesRequestEvent; import ru.gravit.launcher.profiles.ClientProfile; import ru.gravit.launcher.request.auth.AuthServerRequest; import ru.gravit.launcher.request.update.ProfilesRequest; @@ -43,7 +44,7 @@ public static boolean auth(ServerWrapper wrapper) { try { LauncherConfig cfg = Launcher.getConfig(); ServerWrapper.permissions = new AuthServerRequest(cfg, config.login, SecurityHelper.newRSAEncryptCipher(cfg.publicKey).doFinal(IOHelper.encode(config.password)), 0, config.title).request(); - ProfilesRequest.Result result = new ProfilesRequest(cfg).request(); + ProfilesRequestEvent result = new ProfilesRequest(cfg).request(); for (ClientProfile p : result.profiles) { LogHelper.debug("Get profile: %s", p.getTitle()); if (p.getTitle().equals(config.title)) { diff --git a/compat/auth/ips.php b/compat/auth/ips.php new file mode 100644 index 00000000..b454f202 --- /dev/null +++ b/compat/auth/ips.php @@ -0,0 +1,22 @@ +member_id ) +{ + if ( strcmp( $member->members_pass_hash, $member->encryptedPassword( $_GET['password'] ) ) === 0 ) + { + echo 'OK:' . $member->name; + } + else + { + echo 'Incorrect login or password'; + } +} +else +{ + echo 'Incorrect login or password'; +} diff --git a/libLauncher/src/main/java/ru/gravit/launcher/Launcher.java b/libLauncher/src/main/java/ru/gravit/launcher/Launcher.java index c63c2d5d..56a65819 100644 --- a/libLauncher/src/main/java/ru/gravit/launcher/Launcher.java +++ b/libLauncher/src/main/java/ru/gravit/launcher/Launcher.java @@ -60,7 +60,7 @@ public final class Launcher { private static final Pattern UUID_PATTERN = Pattern.compile("-", Pattern.LITERAL); public static final int MAJOR = 4; public static final int MINOR = 3; - public static final int PATCH = 2; + public static final int PATCH = 3; public static final int BUILD = 1; public static final Version.Type RELEASE = Version.Type.STABLE; public static GsonBuilder gsonBuilder; diff --git a/libLauncher/src/main/java/ru/gravit/launcher/LauncherNetworkAPI.java b/libLauncher/src/main/java/ru/gravit/launcher/LauncherNetworkAPI.java new file mode 100644 index 00000000..52eacc8a --- /dev/null +++ b/libLauncher/src/main/java/ru/gravit/launcher/LauncherNetworkAPI.java @@ -0,0 +1,11 @@ +package ru.gravit.launcher; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.CLASS) +@Target({ElementType.TYPE, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.METHOD}) +public @interface LauncherNetworkAPI { +} diff --git a/libLauncher/src/main/java/ru/gravit/launcher/events/request/AuthRequestEvent.java b/libLauncher/src/main/java/ru/gravit/launcher/events/request/AuthRequestEvent.java index c378c916..a61a0a18 100644 --- a/libLauncher/src/main/java/ru/gravit/launcher/events/request/AuthRequestEvent.java +++ b/libLauncher/src/main/java/ru/gravit/launcher/events/request/AuthRequestEvent.java @@ -1,6 +1,7 @@ package ru.gravit.launcher.events.request; import ru.gravit.launcher.ClientPermissions; +import ru.gravit.launcher.LauncherNetworkAPI; import ru.gravit.launcher.profiles.PlayerProfile; import ru.gravit.launcher.request.ResultInterface; import ru.gravit.utils.event.EventInterface; @@ -11,12 +12,21 @@ public class AuthRequestEvent implements EventInterface, ResultInterface { private static final UUID uuid = UUID.fromString("77e1bfd7-adf9-4f5d-87d6-a7dd068deb74"); public AuthRequestEvent() { } - + @LauncherNetworkAPI public String error; + @LauncherNetworkAPI public ClientPermissions permissions; + @LauncherNetworkAPI public PlayerProfile playerProfile; + @LauncherNetworkAPI public String accessToken; + public AuthRequestEvent(PlayerProfile pp, String accessToken, ClientPermissions permissions) { + this.playerProfile = pp; + this.accessToken = accessToken; + this.permissions = permissions; + } + @Override public UUID getUUID() { return uuid; diff --git a/libLauncher/src/main/java/ru/gravit/launcher/events/request/BatchProfileByUsernameRequestEvent.java b/libLauncher/src/main/java/ru/gravit/launcher/events/request/BatchProfileByUsernameRequestEvent.java index 18806ac1..5ea87990 100644 --- a/libLauncher/src/main/java/ru/gravit/launcher/events/request/BatchProfileByUsernameRequestEvent.java +++ b/libLauncher/src/main/java/ru/gravit/launcher/events/request/BatchProfileByUsernameRequestEvent.java @@ -1,5 +1,6 @@ package ru.gravit.launcher.events.request; +import ru.gravit.launcher.LauncherNetworkAPI; import ru.gravit.launcher.profiles.PlayerProfile; import ru.gravit.launcher.request.ResultInterface; import ru.gravit.utils.event.EventInterface; @@ -9,8 +10,18 @@ public class BatchProfileByUsernameRequestEvent implements EventInterface, ResultInterface { private static final UUID uuid = UUID.fromString("c1d6729e-be2c-48cc-b5ae-af8c012232c3"); + @LauncherNetworkAPI public String error; + @LauncherNetworkAPI public PlayerProfile[] playerProfiles; + + public BatchProfileByUsernameRequestEvent(PlayerProfile[] profiles) { + this.playerProfiles = profiles; + } + + public BatchProfileByUsernameRequestEvent() { + } + @Override public UUID getUUID() { return uuid; diff --git a/libLauncher/src/main/java/ru/gravit/launcher/events/request/CheckServerEvent.java b/libLauncher/src/main/java/ru/gravit/launcher/events/request/CheckServerRequestEvent.java similarity index 60% rename from libLauncher/src/main/java/ru/gravit/launcher/events/request/CheckServerEvent.java rename to libLauncher/src/main/java/ru/gravit/launcher/events/request/CheckServerRequestEvent.java index 497a9893..cbe1bd21 100644 --- a/libLauncher/src/main/java/ru/gravit/launcher/events/request/CheckServerEvent.java +++ b/libLauncher/src/main/java/ru/gravit/launcher/events/request/CheckServerRequestEvent.java @@ -1,16 +1,26 @@ package ru.gravit.launcher.events.request; +import ru.gravit.launcher.LauncherNetworkAPI; import ru.gravit.launcher.profiles.PlayerProfile; import ru.gravit.launcher.request.ResultInterface; import ru.gravit.utils.event.EventInterface; import java.util.UUID; -public class CheckServerEvent implements EventInterface, ResultInterface { +public class CheckServerRequestEvent implements EventInterface, ResultInterface { private static final UUID _uuid = UUID.fromString("8801d07c-51ba-4059-b61d-fe1f1510b28a"); - public String type = "success"; + @LauncherNetworkAPI public UUID uuid; + @LauncherNetworkAPI public PlayerProfile playerProfile; + + public CheckServerRequestEvent(PlayerProfile playerProfile) { + this.playerProfile = playerProfile; + } + + public CheckServerRequestEvent() { + } + @Override public UUID getUUID() { return _uuid; diff --git a/libLauncher/src/main/java/ru/gravit/launcher/events/request/EchoRequestEvent.java b/libLauncher/src/main/java/ru/gravit/launcher/events/request/EchoRequestEvent.java new file mode 100644 index 00000000..3395d32a --- /dev/null +++ b/libLauncher/src/main/java/ru/gravit/launcher/events/request/EchoRequestEvent.java @@ -0,0 +1,27 @@ +package ru.gravit.launcher.events.request; + +import ru.gravit.launcher.LauncherNetworkAPI; +import ru.gravit.launcher.request.ResultInterface; +import ru.gravit.utils.event.EventInterface; + +import java.util.UUID; + +public class EchoRequestEvent implements ResultInterface, EventInterface { + private static final UUID uuid = UUID.fromString("0a1f820f-7cd5-47a5-ae0e-17492e0e1fe1"); + @LauncherNetworkAPI + public String echo; + + public EchoRequestEvent(String echo) { + this.echo = echo; + } + + @Override + public String getType() { + return "echo"; + } + + @Override + public UUID getUUID() { + return uuid; + } +} diff --git a/libLauncher/src/main/java/ru/gravit/launcher/events/request/ErrorRequestEvent.java b/libLauncher/src/main/java/ru/gravit/launcher/events/request/ErrorRequestEvent.java new file mode 100644 index 00000000..4f27c76d --- /dev/null +++ b/libLauncher/src/main/java/ru/gravit/launcher/events/request/ErrorRequestEvent.java @@ -0,0 +1,25 @@ +package ru.gravit.launcher.events.request; + +import ru.gravit.launcher.request.ResultInterface; +import ru.gravit.utils.event.EventInterface; + +import java.util.UUID; + +public class ErrorRequestEvent implements ResultInterface, EventInterface { + public static UUID uuid = UUID.fromString("0af22bc7-aa01-4881-bdbb-dc62b3cdac96"); + public ErrorRequestEvent(String error) { + this.error = error; + } + + public final String error; + + @Override + public String getType() { + return "error"; + } + + @Override + public UUID getUUID() { + return null; + } +} diff --git a/libLauncher/src/main/java/ru/gravit/launcher/events/request/ExecCommandRequestEvent.java b/libLauncher/src/main/java/ru/gravit/launcher/events/request/ExecCommandRequestEvent.java new file mode 100644 index 00000000..d1eafbf7 --- /dev/null +++ b/libLauncher/src/main/java/ru/gravit/launcher/events/request/ExecCommandRequestEvent.java @@ -0,0 +1,15 @@ +package ru.gravit.launcher.events.request; + +import ru.gravit.launcher.request.ResultInterface; + +public class ExecCommandRequestEvent implements ResultInterface { + @Override + public String getType() { + return "execCmd"; + } + boolean success; + + public ExecCommandRequestEvent(boolean success) { + this.success = success; + } +} diff --git a/libLauncher/src/main/java/ru/gravit/launcher/events/request/JoinServerRequestEvent.java b/libLauncher/src/main/java/ru/gravit/launcher/events/request/JoinServerRequestEvent.java index 3a76863c..ae3948d2 100644 --- a/libLauncher/src/main/java/ru/gravit/launcher/events/request/JoinServerRequestEvent.java +++ b/libLauncher/src/main/java/ru/gravit/launcher/events/request/JoinServerRequestEvent.java @@ -7,7 +7,6 @@ public class JoinServerRequestEvent implements EventInterface, ResultInterface { private static final UUID uuid = UUID.fromString("2a12e7b5-3f4a-4891-a2f9-ea141c8e1995"); - public String type = "success"; public JoinServerRequestEvent(boolean allow) { this.allow = allow; diff --git a/libLauncher/src/main/java/ru/gravit/launcher/events/request/LauncherRequestEvent.java b/libLauncher/src/main/java/ru/gravit/launcher/events/request/LauncherRequestEvent.java index 55f37ed2..24e57760 100644 --- a/libLauncher/src/main/java/ru/gravit/launcher/events/request/LauncherRequestEvent.java +++ b/libLauncher/src/main/java/ru/gravit/launcher/events/request/LauncherRequestEvent.java @@ -1,5 +1,6 @@ package ru.gravit.launcher.events.request; +import ru.gravit.launcher.LauncherNetworkAPI; import ru.gravit.launcher.request.ResultInterface; import ru.gravit.utils.event.EventInterface; @@ -7,8 +8,12 @@ public class LauncherRequestEvent implements EventInterface, ResultInterface { private static final UUID uuid = UUID.fromString("d54cc12a-4f59-4f23-9b10-f527fdd2e38f"); - public String type = "success"; + @LauncherNetworkAPI public String url; + @LauncherNetworkAPI + public byte[] digest; + @LauncherNetworkAPI + public byte[] binary; public LauncherRequestEvent(boolean needUpdate, String url) { this.needUpdate = needUpdate; @@ -16,6 +21,17 @@ public LauncherRequestEvent(boolean needUpdate, String url) { } public boolean needUpdate; + + public LauncherRequestEvent(boolean b, byte[] digest) { + this.needUpdate = b; + this.digest = digest; + } + + public LauncherRequestEvent(byte[] binary, byte[] digest) { //Legacy support constructor + this.binary = binary; + this.digest = digest; + } + @Override public UUID getUUID() { return uuid; diff --git a/libLauncher/src/main/java/ru/gravit/launcher/events/request/LogEvent.java b/libLauncher/src/main/java/ru/gravit/launcher/events/request/LogEvent.java new file mode 100644 index 00000000..6afbc640 --- /dev/null +++ b/libLauncher/src/main/java/ru/gravit/launcher/events/request/LogEvent.java @@ -0,0 +1,15 @@ +package ru.gravit.launcher.events.request; + +import ru.gravit.launcher.request.ResultInterface; + +public class LogEvent implements ResultInterface { + @Override + public String getType() { + return "log"; + } + public String string; + + public LogEvent(String string) { + this.string = string; + } +} diff --git a/libLauncher/src/main/java/ru/gravit/launcher/events/request/ProfileByUUIDRequestEvent.java b/libLauncher/src/main/java/ru/gravit/launcher/events/request/ProfileByUUIDRequestEvent.java index 27c73810..c68a0bc5 100644 --- a/libLauncher/src/main/java/ru/gravit/launcher/events/request/ProfileByUUIDRequestEvent.java +++ b/libLauncher/src/main/java/ru/gravit/launcher/events/request/ProfileByUUIDRequestEvent.java @@ -1,5 +1,6 @@ package ru.gravit.launcher.events.request; +import ru.gravit.launcher.LauncherNetworkAPI; import ru.gravit.launcher.profiles.PlayerProfile; import ru.gravit.launcher.request.ResultInterface; import ru.gravit.utils.event.EventInterface; @@ -9,12 +10,18 @@ public class ProfileByUUIDRequestEvent implements EventInterface, ResultInterface { private static final UUID uuid = UUID.fromString("b9014cf3-4b95-4d38-8c5f-867f190a18a0"); - String error; - PlayerProfile playerProfile; + @LauncherNetworkAPI + public String error; + @LauncherNetworkAPI + public PlayerProfile playerProfile; public ProfileByUUIDRequestEvent(PlayerProfile playerProfile) { this.playerProfile = playerProfile; } + + public ProfileByUUIDRequestEvent() { + } + @Override public UUID getUUID() { return uuid; diff --git a/libLauncher/src/main/java/ru/gravit/launcher/events/request/ProfileByUsernameRequestEvent.java b/libLauncher/src/main/java/ru/gravit/launcher/events/request/ProfileByUsernameRequestEvent.java index b85829f1..bda26360 100644 --- a/libLauncher/src/main/java/ru/gravit/launcher/events/request/ProfileByUsernameRequestEvent.java +++ b/libLauncher/src/main/java/ru/gravit/launcher/events/request/ProfileByUsernameRequestEvent.java @@ -1,5 +1,6 @@ package ru.gravit.launcher.events.request; +import ru.gravit.launcher.LauncherNetworkAPI; import ru.gravit.launcher.profiles.PlayerProfile; import ru.gravit.launcher.request.ResultInterface; import ru.gravit.utils.event.EventInterface; @@ -9,8 +10,10 @@ public class ProfileByUsernameRequestEvent implements EventInterface, ResultInterface { private static final UUID uuid = UUID.fromString("06204302-ff6b-4779-b97d-541e3bc39aa1"); - String error; - PlayerProfile playerProfile; + @LauncherNetworkAPI + public String error; + @LauncherNetworkAPI + public PlayerProfile playerProfile; public ProfileByUsernameRequestEvent(PlayerProfile playerProfile) { this.playerProfile = playerProfile; diff --git a/libLauncher/src/main/java/ru/gravit/launcher/events/request/ProfilesRequestEvent.java b/libLauncher/src/main/java/ru/gravit/launcher/events/request/ProfilesRequestEvent.java index 3b788f17..6ce432b1 100644 --- a/libLauncher/src/main/java/ru/gravit/launcher/events/request/ProfilesRequestEvent.java +++ b/libLauncher/src/main/java/ru/gravit/launcher/events/request/ProfilesRequestEvent.java @@ -1,5 +1,6 @@ package ru.gravit.launcher.events.request; +import ru.gravit.launcher.LauncherNetworkAPI; import ru.gravit.launcher.profiles.ClientProfile; import ru.gravit.launcher.request.ResultInterface; import ru.gravit.utils.event.EventInterface; @@ -10,12 +11,16 @@ public class ProfilesRequestEvent implements EventInterface, ResultInterface { private static final UUID uuid = UUID.fromString("2f26fbdf-598a-46dd-92fc-1699c0e173b1"); - List profiles; + @LauncherNetworkAPI + public List profiles; public ProfilesRequestEvent(List profiles) { this.profiles = profiles; } + public ProfilesRequestEvent() { + } + String error; @Override public UUID getUUID() { diff --git a/libLauncher/src/main/java/ru/gravit/launcher/events/request/SetProfileRequestEvent.java b/libLauncher/src/main/java/ru/gravit/launcher/events/request/SetProfileRequestEvent.java new file mode 100644 index 00000000..5a0ba168 --- /dev/null +++ b/libLauncher/src/main/java/ru/gravit/launcher/events/request/SetProfileRequestEvent.java @@ -0,0 +1,26 @@ +package ru.gravit.launcher.events.request; + +import ru.gravit.launcher.profiles.ClientProfile; +import ru.gravit.launcher.request.ResultInterface; +import ru.gravit.utils.event.EventInterface; + +import java.util.UUID; + +public class SetProfileRequestEvent implements ResultInterface, EventInterface { + private static final UUID uuid = UUID.fromString("08c0de9e-4364-4152-9066-8354a3a48541"); + public ClientProfile newProfile; + + public SetProfileRequestEvent(ClientProfile newProfile) { + this.newProfile = newProfile; + } + + @Override + public String getType() { + return "setProfile"; + } + + @Override + public UUID getUUID() { + return uuid; + } +} diff --git a/libLauncher/src/main/java/ru/gravit/launcher/events/request/UpdateListRequestEvent.java b/libLauncher/src/main/java/ru/gravit/launcher/events/request/UpdateListRequestEvent.java index 73136430..6319a855 100644 --- a/libLauncher/src/main/java/ru/gravit/launcher/events/request/UpdateListRequestEvent.java +++ b/libLauncher/src/main/java/ru/gravit/launcher/events/request/UpdateListRequestEvent.java @@ -1,19 +1,19 @@ package ru.gravit.launcher.events.request; -import ru.gravit.launcher.hasher.HashedDir; +import ru.gravit.launcher.LauncherNetworkAPI; import ru.gravit.launcher.request.ResultInterface; import ru.gravit.utils.event.EventInterface; +import java.util.HashSet; import java.util.UUID; public class UpdateListRequestEvent implements EventInterface, ResultInterface { private static final UUID uuid = UUID.fromString("5fa836ae-6b61-401c-96ac-d8396f07ec6b"); - public final String type; - public final HashedDir dir; + @LauncherNetworkAPI + public final HashSet dirs; - public UpdateListRequestEvent(HashedDir dir) { - this.dir = dir; - type = "success"; + public UpdateListRequestEvent(HashSet dirs) { + this.dirs = dirs; } @Override public UUID getUUID() { diff --git a/libLauncher/src/main/java/ru/gravit/utils/helper/IOHelper.java b/libLauncher/src/main/java/ru/gravit/utils/helper/IOHelper.java index 05514c30..d4e1ad33 100644 --- a/libLauncher/src/main/java/ru/gravit/utils/helper/IOHelper.java +++ b/libLauncher/src/main/java/ru/gravit/utils/helper/IOHelper.java @@ -338,23 +338,42 @@ public static Inflater newInflater() { public static InputStream newInput(Path file) throws IOException { return Files.newInputStream(file, READ_OPTIONS); } + @LauncherAPI + public static InputStream newBufferedInput(Path file) throws IOException { + return new BufferedInputStream(Files.newInputStream(file, READ_OPTIONS)); + } @LauncherAPI public static InputStream newInput(URL url) throws IOException { return newConnection(url).getInputStream(); } + @LauncherAPI + public static BufferedInputStream newBufferedInput(URL url) throws IOException { + return new BufferedInputStream(newConnection(url).getInputStream()); + } @LauncherAPI public static OutputStream newOutput(Path file) throws IOException { return newOutput(file, false); } + @LauncherAPI + public static OutputStream newBufferedOutput(Path file) throws IOException { + return newBufferedOutput(file, false); + } + @LauncherAPI public static OutputStream newOutput(Path file, boolean append) throws IOException { createParentDirs(file); return Files.newOutputStream(file, append ? APPEND_OPTIONS : WRITE_OPTIONS); } + @LauncherAPI + public static OutputStream newBufferedOutput(Path file, boolean append) throws IOException { + createParentDirs(file); + return new BufferedOutputStream(Files.newOutputStream(file, append ? APPEND_OPTIONS : WRITE_OPTIONS)); + } + @LauncherAPI public static BufferedReader newReader(InputStream input) { return newReader(input, UNICODE_CHARSET); diff --git a/libLauncher/src/main/java/ru/gravit/utils/helper/LogHelper.java b/libLauncher/src/main/java/ru/gravit/utils/helper/LogHelper.java index 4e76fa66..2240e757 100644 --- a/libLauncher/src/main/java/ru/gravit/utils/helper/LogHelper.java +++ b/libLauncher/src/main/java/ru/gravit/utils/helper/LogHelper.java @@ -35,21 +35,39 @@ public final class LogHelper { private static final AtomicBoolean DEBUG_ENABLED = new AtomicBoolean(Boolean.getBoolean(DEBUG_PROPERTY)); private static final AtomicBoolean STACKTRACE_ENABLED = new AtomicBoolean(Boolean.getBoolean(STACKTRACE_PROPERTY)); private static final AtomicBoolean DEV_ENABLED = new AtomicBoolean(Boolean.getBoolean(DEV_PROPERTY)); - private static final Set OUTPUTS = Collections.newSetFromMap(new ConcurrentHashMap<>(2)); - private static final Output STD_OUTPUT; + public static class OutputEnity + { + public Output output; + public OutputTypes type; + + public OutputEnity(Output output, OutputTypes type) { + this.output = output; + this.type = type; + } + } + public enum OutputTypes + { + PLAIN, JANSI, HTML + } + private static final Set OUTPUTS = Collections.newSetFromMap(new ConcurrentHashMap<>(2)); + private static final OutputEnity STD_OUTPUT; private LogHelper() { } @LauncherAPI - public static void addOutput(Output output) { + public static void addOutput(OutputEnity output) { OUTPUTS.add(Objects.requireNonNull(output, "output")); } + @LauncherAPI + public static void addOutput(Output output, OutputTypes type) { + OUTPUTS.add(new OutputEnity(Objects.requireNonNull(output, "output"),type)); + } @LauncherAPI public static void addOutput(Path file) throws IOException { if (JANSI) { - addOutput(new JAnsiOutput(IOHelper.newOutput(file, true))); + addOutput(new JAnsiOutput(IOHelper.newOutput(file, true)),OutputTypes.JANSI); } else { addOutput(IOHelper.newWriter(file, true)); } @@ -57,7 +75,7 @@ public static void addOutput(Path file) throws IOException { @LauncherAPI public static void addOutput(Writer writer) { - addOutput(new WriterOutput(writer)); + addOutput(new WriterOutput(writer), OutputTypes.PLAIN); } @LauncherAPI @@ -142,29 +160,87 @@ public static void setDevEnabled(boolean stacktraceEnabled) { @LauncherAPI public static void log(Level level, String message, boolean sub) { String dateTime = DATE_TIME_FORMATTER.format(LocalDateTime.now()); - println(JANSI ? ansiFormatLog(level, dateTime, message, sub) : - formatLog(level, message, dateTime, sub)); - } + String jansiString = null, plainString = null; + for (OutputEnity output : OUTPUTS) { + if(output.type == OutputTypes.JANSI && JANSI) + { + if(jansiString != null){ + output.output.println(jansiString); + continue; + } - @LauncherAPI - public static void printVersion(String product) { - println(JANSI ? ansiFormatVersion(product) : formatVersion(product)); - } + jansiString = ansiFormatLog(level, dateTime, message, sub); + output.output.println(jansiString); + } + else + { + if(plainString != null){ + output.output.println(plainString); + continue; + } - @LauncherAPI - public static void printLicense(String product) { - println(JANSI ? ansiFormatLicense(product) : formatLicense(product)); - } - - @LauncherAPI - public static synchronized void println(String message) { - for (Output output : OUTPUTS) { - output.println(message); + plainString = formatLog(level, message, dateTime, sub); + output.output.println(plainString); + } } } @LauncherAPI - public static boolean removeOutput(Output output) { + public static void printVersion(String product) { + String jansiString = null, plainString = null; + for (OutputEnity output : OUTPUTS) { + if(output.type == OutputTypes.JANSI && JANSI) + { + if(jansiString != null){ + output.output.println(jansiString); + continue; + } + + jansiString = ansiFormatVersion(product); + output.output.println(jansiString); + } + else + { + if(plainString != null){ + output.output.println(plainString); + continue; + } + + plainString = formatVersion(product); + output.output.println(plainString); + } + } + } + + @LauncherAPI + public static void printLicense(String product) { + String jansiString = null, plainString = null; + for (OutputEnity output : OUTPUTS) { + if(output.type == OutputTypes.JANSI && JANSI) + { + if(jansiString != null){ + output.output.println(jansiString); + continue; + } + + jansiString = ansiFormatLicense(product); + output.output.println(jansiString); + } + else + { + if(plainString != null){ + output.output.println(plainString); + continue; + } + + plainString = formatLicense(product); + output.output.println(plainString); + } + } + } + + @LauncherAPI + public static boolean removeOutput(OutputEnity output) { return OUTPUTS.remove(output); } @@ -321,7 +397,7 @@ private static String formatLicense(String product) { JANSI = jansi; // Add std writer - STD_OUTPUT = System.out::println; + STD_OUTPUT = new OutputEnity(System.out::println, JANSI ? OutputTypes.JANSI : OutputTypes.PLAIN); addOutput(STD_OUTPUT); // Add file log writer diff --git a/modules b/modules index 9a7e59fb..90a3b3ea 160000 --- a/modules +++ b/modules @@ -1 +1 @@ -Subproject commit 9a7e59fb8df543305a2b708822a398dcabcac4b9 +Subproject commit 90a3b3eac726659a64410ea3134f8bc22893de32