mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-12-23 09:01:08 +03:00
[REFRACTOR] Удалены все запросы и большинство ответов по протоколу сашка
This commit is contained in:
parent
d805fb7515
commit
dbb07dee79
46 changed files with 39 additions and 1506 deletions
|
@ -1,6 +1,6 @@
|
||||||
package ru.gravit.launchserver.auth.protect;
|
package ru.gravit.launchserver.auth.protect;
|
||||||
|
|
||||||
import ru.gravit.launchserver.response.auth.AuthResponse;
|
import ru.gravit.launchserver.socket.websocket.json.auth.AuthResponse;
|
||||||
import ru.gravit.utils.helper.SecurityHelper;
|
import ru.gravit.utils.helper.SecurityHelper;
|
||||||
|
|
||||||
public class NoProtectHandler extends ProtectHandler {
|
public class NoProtectHandler extends ProtectHandler {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package ru.gravit.launchserver.auth.protect;
|
package ru.gravit.launchserver.auth.protect;
|
||||||
|
|
||||||
import ru.gravit.launchserver.response.auth.AuthResponse;
|
import ru.gravit.launchserver.socket.websocket.json.auth.AuthResponse;
|
||||||
import ru.gravit.utils.helper.VerifyHelper;
|
import ru.gravit.utils.helper.VerifyHelper;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
|
@ -200,7 +200,7 @@ public Path process(Path inputJar) throws IOException {
|
||||||
byte[] launcherConfigBytes;
|
byte[] launcherConfigBytes;
|
||||||
try (ByteArrayOutputStream configArray = IOHelper.newByteArrayOutput()) {
|
try (ByteArrayOutputStream configArray = IOHelper.newByteArrayOutput()) {
|
||||||
try (HOutput configOutput = new HOutput(configArray)) {
|
try (HOutput configOutput = new HOutput(configArray)) {
|
||||||
new LauncherConfig(server.config.getAddress(), server.config.port, server.publicKey, runtime)
|
new LauncherConfig(server.config.netty.address, server.publicKey, runtime)
|
||||||
.write(configOutput);
|
.write(configOutput);
|
||||||
}
|
}
|
||||||
launcherConfigBytes = configArray.toByteArray();
|
launcherConfigBytes = configArray.toByteArray();
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
import ru.gravit.launchserver.LaunchServer;
|
||||||
import ru.gravit.launchserver.auth.AuthException;
|
import ru.gravit.launchserver.auth.AuthException;
|
||||||
import ru.gravit.launchserver.auth.provider.AuthProvider;
|
import ru.gravit.launchserver.auth.provider.AuthProvider;
|
||||||
import ru.gravit.launchserver.response.auth.AuthResponse;
|
|
||||||
import ru.gravit.launchserver.socket.Client;
|
import ru.gravit.launchserver.socket.Client;
|
||||||
|
import ru.gravit.launchserver.socket.websocket.json.auth.AuthResponse;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package ru.gravit.launchserver.manangers.hook;
|
package ru.gravit.launchserver.manangers.hook;
|
||||||
|
|
||||||
import ru.gravit.launchserver.auth.AuthException;
|
import ru.gravit.launchserver.auth.AuthException;
|
||||||
import ru.gravit.launchserver.response.auth.AuthResponse;
|
|
||||||
import ru.gravit.launchserver.socket.Client;
|
import ru.gravit.launchserver.socket.Client;
|
||||||
|
import ru.gravit.launchserver.socket.websocket.json.auth.AuthResponse;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
|
@ -5,11 +5,6 @@
|
||||||
import ru.gravit.launcher.serialize.HInput;
|
import ru.gravit.launcher.serialize.HInput;
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
import ru.gravit.launcher.serialize.HOutput;
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
import ru.gravit.launchserver.LaunchServer;
|
||||||
import ru.gravit.launchserver.response.admin.ExecCommandResponse;
|
|
||||||
import ru.gravit.launchserver.response.auth.*;
|
|
||||||
import ru.gravit.launchserver.response.profile.BatchProfileByUsernameResponse;
|
|
||||||
import ru.gravit.launchserver.response.profile.ProfileByUUIDResponse;
|
|
||||||
import ru.gravit.launchserver.response.profile.ProfileByUsernameResponse;
|
|
||||||
import ru.gravit.launchserver.response.update.*;
|
import ru.gravit.launchserver.response.update.*;
|
||||||
import ru.gravit.launchserver.socket.Client;
|
import ru.gravit.launchserver.socket.Client;
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
import ru.gravit.utils.helper.LogHelper;
|
||||||
|
@ -37,23 +32,8 @@ public static void registerResponse(int type, Factory<?> factory) {
|
||||||
|
|
||||||
public static void registerResponses() {
|
public static void registerResponses() {
|
||||||
registerResponse(RequestType.PING.getNumber(), PingResponse::new);
|
registerResponse(RequestType.PING.getNumber(), PingResponse::new);
|
||||||
registerResponse(RequestType.AUTH.getNumber(), AuthResponse::new);
|
|
||||||
registerResponse(RequestType.CHECK_SERVER.getNumber(), CheckServerResponse::new);
|
|
||||||
registerResponse(RequestType.JOIN_SERVER.getNumber(), JoinServerResponse::new);
|
|
||||||
|
|
||||||
registerResponse(RequestType.BATCH_PROFILE_BY_USERNAME.getNumber(), BatchProfileByUsernameResponse::new);
|
|
||||||
registerResponse(RequestType.PROFILE_BY_USERNAME.getNumber(), ProfileByUsernameResponse::new);
|
|
||||||
registerResponse(RequestType.PROFILE_BY_UUID.getNumber(), ProfileByUUIDResponse::new);
|
|
||||||
|
|
||||||
registerResponse(RequestType.LEGACYLAUNCHER.getNumber(), LegacyLauncherResponse::new);
|
registerResponse(RequestType.LEGACYLAUNCHER.getNumber(), LegacyLauncherResponse::new);
|
||||||
registerResponse(RequestType.LAUNCHER.getNumber(), LauncherResponse::new);
|
registerResponse(RequestType.LAUNCHER.getNumber(), LauncherResponse::new);
|
||||||
registerResponse(RequestType.UPDATE_LIST.getNumber(), UpdateListResponse::new);
|
|
||||||
registerResponse(RequestType.UPDATE.getNumber(), UpdateResponse::new);
|
|
||||||
registerResponse(RequestType.PROFILES.getNumber(), ProfilesResponse::new);
|
|
||||||
registerResponse(RequestType.SERVERAUTH.getNumber(), AuthServerResponse::new);
|
|
||||||
registerResponse(RequestType.SETPROFILE.getNumber(), SetProfileResponse::new);
|
|
||||||
registerResponse(RequestType.CHANGESERVER.getNumber(), ChangeServerResponse::new);
|
|
||||||
registerResponse(RequestType.EXECCOMMAND.getNumber(), ExecCommandResponse::new);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
package ru.gravit.launchserver.response.admin;
|
|
||||||
|
|
||||||
import ru.gravit.launcher.serialize.HInput;
|
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
|
||||||
import ru.gravit.launcher.serialize.SerializeLimits;
|
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
|
||||||
import ru.gravit.launchserver.response.Response;
|
|
||||||
import ru.gravit.launchserver.socket.Client;
|
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class ExecCommandResponse extends Response {
|
|
||||||
public ExecCommandResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
|
||||||
super(server, session, input, output, ip, clientData);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reply() throws Exception {
|
|
||||||
Client clientData = server.sessionManager.getClient(session);
|
|
||||||
if (!clientData.isAuth || !clientData.permissions.canAdmin || !server.config.enableRcon)
|
|
||||||
requestError("Access denied");
|
|
||||||
writeNoError(output);
|
|
||||||
String cmd = input.readString(SerializeLimits.MAX_COMMAND);
|
|
||||||
LogHelper.OutputEnity loutput = new LogHelper.OutputEnity(message -> {
|
|
||||||
try {
|
|
||||||
output.writeBoolean(true);
|
|
||||||
output.writeString(message, SerializeLimits.MAX_COMMAND);
|
|
||||||
} catch (IOException e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
}
|
|
||||||
}, LogHelper.OutputTypes.PLAIN);
|
|
||||||
LogHelper.addOutput(loutput);
|
|
||||||
try {
|
|
||||||
server.commandHandler.eval(cmd, false);
|
|
||||||
output.writeBoolean(false);
|
|
||||||
} finally {
|
|
||||||
LogHelper.removeOutput(loutput);
|
|
||||||
}
|
|
||||||
writeNoError(output);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,154 +0,0 @@
|
||||||
package ru.gravit.launchserver.response.auth;
|
|
||||||
|
|
||||||
import ru.gravit.launcher.OshiHWID;
|
|
||||||
import ru.gravit.launcher.profiles.ClientProfile;
|
|
||||||
import ru.gravit.launcher.serialize.HInput;
|
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
|
||||||
import ru.gravit.launcher.serialize.SerializeLimits;
|
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
|
||||||
import ru.gravit.launchserver.auth.AuthException;
|
|
||||||
import ru.gravit.launchserver.auth.AuthProviderPair;
|
|
||||||
import ru.gravit.launchserver.auth.hwid.HWIDException;
|
|
||||||
import ru.gravit.launchserver.auth.provider.AuthProvider;
|
|
||||||
import ru.gravit.launchserver.auth.provider.AuthProviderResult;
|
|
||||||
import ru.gravit.launchserver.response.Response;
|
|
||||||
import ru.gravit.launchserver.response.profile.ProfileByUUIDResponse;
|
|
||||||
import ru.gravit.launchserver.socket.Client;
|
|
||||||
import ru.gravit.utils.helper.IOHelper;
|
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
|
||||||
import ru.gravit.utils.helper.SecurityHelper;
|
|
||||||
import ru.gravit.utils.helper.VerifyHelper;
|
|
||||||
|
|
||||||
import javax.crypto.BadPaddingException;
|
|
||||||
import javax.crypto.IllegalBlockSizeException;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public final class AuthResponse extends Response {
|
|
||||||
private static String echo(int length) {
|
|
||||||
char[] chars = new char[length];
|
|
||||||
Arrays.fill(chars, '*');
|
|
||||||
return new String(chars);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
|
||||||
super(server, session, input, output, ip, clientData);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class AuthContext {
|
|
||||||
public AuthContext(long session, String login, int password_lenght, String customText, String client, String hwid, String ip, boolean isServerAuth) {
|
|
||||||
this.session = session;
|
|
||||||
this.login = login;
|
|
||||||
this.password_lenght = password_lenght;
|
|
||||||
this.customText = customText;
|
|
||||||
this.client = client;
|
|
||||||
this.hwid = hwid;
|
|
||||||
this.ip = ip;
|
|
||||||
this.isServerAuth = isServerAuth;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long session;
|
|
||||||
public String login;
|
|
||||||
public int password_lenght; //Use AuthProvider for get password
|
|
||||||
public String client;
|
|
||||||
public String hwid;
|
|
||||||
public String customText;
|
|
||||||
public String ip;
|
|
||||||
public boolean isServerAuth;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reply() throws Exception {
|
|
||||||
String login = input.readString(SerializeLimits.MAX_LOGIN);
|
|
||||||
boolean isClient = input.readBoolean();
|
|
||||||
String client = null;
|
|
||||||
if (isClient)
|
|
||||||
client = input.readString(SerializeLimits.MAX_CLIENT);
|
|
||||||
String auth_id = input.readString(SerializeLimits.MAX_QUEUE_SIZE);
|
|
||||||
String hwid_str = input.readString(SerializeLimits.MAX_HWID_STR);
|
|
||||||
byte[] encryptedPassword = input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH);
|
|
||||||
String customText = input.readString(SerializeLimits.MAX_CUSTOM_TEXT);
|
|
||||||
// Decrypt password
|
|
||||||
String password;
|
|
||||||
try {
|
|
||||||
password = IOHelper.decode(SecurityHelper.newRSADecryptCipher(server.privateKey).
|
|
||||||
doFinal(encryptedPassword));
|
|
||||||
} catch (IllegalBlockSizeException | BadPaddingException ignored) {
|
|
||||||
requestError("Password decryption error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Authenticate
|
|
||||||
debug("Login: '%s', Password: '%s'", login, echo(password.length()));
|
|
||||||
AuthProviderResult result;
|
|
||||||
AuthProviderPair pair;
|
|
||||||
if (auth_id.isEmpty()) pair = server.config.getAuthProviderPair();
|
|
||||||
else pair = server.config.getAuthProviderPair(auth_id);
|
|
||||||
if (pair == null) requestError("Auth type not found");
|
|
||||||
AuthProvider provider = pair.provider;
|
|
||||||
clientData.type = Client.Type.USER;
|
|
||||||
AuthContext context = new AuthContext(session, login, password.length(), customText, client, hwid_str, ip, false);
|
|
||||||
try {
|
|
||||||
server.authHookManager.preHook(context, clientData);
|
|
||||||
if (!clientData.checkSign) {
|
|
||||||
throw new AuthException("You must using checkLauncher");
|
|
||||||
}
|
|
||||||
provider.preAuth(login, password, customText, ip);
|
|
||||||
result = provider.auth(login, password, ip);
|
|
||||||
if (!VerifyHelper.isValidUsername(result.username)) {
|
|
||||||
AuthProvider.authError(String.format("Illegal result: '%s'", result.username));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (isClient) {
|
|
||||||
Collection<ClientProfile> profiles = server.getProfiles();
|
|
||||||
for (ClientProfile p : profiles) {
|
|
||||||
if (p.getTitle().equals(client)) {
|
|
||||||
if (!p.isWhitelistContains(login)) {
|
|
||||||
throw new AuthException(server.config.whitelistRejectString);
|
|
||||||
}
|
|
||||||
clientData.profile = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (clientData.profile == null) {
|
|
||||||
throw new AuthException("Your profile is not found");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
server.config.hwidHandler.check(OshiHWID.gson.fromJson(hwid_str, OshiHWID.class), result.username);
|
|
||||||
server.authHookManager.postHook(context, clientData);
|
|
||||||
} catch (AuthException | HWIDException e) {
|
|
||||||
if (e.getMessage() == null) LogHelper.error(e);
|
|
||||||
requestError(e.getMessage());
|
|
||||||
return;
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
requestError("Internal auth provider error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
debug("Auth: '%s' -> '%s', '%s'", login, result.username, result.accessToken);
|
|
||||||
clientData.isAuth = true;
|
|
||||||
clientData.permissions = result.permissions;
|
|
||||||
clientData.username = result.username;
|
|
||||||
clientData.auth_id = auth_id;
|
|
||||||
clientData.updateAuth();
|
|
||||||
// Authenticate on server (and get UUID)
|
|
||||||
UUID uuid;
|
|
||||||
try {
|
|
||||||
uuid = pair.handler.auth(result);
|
|
||||||
} catch (AuthException e) {
|
|
||||||
requestError(e.getMessage());
|
|
||||||
return;
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
requestError("Internal auth handler error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String protectToken = server.config.protectHandler.generateSecureToken(context);
|
|
||||||
writeNoError(output);
|
|
||||||
// Write profile and UUID
|
|
||||||
ProfileByUUIDResponse.getProfile(server, uuid, result.username, client, clientData.auth.textureProvider).write(output);
|
|
||||||
output.writeASCII(result.accessToken, -SecurityHelper.TOKEN_STRING_LENGTH);
|
|
||||||
clientData.permissions.write(output);
|
|
||||||
output.writeString(protectToken, SerializeLimits.MAX_CUSTOM_TEXT);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,98 +0,0 @@
|
||||||
package ru.gravit.launchserver.response.auth;
|
|
||||||
|
|
||||||
import ru.gravit.launcher.profiles.ClientProfile;
|
|
||||||
import ru.gravit.launcher.serialize.HInput;
|
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
|
||||||
import ru.gravit.launcher.serialize.SerializeLimits;
|
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
|
||||||
import ru.gravit.launchserver.auth.AuthException;
|
|
||||||
import ru.gravit.launchserver.auth.AuthProviderPair;
|
|
||||||
import ru.gravit.launchserver.auth.hwid.HWIDException;
|
|
||||||
import ru.gravit.launchserver.auth.provider.AuthProvider;
|
|
||||||
import ru.gravit.launchserver.auth.provider.AuthProviderResult;
|
|
||||||
import ru.gravit.launchserver.response.Response;
|
|
||||||
import ru.gravit.launchserver.socket.Client;
|
|
||||||
import ru.gravit.utils.helper.IOHelper;
|
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
|
||||||
import ru.gravit.utils.helper.SecurityHelper;
|
|
||||||
import ru.gravit.utils.helper.VerifyHelper;
|
|
||||||
|
|
||||||
import javax.crypto.BadPaddingException;
|
|
||||||
import javax.crypto.IllegalBlockSizeException;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public final class AuthServerResponse extends Response {
|
|
||||||
private static String echo(int length) {
|
|
||||||
char[] chars = new char[length];
|
|
||||||
Arrays.fill(chars, '*');
|
|
||||||
return new String(chars);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthServerResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
|
||||||
super(server, session, input, output, ip, clientData);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reply() throws Exception {
|
|
||||||
String login = input.readString(SerializeLimits.MAX_LOGIN);
|
|
||||||
String client = input.readString(SerializeLimits.MAX_CLIENT);
|
|
||||||
String auth_id = input.readString(SerializeLimits.MAX_QUEUE_SIZE);
|
|
||||||
byte[] encryptedPassword = input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH);
|
|
||||||
// Decrypt password
|
|
||||||
String password;
|
|
||||||
try {
|
|
||||||
password = IOHelper.decode(SecurityHelper.newRSADecryptCipher(server.privateKey).
|
|
||||||
doFinal(encryptedPassword));
|
|
||||||
} catch (IllegalBlockSizeException | BadPaddingException ignored) {
|
|
||||||
requestError("ServerPassword decryption error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Authenticate
|
|
||||||
debug("ServerLogin: '%s', Password: '%s'", login, echo(password.length()));
|
|
||||||
AuthProviderResult result;
|
|
||||||
AuthProviderPair pair;
|
|
||||||
if (auth_id.isEmpty()) pair = server.config.getAuthProviderPair();
|
|
||||||
else pair = server.config.getAuthProviderPair(auth_id);
|
|
||||||
if (pair == null) requestError("Auth type not found");
|
|
||||||
AuthProvider provider = pair.provider;
|
|
||||||
AuthResponse.AuthContext context = new AuthResponse.AuthContext(session, login, password.length(), null, client, null, ip, true);
|
|
||||||
try {
|
|
||||||
server.authHookManager.preHook(context, clientData);
|
|
||||||
result = provider.auth(login, password, ip);
|
|
||||||
if (!VerifyHelper.isValidUsername(result.username)) {
|
|
||||||
AuthProvider.authError(String.format("Illegal result: '%s'", result.username));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Collection<ClientProfile> profiles = server.getProfiles();
|
|
||||||
for (ClientProfile p : profiles) {
|
|
||||||
if (p.getTitle().equals(client)) {
|
|
||||||
clientData.profile = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (clientData.profile == null) {
|
|
||||||
throw new AuthException("Your profile is not found");
|
|
||||||
}
|
|
||||||
clientData.permissions = server.config.permissionsHandler.getPermissions(login);
|
|
||||||
if (!clientData.permissions.canServer) {
|
|
||||||
throw new AuthException("Your account cannot be a server");
|
|
||||||
}
|
|
||||||
clientData.type = Client.Type.SERVER;
|
|
||||||
clientData.username = result.username;
|
|
||||||
server.authHookManager.postHook(context, clientData);
|
|
||||||
} catch (AuthException | HWIDException e) {
|
|
||||||
requestError(e.getMessage());
|
|
||||||
return;
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
requestError("Internal auth provider error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
debug("ServerAuth: '%s' -> '%s', '%s'", login, result.username, result.accessToken);
|
|
||||||
clientData.isAuth = true;
|
|
||||||
clientData.auth_id = auth_id;
|
|
||||||
clientData.updateAuth();
|
|
||||||
writeNoError(output);
|
|
||||||
clientData.permissions.write(output);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package ru.gravit.launchserver.response.auth;
|
|
||||||
|
|
||||||
import ru.gravit.launcher.serialize.HInput;
|
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
|
||||||
import ru.gravit.launchserver.response.Response;
|
|
||||||
import ru.gravit.launchserver.socket.Client;
|
|
||||||
|
|
||||||
public class ChangeServerResponse extends Response {
|
|
||||||
public static boolean needChange = false;
|
|
||||||
public static String address;
|
|
||||||
public static int port;
|
|
||||||
|
|
||||||
public ChangeServerResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
|
||||||
super(server, session, input, output, ip, clientData);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reply() throws Exception {
|
|
||||||
writeNoError(output);
|
|
||||||
output.writeBoolean(needChange);
|
|
||||||
//if true
|
|
||||||
if (needChange) {
|
|
||||||
output.writeString(address, 255);
|
|
||||||
output.writeInt(port);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
package ru.gravit.launchserver.response.auth;
|
|
||||||
|
|
||||||
import ru.gravit.launcher.serialize.HInput;
|
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
|
||||||
import ru.gravit.launcher.serialize.SerializeLimits;
|
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
|
||||||
import ru.gravit.launchserver.auth.AuthException;
|
|
||||||
import ru.gravit.launchserver.response.Response;
|
|
||||||
import ru.gravit.launchserver.response.profile.ProfileByUUIDResponse;
|
|
||||||
import ru.gravit.launchserver.socket.Client;
|
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
|
||||||
import ru.gravit.utils.helper.VerifyHelper;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public final class CheckServerResponse extends Response {
|
|
||||||
|
|
||||||
public CheckServerResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
|
||||||
super(server, session, input, output, ip, clientData);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reply() throws IOException {
|
|
||||||
String username = VerifyHelper.verifyUsername(input.readString(SerializeLimits.MAX_LOGIN));
|
|
||||||
String serverID = VerifyHelper.verifyServerID(input.readASCII(41)); // With minus sign
|
|
||||||
String client = input.readString(SerializeLimits.MAX_CLIENT);
|
|
||||||
debug("Username: %s, Server ID: %s", username, serverID);
|
|
||||||
if (!clientData.isAuth || clientData.type != Client.Type.SERVER) {
|
|
||||||
requestError("Access denied");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Try check server with auth handler
|
|
||||||
UUID uuid;
|
|
||||||
try {
|
|
||||||
server.authHookManager.checkServerHook(username, serverID);
|
|
||||||
uuid = clientData.auth.handler.checkServer(username, serverID);
|
|
||||||
} catch (AuthException e) {
|
|
||||||
requestError(e.getMessage());
|
|
||||||
return;
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
requestError("Internal auth handler error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
writeNoError(output);
|
|
||||||
|
|
||||||
// Write profile and UUID
|
|
||||||
output.writeBoolean(uuid != null);
|
|
||||||
if (uuid != null)
|
|
||||||
ProfileByUUIDResponse.getProfile(server, uuid, username, client, clientData.auth.textureProvider).write(output);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
package ru.gravit.launchserver.response.auth;
|
|
||||||
|
|
||||||
import ru.gravit.launcher.serialize.HInput;
|
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
|
||||||
import ru.gravit.launcher.serialize.SerializeLimits;
|
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
|
||||||
import ru.gravit.launchserver.auth.AuthException;
|
|
||||||
import ru.gravit.launchserver.response.Response;
|
|
||||||
import ru.gravit.launchserver.socket.Client;
|
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
|
||||||
import ru.gravit.utils.helper.SecurityHelper;
|
|
||||||
import ru.gravit.utils.helper.VerifyHelper;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public final class JoinServerResponse extends Response {
|
|
||||||
|
|
||||||
public JoinServerResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
|
||||||
super(server, session, input, output, ip, clientData);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reply() throws IOException {
|
|
||||||
String username = VerifyHelper.verifyUsername(input.readString(SerializeLimits.MAX_LOGIN));
|
|
||||||
String accessToken = SecurityHelper.verifyToken(input.readASCII(-SecurityHelper.TOKEN_STRING_LENGTH));
|
|
||||||
String serverID = VerifyHelper.verifyServerID(input.readASCII(SerializeLimits.MAX_SERVERID)); // With minus sign
|
|
||||||
if (!clientData.isAuth || clientData.type != Client.Type.USER) {
|
|
||||||
requestError("Access denied");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Try join server with auth handler
|
|
||||||
debug("Username: '%s', Access token: %s, Server ID: %s", username, accessToken, serverID);
|
|
||||||
boolean success;
|
|
||||||
try {
|
|
||||||
server.authHookManager.joinServerHook(username, accessToken, serverID);
|
|
||||||
success = clientData.auth.handler.joinServer(username, accessToken, serverID);
|
|
||||||
} catch (AuthException e) {
|
|
||||||
requestError(e.getMessage());
|
|
||||||
return;
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
requestError("Internal auth handler error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
writeNoError(output);
|
|
||||||
|
|
||||||
// Write response
|
|
||||||
output.writeBoolean(success);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package ru.gravit.launchserver.response.auth;
|
|
||||||
|
|
||||||
import ru.gravit.launcher.profiles.ClientProfile;
|
|
||||||
import ru.gravit.launcher.serialize.HInput;
|
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
|
||||||
import ru.gravit.launcher.serialize.SerializeLimits;
|
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
|
||||||
import ru.gravit.launchserver.response.Response;
|
|
||||||
import ru.gravit.launchserver.socket.Client;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public class SetProfileResponse extends Response {
|
|
||||||
public SetProfileResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
|
||||||
super(server, session, input, output, ip, clientData);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reply() throws Exception {
|
|
||||||
String client = input.readString(SerializeLimits.MAX_CLIENT);
|
|
||||||
if (!clientData.isAuth) requestError("You not auth");
|
|
||||||
Collection<ClientProfile> profiles = server.getProfiles();
|
|
||||||
for (ClientProfile p : profiles) {
|
|
||||||
if (p.getTitle().equals(client)) {
|
|
||||||
if (!p.isWhitelistContains(clientData.username)) {
|
|
||||||
requestError(server.config.whitelistRejectString);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
clientData.profile = p;
|
|
||||||
writeNoError(output);
|
|
||||||
output.writeBoolean(true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
package ru.gravit.launchserver.response.profile;
|
|
||||||
|
|
||||||
import ru.gravit.launcher.serialize.HInput;
|
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
|
||||||
import ru.gravit.launcher.serialize.SerializeLimits;
|
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
|
||||||
import ru.gravit.launchserver.response.Response;
|
|
||||||
import ru.gravit.launchserver.socket.Client;
|
|
||||||
import ru.gravit.utils.helper.VerifyHelper;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
public final class BatchProfileByUsernameResponse extends Response {
|
|
||||||
|
|
||||||
public BatchProfileByUsernameResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
|
||||||
super(server, session, input, output, ip, clientData);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reply() throws IOException {
|
|
||||||
int length = input.readLength(SerializeLimits.MAX_BATCH_SIZE);
|
|
||||||
String[] usernames = new String[length];
|
|
||||||
String[] clients = new String[length];
|
|
||||||
for (int i = 0; i < usernames.length; i++) {
|
|
||||||
usernames[i] = VerifyHelper.verifyUsername(input.readString(64));
|
|
||||||
clients[i] = input.readString(SerializeLimits.MAX_CLIENT);
|
|
||||||
}
|
|
||||||
debug("Usernames: " + Arrays.toString(usernames));
|
|
||||||
|
|
||||||
// Respond with profiles array
|
|
||||||
for (int i = 0; i < usernames.length; i++)
|
|
||||||
ProfileByUsernameResponse.writeProfile(server, output, usernames[i], clients[i], clientData.auth);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
package ru.gravit.launchserver.response.profile;
|
|
||||||
|
|
||||||
import ru.gravit.launcher.profiles.PlayerProfile;
|
|
||||||
import ru.gravit.launcher.profiles.Texture;
|
|
||||||
import ru.gravit.launcher.serialize.HInput;
|
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
|
||||||
import ru.gravit.launcher.serialize.SerializeLimits;
|
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
|
||||||
import ru.gravit.launchserver.response.Response;
|
|
||||||
import ru.gravit.launchserver.socket.Client;
|
|
||||||
import ru.gravit.launchserver.texture.TextureProvider;
|
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public final class ProfileByUUIDResponse extends Response {
|
|
||||||
|
|
||||||
public static PlayerProfile getProfile(LaunchServer server, UUID uuid, String username, String client, TextureProvider textureProvider) {
|
|
||||||
// Get skin texture
|
|
||||||
Texture skin;
|
|
||||||
try {
|
|
||||||
skin = textureProvider.getSkinTexture(uuid, username, client);
|
|
||||||
} catch (IOException e) {
|
|
||||||
LogHelper.error(new IOException(String.format("Can't get skin texture: '%s'", username), e));
|
|
||||||
skin = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get cloak texture
|
|
||||||
Texture cloak;
|
|
||||||
try {
|
|
||||||
cloak = textureProvider.getCloakTexture(uuid, username, client);
|
|
||||||
} catch (IOException e) {
|
|
||||||
LogHelper.error(new IOException(String.format("Can't get cloak texture: '%s'", username), e));
|
|
||||||
cloak = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return combined profile
|
|
||||||
return new PlayerProfile(uuid, username, skin, cloak);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProfileByUUIDResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
|
||||||
super(server, session, input, output, ip, clientData);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reply() throws IOException {
|
|
||||||
UUID uuid = input.readUUID();
|
|
||||||
debug("UUID: " + uuid);
|
|
||||||
String client = input.readString(SerializeLimits.MAX_CLIENT);
|
|
||||||
// Verify has such profile
|
|
||||||
String username = clientData.auth.handler.uuidToUsername(uuid);
|
|
||||||
if (username == null) {
|
|
||||||
output.writeBoolean(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write profile
|
|
||||||
output.writeBoolean(true);
|
|
||||||
getProfile(server, uuid, username, client, clientData.auth.textureProvider).write(output);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
package ru.gravit.launchserver.response.profile;
|
|
||||||
|
|
||||||
import ru.gravit.launcher.serialize.HInput;
|
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
|
||||||
import ru.gravit.launcher.serialize.SerializeLimits;
|
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
|
||||||
import ru.gravit.launchserver.auth.AuthProviderPair;
|
|
||||||
import ru.gravit.launchserver.response.Response;
|
|
||||||
import ru.gravit.launchserver.socket.Client;
|
|
||||||
import ru.gravit.utils.helper.VerifyHelper;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public final class ProfileByUsernameResponse extends Response {
|
|
||||||
|
|
||||||
public static void writeProfile(LaunchServer server, HOutput output, String username, String client, AuthProviderPair pair) throws IOException {
|
|
||||||
UUID uuid = pair.handler.usernameToUUID(username);
|
|
||||||
if (uuid == null) {
|
|
||||||
output.writeBoolean(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write profile
|
|
||||||
output.writeBoolean(true);
|
|
||||||
ProfileByUUIDResponse.getProfile(server, uuid, username, client, pair.textureProvider).write(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProfileByUsernameResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
|
||||||
super(server, session, input, output, ip, clientData);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reply() throws IOException {
|
|
||||||
String username = VerifyHelper.verifyUsername(input.readString(64));
|
|
||||||
debug("Username: " + username);
|
|
||||||
String client = input.readString(SerializeLimits.MAX_CLIENT);
|
|
||||||
// Write response
|
|
||||||
writeProfile(server, output, username, client, clientData.auth);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
package ru.gravit.launchserver.response.update;
|
|
||||||
|
|
||||||
import ru.gravit.launcher.Launcher;
|
|
||||||
import ru.gravit.launcher.profiles.ClientProfile;
|
|
||||||
import ru.gravit.launcher.serialize.HInput;
|
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
|
||||||
import ru.gravit.launchserver.response.Response;
|
|
||||||
import ru.gravit.launchserver.socket.Client;
|
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public final class ProfilesResponse extends Response {
|
|
||||||
|
|
||||||
public ProfilesResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
|
||||||
super(server, session, input, output, ip, clientData);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reply() throws IOException {
|
|
||||||
// Resolve launcher binary
|
|
||||||
input.readBoolean();
|
|
||||||
if (clientData.type == Client.Type.USER && !clientData.checkSign) {
|
|
||||||
LogHelper.warning("User session: %d ip %s try get profiles", session, ip);
|
|
||||||
requestError("Access denied");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
writeNoError(output);
|
|
||||||
Collection<ClientProfile> profiles = server.getProfiles();
|
|
||||||
output.writeLength(profiles.size(), 0);
|
|
||||||
for (ClientProfile profile : profiles) {
|
|
||||||
LogHelper.debug("Writted profile: %s", profile.getTitle());
|
|
||||||
output.writeString(Launcher.gson.toJson(profile), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package ru.gravit.launchserver.response.update;
|
|
||||||
|
|
||||||
import ru.gravit.launcher.hasher.HashedDir;
|
|
||||||
import ru.gravit.launcher.serialize.HInput;
|
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
|
||||||
import ru.gravit.launcher.serialize.signed.SignedObjectHolder;
|
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
|
||||||
import ru.gravit.launchserver.response.Response;
|
|
||||||
import ru.gravit.launchserver.socket.Client;
|
|
||||||
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public final class UpdateListResponse extends Response {
|
|
||||||
|
|
||||||
public UpdateListResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
|
||||||
super(server, session, input, output, ip, clientData);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reply() throws Exception {
|
|
||||||
Set<Entry<String, SignedObjectHolder<HashedDir>>> updateDirs = server.getUpdateDirs();
|
|
||||||
// Write all update dirs names
|
|
||||||
output.writeLength(updateDirs.size(), 0);
|
|
||||||
for (Entry<String, SignedObjectHolder<HashedDir>> entry : updateDirs)
|
|
||||||
output.writeString(entry.getKey(), 255);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,140 +0,0 @@
|
||||||
package ru.gravit.launchserver.response.update;
|
|
||||||
|
|
||||||
import ru.gravit.launcher.hasher.HashedDir;
|
|
||||||
import ru.gravit.launcher.hasher.HashedEntry;
|
|
||||||
import ru.gravit.launcher.hasher.HashedEntry.Type;
|
|
||||||
import ru.gravit.launcher.profiles.ClientProfile;
|
|
||||||
import ru.gravit.launcher.request.UpdateAction;
|
|
||||||
import ru.gravit.launcher.serialize.HInput;
|
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
|
||||||
import ru.gravit.launcher.serialize.SerializeLimits;
|
|
||||||
import ru.gravit.launcher.serialize.signed.SignedObjectHolder;
|
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
|
||||||
import ru.gravit.launchserver.response.Response;
|
|
||||||
import ru.gravit.launchserver.socket.Client;
|
|
||||||
import ru.gravit.utils.helper.IOHelper;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.Deque;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.zip.DeflaterOutputStream;
|
|
||||||
|
|
||||||
public final class UpdateResponse extends Response {
|
|
||||||
|
|
||||||
public UpdateResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
|
||||||
super(server, session, input, output, ip, clientData);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reply() throws IOException {
|
|
||||||
// Read update dir name
|
|
||||||
String updateDirName = IOHelper.verifyFileName(input.readString(255));
|
|
||||||
SignedObjectHolder<HashedDir> hdir = server.getUpdateDir(updateDirName);
|
|
||||||
if (hdir == null) {
|
|
||||||
requestError(String.format("Unknown update dir: %s", updateDirName));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!clientData.isAuth || clientData.type != Client.Type.USER || clientData.profile == null) {
|
|
||||||
requestError("Access denied");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!clientData.permissions.canAdmin) {
|
|
||||||
for (ClientProfile p : server.getProfiles()) {
|
|
||||||
if (!clientData.profile.getTitle().equals(p.getTitle())) continue;
|
|
||||||
if (!p.isWhitelistContains(clientData.username)) {
|
|
||||||
requestError("You don't download this folder");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
writeNoError(output);
|
|
||||||
|
|
||||||
// Write update hdir
|
|
||||||
debug("Update dir: '%s'", updateDirName);
|
|
||||||
hdir.write(output);
|
|
||||||
output.writeBoolean(server.config.compress);
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
// Prepare variables for actions queue
|
|
||||||
Path dir = server.updatesDir.resolve(updateDirName);
|
|
||||||
Deque<HashedDir> dirStack = new LinkedList<>();
|
|
||||||
dirStack.add(hdir.object);
|
|
||||||
|
|
||||||
// Perform update
|
|
||||||
// noinspection IOResourceOpenedButNotSafelyClosed
|
|
||||||
OutputStream fileOutput = server.config.compress ? new DeflaterOutputStream(output.stream, IOHelper.newDeflater(), IOHelper.BUFFER_SIZE, true) : output.stream;
|
|
||||||
UpdateAction[] actionsSlice = new UpdateAction[SerializeLimits.MAX_QUEUE_SIZE];
|
|
||||||
loop:
|
|
||||||
while (true) {
|
|
||||||
// Read actions slice
|
|
||||||
int length = input.readLength(actionsSlice.length);
|
|
||||||
for (int i = 0; i < length; i++)
|
|
||||||
actionsSlice[i] = new UpdateAction(input);
|
|
||||||
|
|
||||||
// Perform actions
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
UpdateAction action = actionsSlice[i];
|
|
||||||
switch (action.type) {
|
|
||||||
case CD:
|
|
||||||
debug("CD '%s'", action.name);
|
|
||||||
|
|
||||||
// Get hashed dir (for validation)
|
|
||||||
HashedEntry hSubdir = dirStack.getLast().getEntry(action.name);
|
|
||||||
if (hSubdir == null || hSubdir.getType() != Type.DIR)
|
|
||||||
throw new IOException("Unknown hashed dir: " + action.name);
|
|
||||||
dirStack.add((HashedDir) hSubdir);
|
|
||||||
|
|
||||||
// Resolve dir
|
|
||||||
dir = dir.resolve(action.name);
|
|
||||||
break;
|
|
||||||
case GET:
|
|
||||||
debug("GET '%s'", action.name);
|
|
||||||
|
|
||||||
// Get hashed file (for validation)
|
|
||||||
HashedEntry hFile = dirStack.getLast().getEntry(action.name);
|
|
||||||
if (hFile == null || hFile.getType() != Type.FILE)
|
|
||||||
throw new IOException("Unknown hashed file: " + action.name);
|
|
||||||
|
|
||||||
// Resolve and write file
|
|
||||||
Path file = dir.resolve(action.name);
|
|
||||||
if (IOHelper.readAttributes(file).size() != hFile.size()) {
|
|
||||||
fileOutput.write(0x0);
|
|
||||||
fileOutput.flush();
|
|
||||||
throw new IOException("Unknown hashed file: " + action.name);
|
|
||||||
}
|
|
||||||
fileOutput.write(0xFF);
|
|
||||||
try (InputStream fileInput = IOHelper.newInput(file)) {
|
|
||||||
IOHelper.transfer(fileInput, fileOutput);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CD_BACK:
|
|
||||||
debug("CD ..");
|
|
||||||
|
|
||||||
// Remove from hashed dir stack
|
|
||||||
dirStack.removeLast();
|
|
||||||
if (dirStack.isEmpty())
|
|
||||||
throw new IOException("Empty hDir stack");
|
|
||||||
|
|
||||||
// Get parent
|
|
||||||
dir = dir.getParent();
|
|
||||||
break;
|
|
||||||
case FINISH:
|
|
||||||
break loop;
|
|
||||||
default:
|
|
||||||
throw new AssertionError(String.format("Unsupported action type: '%s'", action.type.name()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flush all actions
|
|
||||||
fileOutput.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
// So we've updated :)
|
|
||||||
if (fileOutput instanceof DeflaterOutputStream)
|
|
||||||
((DeflaterOutputStream) fileOutput).finish();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,10 +11,10 @@
|
||||||
import ru.gravit.launchserver.auth.hwid.HWIDException;
|
import ru.gravit.launchserver.auth.hwid.HWIDException;
|
||||||
import ru.gravit.launchserver.auth.provider.AuthProvider;
|
import ru.gravit.launchserver.auth.provider.AuthProvider;
|
||||||
import ru.gravit.launchserver.auth.provider.AuthProviderResult;
|
import ru.gravit.launchserver.auth.provider.AuthProviderResult;
|
||||||
import ru.gravit.launchserver.response.profile.ProfileByUUIDResponse;
|
|
||||||
import ru.gravit.launchserver.socket.Client;
|
import ru.gravit.launchserver.socket.Client;
|
||||||
import ru.gravit.launchserver.socket.websocket.WebSocketService;
|
import ru.gravit.launchserver.socket.websocket.WebSocketService;
|
||||||
import ru.gravit.launchserver.socket.websocket.json.JsonResponseInterface;
|
import ru.gravit.launchserver.socket.websocket.json.JsonResponseInterface;
|
||||||
|
import ru.gravit.launchserver.socket.websocket.json.profile.ProfileByUUIDResponse;
|
||||||
import ru.gravit.utils.helper.IOHelper;
|
import ru.gravit.utils.helper.IOHelper;
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
import ru.gravit.utils.helper.LogHelper;
|
||||||
import ru.gravit.utils.helper.SecurityHelper;
|
import ru.gravit.utils.helper.SecurityHelper;
|
||||||
|
@ -84,7 +84,7 @@ public void execute(WebSocketService service, ChannelHandlerContext ctx, Client
|
||||||
AuthProviderPair pair;
|
AuthProviderPair pair;
|
||||||
if (auth_id.isEmpty()) pair = LaunchServer.server.config.getAuthProviderPair();
|
if (auth_id.isEmpty()) pair = LaunchServer.server.config.getAuthProviderPair();
|
||||||
else pair = LaunchServer.server.config.getAuthProviderPair(auth_id);
|
else pair = LaunchServer.server.config.getAuthProviderPair(auth_id);
|
||||||
ru.gravit.launchserver.response.auth.AuthResponse.AuthContext context = new ru.gravit.launchserver.response.auth.AuthResponse.AuthContext(0, login, password.length(), customText, client, ip, null, false);
|
AuthContext context = new AuthContext(0, login, password.length(), customText, client, ip, null, false);
|
||||||
AuthProvider provider = pair.provider;
|
AuthProvider provider = pair.provider;
|
||||||
LaunchServer.server.authHookManager.preHook(context, clientData);
|
LaunchServer.server.authHookManager.preHook(context, clientData);
|
||||||
provider.preAuth(login, password, customText, ip);
|
provider.preAuth(login, password, customText, ip);
|
||||||
|
@ -128,5 +128,25 @@ public void execute(WebSocketService service, ChannelHandlerContext ctx, Client
|
||||||
service.sendObject(ctx, new ErrorRequestEvent(e.getMessage()));
|
service.sendObject(ctx, new ErrorRequestEvent(e.getMessage()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static class AuthContext {
|
||||||
|
public AuthContext(long session, String login, int password_lenght, String customText, String client, String hwid, String ip, boolean isServerAuth) {
|
||||||
|
this.session = session;
|
||||||
|
this.login = login;
|
||||||
|
this.password_lenght = password_lenght;
|
||||||
|
this.customText = customText;
|
||||||
|
this.client = client;
|
||||||
|
this.hwid = hwid;
|
||||||
|
this.ip = ip;
|
||||||
|
this.isServerAuth = isServerAuth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long session;
|
||||||
|
public String login;
|
||||||
|
public int password_lenght; //Use AuthProvider for get password
|
||||||
|
public String client;
|
||||||
|
public String hwid;
|
||||||
|
public String customText;
|
||||||
|
public String ip;
|
||||||
|
public boolean isServerAuth;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,10 @@
|
||||||
import ru.gravit.launcher.events.request.ErrorRequestEvent;
|
import ru.gravit.launcher.events.request.ErrorRequestEvent;
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
import ru.gravit.launchserver.LaunchServer;
|
||||||
import ru.gravit.launchserver.auth.AuthException;
|
import ru.gravit.launchserver.auth.AuthException;
|
||||||
import ru.gravit.launchserver.response.profile.ProfileByUUIDResponse;
|
|
||||||
import ru.gravit.launchserver.socket.Client;
|
import ru.gravit.launchserver.socket.Client;
|
||||||
import ru.gravit.launchserver.socket.websocket.WebSocketService;
|
import ru.gravit.launchserver.socket.websocket.WebSocketService;
|
||||||
import ru.gravit.launchserver.socket.websocket.json.JsonResponseInterface;
|
import ru.gravit.launchserver.socket.websocket.json.JsonResponseInterface;
|
||||||
|
import ru.gravit.launchserver.socket.websocket.json.profile.ProfileByUUIDResponse;
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
import ru.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
public class CheckServerResponse implements JsonResponseInterface {
|
public class CheckServerResponse implements JsonResponseInterface {
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package ru.gravit.launchserver.console;
|
package ru.gravit.launchserver.console;
|
||||||
|
|
||||||
import ru.gravit.launcher.request.admin.ExecCommandRequest;
|
|
||||||
import ru.gravit.utils.command.JLineCommandHandler;
|
import ru.gravit.utils.command.JLineCommandHandler;
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -13,11 +11,5 @@ public RemoteJLineCommandHandler() throws IOException {
|
||||||
@Override
|
@Override
|
||||||
public void eval(String line, boolean bell) {
|
public void eval(String line, boolean bell) {
|
||||||
if (line.equals("exit")) System.exit(0);
|
if (line.equals("exit")) System.exit(0);
|
||||||
ExecCommandRequest request = new ExecCommandRequest(System.out::println, line);
|
|
||||||
try {
|
|
||||||
request.request();
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package ru.gravit.launchserver.console;
|
package ru.gravit.launchserver.console;
|
||||||
|
|
||||||
import ru.gravit.launcher.request.admin.ExecCommandRequest;
|
|
||||||
import ru.gravit.utils.command.StdCommandHandler;
|
import ru.gravit.utils.command.StdCommandHandler;
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
|
||||||
|
|
||||||
public class RemoteStdCommandHandler extends StdCommandHandler {
|
public class RemoteStdCommandHandler extends StdCommandHandler {
|
||||||
public RemoteStdCommandHandler(boolean readCommands) {
|
public RemoteStdCommandHandler(boolean readCommands) {
|
||||||
|
@ -12,11 +10,5 @@ public RemoteStdCommandHandler(boolean readCommands) {
|
||||||
@Override
|
@Override
|
||||||
public void eval(String line, boolean bell) {
|
public void eval(String line, boolean bell) {
|
||||||
if (line.equals("exit")) System.exit(0);
|
if (line.equals("exit")) System.exit(0);
|
||||||
ExecCommandRequest request = new ExecCommandRequest(System.out::println, line);
|
|
||||||
try {
|
|
||||||
request.request();
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,6 @@ public static void addLauncherClassBindings(Map<String, Object> bindings) {
|
||||||
bindings.put("RequestClass", Request.class);
|
bindings.put("RequestClass", Request.class);
|
||||||
bindings.put("RequestTypeClass", RequestType.class);
|
bindings.put("RequestTypeClass", RequestType.class);
|
||||||
bindings.put("RequestExceptionClass", RequestException.class);
|
bindings.put("RequestExceptionClass", RequestException.class);
|
||||||
bindings.put("CustomRequestClass", CustomRequest.class);
|
|
||||||
bindings.put("PingRequestClass", PingRequest.class);
|
bindings.put("PingRequestClass", PingRequest.class);
|
||||||
bindings.put("AuthRequestClass", AuthRequest.class);
|
bindings.put("AuthRequestClass", AuthRequest.class);
|
||||||
bindings.put("JoinServerRequestClass", JoinServerRequest.class);
|
bindings.put("JoinServerRequestClass", JoinServerRequest.class);
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
package ru.gravit.launcher.request;
|
|
||||||
|
|
||||||
import ru.gravit.launcher.LauncherAPI;
|
|
||||||
import ru.gravit.launcher.LauncherConfig;
|
|
||||||
import ru.gravit.launcher.serialize.HInput;
|
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
|
||||||
import ru.gravit.utils.helper.VerifyHelper;
|
|
||||||
|
|
||||||
public abstract class CustomRequest<T> extends Request<T> {
|
|
||||||
@LauncherAPI
|
|
||||||
public CustomRequest() {
|
|
||||||
this(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@LauncherAPI
|
|
||||||
public CustomRequest(LauncherConfig config) {
|
|
||||||
super(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
@LauncherAPI
|
|
||||||
public abstract String getName();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final Integer getLegacyType() {
|
|
||||||
return 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected final T requestDo(HInput input, HOutput output) throws Exception {
|
|
||||||
output.writeASCII(VerifyHelper.verifyIDName(getName()), 255);
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
// Custom request redirect
|
|
||||||
return requestDoCustom(input, output);
|
|
||||||
}
|
|
||||||
|
|
||||||
@LauncherAPI
|
|
||||||
protected abstract T requestDoCustom(HInput input, HOutput output);
|
|
||||||
}
|
|
|
@ -19,17 +19,4 @@ public PingRequest() {
|
||||||
public PingRequest(LauncherConfig config) {
|
public PingRequest(LauncherConfig config) {
|
||||||
super(config);
|
super(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getLegacyType() {
|
|
||||||
return RequestType.PING.getNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Void requestDo(HInput input, HOutput output) throws IOException {
|
|
||||||
byte pong = (byte) input.readUnsignedByte();
|
|
||||||
if (pong != SerializeLimits.EXPECTED_BYTE)
|
|
||||||
throw new IOException("Illegal ping response: " + pong);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,9 +43,6 @@ protected Request(LauncherConfig config) {
|
||||||
this.config = config == null ? Launcher.getConfig() : config;
|
this.config = config == null ? Launcher.getConfig() : config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
|
||||||
public abstract Integer getLegacyType();
|
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
protected final void readError(HInput input) throws IOException {
|
protected final void readError(HInput input) throws IOException {
|
||||||
String error = input.readString(0);
|
String error = input.readString(0);
|
||||||
|
@ -57,39 +54,11 @@ protected final void readError(HInput input) throws IOException {
|
||||||
public R request() throws Exception {
|
public R request() throws Exception {
|
||||||
if (!started.compareAndSet(false, true))
|
if (!started.compareAndSet(false, true))
|
||||||
throw new IllegalStateException("Request already started");
|
throw new IllegalStateException("Request already started");
|
||||||
R wsResult = null;
|
return requestWebSockets();
|
||||||
if (config.isNettyEnabled)
|
|
||||||
wsResult = requestWebSockets();
|
|
||||||
if (wsResult != null) return wsResult;
|
|
||||||
// Make request to LaunchServer
|
|
||||||
try (Socket socket = IOHelper.newSocket()) {
|
|
||||||
socket.connect(IOHelper.resolve(config.address));
|
|
||||||
try (HInput input = new HInput(socket.getInputStream());
|
|
||||||
HOutput output = new HOutput(socket.getOutputStream())) {
|
|
||||||
writeHandshake(input, output);
|
|
||||||
return requestDo(input, output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected R requestWebSockets() throws Exception {
|
protected R requestWebSockets() throws Exception {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
|
||||||
protected abstract R requestDo(HInput input, HOutput output) throws Exception;
|
|
||||||
|
|
||||||
private void writeHandshake(HInput input, HOutput output) throws IOException {
|
|
||||||
// Write handshake
|
|
||||||
output.writeInt(Launcher.PROTOCOL_MAGIC);
|
|
||||||
output.writeBigInteger(config.publicKey.getModulus(), SecurityHelper.RSA_KEY_LENGTH + 1);
|
|
||||||
output.writeLong(session);
|
|
||||||
output.writeVarInt(getLegacyType());
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
// Verify is accepted
|
|
||||||
if (!input.readBoolean())
|
|
||||||
requestError("Serverside not accepted this connection");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
package ru.gravit.launcher.request.admin;
|
|
||||||
|
|
||||||
import ru.gravit.launcher.request.Request;
|
|
||||||
import ru.gravit.launcher.request.RequestType;
|
|
||||||
import ru.gravit.launcher.serialize.HInput;
|
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
|
||||||
import ru.gravit.launcher.serialize.SerializeLimits;
|
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
|
||||||
|
|
||||||
public class ExecCommandRequest extends Request<Boolean> {
|
|
||||||
public LogHelper.Output loutput;
|
|
||||||
public String cmd;
|
|
||||||
|
|
||||||
public ExecCommandRequest(LogHelper.Output output, String cmd) {
|
|
||||||
this.loutput = output;
|
|
||||||
this.cmd = cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getLegacyType() {
|
|
||||||
return RequestType.EXECCOMMAND.getNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Boolean requestDo(HInput input, HOutput output) throws Exception {
|
|
||||||
readError(input);
|
|
||||||
output.writeString(cmd, SerializeLimits.MAX_COMMAND);
|
|
||||||
boolean isContinue = true;
|
|
||||||
while (isContinue) {
|
|
||||||
isContinue = input.readBoolean();
|
|
||||||
if (isContinue) {
|
|
||||||
String log = input.readString(SerializeLimits.MAX_COMMAND);
|
|
||||||
if (loutput != null) loutput.println(log);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
readError(input);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -96,53 +96,6 @@ public AuthRequest(String login, byte[] password, HWID hwid, String auth_id) {
|
||||||
this(null, login, password, hwid, auth_id);
|
this(null, login, password, hwid, auth_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getLegacyType() {
|
|
||||||
return RequestType.AUTH.getNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*public class EchoRequest implements RequestInterface
|
|
||||||
{
|
|
||||||
String echo;
|
|
||||||
|
|
||||||
public EchoRequest(String echo) {
|
|
||||||
this.echo = echo;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getLegacyType() {
|
|
||||||
return "echo";
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
@Override
|
|
||||||
protected AuthRequestEvent requestDo(HInput input, HOutput output) throws IOException {
|
|
||||||
/*try {
|
|
||||||
LegacyRequestBridge.sendRequest(new EchoRequest("Hello World!"));
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}*/
|
|
||||||
output.writeString(login, SerializeLimits.MAX_LOGIN);
|
|
||||||
output.writeBoolean(Launcher.profile != null);
|
|
||||||
if (Launcher.profile != null)
|
|
||||||
output.writeString(Launcher.profile.getTitle(), SerializeLimits.MAX_CLIENT);
|
|
||||||
output.writeString(auth_id, SerializeLimits.MAX_QUEUE_SIZE);
|
|
||||||
output.writeString(hwid.getSerializeString(), 0);
|
|
||||||
//output.writeLong(0);
|
|
||||||
//output.writeLong(0);
|
|
||||||
//output.writeLong(0);
|
|
||||||
output.writeByteArray(encryptedPassword, SecurityHelper.CRYPTO_MAX_LENGTH);
|
|
||||||
output.writeString(customText, SerializeLimits.MAX_CUSTOM_TEXT);
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
// Read UUID and access token
|
|
||||||
readError(input);
|
|
||||||
PlayerProfile pp = new PlayerProfile(input);
|
|
||||||
String accessToken = input.readASCII(-SecurityHelper.TOKEN_STRING_LENGTH);
|
|
||||||
ClientPermissions permissions = new ClientPermissions(input);
|
|
||||||
String protectToken = input.readString(SerializeLimits.MAX_CUSTOM_TEXT);
|
|
||||||
return new AuthRequestEvent(permissions, pp, accessToken, protectToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return "auth";
|
return "auth";
|
||||||
|
|
|
@ -1,93 +0,0 @@
|
||||||
package ru.gravit.launcher.request.auth;
|
|
||||||
|
|
||||||
import ru.gravit.launcher.ClientPermissions;
|
|
||||||
import ru.gravit.launcher.LauncherAPI;
|
|
||||||
import ru.gravit.launcher.LauncherConfig;
|
|
||||||
import ru.gravit.launcher.LauncherNetworkAPI;
|
|
||||||
import ru.gravit.launcher.profiles.PlayerProfile;
|
|
||||||
import ru.gravit.launcher.request.Request;
|
|
||||||
import ru.gravit.launcher.request.RequestType;
|
|
||||||
import ru.gravit.launcher.serialize.HInput;
|
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
|
||||||
import ru.gravit.launcher.serialize.SerializeLimits;
|
|
||||||
import ru.gravit.utils.helper.SecurityHelper;
|
|
||||||
import ru.gravit.utils.helper.VerifyHelper;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public final class AuthServerRequest extends Request<ClientPermissions> {
|
|
||||||
public static final class Result {
|
|
||||||
@LauncherAPI
|
|
||||||
public final PlayerProfile pp;
|
|
||||||
@LauncherAPI
|
|
||||||
public final String accessToken;
|
|
||||||
|
|
||||||
private Result(PlayerProfile pp, String accessToken) {
|
|
||||||
this.pp = pp;
|
|
||||||
this.accessToken = accessToken;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
private final String login;
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
private final byte[] encryptedPassword;
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
private final String auth_id;
|
|
||||||
@LauncherNetworkAPI
|
|
||||||
private final String title;
|
|
||||||
|
|
||||||
@LauncherAPI
|
|
||||||
public AuthServerRequest(LauncherConfig config, String login, byte[] encryptedPassword) {
|
|
||||||
super(config);
|
|
||||||
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
|
|
||||||
this.encryptedPassword = encryptedPassword.clone();
|
|
||||||
auth_id = "";
|
|
||||||
title = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
@LauncherAPI
|
|
||||||
public AuthServerRequest(LauncherConfig config, String login, byte[] encryptedPassword, String auth_id) {
|
|
||||||
super(config);
|
|
||||||
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
|
|
||||||
this.encryptedPassword = encryptedPassword.clone();
|
|
||||||
this.auth_id = auth_id;
|
|
||||||
title = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
@LauncherAPI
|
|
||||||
public AuthServerRequest(LauncherConfig config, String login, byte[] encryptedPassword, String auth_id, String title) {
|
|
||||||
super(config);
|
|
||||||
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
|
|
||||||
this.encryptedPassword = encryptedPassword.clone();
|
|
||||||
this.auth_id = auth_id;
|
|
||||||
this.title = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
@LauncherAPI
|
|
||||||
public AuthServerRequest(String login, byte[] encryptedPassword) {
|
|
||||||
this(null, login, encryptedPassword);
|
|
||||||
}
|
|
||||||
|
|
||||||
@LauncherAPI
|
|
||||||
public AuthServerRequest(String login, byte[] encryptedPassword, String auth_id) {
|
|
||||||
this(null, login, encryptedPassword, auth_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getLegacyType() {
|
|
||||||
return RequestType.SERVERAUTH.getNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ClientPermissions requestDo(HInput input, HOutput output) throws IOException {
|
|
||||||
output.writeString(login, SerializeLimits.MAX_LOGIN);
|
|
||||||
output.writeString(title, SerializeLimits.MAX_CLIENT);
|
|
||||||
output.writeString(auth_id, SerializeLimits.MAX_QUEUE_SIZE);
|
|
||||||
output.writeByteArray(encryptedPassword, SecurityHelper.CRYPTO_MAX_LENGTH);
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
// Read UUID and access token
|
|
||||||
readError(input);
|
|
||||||
return new ClientPermissions(input);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
package ru.gravit.launcher.request.auth;
|
|
||||||
|
|
||||||
import ru.gravit.launcher.Launcher;
|
|
||||||
import ru.gravit.launcher.request.Request;
|
|
||||||
import ru.gravit.launcher.request.RequestType;
|
|
||||||
import ru.gravit.launcher.serialize.HInput;
|
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
|
|
||||||
public class ChangeServerRequest extends Request<ChangeServerRequest.Result> {
|
|
||||||
@Override
|
|
||||||
public Integer getLegacyType() {
|
|
||||||
return RequestType.CHANGESERVER.getNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean change(Result result) {
|
|
||||||
if (!result.needChange) return false;
|
|
||||||
Launcher.getConfig().address = InetSocketAddress.createUnresolved(result.address, result.port);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Result requestDo(HInput input, HOutput output) throws Exception {
|
|
||||||
readError(input);
|
|
||||||
Result result = new Result();
|
|
||||||
result.needChange = input.readBoolean();
|
|
||||||
if (result.needChange) {
|
|
||||||
result.address = input.readString(255);
|
|
||||||
result.port = input.readInt();
|
|
||||||
}
|
|
||||||
if (result.needChange) change(result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Result {
|
|
||||||
public boolean needChange;
|
|
||||||
public String address;
|
|
||||||
public int port;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -43,27 +43,6 @@ public CheckServerRequestEvent requestWebSockets() throws Exception
|
||||||
return (CheckServerRequestEvent) LegacyRequestBridge.sendRequest(this);
|
return (CheckServerRequestEvent) LegacyRequestBridge.sendRequest(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getLegacyType() {
|
|
||||||
return RequestType.CHECK_SERVER.getNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
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) {
|
|
||||||
LogHelper.error("Profile is null. Title is not net.");
|
|
||||||
output.writeString("", SerializeLimits.MAX_CLIENT);
|
|
||||||
} else
|
|
||||||
output.writeString(Launcher.profile.getTitle(), SerializeLimits.MAX_CLIENT);
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
// Read response
|
|
||||||
readError(input);
|
|
||||||
return input.readBoolean() ? new CheckServerRequestEvent(new PlayerProfile(input)) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return "checkServer";
|
return "checkServer";
|
||||||
|
|
|
@ -43,24 +43,6 @@ public JoinServerRequestEvent requestWebSockets() throws IOException, Interrupte
|
||||||
public JoinServerRequest(String username, String accessToken, String serverID) {
|
public JoinServerRequest(String username, String accessToken, String serverID) {
|
||||||
this(null, username, accessToken, serverID);
|
this(null, username, accessToken, serverID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getLegacyType() {
|
|
||||||
return RequestType.JOIN_SERVER.getNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
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
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
// Read response
|
|
||||||
readError(input);
|
|
||||||
return new JoinServerRequestEvent(input.readBoolean());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return "joinServer";
|
return "joinServer";
|
||||||
|
|
|
@ -23,16 +23,6 @@ public RestoreSessionRequestEvent requestWebSockets() throws IOException, Interr
|
||||||
return (RestoreSessionRequestEvent) LegacyRequestBridge.sendRequest(this);
|
return (RestoreSessionRequestEvent) LegacyRequestBridge.sendRequest(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getLegacyType() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected RestoreSessionRequestEvent requestDo(HInput input, HOutput output) throws Exception {
|
|
||||||
return new RestoreSessionRequestEvent();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return "restoreSession";
|
return "restoreSession";
|
||||||
|
|
|
@ -28,18 +28,6 @@ public SetProfileRequestEvent requestWebSockets() throws Exception {
|
||||||
return (SetProfileRequestEvent) LegacyRequestBridge.sendRequest(this);
|
return (SetProfileRequestEvent) LegacyRequestBridge.sendRequest(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getLegacyType() {
|
|
||||||
return RequestType.SETPROFILE.getNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected SetProfileRequestEvent requestDo(HInput input, HOutput output) throws Exception {
|
|
||||||
output.writeString(profile.getTitle(), SerializeLimits.MAX_CLIENT);
|
|
||||||
readError(input);
|
|
||||||
return new SetProfileRequestEvent(profile);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return "setProfile";
|
return "setProfile";
|
||||||
|
|
|
@ -93,30 +93,6 @@ public LauncherRequest(LauncherConfig config) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getLegacyType() {
|
|
||||||
return RequestType.LAUNCHER.getNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected LauncherRequestEvent requestDo(HInput input, HOutput output) throws Exception {
|
|
||||||
output.writeBoolean(EXE_BINARY);
|
|
||||||
output.writeByteArray(digest, 0);
|
|
||||||
output.flush();
|
|
||||||
readError(input);
|
|
||||||
|
|
||||||
// Verify launcher sign
|
|
||||||
boolean shouldUpdate = input.readBoolean();
|
|
||||||
if (shouldUpdate) {
|
|
||||||
byte[] binary = input.readByteArray(0);
|
|
||||||
LauncherRequestEvent result = new LauncherRequestEvent(binary, digest);
|
|
||||||
update(Launcher.getConfig(), result);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return request result
|
|
||||||
return new LauncherRequestEvent(null, digest);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return "launcher";
|
return "launcher";
|
||||||
|
|
|
@ -84,41 +84,4 @@ public LegacyLauncherRequest() {
|
||||||
public LegacyLauncherRequest(LauncherConfig config) {
|
public LegacyLauncherRequest(LauncherConfig config) {
|
||||||
super(config);
|
super(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getLegacyType() {
|
|
||||||
return RequestType.LEGACYLAUNCHER.getNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Result requestDo(HInput input, HOutput output) throws Exception {
|
|
||||||
output.writeBoolean(EXE_BINARY);
|
|
||||||
output.flush();
|
|
||||||
readError(input);
|
|
||||||
|
|
||||||
// Verify launcher sign
|
|
||||||
RSAPublicKey publicKey = config.publicKey;
|
|
||||||
byte[] sign = input.readByteArray(-SecurityHelper.RSA_KEY_LENGTH);
|
|
||||||
boolean shouldUpdate = !SecurityHelper.isValidSign(BINARY_PATH, sign, publicKey);
|
|
||||||
|
|
||||||
// Update launcher if need
|
|
||||||
output.writeBoolean(shouldUpdate);
|
|
||||||
output.flush();
|
|
||||||
if (shouldUpdate) {
|
|
||||||
byte[] binary = input.readByteArray(0);
|
|
||||||
SecurityHelper.verifySign(binary, sign, config.publicKey);
|
|
||||||
return new Result(binary, sign, Collections.emptyList());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read clients profiles list
|
|
||||||
int count = input.readLength(0);
|
|
||||||
List<ClientProfile> profiles = new ArrayList<>(count);
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
String prof = input.readString(0);
|
|
||||||
profiles.add(Launcher.gson.fromJson(prof, ClientProfile.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return request result
|
|
||||||
return new Result(null, sign, profiles);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,32 +27,11 @@ public ProfilesRequest(LauncherConfig config) {
|
||||||
super(config);
|
super(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getLegacyType() {
|
|
||||||
return RequestType.PROFILES.getNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ProfilesRequestEvent requestWebSockets() throws Exception {
|
public ProfilesRequestEvent requestWebSockets() throws Exception {
|
||||||
return (ProfilesRequestEvent) LegacyRequestBridge.sendRequest(this);
|
return (ProfilesRequestEvent) LegacyRequestBridge.sendRequest(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ProfilesRequestEvent requestDo(HInput input, HOutput output) throws Exception {
|
|
||||||
output.writeBoolean(true);
|
|
||||||
output.flush();
|
|
||||||
readError(input);
|
|
||||||
|
|
||||||
int count = input.readLength(0);
|
|
||||||
List<ClientProfile> profiles = new ArrayList<>(count);
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
String prof = input.readString(0);
|
|
||||||
profiles.add(Launcher.gson.fromJson(prof, ClientProfile.class));
|
|
||||||
}
|
|
||||||
// Return request result
|
|
||||||
return new ProfilesRequestEvent(profiles);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return "profiles";
|
return "profiles";
|
||||||
|
|
|
@ -30,24 +30,6 @@ public UpdateListRequestEvent requestWebSockets() throws Exception {
|
||||||
return (UpdateListRequestEvent) LegacyRequestBridge.sendRequest(this);
|
return (UpdateListRequestEvent) LegacyRequestBridge.sendRequest(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getLegacyType() {
|
|
||||||
return RequestType.UPDATE_LIST.getNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected UpdateListRequestEvent requestDo(HInput input, HOutput output) throws IOException {
|
|
||||||
int count = input.readLength(0);
|
|
||||||
|
|
||||||
// Read all update dirs names
|
|
||||||
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 new UpdateListRequestEvent(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return "updateList";
|
return "updateList";
|
||||||
|
|
|
@ -284,48 +284,6 @@ private void deleteExtraDir(Path subDir, HashedDir subHDir, boolean flag) throws
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void downloadFile(Path file, HashedFile hFile, InputStream input) throws IOException {
|
|
||||||
String filePath = IOHelper.toString(dir.relativize(file));
|
|
||||||
updateState(filePath, 0L, hFile.size);
|
|
||||||
|
|
||||||
// Start file update
|
|
||||||
MessageDigest digest = this.digest ? SecurityHelper.newDigest(DigestAlgorithm.MD5) : null;
|
|
||||||
try (OutputStream fileOutput = IOHelper.newOutput(file)) {
|
|
||||||
long downloaded = 0L;
|
|
||||||
|
|
||||||
// Download with digest update
|
|
||||||
byte[] bytes = IOHelper.newBuffer();
|
|
||||||
while (downloaded < hFile.size) {
|
|
||||||
int remaining = (int) Math.min(hFile.size - downloaded, bytes.length);
|
|
||||||
int length = input.read(bytes, 0, remaining);
|
|
||||||
if (length < 0)
|
|
||||||
throw new EOFException(String.format("%d bytes remaining", hFile.size - downloaded));
|
|
||||||
|
|
||||||
// Update file
|
|
||||||
fileOutput.write(bytes, 0, length);
|
|
||||||
if (digest != null)
|
|
||||||
digest.update(bytes, 0, length);
|
|
||||||
|
|
||||||
// Update state
|
|
||||||
downloaded += length;
|
|
||||||
totalDownloaded += length;
|
|
||||||
updateState(filePath, downloaded, hFile.size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify digest
|
|
||||||
if (digest != null) {
|
|
||||||
byte[] digestBytes = digest.digest();
|
|
||||||
if (!hFile.isSameDigest(digestBytes))
|
|
||||||
throw new SecurityException(String.format("File digest mismatch: '%s'", filePath));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getLegacyType() {
|
|
||||||
return RequestType.UPDATE.getNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UpdateRequestEvent request() throws Exception {
|
public UpdateRequestEvent request() throws Exception {
|
||||||
Files.createDirectories(dir);
|
Files.createDirectories(dir);
|
||||||
|
@ -335,76 +293,6 @@ public UpdateRequestEvent request() throws Exception {
|
||||||
return super.request();
|
return super.request();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected UpdateRequestEvent requestDo(HInput input, HOutput output) throws IOException, SignatureException {
|
|
||||||
// Write update dir name
|
|
||||||
output.writeString(dirName, 255);
|
|
||||||
output.flush();
|
|
||||||
readError(input);
|
|
||||||
|
|
||||||
// Get diff between local and remote dir
|
|
||||||
SignedObjectHolder<HashedDir> remoteHDirHolder = new SignedObjectHolder<>(input, config.publicKey, HashedDir::new);
|
|
||||||
HashedDir hackHackedDir = remoteHDirHolder.object;
|
|
||||||
Launcher.profile.pushOptionalFile(hackHackedDir, !Launcher.profile.isUpdateFastCheck());
|
|
||||||
HashedDir.Diff diff = hackHackedDir.diff(localDir, matcher);
|
|
||||||
totalSize = diff.mismatch.size();
|
|
||||||
boolean compress = input.readBoolean();
|
|
||||||
|
|
||||||
// Build actions queue
|
|
||||||
Queue<UpdateAction> queue = new LinkedList<>();
|
|
||||||
fillActionsQueue(queue, diff.mismatch);
|
|
||||||
queue.add(UpdateAction.FINISH);
|
|
||||||
|
|
||||||
// noinspection IOResourceOpenedButNotSafelyClosed
|
|
||||||
InputStream fileInput = compress ? new InflaterInputStream(input.stream, IOHelper.newInflater(), IOHelper.BUFFER_SIZE) : input.stream;
|
|
||||||
|
|
||||||
// Download missing first
|
|
||||||
// (otherwise it will cause mustdie indexing bug)
|
|
||||||
startTime = Instant.now();
|
|
||||||
Path currentDir = dir;
|
|
||||||
UpdateAction[] actionsSlice = new UpdateAction[SerializeLimits.MAX_QUEUE_SIZE];
|
|
||||||
while (!queue.isEmpty()) {
|
|
||||||
int length = Math.min(queue.size(), SerializeLimits.MAX_QUEUE_SIZE);
|
|
||||||
|
|
||||||
// Write actions slice
|
|
||||||
output.writeLength(length, SerializeLimits.MAX_QUEUE_SIZE);
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
UpdateAction action = queue.remove();
|
|
||||||
actionsSlice[i] = action;
|
|
||||||
action.write(output);
|
|
||||||
}
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
// Perform actions
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
UpdateAction action = actionsSlice[i];
|
|
||||||
switch (action.type) {
|
|
||||||
case CD:
|
|
||||||
currentDir = currentDir.resolve(action.name);
|
|
||||||
Files.createDirectories(currentDir);
|
|
||||||
break;
|
|
||||||
case GET:
|
|
||||||
Path targetFile = currentDir.resolve(action.name);
|
|
||||||
if (fileInput.read() != 0xFF)
|
|
||||||
throw new IOException("Serverside cached size mismath for file " + action.name);
|
|
||||||
downloadFile(targetFile, (HashedFile) action.entry, fileInput);
|
|
||||||
break;
|
|
||||||
case CD_BACK:
|
|
||||||
currentDir = currentDir.getParent();
|
|
||||||
break;
|
|
||||||
case FINISH:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new AssertionError(String.format("Unsupported action type: '%s'", action.type.name()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write update completed packet
|
|
||||||
deleteExtraDir(dir, diff.extra, diff.extra.flag);
|
|
||||||
return new UpdateRequestEvent(remoteHDirHolder.object);
|
|
||||||
}
|
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public void setStateCallback(Callback callback) {
|
public void setStateCallback(Callback callback) {
|
||||||
stateCallback = callback;
|
stateCallback = callback;
|
||||||
|
|
|
@ -50,29 +50,6 @@ public BatchProfileByUsernameRequestEvent requestWebSockets() throws IOException
|
||||||
return (BatchProfileByUsernameRequestEvent) LegacyRequestBridge.sendRequest(this);
|
return (BatchProfileByUsernameRequestEvent) LegacyRequestBridge.sendRequest(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getLegacyType() {
|
|
||||||
return RequestType.BATCH_PROFILE_BY_USERNAME.getNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected BatchProfileByUsernameRequestEvent requestDo(HInput input, HOutput output) throws IOException {
|
|
||||||
output.writeLength(list.length, SerializeLimits.MAX_BATCH_SIZE);
|
|
||||||
for (Entry username : list) {
|
|
||||||
output.writeString(username.username, SerializeLimits.MAX_LOGIN);
|
|
||||||
output.writeString(username.client, SerializeLimits.MAX_CLIENT);
|
|
||||||
}
|
|
||||||
output.flush();
|
|
||||||
|
|
||||||
// Read profiles response
|
|
||||||
PlayerProfile[] profiles = new PlayerProfile[list.length];
|
|
||||||
for (int i = 0; i < profiles.length; i++)
|
|
||||||
profiles[i] = input.readBoolean() ? new PlayerProfile(input) : null;
|
|
||||||
|
|
||||||
// Return result
|
|
||||||
return new BatchProfileByUsernameRequestEvent(profiles);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return "batchProfileByUsername";
|
return "batchProfileByUsername";
|
||||||
|
|
|
@ -38,21 +38,6 @@ public ProfileByUUIDRequestEvent requestWebSockets() throws IOException, Interru
|
||||||
return (ProfileByUUIDRequestEvent) LegacyRequestBridge.sendRequest(this);
|
return (ProfileByUUIDRequestEvent) LegacyRequestBridge.sendRequest(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getLegacyType() {
|
|
||||||
return RequestType.PROFILE_BY_UUID.getNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
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 ProfileByUUIDRequestEvent(new PlayerProfile(input)) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return "profileByUUID";
|
return "profileByUUID";
|
||||||
|
|
|
@ -37,20 +37,6 @@ public ProfileByUsernameRequestEvent requestWebSockets() throws IOException, Int
|
||||||
return (ProfileByUsernameRequestEvent) LegacyRequestBridge.sendRequest(this);
|
return (ProfileByUsernameRequestEvent) LegacyRequestBridge.sendRequest(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getLegacyType() {
|
|
||||||
return RequestType.PROFILE_BY_USERNAME.getNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
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 ProfileByUsernameRequestEvent(new PlayerProfile(input)) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return "profileByUsername";
|
return "profileByUsername";
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
import ru.gravit.launcher.events.request.ProfilesRequestEvent;
|
import ru.gravit.launcher.events.request.ProfilesRequestEvent;
|
||||||
import ru.gravit.launcher.profiles.ClientProfile;
|
import ru.gravit.launcher.profiles.ClientProfile;
|
||||||
import ru.gravit.launcher.request.auth.AuthRequest;
|
import ru.gravit.launcher.request.auth.AuthRequest;
|
||||||
import ru.gravit.launcher.request.auth.AuthServerRequest;
|
|
||||||
import ru.gravit.launcher.request.update.ProfilesRequest;
|
import ru.gravit.launcher.request.update.ProfilesRequest;
|
||||||
import ru.gravit.launcher.request.websockets.LegacyRequestBridge;
|
import ru.gravit.launcher.request.websockets.LegacyRequestBridge;
|
||||||
import ru.gravit.launcher.server.setup.ServerWrapperSetup;
|
import ru.gravit.launcher.server.setup.ServerWrapperSetup;
|
||||||
|
@ -53,13 +52,8 @@ public ServerWrapper(Type type, Path configPath) {
|
||||||
public boolean auth() {
|
public boolean auth() {
|
||||||
try {
|
try {
|
||||||
LauncherConfig cfg = Launcher.getConfig();
|
LauncherConfig cfg = Launcher.getConfig();
|
||||||
if(!config.websocket.enabled)
|
|
||||||
permissions = new AuthServerRequest(cfg, config.login, SecurityHelper.newRSAEncryptCipher(cfg.publicKey).doFinal(IOHelper.encode(config.password)), config.auth_id, config.title).request();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AuthRequest request = new AuthRequest(config.login, SecurityHelper.newRSAEncryptCipher(cfg.publicKey).doFinal(IOHelper.encode(config.password)), config.auth_id, AuthRequest.ConnectTypes.SERVER);
|
AuthRequest request = new AuthRequest(config.login, SecurityHelper.newRSAEncryptCipher(cfg.publicKey).doFinal(IOHelper.encode(config.password)), config.auth_id, AuthRequest.ConnectTypes.SERVER);
|
||||||
permissions = request.request().permissions;
|
permissions = request.request().permissions;
|
||||||
}
|
|
||||||
ProfilesRequestEvent result = new ProfilesRequest(cfg).request();
|
ProfilesRequestEvent result = new ProfilesRequest(cfg).request();
|
||||||
for (ClientProfile p : result.profiles) {
|
for (ClientProfile p : result.profiles) {
|
||||||
LogHelper.debug("Get profile: %s", p.getTitle());
|
LogHelper.debug("Get profile: %s", p.getTitle());
|
||||||
|
@ -184,7 +178,7 @@ public void run(String... args) throws Throwable {
|
||||||
auth();
|
auth();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
LogHelper.info("ServerWrapper: Project %s, LaunchServer address: %s port %d. Title: %s", config.projectname, config.address, config.port, config.title);
|
LogHelper.info("ServerWrapper: Project %s, LaunchServer address: %s port %d. Title: %s", config.projectname, config.websocket.address, config.title);
|
||||||
LogHelper.info("Minecraft Version (for profile): %s", wrapper.profile == null ? "unknown" : wrapper.profile.getVersion().name);
|
LogHelper.info("Minecraft Version (for profile): %s", wrapper.profile == null ? "unknown" : wrapper.profile.getVersion().name);
|
||||||
LogHelper.info("Start Minecraft Server");
|
LogHelper.info("Start Minecraft Server");
|
||||||
LogHelper.debug("Invoke main method %s", mainClass.getName());
|
LogHelper.debug("Invoke main method %s", mainClass.getName());
|
||||||
|
@ -205,7 +199,7 @@ public void updateLauncherConfig() {
|
||||||
|
|
||||||
LauncherConfig cfg = null;
|
LauncherConfig cfg = null;
|
||||||
try {
|
try {
|
||||||
cfg = new LauncherConfig(config.address, config.port, SecurityHelper.toPublicRSAKey(IOHelper.read(publicKeyFile)), new HashMap<>(), config.projectname);
|
cfg = new LauncherConfig(config.websocket.address, SecurityHelper.toPublicRSAKey(IOHelper.read(publicKeyFile)), new HashMap<>(), config.projectname);
|
||||||
if(config.websocket != null && config.websocket.enabled)
|
if(config.websocket != null && config.websocket.enabled)
|
||||||
{
|
{
|
||||||
cfg.isNettyEnabled = true;
|
cfg.isNettyEnabled = true;
|
||||||
|
@ -235,8 +229,6 @@ public Config getDefaultConfig() {
|
||||||
Config newConfig = new Config();
|
Config newConfig = new Config();
|
||||||
newConfig.title = "Your profile title";
|
newConfig.title = "Your profile title";
|
||||||
newConfig.projectname = "MineCraft";
|
newConfig.projectname = "MineCraft";
|
||||||
newConfig.address = "localhost";
|
|
||||||
newConfig.port = 7240;
|
|
||||||
newConfig.login = "login";
|
newConfig.login = "login";
|
||||||
newConfig.password = "password";
|
newConfig.password = "password";
|
||||||
newConfig.mainclass = "";
|
newConfig.mainclass = "";
|
||||||
|
@ -259,9 +251,7 @@ public void setConfig(Config config) {
|
||||||
public static final class Config {
|
public static final class Config {
|
||||||
public String title;
|
public String title;
|
||||||
public String projectname;
|
public String projectname;
|
||||||
public String address;
|
|
||||||
public WebSocketConf websocket;
|
public WebSocketConf websocket;
|
||||||
public int port;
|
|
||||||
public int reconnectCount;
|
public int reconnectCount;
|
||||||
public int reconnectSleep;
|
public int reconnectSleep;
|
||||||
public boolean customClassPath;
|
public boolean customClassPath;
|
||||||
|
|
|
@ -40,13 +40,10 @@ public void run() throws IOException {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LogHelper.info("Found MainClass %s", mainClassName);
|
LogHelper.info("Found MainClass %s", mainClassName);
|
||||||
System.out.println("Print launchserver host:");
|
System.out.println("Print launchserver websocket host:");
|
||||||
String address = commands.commandHandler.readLine();
|
String address = commands.commandHandler.readLine();
|
||||||
System.out.println("Print launchserver port:");
|
|
||||||
int port = Integer.valueOf(commands.commandHandler.readLine());
|
|
||||||
wrapper.config.mainclass = mainClassName;
|
wrapper.config.mainclass = mainClassName;
|
||||||
wrapper.config.address = address;
|
wrapper.config.websocket.address = address;
|
||||||
wrapper.config.port = port;
|
|
||||||
if (!Files.exists(ServerWrapper.publicKeyFile)) {
|
if (!Files.exists(ServerWrapper.publicKeyFile)) {
|
||||||
LogHelper.error("public.key not found");
|
LogHelper.error("public.key not found");
|
||||||
for (int i = 0; i < 10; ++i) {
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
import ru.gravit.utils.helper.VerifyHelper;
|
import ru.gravit.utils.helper.VerifyHelper;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.security.interfaces.RSAPublicKey;
|
import java.security.interfaces.RSAPublicKey;
|
||||||
import java.security.spec.InvalidKeySpecException;
|
import java.security.spec.InvalidKeySpecException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -21,8 +20,6 @@ public static AutogenConfig getAutogenConfig() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instance
|
// Instance
|
||||||
@LauncherAPI
|
|
||||||
public InetSocketAddress address;
|
|
||||||
public String nettyAddress;
|
public String nettyAddress;
|
||||||
public int nettyPort;
|
public int nettyPort;
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
|
@ -46,7 +43,6 @@ public static AutogenConfig getAutogenConfig() {
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException {
|
public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException {
|
||||||
address = InetSocketAddress.createUnresolved(config.address, config.port);
|
|
||||||
publicKey = SecurityHelper.toPublicRSAKey(input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH));
|
publicKey = SecurityHelper.toPublicRSAKey(input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH));
|
||||||
projectname = config.projectname;
|
projectname = config.projectname;
|
||||||
clientPort = config.clientPort;
|
clientPort = config.clientPort;
|
||||||
|
@ -80,8 +76,8 @@ public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public LauncherConfig(String address, int port, RSAPublicKey publicKey, Map<String, byte[]> runtime, String projectname) {
|
public LauncherConfig(String address, RSAPublicKey publicKey, Map<String, byte[]> runtime, String projectname) {
|
||||||
this.address = InetSocketAddress.createUnresolved(address, port);
|
this.nettyAddress = address;
|
||||||
this.publicKey = Objects.requireNonNull(publicKey, "publicKey");
|
this.publicKey = Objects.requireNonNull(publicKey, "publicKey");
|
||||||
this.runtime = Collections.unmodifiableMap(new HashMap<>(runtime));
|
this.runtime = Collections.unmodifiableMap(new HashMap<>(runtime));
|
||||||
this.projectname = projectname;
|
this.projectname = projectname;
|
||||||
|
@ -96,8 +92,8 @@ public LauncherConfig(String address, int port, RSAPublicKey publicKey, Map<Stri
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public LauncherConfig(String address, int port, RSAPublicKey publicKey, Map<String, byte[]> runtime) {
|
public LauncherConfig(String address, RSAPublicKey publicKey, Map<String, byte[]> runtime) {
|
||||||
this.address = InetSocketAddress.createUnresolved(address, port);
|
this.nettyAddress = address;
|
||||||
this.publicKey = Objects.requireNonNull(publicKey, "publicKey");
|
this.publicKey = Objects.requireNonNull(publicKey, "publicKey");
|
||||||
this.runtime = Collections.unmodifiableMap(new HashMap<>(runtime));
|
this.runtime = Collections.unmodifiableMap(new HashMap<>(runtime));
|
||||||
this.projectname = "Minecraft";
|
this.projectname = "Minecraft";
|
||||||
|
|
Loading…
Reference in a new issue