Merge pull request #355 from GravitLauncher/feature/newProp

[FEATURE] Переход на новое API хранения данных на уровне байткода.
This commit is contained in:
Gravit 2020-02-01 13:32:16 +07:00 committed by GitHub
commit 63ea1f59b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 150 additions and 309 deletions

View file

@ -1,84 +0,0 @@
package pro.gravit.launchserver.asm;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.*;
import java.util.Base64;
import java.util.List;
public class ConfigGenerator {
protected static final String stringDesc = Type.getDescriptor(String.class);
protected static final String byteArrDesc = Type.getDescriptor(byte[].class);
protected static final String base64DecDesc = "(" + stringDesc + ")" + byteArrDesc;
protected final ClassNode configclass;
protected final MethodNode constructor;
public ConfigGenerator(ClassNode configclass) {
this.configclass = configclass;
constructor = this.configclass.methods.stream().filter(e -> "<init>".equals(e.name)).findFirst().get();
constructor.instructions = new InsnList();
constructor.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
constructor.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), "<init>", "()V"));
}
public byte[] getBytecode(ClassMetadataReader reader) {
constructor.instructions.add(new InsnNode(Opcodes.RETURN));
ClassWriter cw = new SafeClassWriter(reader, ClassWriter.COMPUTE_FRAMES);
configclass.accept(cw);
return cw.toByteArray();
}
public String getZipEntryPath() {
return configclass.name.concat(".class");
}
public void setStringField(String name, String value) {
constructor.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
constructor.instructions.add(NodeUtils.getSafeStringInsnList(value));
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, configclass.name, name, stringDesc));
}
public void setByteArrayField(String name, byte[] value) {
constructor.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
constructor.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/util/Base64", "getDecoder", "()Ljava/util/Base64$Decoder;", false));
constructor.instructions.add(NodeUtils.getSafeStringInsnList(Base64.getEncoder().encodeToString(value)));
constructor.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/util/Base64$Decoder", "decode", base64DecDesc, false));
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, configclass.name, name, stringDesc));
}
public void setByteArrayListField(String name, List<byte[]> b) {
constructor.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
constructor.instructions.add(new TypeInsnNode(Opcodes.NEW, "java/util/ArrayList"));
constructor.instructions.add(new InsnNode(Opcodes.DUP)); // +1
constructor.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/util/ArrayList", "<init>", "()V"));
for (byte[] value : b) {
constructor.instructions.add(new InsnNode(Opcodes.DUP)); // +1-1
constructor.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/util/Base64", "getDecoder", "()Ljava/util/Base64$Decoder;", false));
constructor.instructions.add(NodeUtils.getSafeStringInsnList(Base64.getEncoder().encodeToString(value)));
constructor.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/util/Base64$Decoder", "decode", base64DecDesc, false));
constructor.instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, "java/util/List", "add", "(Ljava/lang/Object;)Z", true));
constructor.instructions.add(new InsnNode(Opcodes.POP));
}
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, configclass.name, name, "Ljava/util/List;"));
}
public void setIntegerField(String name, int value) {
constructor.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
constructor.instructions.add(NodeUtils.push(value));
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, configclass.name, name, Type.INT_TYPE.getInternalName()));
}
public void setLongField(String name, long value) {
constructor.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
constructor.instructions.add(new LdcInsnNode(value));
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, configclass.name, name, Type.INT_TYPE.getInternalName()));
}
public void setBooleanField(String name, boolean b) {
constructor.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
constructor.instructions.add(new InsnNode(b ? Opcodes.ICONST_1 : Opcodes.ICONST_0));
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, configclass.name, name, Type.BOOLEAN_TYPE.getInternalName()));
}
}

View file

