[FEATURE] Переделываю генератор конфига, часть 1

This commit is contained in:
Zaxar163 2019-10-18 16:16:06 +02:00
parent 7ef7099430
commit 96d8883ecb
No known key found for this signature in database
GPG key ID: 1FE4F2E1F053831B
3 changed files with 86 additions and 68 deletions

View file

@ -0,0 +1,66 @@
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.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.VarInsnNode;
public class ConfigGenerator {
protected static final String stringDesc = Type.getDescriptor(String.class);
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 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

@ -2,7 +2,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -163,7 +162,7 @@ public static int opcodeEmulation(AbstractInsnNode e) {
public static InsnList getSafeStringInsnList(String string) {
InsnList insnList = new InsnList();
if (string.length() * 2 < MAX_SAFE_BYTE_COUNT) {
if ((string.length() * 3) < MAX_SAFE_BYTE_COUNT) { // faster check
insnList.add(new LdcInsnNode(string));
return insnList;
}
@ -219,4 +218,17 @@ public static int getUtf8CharSize(char c) {
}
return 3;
}
public static InsnList push(final int value) {
InsnList ret = new InsnList();
if (value >= -1 && value <= 5)
ret.add(new InsnNode(Opcodes.ICONST_0 + value));
else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE)
ret.add(new IntInsnNode(Opcodes.BIPUSH, value));
else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE)
ret.add(new IntInsnNode(Opcodes.SIPUSH, value));
else
ret.add(new LdcInsnNode(value));
return ret;
}
}

View file

@ -1,42 +1,28 @@
package pro.gravit.launchserver.binary;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.IntInsnNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.VarInsnNode;
import pro.gravit.launcher.AutogenConfig;
import pro.gravit.launcher.LauncherConfig;
import pro.gravit.launcher.modules.LauncherModule;
import pro.gravit.launchserver.asm.ClassMetadataReader;
import pro.gravit.launchserver.asm.SafeClassWriter;
import pro.gravit.launchserver.asm.ConfigGenerator;
public class LauncherConfigurator {
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 static final String autoGenConfigName = Type.getInternalName(AutogenConfig.class);
private static final String stringDesc = Type.getDescriptor(String.class);
private final ClassNode configclass;
private final MethodNode constructor;
private final MethodNode initModuleMethod;
public LauncherConfigurator(ClassNode configclass) {
this.configclass = configclass;
constructor = 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"));
super(configclass);
initModuleMethod = configclass.methods.stream().filter(e -> "initModules".equals(e.name)).findFirst().get();
initModuleMethod.instructions = new InsnList();
}
@ -49,18 +35,6 @@ public void addModuleClass(String fullName) {
initModuleMethod.instructions.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, modulesManagerName, "loadModule", registerModDesc));
}
public byte[] getBytecode(ClassMetadataReader reader) {
constructor.instructions.add(new InsnNode(Opcodes.RETURN));
initModuleMethod.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 setAddress(String address) {
setStringField("address", address);
}
@ -81,36 +55,17 @@ public void setOemUnlockKey(String key) {
setStringField("oemUnlockKey", key);
}
private void setStringField(String name, String value)
{
constructor.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
constructor.instructions.add(new LdcInsnNode(value));
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, name, stringDesc));
}
public void setGuardType(String key) {
setStringField("guardType", key);
}
public void setSecureCheck(String hash, String salt) {
setStringField("secureCheckHash", hash);
setStringField("secureCheckSalt", salt);
}
private void push(final int value) {
if (value >= -1 && value <= 5)
constructor.instructions.add(new InsnNode(Opcodes.ICONST_0 + value));
else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE)
constructor.instructions.add(new IntInsnNode(Opcodes.BIPUSH, value));
else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE)
constructor.instructions.add(new IntInsnNode(Opcodes.SIPUSH, value));
else
constructor.instructions.add(new LdcInsnNode(value));
}
public void setEnv(LauncherConfig.LauncherEnvironment env) {
constructor.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
int i = 2;
switch (env) {
case DEV:
i = 0;
@ -125,29 +80,14 @@ public void setEnv(LauncherConfig.LauncherEnvironment env) {
i = 3;
break;
}
push(i);
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, "env", Type.INT_TYPE.getInternalName()));
setIntegerField("env", i);
}
public void setClientPort(int port) {
setIntegerField("clientPort", port);
}
public void setIntegerField(String name, int value)
{
constructor.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
push(value);
constructor.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, autoGenConfigName, name, Type.INT_TYPE.getInternalName()));
}
public void setWarningMissArchJava(boolean b) {
setBooleanField("isWarningMissArchJava", b);
}
private 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, autoGenConfigName, name, Type.BOOLEAN_TYPE.getInternalName()));
}
}