mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-11-15 03:31:15 +03:00
Merge pull request #355 from GravitLauncher/feature/newProp
[FEATURE] Переход на новое API хранения данных на уровне байткода.
This commit is contained in:
commit
63ea1f59b0
16 changed files with 150 additions and 309 deletions
|
@ -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()));
|
||||
}
|
||||
}
|
|
@ -123,6 +123,11 @@ public void visit(final String name, final Object value) {
|
|||
serializers.put(byte[].class, new ByteArraySerializer());
|
||||
serializers.put(Short.class, serializerClass(Opcodes.I2S));
|
||||
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 -> {
|
||||
InsnList ret = new InsnList();
|
||||
ret.add(new InsnNode(e ? Opcodes.ICONST_1 : Opcodes.ICONST_0));
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
|
||||
public class BuildContext {
|
||||
public final ZipOutputStream output;
|
||||
public final LauncherConfigurator config;
|
||||
public final List<JarFile> readerClassPath;
|
||||
public final MainBuildTask task;
|
||||
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.config = config;
|
||||
this.readerClassPath = readerClassPath;
|
||||
this.task = task;
|
||||
fileList = new HashSet<>(1024);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -2,23 +2,19 @@
|
|||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.tree.AnnotationNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.FieldNode;
|
||||
import pro.gravit.launcher.AutogenConfig;
|
||||
import pro.gravit.launcher.Launcher;
|
||||
import pro.gravit.launcher.LauncherConfig;
|
||||
import pro.gravit.launcher.SecureAutogenConfig;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.asm.ClassMetadataReader;
|
||||
import pro.gravit.launchserver.asm.ConfigGenerator;
|
||||
import pro.gravit.launchserver.asm.InjectClassAcceptor;
|
||||
import pro.gravit.launchserver.asm.SafeClassWriter;
|
||||
import pro.gravit.launchserver.binary.BuildContext;
|
||||
import pro.gravit.launchserver.binary.LauncherConfigurator;
|
||||
import pro.gravit.utils.HookException;
|
||||
import pro.gravit.utils.helper.IOHelper;
|
||||
import pro.gravit.utils.helper.JarHelper;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
import pro.gravit.utils.helper.SecurityHelper;
|
||||
|
||||
|
@ -137,49 +133,11 @@ public String getName() {
|
|||
public Path process(Path inputJar) throws IOException {
|
||||
Path outputJar = server.launcherBinary.nextPath("main");
|
||||
try (ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(outputJar))) {
|
||||
ClassNode cn = new ClassNode();
|
||||
new ClassReader(JarHelper.getClassBytes(AutogenConfig.class)).accept(cn, 0);
|
||||
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);
|
||||
BuildContext context = new BuildContext(output, reader.getCp(), this);
|
||||
initProps();
|
||||
preBuildHook.hook(context);
|
||||
launcherConfigurator.setStringField("address", server.config.netty.address);
|
||||
launcherConfigurator.setStringField("projectname", server.config.projectName);
|
||||
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);
|
||||
properties.put("launcher.modules", context.clientModules.stream().map(e -> Type.getObjectType(e.replace('.', '/'))).collect(Collectors.toList()));
|
||||
postInitProps();
|
||||
reader.getCp().add(new JarFile(inputJar.toFile()));
|
||||
server.launcherBinary.coreLibs.forEach(e -> {
|
||||
try {
|
||||
|
@ -188,9 +146,6 @@ public Path process(Path inputJar) throws IOException {
|
|||
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);
|
||||
|
||||
// map for guard
|
||||
|
@ -207,7 +162,49 @@ public Path process(Path inputJar) throws IOException {
|
|||
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;
|
||||
ClassReader cr = null;
|
||||
|
|
|
@ -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
|
||||
// JRE 8
|
||||
// File constants
|
||||
private final Path faviconFile;
|
||||
|
||||
// File constants
|
||||
private final LaunchServer server;
|
||||
|
||||
public Launch4JTask(LaunchServer launchServer) {
|
||||
|
|
|
@ -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": []
|
||||
}
|
|
@ -31,7 +31,7 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep
|
|||
EnvHelper.checkDangerousParams();
|
||||
LauncherConfig config = Launcher.getConfig();
|
||||
LauncherEngine.modulesManager = new ClientModuleManager();
|
||||
LauncherConfig.getAutogenConfig().initModules();
|
||||
LauncherConfig.initModules(LauncherEngine.modulesManager);
|
||||
|
||||
LogHelper.info("Launcher for project %s", config.projectName);
|
||||
if (config.environment.equals(LauncherConfig.LauncherEnvironment.PROD)) {
|
||||
|
|
|
@ -80,7 +80,7 @@ public static void main(String... args) throws Throwable {
|
|||
LauncherEngine.checkClass(LauncherAgent.class);
|
||||
LauncherEngine.checkClass(ClientLauncher.class);
|
||||
LauncherEngine.modulesManager = new ClientModuleManager();
|
||||
LauncherConfig.getAutogenConfig().initModules();
|
||||
LauncherConfig.initModules(LauncherEngine.modulesManager);
|
||||
LauncherEngine.modulesManager.initModules(null);
|
||||
// Start Launcher
|
||||
initGson(LauncherEngine.modulesManager);
|
||||
|
|
|
@ -443,7 +443,7 @@ public static void main(String... args) throws Throwable {
|
|||
LauncherEngine.checkClass(LauncherAgent.class);
|
||||
LauncherEngine.checkClass(ClientLauncher.class);
|
||||
LauncherEngine.modulesManager = new ClientModuleManager();
|
||||
LauncherConfig.getAutogenConfig().initModules(); //INIT
|
||||
LauncherConfig.initModules(LauncherEngine.modulesManager); //INIT
|
||||
LauncherEngine.modulesManager.initModules(null);
|
||||
initGson(LauncherEngine.modulesManager);
|
||||
LauncherEngine.verifyNoAgent();
|
||||
|
|
|
@ -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() {
|
||||
|
||||
}
|
||||
}
|
|
@ -1,32 +1,38 @@
|
|||
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.HOutput;
|
||||
import pro.gravit.launcher.serialize.stream.StreamObject;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
import pro.gravit.utils.helper.SecurityHelper;
|
||||
import pro.gravit.utils.helper.VerifyHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.interfaces.ECPublicKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.util.*;
|
||||
|
||||
public final class LauncherConfig extends StreamObject {
|
||||
private static final AutogenConfig config = new AutogenConfig();
|
||||
private static final SecureAutogenConfig secureConfig = new SecureAutogenConfig();
|
||||
|
||||
|
||||
public static AutogenConfig getAutogenConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
// Instance
|
||||
public String address;
|
||||
|
||||
@LauncherInject("launchercore.env")
|
||||
private static final int cenv = -1;
|
||||
@LauncherInject("launchercore.certificates")
|
||||
private static final List<byte[]> secureConfigCertificates = null;
|
||||
@LauncherInject("launcher.modules")
|
||||
private static final List<Class<?>> modulesClasses = null;
|
||||
@LauncherInject("launcher.address")
|
||||
public String address;
|
||||
@LauncherInject("launcher.projectName")
|
||||
public final String projectName;
|
||||
@LauncherInject("launcher.port")
|
||||
public final int clientPort;
|
||||
@LauncherInject("runtimeconfig.secretKeyClient")
|
||||
public String secretKeyClient;
|
||||
@LauncherInject("runtimeconfig.oemUnlockKey")
|
||||
public String oemUnlockKey;
|
||||
public final LauncherTrustManager trustManager;
|
||||
|
||||
|
@ -34,40 +40,43 @@ public static AutogenConfig getAutogenConfig() {
|
|||
|
||||
|
||||
public final Map<String, byte[]> runtime;
|
||||
@LauncherInject("launcher.isWarningMissArchJava")
|
||||
public final boolean isWarningMissArchJava;
|
||||
public boolean isNettyEnabled;
|
||||
public LauncherEnvironment environment;
|
||||
|
||||
@LauncherInject("launcher.guardType")
|
||||
public final String guardType;
|
||||
|
||||
@LauncherInject("runtimeconfig.secureCheckHash")
|
||||
public final String secureCheckHash;
|
||||
@LauncherInject("runtimeconfig.secureCheckSalt")
|
||||
public final String secureCheckSalt;
|
||||
@LauncherInject("runtimeconfig.passwordEncryptKey")
|
||||
public final String passwordEncryptKey;
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@LauncherInjectionConstructor
|
||||
public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException {
|
||||
publicKey = SecurityHelper.toPublicECKey(input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH));
|
||||
secureCheckHash = config.secureCheckHash;
|
||||
secureCheckSalt = config.secureCheckSalt;
|
||||
passwordEncryptKey = config.passwordEncryptKey;
|
||||
projectName = config.projectname;
|
||||
clientPort = config.clientPort;
|
||||
secretKeyClient = config.secretKeyClient;
|
||||
oemUnlockKey = config.oemUnlockKey;
|
||||
secureCheckHash = null;
|
||||
secureCheckSalt = null;
|
||||
passwordEncryptKey = null;
|
||||
projectName = null;
|
||||
clientPort = -1;
|
||||
secretKeyClient = null;
|
||||
oemUnlockKey = null;
|
||||
try {
|
||||
trustManager = new LauncherTrustManager(secureConfig.certificates);
|
||||
trustManager = new LauncherTrustManager(secureConfigCertificates);
|
||||
} catch (CertificateException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
|
||||
isWarningMissArchJava = config.isWarningMissArchJava;
|
||||
guardType = config.guardType;
|
||||
address = config.address;
|
||||
isWarningMissArchJava = false;
|
||||
guardType = null;
|
||||
address = null;
|
||||
LauncherEnvironment env;
|
||||
if (config.env == 0) env = LauncherEnvironment.DEV;
|
||||
else if (config.env == 1) env = LauncherEnvironment.DEBUG;
|
||||
else if (config.env == 2) env = LauncherEnvironment.STD;
|
||||
else if (config.env == 3) env = LauncherEnvironment.PROD;
|
||||
if (cenv == 0) env = LauncherEnvironment.DEV;
|
||||
else if (cenv == 1) env = LauncherEnvironment.DEBUG;
|
||||
else if (cenv == 2) env = LauncherEnvironment.STD;
|
||||
else if (cenv == 3) env = LauncherEnvironment.PROD;
|
||||
else env = LauncherEnvironment.STD;
|
||||
Launcher.applyLauncherEnv(env);
|
||||
environment = env;
|
||||
|
@ -92,7 +101,6 @@ public LauncherConfig(String address, ECPublicKey publicKey, Map<String, byte[]>
|
|||
this.clientPort = 32148;
|
||||
guardType = "no";
|
||||
isWarningMissArchJava = true;
|
||||
isNettyEnabled = false;
|
||||
environment = LauncherEnvironment.STD;
|
||||
secureCheckSalt = null;
|
||||
secureCheckHash = null;
|
||||
|
@ -116,4 +124,17 @@ public void write(HOutput output) throws IOException {
|
|||
public enum LauncherEnvironment {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));*/
|
||||
}
|
||||
}
|
|
@ -41,7 +41,8 @@ public enum Version {
|
|||
MC1143("1.14.3", 490),
|
||||
MC1144("1.14.4", 498),
|
||||
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;
|
||||
|
||||
static {
|
||||
|
|
|
@ -196,7 +196,6 @@ public void updateLauncherConfig() {
|
|||
if(IOHelper.isFile(publicKeyFile))
|
||||
publicKey = SecurityHelper.toPublicECKey(IOHelper.read(publicKeyFile));
|
||||
cfg = new LauncherConfig(config.address, publicKey, new HashMap<>(), config.projectname);
|
||||
cfg.isNettyEnabled = true;
|
||||
cfg.address = config.address;
|
||||
} catch (InvalidKeySpecException | IOException e) {
|
||||
LogHelper.error(e);
|
||||
|
|
2
modules
2
modules
|
@ -1 +1 @@
|
|||
Subproject commit 5464417b18e27d7ae8ce91861e42f167e11b8215
|
||||
Subproject commit 0fbc3fb26c505800a61976cdf1310cad6ab7808d
|
Loading…
Reference in a new issue