mirror of
https://github.com/GravitLauncher/Launcher
synced 2025-01-09 00:59:44 +03:00
Merge branch 'release/4.3.3'
This commit is contained in:
commit
2e1aa5918a
89 changed files with 788 additions and 1625 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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<Map.Entry<UUID, Entry>> entrySet = entrySet();
|
||||
try (HOutput output = new HOutput(IOHelper.newOutput(fileTmp))) {
|
||||
output.writeLength(entrySet.size(), 0);
|
||||
for (Map.Entry<UUID, Entry> entry : entrySet) {
|
||||
output.writeUUID(entry.getKey());
|
||||
entry.getValue().write(output);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<UUID, Entry> entryMap = new HashMap<>(256);
|
||||
|
||||
private final Map<String, UUID> 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<Map.Entry<UUID, Entry>> 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;
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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<ClientProfile>) LaunchServer.server.getProfiles()));
|
||||
|
|
|
@ -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<ClientProfile> 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"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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<String> set = new HashSet<>();
|
||||
for(Map.Entry<String, SignedObjectHolder<HashedDir>> entry : LaunchServer.server.updatesDirMap.entrySet())
|
||||
set.add(entry.getKey());
|
||||
service.sendObject(ctx, new UpdateListRequestEvent(set));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,6 +31,11 @@
|
|||
<methods>;
|
||||
}
|
||||
|
||||
-keepclassmembers @ru.gravit.launcher.LauncherNetworkAPI class ** {
|
||||
<fields>;
|
||||
<methods>;
|
||||
}
|
||||
|
||||
-keepclassmembers class ** {
|
||||
@ru.gravit.launcher.LauncherAPI
|
||||
<fields>;
|
||||
|
@ -38,6 +43,13 @@
|
|||
<methods>;
|
||||
}
|
||||
|
||||
-keepclassmembers class ** {
|
||||
@ru.gravit.launcher.LauncherNetworkAPI
|
||||
<fields>;
|
||||
@ru.gravit.launcher.LauncherNetworkAPI
|
||||
<methods>;
|
||||
}
|
||||
|
||||
-keepclassmembers public class ** {
|
||||
public static void main(java.lang.String[]);
|
||||
public static void premain(java.lang.String, java.lang.instrument.Instrumentation);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<Runnable> 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");
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<String, Object> 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");
|
||||
}
|
||||
|
|
|
@ -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<T> implements IndexedCheckModel<T> {
|
||||
private final Map<T, BooleanProperty> itemBooleanMap;
|
||||
|
||||
private final BitSet checkedIndices;
|
||||
private final ReadOnlyUnbackedObservableList<Integer> checkedIndicesList;
|
||||
private final ReadOnlyUnbackedObservableList<T> checkedItemsList;
|
||||
|
||||
CheckBitSetModelBase(final Map<T, BooleanProperty> itemBooleanMap) {
|
||||
this.itemBooleanMap = itemBooleanMap;
|
||||
|
||||
this.checkedIndices = new BitSet();
|
||||
|
||||
this.checkedIndicesList = new ReadOnlyUnbackedObservableList<Integer>() {
|
||||
@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<T>() {
|
||||
@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<Integer, T> map = this::getItem;
|
||||
|
||||
checkedIndicesList.addListener((ListChangeListener<Integer>) 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<T>) 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<Integer> getCheckedIndices() {
|
||||
return checkedIndicesList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObservableList<T> 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));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<T> extends ControlsFXControl {
|
||||
private static class CheckComboBoxBitSetCheckModel<T> extends CheckBitSetModelBase<T> {
|
||||
private final ObservableList<T> items;
|
||||
|
||||
CheckComboBoxBitSetCheckModel(final ObservableList<T> items, final Map<T, BooleanProperty> itemBooleanMap) {
|
||||
super(itemBooleanMap);
|
||||
|
||||
this.items = items;
|
||||
this.items.addListener((ListChangeListener<T>) 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<T> items;
|
||||
private final Map<T, BooleanProperty> itemBooleanMap;
|
||||
private CheckComboBoxSkin<T> checkComboBoxSkin;
|
||||
private ObjectProperty<IndexedCheckModel<T>> checkModel = new SimpleObjectProperty<>(this, "checkModel");
|
||||
private ObjectProperty<StringConverter<T>> converter = new SimpleObjectProperty<>(this,
|
||||
"converter");
|
||||
private StringProperty title = new SimpleStringProperty(null);
|
||||
|
||||
public CheckComboBox() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public CheckComboBox(final ObservableList<T> 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<IndexedCheckModel<T>> checkModelProperty() {
|
||||
return checkModel;
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public final ObjectProperty<StringConverter<T>> converterProperty() {
|
||||
return converter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Skin<?> createDefaultSkin() {
|
||||
checkComboBoxSkin = new CheckComboBoxSkin<>(this);
|
||||
return checkComboBoxSkin;
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public final IndexedCheckModel<T> getCheckModel() {
|
||||
return checkModel == null ? null : checkModel.get();
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public final StringConverter<T> 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<T> 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<T> value) {
|
||||
checkModelProperty().set(value);
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public final void setConverter(StringConverter<T> 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;
|
||||
}
|
||||
}
|
|
@ -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<T> extends BehaviorSkinBase<CheckComboBox<T>, BehaviorBase<CheckComboBox<T>>> {
|
||||
|
||||
private final ComboBox<T> comboBox;
|
||||
private final ListCell<T> buttonCell;
|
||||
|
||||
private final CheckComboBox<T> control;
|
||||
private final ReadOnlyUnbackedObservableList<T> selectedItems;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public CheckComboBoxSkin(final CheckComboBox<T> control) {
|
||||
super(control, new BehaviorBase<>(control, Collections.emptyList()));
|
||||
|
||||
this.control = control;
|
||||
ObservableList<T> items = control.getItems();
|
||||
|
||||
ReadOnlyUnbackedObservableList<Integer> selectedIndices = (ReadOnlyUnbackedObservableList<Integer>) control.getCheckModel().getCheckedIndices();
|
||||
selectedItems = (ReadOnlyUnbackedObservableList<T>) control.getCheckModel().getCheckedItems();
|
||||
|
||||
comboBox = new ComboBox<T>(items) {
|
||||
@Override
|
||||
protected javafx.scene.control.Skin<?> createDefaultSkin() {
|
||||
return createComboBoxListViewSkin(this);
|
||||
}
|
||||
};
|
||||
comboBox.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
|
||||
|
||||
comboBox.setCellFactory(listView -> {
|
||||
CheckBoxListCell<T> 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<T>() {
|
||||
@Override
|
||||
protected void updateItem(T item, boolean empty) {
|
||||
setText(getTextString());
|
||||
}
|
||||
};
|
||||
comboBox.setButtonCell(buttonCell);
|
||||
comboBox.setValue((T) getTextString());
|
||||
|
||||
selectedIndices.addListener((ListChangeListener<Integer>) 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<T> comboBox) {
|
||||
final ComboBoxListViewSkin<T> comboBoxListViewSkin = new ComboBoxListViewSkin<T>(comboBox) {
|
||||
@Override
|
||||
protected boolean isHideOnClickEnabled() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@SuppressWarnings("unchecked") final ListView<T> listView = (ListView<T>) comboBoxListViewSkin.getPopupContent();
|
||||
listView.setOnKeyPressed(e -> {
|
||||
if (e.getCode() == KeyCode.SPACE) {
|
||||
T item = listView.getSelectionModel().getSelectedItem();
|
||||
if (item != null) {
|
||||
final IndexedCheckModel<T> 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();
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
package ru.gravit.launcher.gui.choosebox;
|
||||
|
||||
import javafx.collections.ObservableList;
|
||||
import ru.gravit.launcher.LauncherAPI;
|
||||
|
||||
public interface CheckModel<T> {
|
||||
@LauncherAPI
|
||||
void check(T item);
|
||||
|
||||
@LauncherAPI
|
||||
void checkAll();
|
||||
|
||||
@LauncherAPI
|
||||
void clearCheck(T item);
|
||||
|
||||
@LauncherAPI
|
||||
void clearChecks();
|
||||
|
||||
@LauncherAPI
|
||||
ObservableList<T> getCheckedItems();
|
||||
|
||||
@LauncherAPI
|
||||
int getItemCount();
|
||||
|
||||
@LauncherAPI
|
||||
boolean isChecked(T item);
|
||||
|
||||
@LauncherAPI
|
||||
boolean isEmpty();
|
||||
|
||||
@LauncherAPI
|
||||
void toggleCheckState(T item);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package ru.gravit.launcher.gui.choosebox;
|
||||
|
||||
import javafx.collections.ObservableList;
|
||||
import ru.gravit.launcher.LauncherAPI;
|
||||
|
||||
public interface IndexedCheckModel<T> extends CheckModel<T> {
|
||||
@LauncherAPI
|
||||
void check(int index);
|
||||
|
||||
@LauncherAPI
|
||||
void checkIndices(int... indices);
|
||||
|
||||
@LauncherAPI
|
||||
void clearCheck(int index);
|
||||
|
||||
@LauncherAPI
|
||||
ObservableList<Integer> getCheckedIndices();
|
||||
|
||||
@LauncherAPI
|
||||
T getItem(int index);
|
||||
|
||||
@LauncherAPI
|
||||
int getItemIndex(T item);
|
||||
|
||||
@LauncherAPI
|
||||
boolean isChecked(int index);
|
||||
|
||||
@LauncherAPI
|
||||
void toggleCheckState(int index);
|
||||
|
||||
}
|
|
@ -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<ProgressCircleIndicator, Number> getCssMetaData() {
|
||||
return StyleableProperties.INNER_CIRCLE_RADIUS;
|
||||
}
|
||||
};
|
||||
|
||||
private static class StyleableProperties {
|
||||
private static final CssMetaData<ProgressCircleIndicator, Number> INNER_CIRCLE_RADIUS = new CssMetaData<ProgressCircleIndicator, Number>(
|
||||
"-fx-inner-radius", SizeConverter.getInstance(), 60) {
|
||||
|
||||
@Override
|
||||
public boolean isSettable(ProgressCircleIndicator n) {
|
||||
return n.innerCircleRadiusProperty() == null || !n.innerCircleRadiusProperty().isBound();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public StyleableProperty<Number> getStyleableProperty(ProgressCircleIndicator n) {
|
||||
return (StyleableProperty<Number>) n.innerCircleRadiusProperty();
|
||||
}
|
||||
};
|
||||
|
||||
public static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
|
||||
|
||||
static {
|
||||
final List<CssMetaData<? extends Styleable, ?>> styleables = new ArrayList<>(Control.getClassCssMetaData());
|
||||
styleables.add(INNER_CIRCLE_RADIUS);
|
||||
STYLEABLES = Collections.unmodifiableList(styleables);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
|
||||
return StyleableProperties.STYLEABLES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CssMetaData<? extends Styleable, ?>> getControlCssMetaData() {
|
||||
return StyleableProperties.STYLEABLES;
|
||||
}
|
||||
}
|
|
@ -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<RingProgressIndicator, Number> getCssMetaData() {
|
||||
return StyleableProperties.RING_WIDTH;
|
||||
}
|
||||
};
|
||||
|
||||
private static class StyleableProperties {
|
||||
private static final CssMetaData<RingProgressIndicator, Number> RING_WIDTH = new CssMetaData<RingProgressIndicator, Number>(
|
||||
"-fx-ring-width", SizeConverter.getInstance(), 22) {
|
||||
|
||||
@Override
|
||||
public boolean isSettable(RingProgressIndicator n) {
|
||||
return n.ringWidth == null || !n.ringWidth.isBound();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public StyleableProperty<Number> getStyleableProperty(RingProgressIndicator n) {
|
||||
return (StyleableProperty<Number>) n.ringWidth;
|
||||
}
|
||||
};
|
||||
|
||||
public static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
|
||||
|
||||
static {
|
||||
final List<CssMetaData<? extends Styleable, ?>> styleables = new ArrayList<>(Control.getClassCssMetaData());
|
||||
styleables.addAll(getClassCssMetaData());
|
||||
styleables.add(RING_WIDTH);
|
||||
STYLEABLES = Collections.unmodifiableList(styleables);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CssMetaData<? extends Styleable, ?>> getControlCssMetaData() {
|
||||
return StyleableProperties.STYLEABLES;
|
||||
}
|
||||
}
|
|
@ -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<RingProgressIndicator> {
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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];
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ public CustomRequest(LauncherConfig config) {
|
|||
public abstract String getName();
|
||||
|
||||
@Override
|
||||
public final Integer getType() {
|
||||
public final Integer getLegacyType() {
|
||||
return 255;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ public PingRequest(LauncherConfig config) {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Integer getType() {
|
||||
public Integer getLegacyType() {
|
||||
return RequestType.PING.getNumber();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -17,7 +17,7 @@ public ExecCommandRequest(LogHelper.Output output, String cmd) {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Integer getType() {
|
||||
public Integer getLegacyType() {
|
||||
return RequestType.EXECCOMMAND.getNumber();
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Result> {
|
||||
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<AuthRequestEvent> 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";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ public AuthServerRequest(String login, byte[] encryptedPassword, int auth_id) {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Integer getType() {
|
||||
public Integer getLegacyType() {
|
||||
return RequestType.SERVERAUTH.getNumber();
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
public class ChangeServerRequest extends Request<ChangeServerRequest.Result> {
|
||||
@Override
|
||||
public Integer getType() {
|
||||
public Integer getLegacyType() {
|
||||
return RequestType.CHANGESERVER.getNumber();
|
||||
}
|
||||
|
||||
|
|
|
@ -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<PlayerProfile> {
|
||||
public final class CheckServerRequest extends Request<CheckServerRequestEvent> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Boolean> {
|
||||
public final class JoinServerRequest extends Request<JoinServerRequestEvent> {
|
||||
|
||||
// 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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<Boolean> {
|
||||
private ClientProfile profile;
|
||||
public class SetProfileRequest extends Request<SetProfileRequestEvent> 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";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<LauncherRequest.Result> {
|
||||
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<LauncherRequestEvent> 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<String> 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";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ public LegacyLauncherRequest(LauncherConfig config) {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Integer getType() {
|
||||
public Integer getLegacyType() {
|
||||
return RequestType.LEGACYLAUNCHER.getNumber();
|
||||
}
|
||||
|
||||
|
|
|
@ -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<ProfilesRequest.Result> {
|
||||
|
||||
public static final class Result {
|
||||
@LauncherAPI
|
||||
public final List<ClientProfile> profiles;
|
||||
|
||||
private Result(List<ClientProfile> profiles) {
|
||||
this.profiles = Collections.unmodifiableList(profiles);
|
||||
}
|
||||
}
|
||||
public final class ProfilesRequest extends Request<ProfilesRequestEvent> 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";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Set<String>> {
|
||||
public final class UpdateListRequest extends Request<UpdateListRequestEvent> 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<String> 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<String> result = new HashSet<>(count);
|
||||
HashSet<String> 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";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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<PlayerProfile[]> {
|
||||
public final class BatchProfileByUsernameRequest extends Request<BatchProfileByUsernameRequestEvent> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<PlayerProfile> {
|
||||
public final class ProfileByUUIDRequest extends Request<ProfileByUUIDRequestEvent> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<PlayerProfile> {
|
||||
public final class ProfileByUsernameRequest extends Request<ProfileByUsernameRequestEvent> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<? extends RequestInterface> getRequestClass(String key) {
|
||||
return requests.get(key);
|
||||
|
@ -69,7 +76,18 @@ public void registerResult(String key, Class<? extends ResultInterface> 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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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<ResultEvent> requests;
|
||||
public HashSet<ResultEvent> 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;
|
||||
|
|
|
@ -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)) {
|
||||
|
|
22
compat/auth/ips.php
Normal file
22
compat/auth/ips.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
if ( !isset( $_GET['login'] ) OR !isset( $_GET['password'] ) )
|
||||
{
|
||||
exit;
|
||||
}
|
||||
require_once 'init.php';
|
||||
$member = \IPS\Member::load( $_GET['login'], 'name' );
|
||||
if ( $member->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';
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<ClientProfile> profiles;
|
||||
@LauncherNetworkAPI
|
||||
public List<ClientProfile> profiles;
|
||||
|
||||
public ProfilesRequestEvent(List<ClientProfile> profiles) {
|
||||
this.profiles = profiles;
|
||||
}
|
||||
|
||||
public ProfilesRequestEvent() {
|
||||
}
|
||||
|
||||
String error;
|
||||
@Override
|
||||
public UUID getUUID() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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<String> dirs;
|
||||
|
||||
public UpdateListRequestEvent(HashedDir dir) {
|
||||
this.dir = dir;
|
||||
type = "success";
|
||||
public UpdateListRequestEvent(HashSet<String> dirs) {
|
||||
this.dirs = dirs;
|
||||
}
|
||||
@Override
|
||||
public UUID getUUID() {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<Output> 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<OutputEnity> 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
|
||||
|
|
2
modules
2
modules
|
@ -1 +1 @@
|
|||
Subproject commit 9a7e59fb8df543305a2b708822a398dcabcac4b9
|
||||
Subproject commit 90a3b3eac726659a64410ea3134f8bc22893de32
|
Loading…
Reference in a new issue