@ -123,6 +123,11 @@ public void visit(final String name, final Object value) {
serializers.put(byte[].class, new ByteArraySerializer()); serializers.put(byte[].class, new ByteArraySerializer());
serializers.put(Short.class, serializerClass(Opcodes.I2S)); serializers.put(Short.class, serializerClass(Opcodes.I2S));
serializers.put(Byte.class, serializerClass(Opcodes.I2B)); serializers.put(Byte.class, serializerClass(Opcodes.I2B));
serializers.put(Type.class, (Serializer<Type>) e -> { // ow.Type == java.lang.Class in LDC
InsnList ret = new InsnList();
ret.add(new LdcInsnNode(e));
return ret;
});
serializers.put(Boolean.class, (Serializer<Boolean>) e -> { serializers.put(Boolean.class, (Serializer<Boolean>) e -> {
InsnList ret = new InsnList(); InsnList ret = new InsnList();
ret.add(new InsnNode(e ? Opcodes.ICONST_1 : Opcodes.ICONST_0)); ret.add(new InsnNode(e ? Opcodes.ICONST_1 : Opcodes.ICONST_0));

View file

@ -32,7 +32,6 @@
public class BuildContext { public class BuildContext {
public final ZipOutputStream output; public final ZipOutputStream output;
public final LauncherConfigurator config;
public final List<JarFile> readerClassPath; public final List<JarFile> readerClassPath;
public final MainBuildTask task; public final MainBuildTask task;
public final HashSet<String> fileList; public final HashSet<String> fileList;
@ -78,9 +77,8 @@ private ZipEntry newEntry(String fileName) {
} }
public BuildContext(ZipOutputStream output, LauncherConfigurator config, List<JarFile> readerClassPath, MainBuildTask task) { public BuildContext(ZipOutputStream output, List<JarFile> readerClassPath, MainBuildTask task) {
this.output = output; this.output = output;
this.config = config;
this.readerClassPath = readerClassPath; this.readerClassPath = readerClassPath;
this.task = task; this.task = task;
fileList = new HashSet<>(1024); fileList = new HashSet<>(1024);

View file

@ -1,56 +0,0 @@
package pro.gravit.launchserver.binary;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.*;
import pro.gravit.launcher.LauncherConfig;
import pro.gravit.launcher.modules.LauncherModule;
import pro.gravit.launchserver.asm.ClassMetadataReader;
import pro.gravit.launchserver.asm.ConfigGenerator;
public class LauncherConfigurator extends ConfigGenerator {
private static final String modulesManagerName = "pro/gravit/launcher/modules/LauncherModulesManager";
private static final String launcherName = "pro/gravit/launcher/LauncherEngine";
private static final String modulesManagerDesc = "Lpro/gravit/launcher/client/ClientModuleManager;";
private static final String registerModDesc = Type.getMethodDescriptor(Type.getType(LauncherModule.class), Type.getType(LauncherModule.class));
private final MethodNode initModuleMethod;
public LauncherConfigurator(ClassNode configclass) {
super(configclass);
initModuleMethod = configclass.methods.stream().filter(e -> "initModules".equals(e.name)).findFirst().get();
initModuleMethod.instructions = new InsnList();
}
public void addModuleClass(String fullName) {
initModuleMethod.instructions.add(new FieldInsnNode(Opcodes.GETSTATIC, launcherName, "modulesManager", modulesManagerDesc));
initModuleMethod.instructions.add(new TypeInsnNode(Opcodes.NEW, fullName.replace('.', '/')));
initModuleMethod.instructions.add(new InsnNode(Opcodes.DUP));
initModuleMethod.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, fullName.replace('.', '/'), "<init>", "()V"));
initModuleMethod.instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, modulesManagerName, "loadModule", registerModDesc));
}
@Override
public byte[] getBytecode(ClassMetadataReader reader) {
initModuleMethod.instructions.add(new InsnNode(Opcodes.RETURN));
return super.getBytecode(reader);
}
public void setEnv(LauncherConfig.LauncherEnvironment env) {
int i = 2;
switch (env) {
case DEV:
i = 0;
break;
case DEBUG:
i = 1;
break;
case STD:
i = 2;
break;
case PROD:
i = 3;
break;
}
setIntegerField("env", i);
}
}

View file

@ -2,23 +2,19 @@
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AnnotationNode; import org.objectweb.asm.tree.AnnotationNode;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.FieldNode;
import pro.gravit.launcher.AutogenConfig;
import pro.gravit.launcher.Launcher; import pro.gravit.launcher.Launcher;
import pro.gravit.launcher.LauncherConfig; import pro.gravit.launcher.LauncherConfig;
import pro.gravit.launcher.SecureAutogenConfig;
import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.asm.ClassMetadataReader; import pro.gravit.launchserver.asm.ClassMetadataReader;
import pro.gravit.launchserver.asm.ConfigGenerator;
import pro.gravit.launchserver.asm.InjectClassAcceptor; import pro.gravit.launchserver.asm.InjectClassAcceptor;
import pro.gravit.launchserver.asm.SafeClassWriter; import pro.gravit.launchserver.asm.SafeClassWriter;
import pro.gravit.launchserver.binary.BuildContext; import pro.gravit.launchserver.binary.BuildContext;
import pro.gravit.launchserver.binary.LauncherConfigurator;
import pro.gravit.utils.HookException; import pro.gravit.utils.HookException;
import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.IOHelper;
import pro.gravit.utils.helper.JarHelper;
import pro.gravit.utils.helper.LogHelper; import pro.gravit.utils.helper.LogHelper;
import pro.gravit.utils.helper.SecurityHelper; import pro.gravit.utils.helper.SecurityHelper;
@ -137,49 +133,11 @@ public String getName() {
public Path process(Path inputJar) throws IOException { public Path process(Path inputJar) throws IOException {
Path outputJar = server.launcherBinary.nextPath("main"); Path outputJar = server.launcherBinary.nextPath("main");
try (ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(outputJar))) { try (ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(outputJar))) {
ClassNode cn = new ClassNode(); BuildContext context = new BuildContext(output, reader.getCp(), this);
new ClassReader(JarHelper.getClassBytes(AutogenConfig.class)).accept(cn, 0); initProps();
LauncherConfigurator launcherConfigurator = new LauncherConfigurator(cn);
ClassNode cn1 = new ClassNode();
new ClassReader(JarHelper.getClassBytes(SecureAutogenConfig.class)).accept(cn1, 0);
ConfigGenerator secureConfigurator = new ConfigGenerator(cn1);
BuildContext context = new BuildContext(output, launcherConfigurator, reader.getCp(), this);
preBuildHook.hook(context); preBuildHook.hook(context);
launcherConfigurator.setStringField("address", server.config.netty.address); properties.put("launcher.modules", context.clientModules.stream().map(e -> Type.getObjectType(e.replace('.', '/'))).collect(Collectors.toList()));
launcherConfigurator.setStringField("projectname", server.config.projectName); postInitProps();
launcherConfigurator.setStringField("secretKeyClient", SecurityHelper.randomStringAESKey());
launcherConfigurator.setIntegerField("clientPort", 32148 + SecurityHelper.newRandom().nextInt(512));
launcherConfigurator.setStringField("guardType", server.config.launcher.guardType);
launcherConfigurator.setBooleanField("isWarningMissArchJava", server.config.launcher.warningMissArchJava);
launcherConfigurator.setEnv(server.config.env);
launcherConfigurator.setStringField("passwordEncryptKey", server.runtime.passwordEncryptKey);
List<byte[]> certificates = Arrays.stream(server.certificateManager.trustManager.getTrusted()).map(e -> {
try {
return e.getEncoded();
} catch (CertificateEncodingException e2) {
LogHelper.error(e2);
return new byte[0];
}
}).collect(Collectors.toList());
if(!server.config.sign.enabled)
{
CertificateAutogenTask task = server.launcherBinary.getTaskByClass(CertificateAutogenTask.class).get();
try {
certificates.add(task.certificate.getEncoded());
} catch (CertificateEncodingException e) {
throw new InternalError(e);
}
}
secureConfigurator.setByteArrayListField("certificates", certificates);
String launcherSalt = SecurityHelper.randomStringToken();
byte[] launcherSecureHash = SecurityHelper.digest(SecurityHelper.DigestAlgorithm.SHA256,
server.runtime.clientCheckSecret.concat(".").concat(launcherSalt));
launcherConfigurator.setStringField("secureCheckHash", Base64.getEncoder().encodeToString(launcherSecureHash));
launcherConfigurator.setStringField("secureCheckSalt", launcherSalt);
//LogHelper.debug("[checkSecure] %s: %s", launcherSalt, Arrays.toString(launcherSecureHash));
if (server.runtime.oemUnlockKey == null) server.runtime.oemUnlockKey = SecurityHelper.randomStringToken();
launcherConfigurator.setStringField("oemUnlockKey", server.runtime.oemUnlockKey);
context.clientModules.forEach(launcherConfigurator::addModuleClass);
reader.getCp().add(new JarFile(inputJar.toFile())); reader.getCp().add(new JarFile(inputJar.toFile()));
server.launcherBinary.coreLibs.forEach(e -> { server.launcherBinary.coreLibs.forEach(e -> {
try { try {
@ -188,9 +146,6 @@ public Path process(Path inputJar) throws IOException {
LogHelper.error(e1); LogHelper.error(e1);
} }
}); });
context.pushBytes(launcherConfigurator.getZipEntryPath(), launcherConfigurator.getBytecode(reader));
context.pushBytes(secureConfigurator.getZipEntryPath(), secureConfigurator.getBytecode(reader));
context.pushJarFile(inputJar, (e) -> blacklist.contains(e.getName()), (e) -> true); context.pushJarFile(inputJar, (e) -> blacklist.contains(e.getName()), (e) -> true);
// map for guard // map for guard
@ -207,7 +162,49 @@ public Path process(Path inputJar) throws IOException {
return outputJar; return outputJar;
} }
public byte[] transformClass(byte[] bytes, String classname, BuildContext context) protected void postInitProps() {
List<byte[]> certificates = Arrays.stream(server.certificateManager.trustManager.getTrusted()).map(e -> {
try {
return e.getEncoded();
} catch (CertificateEncodingException e2) {
LogHelper.error(e2);
return new byte[0];
}
}).collect(Collectors.toList());
if(!server.config.sign.enabled)
{
CertificateAutogenTask task = server.launcherBinary.getTaskByClass(CertificateAutogenTask.class).get();
try {
certificates.add(task.certificate.getEncoded());
} catch (CertificateEncodingException e) {
throw new InternalError(e);
}
}
properties.put("launchercore.certificates", certificates);
}
protected void initProps() {
properties.clear();
properties.put("launcher.address", server.config.netty.address);
properties.put("launcher.projectName", server.config.projectName);
properties.put("runtimeconfig.secretKeyClient", SecurityHelper.randomStringAESKey());
properties.put("launcher.port", 32148 + SecurityHelper.newRandom().nextInt(512));
properties.put("launcher.guardType", server.config.launcher.guardType);
properties.put("launcher.isWarningMissArchJava", server.config.launcher.warningMissArchJava);
properties.put("launchercore.env" ,server.config.env);
properties.put("runtimeconfig.passwordEncryptKey", server.runtime.passwordEncryptKey);
String launcherSalt = SecurityHelper.randomStringToken();
byte[] launcherSecureHash = SecurityHelper.digest(SecurityHelper.DigestAlgorithm.SHA256,
server.runtime.clientCheckSecret.concat(".").concat(launcherSalt));
properties.put("runtimeconfig.secureCheckHash", Base64.getEncoder().encodeToString(launcherSecureHash));
properties.put("runtimeconfig.secureCheckSalt", launcherSalt);
//LogHelper.debug("[checkSecure] %s: %s", launcherSalt, Arrays.toString(launcherSecureHash));
if (server.runtime.oemUnlockKey == null) server.runtime.oemUnlockKey = SecurityHelper.randomStringToken();
properties.put("runtimeconfig.oemUnlockKey", server.runtime.oemUnlockKey);
}
public byte[] transformClass(byte[] bytes, String classname, BuildContext context)
{ {
byte[] result = bytes; byte[] result = bytes;
ClassReader cr = null; ClassReader cr = null;

View file

@ -27,13 +27,9 @@ public void clear() {
} }
} }
// URL constants
public static final String DOWNLOAD_URL = "http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html"; // Oracle public static final String DOWNLOAD_URL = "http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html"; // Oracle
// JRE 8
// File constants
private final Path faviconFile; private final Path faviconFile;
// File constants
private final LaunchServer server; private final LaunchServer server;
public Launch4JTask(LaunchServer launchServer) { public Launch4JTask(LaunchServer launchServer) {

View file

@ -0,0 +1,38 @@
{
"version": "1.15.2",
"assetIndex": "1.15.2",
"assetDir": "asset1.15.2",
"dir": "HiTech",
"info": "Информация о сервере",
"sortIndex": 0,
"title": "xxxxxxxx",
"serverAddress": "localhost",
"serverPort": 25565,
"update": [
"servers.dat"
],
"updateExclusions": [],
"updateShared": [],
"updateVerify": [
"libraries",
"natives",
"minecraft.jar"
],
"updateOptional": [],
"updateFastCheck": true,
"useWhitelist": false,
"mainClass": "net.minecraft.client.main.Main",
"jvmArgs": [
"-XX:+UseConcMarkSweepGC",
"-XX:+CMSIncrementalMode",
"-XX:-UseAdaptiveSizePolicy",
"-Xmn128M",
"-XX:+DisableAttachMechanism"
],
"classPath": [
"minecraft.jar",
"libraries"
],
"clientArgs": [],
"whitelist": []
}

View file

@ -31,7 +31,7 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep
EnvHelper.checkDangerousParams(); EnvHelper.checkDangerousParams();
LauncherConfig config = Launcher.getConfig(); LauncherConfig config = Launcher.getConfig();
LauncherEngine.modulesManager = new ClientModuleManager(); LauncherEngine.modulesManager = new ClientModuleManager();
LauncherConfig.getAutogenConfig().initModules(); LauncherConfig.initModules(LauncherEngine.modulesManager);
LogHelper.info("Launcher for project %s", config.projectName); LogHelper.info("Launcher for project %s", config.projectName);
if (config.environment.equals(LauncherConfig.LauncherEnvironment.PROD)) { if (config.environment.equals(LauncherConfig.LauncherEnvironment.PROD)) {

View file

@ -80,7 +80,7 @@ public static void main(String... args) throws Throwable {
LauncherEngine.checkClass(LauncherAgent.class); LauncherEngine.checkClass(LauncherAgent.class);
LauncherEngine.checkClass(ClientLauncher.class); LauncherEngine.checkClass(ClientLauncher.class);
LauncherEngine.modulesManager = new ClientModuleManager(); LauncherEngine.modulesManager = new ClientModuleManager();
LauncherConfig.getAutogenConfig().initModules(); LauncherConfig.initModules(LauncherEngine.modulesManager);
LauncherEngine.modulesManager.initModules(null); LauncherEngine.modulesManager.initModules(null);
// Start Launcher // Start Launcher
initGson(LauncherEngine.modulesManager); initGson(LauncherEngine.modulesManager);

View file

@ -443,7 +443,7 @@ public static void main(String... args) throws Throwable {
LauncherEngine.checkClass(LauncherAgent.class); LauncherEngine.checkClass(LauncherAgent.class);
LauncherEngine.checkClass(ClientLauncher.class); LauncherEngine.checkClass(ClientLauncher.class);
LauncherEngine.modulesManager = new ClientModuleManager(); LauncherEngine.modulesManager = new ClientModuleManager();
LauncherConfig.getAutogenConfig().initModules(); //INIT LauncherConfig.initModules(LauncherEngine.modulesManager); //INIT
LauncherEngine.modulesManager.initModules(null); LauncherEngine.modulesManager.initModules(null);
initGson(LauncherEngine.modulesManager); initGson(LauncherEngine.modulesManager);
LauncherEngine.verifyNoAgent(); LauncherEngine.verifyNoAgent();

View file

@ -1,26 +0,0 @@
package pro.gravit.launcher;
public class AutogenConfig {
public String projectname;
public String address;
public int clientPort;
public String guardType;
public String secretKeyClient;
public String oemUnlockKey;
public String secureCheckHash;
public String secureCheckSalt;
public String passwordEncryptKey;
public int env;
public boolean isWarningMissArchJava;
// 0 - Dev (дебаг включен по умолчанию, все сообщения)
// 1 - Debug (дебаг включен по умолчанию, основные сообщения)
// 2 - Std (дебаг выключен по умолчанию, основные сообщения)
// 3 - Production (дебаг выключен, минимальный объем сообщений, stacktrace не выводится)
AutogenConfig() {
}
public void initModules() {
}
}

View file

@ -1,32 +1,38 @@
package pro.gravit.launcher; package pro.gravit.launcher;
import pro.gravit.launcher.modules.LauncherModule;
import pro.gravit.launcher.modules.LauncherModulesManager;
import pro.gravit.launcher.serialize.HInput; import pro.gravit.launcher.serialize.HInput;
import pro.gravit.launcher.serialize.HOutput; import pro.gravit.launcher.serialize.HOutput;
import pro.gravit.launcher.serialize.stream.StreamObject; import pro.gravit.launcher.serialize.stream.StreamObject;
import pro.gravit.utils.helper.LogHelper;
import pro.gravit.utils.helper.SecurityHelper; import pro.gravit.utils.helper.SecurityHelper;
import pro.gravit.utils.helper.VerifyHelper; import pro.gravit.utils.helper.VerifyHelper;
import java.io.IOException; import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.interfaces.ECPublicKey; import java.security.interfaces.ECPublicKey;
import java.security.spec.InvalidKeySpecException; import java.security.spec.InvalidKeySpecException;
import java.util.*; import java.util.*;
public final class LauncherConfig extends StreamObject { public final class LauncherConfig extends StreamObject {
private static final AutogenConfig config = new AutogenConfig(); @LauncherInject("launchercore.env")
private static final SecureAutogenConfig secureConfig = new SecureAutogenConfig(); private static final int cenv = -1;
@LauncherInject("launchercore.certificates")
private static final List<byte[]> secureConfigCertificates = null;
public static AutogenConfig getAutogenConfig() { @LauncherInject("launcher.modules")
return config; private static final List<Class<?>> modulesClasses = null;
} @LauncherInject("launcher.address")
public String address;
// Instance @LauncherInject("launcher.projectName")
public String address;
public final String projectName; public final String projectName;
@LauncherInject("launcher.port")
public final int clientPort; public final int clientPort;
@LauncherInject("runtimeconfig.secretKeyClient")
public String secretKeyClient; public String secretKeyClient;
@LauncherInject("runtimeconfig.oemUnlockKey")
public String oemUnlockKey; public String oemUnlockKey;
public final LauncherTrustManager trustManager; public final LauncherTrustManager trustManager;
@ -34,40 +40,43 @@ public static AutogenConfig getAutogenConfig() {
public final Map<String, byte[]> runtime; public final Map<String, byte[]> runtime;
@LauncherInject("launcher.isWarningMissArchJava")
public final boolean isWarningMissArchJava; public final boolean isWarningMissArchJava;
public boolean isNettyEnabled;
public LauncherEnvironment environment; public LauncherEnvironment environment;
@LauncherInject("launcher.guardType")
public final String guardType; public final String guardType;
@LauncherInject("runtimeconfig.secureCheckHash")
public final String secureCheckHash; public final String secureCheckHash;
@LauncherInject("runtimeconfig.secureCheckSalt")
public final String secureCheckSalt; public final String secureCheckSalt;
@LauncherInject("runtimeconfig.passwordEncryptKey")
public final String passwordEncryptKey; public final String passwordEncryptKey;
@SuppressWarnings("unused")
@LauncherInjectionConstructor
public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException { public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException {
publicKey = SecurityHelper.toPublicECKey(input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH)); publicKey = SecurityHelper.toPublicECKey(input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH));
secureCheckHash = config.secureCheckHash; secureCheckHash = null;
secureCheckSalt = config.secureCheckSalt; secureCheckSalt = null;
passwordEncryptKey = config.passwordEncryptKey; passwordEncryptKey = null;
projectName = config.projectname; projectName = null;
clientPort = config.clientPort; clientPort = -1;
secretKeyClient = config.secretKeyClient; secretKeyClient = null;
oemUnlockKey = config.oemUnlockKey; oemUnlockKey = null;
try { try {
trustManager = new LauncherTrustManager(secureConfig.certificates); trustManager = new LauncherTrustManager(secureConfigCertificates);
} catch (CertificateException e) { } catch (CertificateException e) {
throw new IOException(e); throw new IOException(e);
} }
isWarningMissArchJava = config.isWarningMissArchJava; isWarningMissArchJava = false;
guardType = config.guardType; guardType = null;
address = config.address; address = null;
LauncherEnvironment env; LauncherEnvironment env;
if (config.env == 0) env = LauncherEnvironment.DEV; if (cenv == 0) env = LauncherEnvironment.DEV;
else if (config.env == 1) env = LauncherEnvironment.DEBUG; else if (cenv == 1) env = LauncherEnvironment.DEBUG;
else if (config.env == 2) env = LauncherEnvironment.STD; else if (cenv == 2) env = LauncherEnvironment.STD;
else if (config.env == 3) env = LauncherEnvironment.PROD; else if (cenv == 3) env = LauncherEnvironment.PROD;
else env = LauncherEnvironment.STD; else env = LauncherEnvironment.STD;
Launcher.applyLauncherEnv(env); Launcher.applyLauncherEnv(env);
environment = env; environment = env;
@ -92,7 +101,6 @@ public LauncherConfig(String address, ECPublicKey publicKey, Map<String, byte[]>
this.clientPort = 32148; this.clientPort = 32148;
guardType = "no"; guardType = "no";
isWarningMissArchJava = true; isWarningMissArchJava = true;
isNettyEnabled = false;
environment = LauncherEnvironment.STD; environment = LauncherEnvironment.STD;
secureCheckSalt = null; secureCheckSalt = null;
secureCheckHash = null; secureCheckHash = null;
@ -116,4 +124,17 @@ public void write(HOutput output) throws IOException {
public enum LauncherEnvironment { public enum LauncherEnvironment {
DEV, DEBUG, STD, PROD DEV, DEBUG, STD, PROD
} }
private static final MethodType VOID_TYPE = MethodType.methodType(void.class);
public static void initModules(LauncherModulesManager modulesManager) {
for (Class<?> clazz : modulesClasses)
try {
modulesManager.loadModule((LauncherModule) MethodHandles.publicLookup().findConstructor(clazz, VOID_TYPE).invokeWithArguments(Collections.emptyList()));
} catch (Throwable e) {
LogHelper.error(e);
}
// This method should be called once at exec time.
modulesClasses.clear();
}
} }

View file

@ -1,48 +0,0 @@
package pro.gravit.launcher;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;
public class SecureAutogenConfig {
public static final Charset KEY_CHARSET = StandardCharsets.US_ASCII; // ? Какая из них, но выбрать надо однозачно проверить методом тыка!!!
public final List<byte[]> certificates;
public SecureAutogenConfig() {
//Пока не реализован SecureLauncherConfigurator
certificates = null;/*Arrays.asList(
("-----BEGIN CERTIFICATE-----\n" +
"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\n" +
"-----END CERTIFICATE-----").getBytes(KEY_CHARSET));*/
}
}

View file

@ -41,7 +41,8 @@ public enum Version {
MC1143("1.14.3", 490), MC1143("1.14.3", 490),
MC1144("1.14.4", 498), MC1144("1.14.4", 498),
MC115("1.15", 573), MC115("1.15", 573),
MC1151("1.15.1", 575); MC1151("1.15.1", 575),
MC1152("1.15.2", 578);
private static final Map<String, Version> VERSIONS; private static final Map<String, Version> VERSIONS;
static { static {

View file

@ -196,7 +196,6 @@ public void updateLauncherConfig() {
if(IOHelper.isFile(publicKeyFile)) if(IOHelper.isFile(publicKeyFile))
publicKey = SecurityHelper.toPublicECKey(IOHelper.read(publicKeyFile)); publicKey = SecurityHelper.toPublicECKey(IOHelper.read(publicKeyFile));
cfg = new LauncherConfig(config.address, publicKey, new HashMap<>(), config.projectname); cfg = new LauncherConfig(config.address, publicKey, new HashMap<>(), config.projectname);
cfg.isNettyEnabled = true;
cfg.address = config.address; cfg.address = config.address;
} catch (InvalidKeySpecException | IOException e) { } catch (InvalidKeySpecException | IOException e) {
LogHelper.error(e); LogHelper.error(e);

@ -1 +1 @@
Subproject commit 5464417b18e27d7ae8ce91861e42f167e11b8215 Subproject commit 0fbc3fb26c505800a61976cdf1310cad6ab7808d