mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-11-15 11:39:11 +03:00
Merge branch 'release/4.3.2'
This commit is contained in:
commit
109b3f0423
22 changed files with 239 additions and 103 deletions
|
@ -88,6 +88,7 @@ public static final class Config {
|
||||||
|
|
||||||
public ExeConf launch4j;
|
public ExeConf launch4j;
|
||||||
public NettyConfig netty;
|
public NettyConfig netty;
|
||||||
|
public GuardLicenseConf guardLicense;
|
||||||
|
|
||||||
public boolean compress;
|
public boolean compress;
|
||||||
|
|
||||||
|
@ -185,6 +186,12 @@ public class NettyConfig
|
||||||
public String bindAddress;
|
public String bindAddress;
|
||||||
public int port;
|
public int port;
|
||||||
}
|
}
|
||||||
|
public class GuardLicenseConf
|
||||||
|
{
|
||||||
|
public String name;
|
||||||
|
public String key;
|
||||||
|
public String encryptKey;
|
||||||
|
}
|
||||||
|
|
||||||
private final class ProfilesFileVisitor extends SimpleFileVisitor<Path> {
|
private final class ProfilesFileVisitor extends SimpleFileVisitor<Path> {
|
||||||
private final Collection<ClientProfile> result;
|
private final Collection<ClientProfile> result;
|
||||||
|
|
|
@ -46,6 +46,11 @@ public AuthHandler getAccociateHandler(int this_position) {
|
||||||
|
|
||||||
public abstract AuthProviderResult auth(String login, String password, String ip) throws Exception;
|
public abstract AuthProviderResult auth(String login, String password, String ip) throws Exception;
|
||||||
|
|
||||||
|
public void preAuth(String login, String password, String customText, String ip) throws Exception
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract void close() throws IOException;
|
public abstract void close() throws IOException;
|
||||||
|
|
||||||
|
|
|
@ -141,6 +141,19 @@ public void setWarningMissArchJava(boolean b) {
|
||||||
body.append(";");
|
body.append(";");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setGuardLicense(String name, String key, String encryptKey)
|
||||||
|
{
|
||||||
|
body.append("this.guardLicenseName = \"");
|
||||||
|
body.append(name);
|
||||||
|
body.append("\";");
|
||||||
|
body.append("this.guardLicenseKey = \"");
|
||||||
|
body.append(key);
|
||||||
|
body.append("\";");
|
||||||
|
body.append("this.guardLicenseEncryptKey = \"");
|
||||||
|
body.append(encryptKey);
|
||||||
|
body.append("\";");
|
||||||
|
}
|
||||||
|
|
||||||
public ClassPool getPool() {
|
public ClassPool getPool() {
|
||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,6 +132,8 @@ public Path process(Path inputJar) throws IOException {
|
||||||
jaConfigurator.setPort(server.config.port);
|
jaConfigurator.setPort(server.config.port);
|
||||||
if(server.config.netty != null)
|
if(server.config.netty != null)
|
||||||
jaConfigurator.setNettyPort(server.config.netty.port);
|
jaConfigurator.setNettyPort(server.config.netty.port);
|
||||||
|
if(server.config.guardLicense != null)
|
||||||
|
jaConfigurator.setGuardLicense(server.config.guardLicense.name, server.config.guardLicense.key, server.config.guardLicense.encryptKey);
|
||||||
jaConfigurator.setProjectName(server.config.projectName);
|
jaConfigurator.setProjectName(server.config.projectName);
|
||||||
jaConfigurator.setSecretKey(SecurityHelper.randomStringAESKey());
|
jaConfigurator.setSecretKey(SecurityHelper.randomStringAESKey());
|
||||||
jaConfigurator.setClientPort(32148 + SecurityHelper.newRandom().nextInt(512));
|
jaConfigurator.setClientPort(32148 + SecurityHelper.newRandom().nextInt(512));
|
||||||
|
|
|
@ -36,10 +36,11 @@ public AuthResponse(LaunchServer server, long session, HInput input, HOutput out
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AuthContext {
|
public static class AuthContext {
|
||||||
public AuthContext(long session, String login, int password_lenght, String client, String hwid, boolean isServerAuth) {
|
public AuthContext(long session, String login, int password_lenght, String customText, String client, String hwid, boolean isServerAuth) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.login = login;
|
this.login = login;
|
||||||
this.password_lenght = password_lenght;
|
this.password_lenght = password_lenght;
|
||||||
|
this.customText = customText;
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.hwid = hwid;
|
this.hwid = hwid;
|
||||||
this.isServerAuth = isServerAuth;
|
this.isServerAuth = isServerAuth;
|
||||||
|
@ -50,6 +51,7 @@ public AuthContext(long session, String login, int password_lenght, String clien
|
||||||
public int password_lenght; //Use AuthProvider for get password
|
public int password_lenght; //Use AuthProvider for get password
|
||||||
public String client;
|
public String client;
|
||||||
public String hwid;
|
public String hwid;
|
||||||
|
public String customText;
|
||||||
public boolean isServerAuth;
|
public boolean isServerAuth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +66,7 @@ public void reply() throws Exception {
|
||||||
String hwid_str = input.readString(SerializeLimits.MAX_HWID_STR);
|
String hwid_str = input.readString(SerializeLimits.MAX_HWID_STR);
|
||||||
if (auth_id + 1 > server.config.authProvider.length || auth_id < 0) auth_id = 0;
|
if (auth_id + 1 > server.config.authProvider.length || auth_id < 0) auth_id = 0;
|
||||||
byte[] encryptedPassword = input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH);
|
byte[] encryptedPassword = input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH);
|
||||||
|
String customText = input.readString(SerializeLimits.MAX_CUSTOM_TEXT);
|
||||||
// Decrypt password
|
// Decrypt password
|
||||||
String password;
|
String password;
|
||||||
try {
|
try {
|
||||||
|
@ -80,7 +83,7 @@ public void reply() throws Exception {
|
||||||
AuthProvider provider = server.config.authProvider[auth_id];
|
AuthProvider provider = server.config.authProvider[auth_id];
|
||||||
Client clientData = server.sessionManager.getClient(session);
|
Client clientData = server.sessionManager.getClient(session);
|
||||||
clientData.type = Client.Type.USER;
|
clientData.type = Client.Type.USER;
|
||||||
AuthContext context = new AuthContext(session, login, password.length(), client, hwid_str, false);
|
AuthContext context = new AuthContext(session, login, password.length(), customText, client, hwid_str, false);
|
||||||
try {
|
try {
|
||||||
server.authHookManager.preHook(context, clientData);
|
server.authHookManager.preHook(context, clientData);
|
||||||
if (server.limiter.isLimit(ip)) {
|
if (server.limiter.isLimit(ip)) {
|
||||||
|
@ -90,6 +93,7 @@ public void reply() throws Exception {
|
||||||
if (!clientData.checkSign) {
|
if (!clientData.checkSign) {
|
||||||
throw new AuthException("You must using checkLauncher");
|
throw new AuthException("You must using checkLauncher");
|
||||||
}
|
}
|
||||||
|
provider.preAuth(login,password,customText,ip);
|
||||||
result = provider.auth(login, password, ip);
|
result = provider.auth(login, password, ip);
|
||||||
if (!VerifyHelper.isValidUsername(result.username)) {
|
if (!VerifyHelper.isValidUsername(result.username)) {
|
||||||
AuthProvider.authError(String.format("Illegal result: '%s'", result.username));
|
AuthProvider.authError(String.format("Illegal result: '%s'", result.username));
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
public class AuthResponse implements JsonResponseInterface {
|
public class AuthResponse implements JsonResponseInterface {
|
||||||
public String login;
|
public String login;
|
||||||
public String client;
|
public String client;
|
||||||
|
public String customText;
|
||||||
|
|
||||||
public String password;
|
public String password;
|
||||||
|
|
||||||
|
@ -67,9 +68,10 @@ public void execute(WebSocketService service, ChannelHandlerContext ctx, Client
|
||||||
{
|
{
|
||||||
AuthProvider.authError("authType: SERVER not allowed for this account");
|
AuthProvider.authError("authType: SERVER not allowed for this account");
|
||||||
}
|
}
|
||||||
ru.gravit.launchserver.response.auth.AuthResponse.AuthContext context = new ru.gravit.launchserver.response.auth.AuthResponse.AuthContext(0, login, password.length(), client, null, false);
|
ru.gravit.launchserver.response.auth.AuthResponse.AuthContext context = new ru.gravit.launchserver.response.auth.AuthResponse.AuthContext(0, login, password.length(),customText, client, null, false);
|
||||||
AuthProvider provider = LaunchServer.server.config.authProvider[authid];
|
AuthProvider provider = LaunchServer.server.config.authProvider[authid];
|
||||||
LaunchServer.server.authHookManager.preHook(context, clientData);
|
LaunchServer.server.authHookManager.preHook(context, clientData);
|
||||||
|
provider.preAuth(login,password,customText,ip);
|
||||||
AuthProviderResult aresult = provider.auth(login, password, ip);
|
AuthProviderResult aresult = provider.auth(login, password, ip);
|
||||||
if (!VerifyHelper.isValidUsername(aresult.username)) {
|
if (!VerifyHelper.isValidUsername(aresult.username)) {
|
||||||
AuthProvider.authError(String.format("Illegal result: '%s'", aresult.username));
|
AuthProvider.authError(String.format("Illegal result: '%s'", aresult.username));
|
||||||
|
|
|
@ -27,7 +27,8 @@
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
pack project(':LauncherAPI') // Not error on obf.
|
pack project(':LauncherAPI') // Not error on obf.
|
||||||
bundle 'com.github.oshi:oshi-core:3.11.0'
|
bundle 'com.github.oshi:oshi-core:3.13.0'
|
||||||
|
bundle 'commons-codec:commons-codec:1.11'
|
||||||
}
|
}
|
||||||
|
|
||||||
task genRuntimeJS(type: Zip) {
|
task genRuntimeJS(type: Zip) {
|
||||||
|
|
|
@ -302,6 +302,7 @@ public static Process launch(
|
||||||
ClientProfile profile, Params params, boolean pipeOutput) throws Throwable {
|
ClientProfile profile, Params params, boolean pipeOutput) throws Throwable {
|
||||||
// Write params file (instead of CLI; Mustdie32 API can't handle command line > 32767 chars)
|
// Write params file (instead of CLI; Mustdie32 API can't handle command line > 32767 chars)
|
||||||
LogHelper.debug("Writing ClientLauncher params");
|
LogHelper.debug("Writing ClientLauncher params");
|
||||||
|
ClientLauncherContext context = new ClientLauncherContext();
|
||||||
CommonHelper.newThread("Client params writter", false, () ->
|
CommonHelper.newThread("Client params writter", false, () ->
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
@ -333,53 +334,49 @@ public static Process launch(
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
checkJVMBitsAndVersion();
|
checkJVMBitsAndVersion();
|
||||||
// Fill CLI arguments
|
|
||||||
List<String> args = new LinkedList<>();
|
|
||||||
boolean wrapper = isUsingWrapper();
|
|
||||||
LogHelper.debug("Resolving JVM binary");
|
LogHelper.debug("Resolving JVM binary");
|
||||||
Path javaBin = LauncherGuardManager.getGuardJavaBinPath();
|
Path javaBin = LauncherGuardManager.getGuardJavaBinPath();
|
||||||
args.add(javaBin.toString());
|
context.javaBin = javaBin;
|
||||||
args.add(MAGICAL_INTEL_OPTION);
|
context.clientProfile = profile;
|
||||||
|
context.playerProfile = params.pp;
|
||||||
|
context.args.add(javaBin.toString());
|
||||||
|
context.args.add(MAGICAL_INTEL_OPTION);
|
||||||
if (params.ram > 0 && params.ram <= JVMHelper.RAM) {
|
if (params.ram > 0 && params.ram <= JVMHelper.RAM) {
|
||||||
args.add("-Xms" + params.ram + 'M');
|
context.args.add("-Xms" + params.ram + 'M');
|
||||||
args.add("-Xmx" + params.ram + 'M');
|
context.args.add("-Xmx" + params.ram + 'M');
|
||||||
}
|
}
|
||||||
args.add(JVMHelper.jvmProperty(LogHelper.DEBUG_PROPERTY, Boolean.toString(LogHelper.isDebugEnabled())));
|
context.args.add(JVMHelper.jvmProperty(LogHelper.DEBUG_PROPERTY, Boolean.toString(LogHelper.isDebugEnabled())));
|
||||||
args.add(JVMHelper.jvmProperty(LogHelper.STACKTRACE_PROPERTY, Boolean.toString(LogHelper.isStacktraceEnabled())));
|
context.args.add(JVMHelper.jvmProperty(LogHelper.STACKTRACE_PROPERTY, Boolean.toString(LogHelper.isStacktraceEnabled())));
|
||||||
args.add(JVMHelper.jvmProperty(LogHelper.DEV_PROPERTY, Boolean.toString(LogHelper.isDevEnabled())));
|
context.args.add(JVMHelper.jvmProperty(LogHelper.DEV_PROPERTY, Boolean.toString(LogHelper.isDevEnabled())));
|
||||||
if (LauncherConfig.ADDRESS_OVERRIDE != null)
|
if (LauncherConfig.ADDRESS_OVERRIDE != null)
|
||||||
args.add(JVMHelper.jvmProperty(LauncherConfig.ADDRESS_OVERRIDE_PROPERTY, LauncherConfig.ADDRESS_OVERRIDE));
|
context.args.add(JVMHelper.jvmProperty(LauncherConfig.ADDRESS_OVERRIDE_PROPERTY, LauncherConfig.ADDRESS_OVERRIDE));
|
||||||
if (JVMHelper.OS_TYPE == OS.MUSTDIE) {
|
if (JVMHelper.OS_TYPE == OS.MUSTDIE) {
|
||||||
if (JVMHelper.OS_VERSION.startsWith("10.")) {
|
if (JVMHelper.OS_VERSION.startsWith("10.")) {
|
||||||
LogHelper.debug("MustDie 10 fix is applied");
|
LogHelper.debug("MustDie 10 fix is applied");
|
||||||
args.add(JVMHelper.jvmProperty("os.name", "Windows 10"));
|
context.args.add(JVMHelper.jvmProperty("os.name", "Windows 10"));
|
||||||
args.add(JVMHelper.jvmProperty("os.version", "10.0"));
|
context.args.add(JVMHelper.jvmProperty("os.version", "10.0"));
|
||||||
}
|
}
|
||||||
args.add(JVMHelper.systemToJvmProperty("avn32"));
|
context.args.add(JVMHelper.systemToJvmProperty("avn32"));
|
||||||
args.add(JVMHelper.systemToJvmProperty("avn64"));
|
context.args.add(JVMHelper.systemToJvmProperty("avn64"));
|
||||||
}
|
}
|
||||||
// Add classpath and main class
|
// Add classpath and main class
|
||||||
String pathLauncher = IOHelper.getCodeSource(ClientLauncher.class).toString();
|
String pathLauncher = IOHelper.getCodeSource(ClientLauncher.class).toString();
|
||||||
Collections.addAll(args, profile.getJvmArgs());
|
context.pathLauncher = pathLauncher;
|
||||||
profile.pushOptionalJvmArgs(args);
|
Collections.addAll(context.args, profile.getJvmArgs());
|
||||||
Collections.addAll(args, "-Djava.library.path=".concat(params.clientDir.resolve(NATIVES_DIR).toString())); // Add Native Path
|
profile.pushOptionalJvmArgs(context.args);
|
||||||
Collections.addAll(args, "-javaagent:".concat(pathLauncher));
|
Collections.addAll(context.args, "-Djava.library.path=".concat(params.clientDir.resolve(NATIVES_DIR).toString())); // Add Native Path
|
||||||
if (wrapper)
|
Collections.addAll(context.args, "-javaagent:".concat(pathLauncher));
|
||||||
Collections.addAll(args, "-Djava.class.path=".concat(pathLauncher)); // Add Class Path
|
LauncherGuardManager.guard.addCustomParams(context);
|
||||||
else {
|
Collections.addAll(context.args, ClientLauncher.class.getName());
|
||||||
Collections.addAll(args, "-cp");
|
|
||||||
Collections.addAll(args, pathLauncher);
|
|
||||||
}
|
|
||||||
Collections.addAll(args, ClientLauncher.class.getName());
|
|
||||||
|
|
||||||
// Print commandline debug message
|
// Print commandline debug message
|
||||||
LogHelper.debug("Commandline: " + args);
|
LogHelper.debug("Commandline: " + context.args);
|
||||||
|
|
||||||
// Build client process
|
// Build client process
|
||||||
LogHelper.debug("Launching client instance");
|
LogHelper.debug("Launching client instance");
|
||||||
ProcessBuilder builder = new ProcessBuilder(args);
|
ProcessBuilder builder = new ProcessBuilder(context.args);
|
||||||
if (wrapper)
|
context.builder = builder;
|
||||||
builder.environment().put("JAVA_HOME", System.getProperty("java.home"));
|
LauncherGuardManager.guard.addCustomEnv(context);
|
||||||
//else
|
//else
|
||||||
//builder.environment().put("CLASSPATH", classPathString.toString());
|
//builder.environment().put("CLASSPATH", classPathString.toString());
|
||||||
EnvHelper.addEnv(builder);
|
EnvHelper.addEnv(builder);
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package ru.gravit.launcher.client;
|
||||||
|
|
||||||
|
import ru.gravit.launcher.profiles.ClientProfile;
|
||||||
|
import ru.gravit.launcher.profiles.PlayerProfile;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ClientLauncherContext {
|
||||||
|
public Path javaBin;
|
||||||
|
public List<String> args = new LinkedList<>();
|
||||||
|
public String pathLauncher;
|
||||||
|
public ProcessBuilder builder;
|
||||||
|
public ClientProfile clientProfile;
|
||||||
|
public PlayerProfile playerProfile;
|
||||||
|
}
|
|
@ -1,9 +1,14 @@
|
||||||
package ru.gravit.launcher.guard;
|
package ru.gravit.launcher.guard;
|
||||||
|
|
||||||
|
import ru.gravit.launcher.client.ClientLauncherContext;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
public interface LauncherGuardInterface {
|
public interface LauncherGuardInterface {
|
||||||
String getName();
|
String getName();
|
||||||
Path getJavaBinPath();
|
Path getJavaBinPath();
|
||||||
void init(boolean clientInstance);
|
void init(boolean clientInstance);
|
||||||
|
void addCustomParams(ClientLauncherContext context);
|
||||||
|
void addCustomEnv(ClientLauncherContext context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
package ru.gravit.launcher.guard;
|
package ru.gravit.launcher.guard;
|
||||||
|
|
||||||
import ru.gravit.launcher.client.ClientLauncher;
|
import ru.gravit.launcher.client.ClientLauncher;
|
||||||
|
import ru.gravit.launcher.client.ClientLauncherContext;
|
||||||
import ru.gravit.utils.helper.IOHelper;
|
import ru.gravit.utils.helper.IOHelper;
|
||||||
import ru.gravit.utils.helper.JVMHelper;
|
import ru.gravit.utils.helper.JVMHelper;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
public class LauncherJavaGuard implements LauncherGuardInterface {
|
public class LauncherJavaGuard implements LauncherGuardInterface {
|
||||||
@Override
|
@Override
|
||||||
|
@ -25,4 +28,15 @@ public Path getJavaBinPath() {
|
||||||
public void init(boolean clientInstance) {
|
public void init(boolean clientInstance) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addCustomParams(ClientLauncherContext context) {
|
||||||
|
Collections.addAll(context.args, "-cp");
|
||||||
|
Collections.addAll(context.args, context.pathLauncher);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addCustomEnv(ClientLauncherContext context) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
package ru.gravit.launcher.guard;
|
package ru.gravit.launcher.guard;
|
||||||
|
|
||||||
|
import ru.gravit.launcher.client.ClientLauncherContext;
|
||||||
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 java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
public class LauncherNoGuard implements LauncherGuardInterface {
|
public class LauncherNoGuard implements LauncherGuardInterface {
|
||||||
@Override
|
@Override
|
||||||
|
@ -21,4 +24,15 @@ public Path getJavaBinPath() {
|
||||||
public void init(boolean clientInstance) {
|
public void init(boolean clientInstance) {
|
||||||
LogHelper.warning("Using noGuard interface");
|
LogHelper.warning("Using noGuard interface");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addCustomParams(ClientLauncherContext context) {
|
||||||
|
Collections.addAll(context.args, "-cp");
|
||||||
|
Collections.addAll(context.args, context.pathLauncher);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addCustomEnv(ClientLauncherContext context) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
package ru.gravit.launcher.guard;
|
package ru.gravit.launcher.guard;
|
||||||
|
|
||||||
import ru.gravit.launcher.Launcher;
|
import ru.gravit.launcher.Launcher;
|
||||||
|
import ru.gravit.launcher.LauncherConfig;
|
||||||
|
import ru.gravit.launcher.client.ClientLauncherContext;
|
||||||
import ru.gravit.launcher.client.DirBridge;
|
import ru.gravit.launcher.client.DirBridge;
|
||||||
import ru.gravit.utils.helper.IOHelper;
|
import ru.gravit.utils.helper.*;
|
||||||
import ru.gravit.utils.helper.JVMHelper;
|
|
||||||
import ru.gravit.utils.helper.UnpackHelper;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class LauncherWrapperGuard implements LauncherGuardInterface {
|
public class LauncherWrapperGuard implements LauncherGuardInterface {
|
||||||
@Override
|
@Override
|
||||||
|
@ -19,7 +23,11 @@ public String getName() {
|
||||||
@Override
|
@Override
|
||||||
public Path getJavaBinPath() {
|
public Path getJavaBinPath() {
|
||||||
if(JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE)
|
if(JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE)
|
||||||
return DirBridge.getGuardDir().resolve(JVMHelper.JVM_BITS == 64 ? "wrapper64.exe" : "wrapper32.exe");
|
{
|
||||||
|
String projectName = Launcher.getConfig().projectname;
|
||||||
|
String wrapperUnpackName = JVMHelper.JVM_BITS == 64 ? projectName.concat("64.exe") : projectName.concat("32.exe");
|
||||||
|
return DirBridge.getGuardDir().resolve(wrapperUnpackName);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home")));
|
return IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home")));
|
||||||
}
|
}
|
||||||
|
@ -28,11 +36,34 @@ public Path getJavaBinPath() {
|
||||||
public void init(boolean clientInstance) {
|
public void init(boolean clientInstance) {
|
||||||
try {
|
try {
|
||||||
String wrapperName = JVMHelper.JVM_BITS == 64 ? "wrapper64.exe" : "wrapper32.exe";
|
String wrapperName = JVMHelper.JVM_BITS == 64 ? "wrapper64.exe" : "wrapper32.exe";
|
||||||
|
String projectName = Launcher.getConfig().projectname;
|
||||||
|
String wrapperUnpackName = JVMHelper.JVM_BITS == 64 ? projectName.concat("64.exe") : projectName.concat("32.exe");
|
||||||
String antiInjectName = JVMHelper.JVM_BITS == 64 ? "AntiInject64.dll" : "AntiInject32.dll";
|
String antiInjectName = JVMHelper.JVM_BITS == 64 ? "AntiInject64.dll" : "AntiInject32.dll";
|
||||||
UnpackHelper.unpack(Launcher.getResourceURL(wrapperName, "guard"),DirBridge.getGuardDir().resolve(wrapperName));
|
UnpackHelper.unpack(Launcher.getResourceURL(wrapperName, "guard"),DirBridge.getGuardDir().resolve(wrapperUnpackName));
|
||||||
UnpackHelper.unpack(Launcher.getResourceURL(antiInjectName, "guard"),DirBridge.getGuardDir().resolve(antiInjectName));
|
UnpackHelper.unpack(Launcher.getResourceURL(antiInjectName, "guard"),DirBridge.getGuardDir().resolve(antiInjectName));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new SecurityException(e);
|
throw new SecurityException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addCustomParams(ClientLauncherContext context) {
|
||||||
|
Collections.addAll(context.args, "-Djava.class.path=".concat(context.pathLauncher));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addCustomEnv(ClientLauncherContext context) {
|
||||||
|
Map<String,String> env = context.builder.environment();
|
||||||
|
env.put("JAVA_HOME", System.getProperty("java.home"));
|
||||||
|
LauncherConfig config = Launcher.getConfig();
|
||||||
|
env.put("GUARD_USERNAME", context.playerProfile.username);
|
||||||
|
env.put("GUARD_PUBLICKEY", config.publicKey.getModulus().toString(16));
|
||||||
|
env.put("GUARD_PROJECTNAME", config.projectname);
|
||||||
|
if(config.guardLicenseName != null)
|
||||||
|
env.put("GUARD_LICENSE_NAME", config.guardLicenseName);
|
||||||
|
if(config.guardLicenseKey != null)
|
||||||
|
{
|
||||||
|
env.put("GUARD_LICENSE_KEY", config.guardLicenseKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':libLauncher')
|
compile project(':libLauncher')
|
||||||
compileOnly 'javax.websocket:javax.websocket-client-api:1.1'
|
compile 'org.java-websocket:Java-WebSocket:1.3.9'
|
||||||
compileOnly 'com.google.guava:guava:26.0-jre'
|
compileOnly 'com.google.guava:guava:26.0-jre'
|
||||||
compile files('../compat/authlib/authlib-clean.jar')
|
compile files('../compat/authlib/authlib-clean.jar')
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ private Result(PlayerProfile pp, String accessToken, ClientPermissions permissio
|
||||||
private final byte[] encryptedPassword;
|
private final byte[] encryptedPassword;
|
||||||
private final int auth_id;
|
private final int auth_id;
|
||||||
private final HWID hwid;
|
private final HWID hwid;
|
||||||
|
private final String customText;
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public AuthRequest(LauncherConfig config, String login, byte[] encryptedPassword, HWID hwid) {
|
public AuthRequest(LauncherConfig config, String login, byte[] encryptedPassword, HWID hwid) {
|
||||||
|
@ -41,6 +42,16 @@ public AuthRequest(LauncherConfig config, String login, byte[] encryptedPassword
|
||||||
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
|
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
|
||||||
this.encryptedPassword = encryptedPassword.clone();
|
this.encryptedPassword = encryptedPassword.clone();
|
||||||
this.hwid = hwid;
|
this.hwid = hwid;
|
||||||
|
customText = "";
|
||||||
|
auth_id = 0;
|
||||||
|
}
|
||||||
|
@LauncherAPI
|
||||||
|
public AuthRequest(LauncherConfig config, String login, byte[] encryptedPassword, HWID hwid, String customText) {
|
||||||
|
super(config);
|
||||||
|
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
|
||||||
|
this.encryptedPassword = encryptedPassword.clone();
|
||||||
|
this.hwid = hwid;
|
||||||
|
this.customText = customText;
|
||||||
auth_id = 0;
|
auth_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +62,16 @@ public AuthRequest(LauncherConfig config, String login, byte[] encryptedPassword
|
||||||
this.encryptedPassword = encryptedPassword.clone();
|
this.encryptedPassword = encryptedPassword.clone();
|
||||||
this.hwid = hwid;
|
this.hwid = hwid;
|
||||||
this.auth_id = auth_id;
|
this.auth_id = auth_id;
|
||||||
|
customText = "";
|
||||||
|
}
|
||||||
|
@LauncherAPI
|
||||||
|
public AuthRequest(LauncherConfig config, String login, byte[] encryptedPassword, HWID hwid, String customText, int auth_id) {
|
||||||
|
super(config);
|
||||||
|
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
|
||||||
|
this.encryptedPassword = encryptedPassword.clone();
|
||||||
|
this.hwid = hwid;
|
||||||
|
this.auth_id = auth_id;
|
||||||
|
this.customText = customText;
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
|
@ -97,6 +118,7 @@ protected Result requestDo(HInput input, HOutput output) throws IOException {
|
||||||
//output.writeLong(0);
|
//output.writeLong(0);
|
||||||
//output.writeLong(0);
|
//output.writeLong(0);
|
||||||
output.writeByteArray(encryptedPassword, SecurityHelper.CRYPTO_MAX_LENGTH);
|
output.writeByteArray(encryptedPassword, SecurityHelper.CRYPTO_MAX_LENGTH);
|
||||||
|
output.writeString(customText, SerializeLimits.MAX_CUSTOM_TEXT);
|
||||||
output.flush();
|
output.flush();
|
||||||
|
|
||||||
// Read UUID and access token
|
// Read UUID and access token
|
||||||
|
|
|
@ -1,52 +1,37 @@
|
||||||
package ru.gravit.launcher.request.websockets;
|
package ru.gravit.launcher.request.websockets;
|
||||||
|
|
||||||
import javax.websocket.*;
|
import java.net.URI;
|
||||||
import java.io.IOException;
|
import java.util.Map;
|
||||||
import java.io.Reader;
|
|
||||||
|
|
||||||
/*
|
import org.java_websocket.client.WebSocketClient;
|
||||||
* public class Client {
|
import org.java_websocket.drafts.Draft_6455;
|
||||||
*
|
import org.java_websocket.handshake.ServerHandshake;
|
||||||
* final static CountDownLatch messageLatch = new CountDownLatch(1);
|
|
||||||
*
|
|
||||||
* public static void main(String[] args) {
|
|
||||||
* try {
|
|
||||||
* WebSocketContainer container = ContainerProvider.getWebSocketContainer();
|
|
||||||
* String uri = "ws://echo.websocket.org:80/";
|
|
||||||
* System.out.println("Connecting to " + uri);
|
|
||||||
* container.connectToServer(MyClientEndpoint.class, URI.create(uri));
|
|
||||||
* messageLatch.await(100, TimeUnit.SECONDS);
|
|
||||||
* } catch (DeploymentException | InterruptedException | IOException ex) {
|
|
||||||
* Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
@ClientEndpoint
|
|
||||||
public class ClientJSONPoint {
|
|
||||||
public Session session = null;
|
|
||||||
|
|
||||||
@OnOpen
|
import ru.gravit.utils.helper.LogHelper;
|
||||||
public void onOpen(final Session session_r) {
|
|
||||||
session = session_r;
|
|
||||||
System.out.println("Connected to endpoint: " + session.getBasicRemote());
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnError
|
public class ClientJSONPoint extends WebSocketClient {
|
||||||
public void processError(final Throwable t) {
|
|
||||||
t.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnMessage
|
public ClientJSONPoint(URI serverUri, Map<String, String> httpHeaders, int connectTimeout) {
|
||||||
public void processMessage(Reader message) {
|
super(serverUri, new Draft_6455(), httpHeaders, connectTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
@Override
|
||||||
|
public void onOpen(ServerHandshake handshakedata) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void send(String js) throws IOException {
|
@Override
|
||||||
session.getBasicRemote().sendText(js);
|
public void onMessage(String message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClose(int code, String reason, boolean remote) {
|
||||||
|
LogHelper.debug("Disconnected: " + code + " " + remote + " " + reason != null ? reason : "no reason");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Exception ex) {
|
||||||
|
LogHelper.error(ex);
|
||||||
|
}
|
||||||
|
|
||||||
public void sendAsync(String js) {
|
|
||||||
session.getAsyncRemote().sendText(js);
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -5,9 +5,12 @@
|
||||||
import ru.gravit.launcher.hasher.HashedEntry;
|
import ru.gravit.launcher.hasher.HashedEntry;
|
||||||
import ru.gravit.launcher.hasher.HashedEntryAdapter;
|
import ru.gravit.launcher.hasher.HashedEntryAdapter;
|
||||||
import ru.gravit.launcher.request.ResultInterface;
|
import ru.gravit.launcher.request.ResultInterface;
|
||||||
|
import ru.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.net.URI;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
@ -18,7 +21,8 @@ public class ClientWebSocketService extends ClientJSONPoint {
|
||||||
private HashMap<String, Class<? extends ResultInterface>> results;
|
private HashMap<String, Class<? extends ResultInterface>> results;
|
||||||
private HashSet<EventHandler> handlers;
|
private HashSet<EventHandler> handlers;
|
||||||
|
|
||||||
public ClientWebSocketService(GsonBuilder gsonBuilder) {
|
public ClientWebSocketService(GsonBuilder gsonBuilder, String address, int port, int i) {
|
||||||
|
super(createURL(address, port), Collections.emptyMap(), i);
|
||||||
requests = new HashMap<>();
|
requests = new HashMap<>();
|
||||||
results = new HashMap<>();
|
results = new HashMap<>();
|
||||||
handlers = new HashSet<>();
|
handlers = new HashSet<>();
|
||||||
|
@ -27,9 +31,18 @@ public ClientWebSocketService(GsonBuilder gsonBuilder) {
|
||||||
gsonBuilder.registerTypeAdapter(HashedEntry.class, new HashedEntryAdapter());
|
gsonBuilder.registerTypeAdapter(HashedEntry.class, new HashedEntryAdapter());
|
||||||
this.gson = gsonBuilder.create();
|
this.gson = gsonBuilder.create();
|
||||||
}
|
}
|
||||||
@Override
|
private static URI createURL(String address, int port) {
|
||||||
public void processMessage(Reader reader) {
|
try {
|
||||||
ResultInterface result = gson.fromJson(reader, ResultInterface.class);
|
URL u = new URL(address);
|
||||||
|
return new URL(u.getProtocol(), u.getHost(), port, u.getFile()).toURI();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
LogHelper.error(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onMessage(String message) {
|
||||||
|
ResultInterface result = gson.fromJson(message, ResultInterface.class);
|
||||||
for(EventHandler handler : handlers)
|
for(EventHandler handler : handlers)
|
||||||
{
|
{
|
||||||
handler.process(result);
|
handler.process(result);
|
||||||
|
@ -64,10 +77,6 @@ public void registerHandler(EventHandler eventHandler)
|
||||||
handlers.add(eventHandler);
|
handlers.add(eventHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendObjectAsync(Object obj) throws IOException {
|
|
||||||
sendAsync(gson.toJson(obj));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendObject(Object obj) throws IOException {
|
public void sendObject(Object obj) throws IOException {
|
||||||
send(gson.toJson(obj));
|
send(gson.toJson(obj));
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,7 @@
|
||||||
import ru.gravit.launcher.Launcher;
|
import ru.gravit.launcher.Launcher;
|
||||||
import ru.gravit.launcher.request.ResultInterface;
|
import ru.gravit.launcher.request.ResultInterface;
|
||||||
|
|
||||||
import javax.websocket.ContainerProvider;
|
|
||||||
import javax.websocket.WebSocketContainer;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
|
||||||
|
|
||||||
public class LegacyRequestBridge {
|
public class LegacyRequestBridge {
|
||||||
public static WaitEventHandler waitEventHandler = new WaitEventHandler();
|
public static WaitEventHandler waitEventHandler = new WaitEventHandler();
|
||||||
public static ClientWebSocketService service;
|
public static ClientWebSocketService service;
|
||||||
|
@ -30,13 +26,7 @@ public static ResultInterface sendRequest(RequestInterface request) throws IOExc
|
||||||
}
|
}
|
||||||
public static void initWebSockets(String address, int port)
|
public static void initWebSockets(String address, int port)
|
||||||
{
|
{
|
||||||
service = new ClientWebSocketService(new GsonBuilder());
|
service = new ClientWebSocketService(new GsonBuilder(), address, port, 5000);
|
||||||
try {
|
|
||||||
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
|
|
||||||
container.connectToServer(service, new URI("ws://".concat(address).concat(":".concat(String.valueOf(port)).concat("/api"))));
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
static {
|
static {
|
||||||
if(Launcher.getConfig().nettyPort != 0)
|
if(Launcher.getConfig().nettyPort != 0)
|
||||||
|
|
|
@ -11,6 +11,9 @@ public class AutogenConfig {
|
||||||
public boolean isUsingWrapper;
|
public boolean isUsingWrapper;
|
||||||
public boolean isDownloadJava; //Выставление этого флага требует модификации runtime части
|
public boolean isDownloadJava; //Выставление этого флага требует модификации runtime части
|
||||||
public String secretKeyClient;
|
public String secretKeyClient;
|
||||||
|
public String guardLicenseName;
|
||||||
|
public String guardLicenseKey;
|
||||||
|
public String guardLicenseEncryptKey;
|
||||||
public int env;
|
public int env;
|
||||||
public boolean isWarningMissArchJava;
|
public boolean isWarningMissArchJava;
|
||||||
// 0 - Dev (дебаг включен по умолчанию, все сообщения)
|
// 0 - Dev (дебаг включен по умолчанию, все сообщения)
|
||||||
|
|
|
@ -60,7 +60,7 @@ public final class Launcher {
|
||||||
private static final Pattern UUID_PATTERN = Pattern.compile("-", Pattern.LITERAL);
|
private static final Pattern UUID_PATTERN = Pattern.compile("-", Pattern.LITERAL);
|
||||||
public static final int MAJOR = 4;
|
public static final int MAJOR = 4;
|
||||||
public static final int MINOR = 3;
|
public static final int MINOR = 3;
|
||||||
public static final int PATCH = 1;
|
public static final int PATCH = 2;
|
||||||
public static final int BUILD = 1;
|
public static final int BUILD = 1;
|
||||||
public static final Version.Type RELEASE = Version.Type.STABLE;
|
public static final Version.Type RELEASE = Version.Type.STABLE;
|
||||||
public static GsonBuilder gsonBuilder;
|
public static GsonBuilder gsonBuilder;
|
||||||
|
|
|
@ -43,6 +43,10 @@ public static AutogenConfig getAutogenConfig() {
|
||||||
public final boolean isDownloadJava;
|
public final boolean isDownloadJava;
|
||||||
public final boolean isWarningMissArchJava;
|
public final boolean isWarningMissArchJava;
|
||||||
|
|
||||||
|
public final String guardLicenseName;
|
||||||
|
public final String guardLicenseKey;
|
||||||
|
public final String guardLicenseEncryptKey;
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException {
|
public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException {
|
||||||
String localAddress = config.address;
|
String localAddress = config.address;
|
||||||
|
@ -55,6 +59,9 @@ public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException
|
||||||
isDownloadJava = config.isDownloadJava;
|
isDownloadJava = config.isDownloadJava;
|
||||||
isUsingWrapper = config.isUsingWrapper;
|
isUsingWrapper = config.isUsingWrapper;
|
||||||
isWarningMissArchJava = config.isWarningMissArchJava;
|
isWarningMissArchJava = config.isWarningMissArchJava;
|
||||||
|
guardLicenseEncryptKey = config.guardLicenseEncryptKey;
|
||||||
|
guardLicenseKey = config.guardLicenseKey;
|
||||||
|
guardLicenseName = config.guardLicenseName;
|
||||||
nettyPort = config.nettyPort;
|
nettyPort = config.nettyPort;
|
||||||
LauncherEnvironment env;
|
LauncherEnvironment env;
|
||||||
if (config.env == 0) env = LauncherEnvironment.DEV;
|
if (config.env == 0) env = LauncherEnvironment.DEV;
|
||||||
|
@ -86,6 +93,9 @@ public LauncherConfig(String address, int port, RSAPublicKey publicKey, Map<Stri
|
||||||
this.runtime = Collections.unmodifiableMap(new HashMap<>(runtime));
|
this.runtime = Collections.unmodifiableMap(new HashMap<>(runtime));
|
||||||
this.projectname = projectname;
|
this.projectname = projectname;
|
||||||
this.clientPort = 32148;
|
this.clientPort = 32148;
|
||||||
|
this.guardLicenseName = "FREE";
|
||||||
|
this.guardLicenseKey = "AAAA-BBBB-CCCC-DDDD";
|
||||||
|
this.guardLicenseEncryptKey = "12345";
|
||||||
isUsingWrapper = true;
|
isUsingWrapper = true;
|
||||||
isDownloadJava = false;
|
isDownloadJava = false;
|
||||||
isWarningMissArchJava = true;
|
isWarningMissArchJava = true;
|
||||||
|
@ -97,6 +107,9 @@ public LauncherConfig(String address, int port, RSAPublicKey publicKey, Map<Stri
|
||||||
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";
|
||||||
|
this.guardLicenseName = "FREE";
|
||||||
|
this.guardLicenseKey = "AAAA-BBBB-CCCC-DDDD";
|
||||||
|
this.guardLicenseEncryptKey = "12345";
|
||||||
this.clientPort = 32148;
|
this.clientPort = 32148;
|
||||||
isUsingWrapper = true;
|
isUsingWrapper = true;
|
||||||
isDownloadJava = false;
|
isDownloadJava = false;
|
||||||
|
|
|
@ -6,6 +6,8 @@ public class SerializeLimits {
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public static final int MAX_LOGIN = 1024;
|
public static final int MAX_LOGIN = 1024;
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
|
public static final int MAX_CUSTOM_TEXT = 512;
|
||||||
|
@LauncherAPI
|
||||||
public static final int MAX_CLIENT = 128;
|
public static final int MAX_CLIENT = 128;
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public static final int MAX_SERVERID = 128;
|
public static final int MAX_SERVERID = 128;
|
||||||
|
|
Loading…
Reference in a new issue