[REFACTOR] Mini refactoring

This commit is contained in:
Gravita 2021-04-06 17:39:14 +07:00
parent 1cb2369bfa
commit f1331b6d5d
6 changed files with 241 additions and 98 deletions

View file

@ -40,31 +40,67 @@
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Stream; import java.util.stream.Stream;
/**
* The main LaunchServer class. Contains links to all necessary objects
* Not a singletron
*/
public final class LaunchServer implements Runnable, AutoCloseable, Reconfigurable { public final class LaunchServer implements Runnable, AutoCloseable, Reconfigurable {
public static final Class<? extends LauncherBinary> defaultLauncherEXEBinaryClass = null; public static final Class<? extends LauncherBinary> defaultLauncherEXEBinaryClass = null;
/**
* Working folder path
*/
public final Path dir; public final Path dir;
/**
* Environment type (test / production)
*/
public final LaunchServerEnv env; public final LaunchServerEnv env;
/**
* The path to the folder with libraries for the launcher
*/
public final Path launcherLibraries; public final Path launcherLibraries;
/**
* The path to the folder with compile-only libraries for the launcher
*/
public final Path launcherLibrariesCompile; public final Path launcherLibrariesCompile;
public final Path caCertFile;
// Constant paths // Constant paths
public final Path caKeyFile; /**
public final Path serverCertFile; * The path to the folder with updates/webroot
public final Path serverKeyFile; */
public final Path updatesDir; public final Path updatesDir;
/**
* Save/Reload LaunchServer config
*/
public final LaunchServerConfigManager launchServerConfigManager; public final LaunchServerConfigManager launchServerConfigManager;
/**
* The path to the folder with profiles
*/
public final Path profilesDir; public final Path profilesDir;
/**
* This object contains runtime configuration
*/
public final LaunchServerRuntimeConfig runtime; public final LaunchServerRuntimeConfig runtime;
/**
* Public ECDSA LaunchServer key
*/
public final ECPublicKey publicKey; public final ECPublicKey publicKey;
/**
* Private ECDSA LaunchServer key
*/
public final ECPrivateKey privateKey; public final ECPrivateKey privateKey;
/**
* Pipeline for building JAR
*/
public final JARLauncherBinary launcherBinary; public final JARLauncherBinary launcherBinary;
/**
* Pipeline for building EXE
*/
public final LauncherBinary launcherEXEBinary;
//public static LaunchServer server = null; //public static LaunchServer server = null;
public final Class<? extends LauncherBinary> launcherEXEBinaryClass; public final Class<? extends LauncherBinary> launcherEXEBinaryClass;
// Server config // Server config
public final LauncherBinary launcherEXEBinary;
public final SessionManager sessionManager; public final SessionManager sessionManager;
public final AuthHookManager authHookManager; public final AuthHookManager authHookManager;
public final LaunchServerModulesManager modulesManager; public final LaunchServerModulesManager modulesManager;
@ -106,12 +142,6 @@ public LaunchServer(LaunchServerDirectories directories, LaunchServerEnv env, La
config.setLaunchServer(this); config.setLaunchServer(this);
caCertFile = dir.resolve("ca.crt");
caKeyFile = dir.resolve("ca.key");
serverCertFile = dir.resolve("server.crt");
serverKeyFile = dir.resolve("server.key");
modulesManager.invokeEvent(new NewLaunchServerInstanceEvent(this)); modulesManager.invokeEvent(new NewLaunchServerInstanceEvent(this));
// Print keypair fingerprints // Print keypair fingerprints

View file

@ -72,6 +72,12 @@ private static void visit(ClassNode classNode, Map<String, Object> values) {
classNode.fields.forEach(field -> { classNode.fields.forEach(field -> {
// Notice that fields that will be used with this algo should not have default // Notice that fields that will be used with this algo should not have default
// value by = ...; // value by = ...;
boolean isStatic = (field.access & Opcodes.ACC_STATIC) != 0;
injectTo(isStatic ? clinitMethod : initMethod, classNode, field, isStatic, values);
});
}
public static void injectTo(MethodNode initMethod, ClassNode classNode, FieldNode field, boolean isStatic, Map<String, Object> values) {
AnnotationNode valueAnnotation = field.invisibleAnnotations != null ? field.invisibleAnnotations.stream() AnnotationNode valueAnnotation = field.invisibleAnnotations != null ? field.invisibleAnnotations.stream()
.filter(annotation -> INJECTED_FIELD_DESC.equals(annotation.desc)).findFirst() .filter(annotation -> INJECTED_FIELD_DESC.equals(annotation.desc)).findFirst()
.orElse(null) : null; .orElse(null) : null;
@ -98,23 +104,24 @@ public void visit(final String name, final Object value) {
return; return;
} }
Object value = values.get(valueName.get()); Object value = values.get(valueName.get());
if ((field.access & Opcodes.ACC_STATIC) != 0) { //if ((field.access & Opcodes.ACC_STATIC) != 0) {
if (isStatic) {
if (primitiveLDCDescriptors.contains(field.desc) && primitiveLDCClasses.contains(value.getClass())) { if (primitiveLDCDescriptors.contains(field.desc) && primitiveLDCClasses.contains(value.getClass())) {
field.value = value; field.value = value;
return; return;
} }
List<FieldInsnNode> putStaticNodes = Arrays.stream(clinitMethod.instructions.toArray()) List<FieldInsnNode> putStaticNodes = Arrays.stream(initMethod.instructions.toArray())
.filter(node -> node instanceof FieldInsnNode && node.getOpcode() == Opcodes.PUTSTATIC).map(p -> (FieldInsnNode) p) .filter(node -> node instanceof FieldInsnNode && node.getOpcode() == Opcodes.PUTSTATIC).map(p -> (FieldInsnNode) p)
.filter(node -> node.owner.equals(classNode.name) && node.name.equals(field.name) && node.desc.equals(field.desc)).collect(Collectors.toList()); .filter(node -> node.owner.equals(classNode.name) && node.name.equals(field.name) && node.desc.equals(field.desc)).collect(Collectors.toList());
InsnList setter = serializeValue(value); InsnList setter = serializeValue(value);
if (putStaticNodes.isEmpty()) { if (putStaticNodes.isEmpty()) {
setter.add(new FieldInsnNode(Opcodes.PUTSTATIC, classNode.name, field.name, field.desc)); setter.add(new FieldInsnNode(Opcodes.PUTSTATIC, classNode.name, field.name, field.desc));
Arrays.stream(clinitMethod.instructions.toArray()).filter(node -> node.getOpcode() == Opcodes.RETURN) Arrays.stream(initMethod.instructions.toArray()).filter(node -> node.getOpcode() == Opcodes.RETURN)
.forEach(node -> clinitMethod.instructions.insertBefore(node, setter)); .forEach(node -> initMethod.instructions.insertBefore(node, setter));
} else { } else {
setter.insert(new InsnNode(Type.getType(field.desc).getSize() == 1 ? Opcodes.POP : Opcodes.POP2)); setter.insert(new InsnNode(Type.getType(field.desc).getSize() == 1 ? Opcodes.POP : Opcodes.POP2));
for (FieldInsnNode fieldInsnNode : putStaticNodes) { for (FieldInsnNode fieldInsnNode : putStaticNodes) {
clinitMethod.instructions.insertBefore(fieldInsnNode, setter); initMethod.instructions.insertBefore(fieldInsnNode, setter);
} }
} }
} else { } else {
@ -138,7 +145,6 @@ public void visit(final String name, final Object value) {
} }
} }
} }
});
} }
private static Serializer<?> serializerClass(int opcode) { private static Serializer<?> serializerClass(int opcode) {

View file

@ -16,6 +16,10 @@
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
/**
* Deprecated from 5.2.0
*/
@Deprecated
public abstract class HibernateDaoProvider extends DaoProvider implements Reconfigurable, AutoCloseable { public abstract class HibernateDaoProvider extends DaoProvider implements Reconfigurable, AutoCloseable {
public String driver; public String driver;
public String url; public String url;

View file

@ -0,0 +1,87 @@
package pro.gravit.launchserver;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import pro.gravit.launcher.ClientPermissions;
import pro.gravit.launcher.Launcher;
import pro.gravit.launcher.request.auth.AuthRequest;
import pro.gravit.launcher.request.auth.password.AuthPlainPassword;
import pro.gravit.launchserver.auth.AuthException;
import pro.gravit.launchserver.auth.AuthProviderPair;
import pro.gravit.launchserver.auth.handler.MemoryAuthHandler;
import pro.gravit.launchserver.auth.provider.AuthProvider;
import pro.gravit.launchserver.auth.provider.AuthProviderResult;
import pro.gravit.launchserver.auth.texture.NullTextureProvider;
import pro.gravit.launchserver.config.LaunchServerConfig;
import pro.gravit.launchserver.config.LaunchServerRuntimeConfig;
import pro.gravit.launchserver.impl.TestLaunchServerConfigManager;
import pro.gravit.launchserver.manangers.CertificateManager;
import pro.gravit.launchserver.manangers.LaunchServerGsonManager;
import pro.gravit.launchserver.modules.impl.LaunchServerModulesManager;
import pro.gravit.utils.command.StdCommandHandler;
import pro.gravit.utils.helper.SecurityHelper;
import java.io.IOException;
import java.nio.file.Path;
import java.security.KeyPair;
import java.security.SecureRandom;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
public class ConfigurationTest {
@TempDir
public static Path modulesDir;
@TempDir
public static Path configDir;
@TempDir
public static Path dir;
public static LaunchServer launchServer;
public static TestLaunchServerConfigManager launchServerConfigManager;
@BeforeAll
public static void prepare() throws Throwable {
LaunchServerModulesManager modulesManager = new LaunchServerModulesManager(modulesDir, configDir, null);
LaunchServerConfig config = LaunchServerConfig.getDefault(LaunchServer.LaunchServerEnv.TEST);
Launcher.gsonManager = new LaunchServerGsonManager(modulesManager);
Launcher.gsonManager.initGson();
LaunchServerRuntimeConfig runtimeConfig = new LaunchServerRuntimeConfig();
LaunchServerBuilder builder = new LaunchServerBuilder();
KeyPair pair = SecurityHelper.genECKeyPair(new SecureRandom());
ECPublicKey publicKey = (ECPublicKey) pair.getPublic();
ECPrivateKey privateKey = (ECPrivateKey) pair.getPrivate();
launchServerConfigManager = new TestLaunchServerConfigManager();
builder.setDir(dir)
.setEnv(LaunchServer.LaunchServerEnv.TEST)
.setConfig(config)
.setRuntimeConfig(runtimeConfig)
.setPublicKey(publicKey)
.setPrivateKey(privateKey)
.setCertificateManager(new CertificateManager())
.setLaunchServerConfigManager(launchServerConfigManager)
.setModulesManager(modulesManager)
.setCommandHandler(new StdCommandHandler(false));
launchServer = builder.build();
}
@Test
public static void reloadTest() throws Exception {
AuthProvider provider = new AuthProvider() {
@Override
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws Exception {
if(!(password instanceof AuthPlainPassword)) throw new UnsupportedOperationException();
if(login.equals("test") && ((AuthPlainPassword) password).password.equals("test")) {
return new AuthProviderResult(login, SecurityHelper.randomStringToken(), new ClientPermissions());
}
throw new AuthException("Incorrect password");
}
@Override
public void close() throws IOException {
}
};
AuthProviderPair pair = new AuthProviderPair(provider, new MemoryAuthHandler(), new NullTextureProvider());
launchServerConfigManager.config.auth.put("std", pair);
launchServer.reload(LaunchServer.ReloadType.FULL);
}
}

View file

@ -7,6 +7,7 @@
import pro.gravit.launcher.Launcher; import pro.gravit.launcher.Launcher;
import pro.gravit.launchserver.config.LaunchServerConfig; import pro.gravit.launchserver.config.LaunchServerConfig;
import pro.gravit.launchserver.config.LaunchServerRuntimeConfig; import pro.gravit.launchserver.config.LaunchServerRuntimeConfig;
import pro.gravit.launchserver.impl.TestLaunchServerConfigManager;
import pro.gravit.launchserver.manangers.CertificateManager; import pro.gravit.launchserver.manangers.CertificateManager;
import pro.gravit.launchserver.manangers.LaunchServerGsonManager; import pro.gravit.launchserver.manangers.LaunchServerGsonManager;
import pro.gravit.launchserver.modules.impl.LaunchServerModulesManager; import pro.gravit.launchserver.modules.impl.LaunchServerModulesManager;
@ -46,29 +47,7 @@ public static void prepare() throws Throwable {
.setPublicKey(publicKey) .setPublicKey(publicKey)
.setPrivateKey(privateKey) .setPrivateKey(privateKey)
.setCertificateManager(new CertificateManager()) .setCertificateManager(new CertificateManager())
.setLaunchServerConfigManager(new LaunchServer.LaunchServerConfigManager() { .setLaunchServerConfigManager(new TestLaunchServerConfigManager())
@Override
public LaunchServerConfig readConfig() {
return LaunchServerConfig.getDefault(LaunchServer.LaunchServerEnv.TEST);
}
@Override
public LaunchServerRuntimeConfig readRuntimeConfig() {
LaunchServerRuntimeConfig r = new LaunchServerRuntimeConfig();
r.reset();
return r;
}
@Override
public void writeConfig(LaunchServerConfig config) {
}
@Override
public void writeRuntimeConfig(LaunchServerRuntimeConfig config) {
}
})
.setModulesManager(modulesManager) .setModulesManager(modulesManager)
.setCommandHandler(new StdCommandHandler(false)); .setCommandHandler(new StdCommandHandler(false));
launchServer = builder.build(); launchServer = builder.build();

View file

@ -0,0 +1,37 @@
package pro.gravit.launchserver.impl;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.config.LaunchServerConfig;
import pro.gravit.launchserver.config.LaunchServerRuntimeConfig;
import java.io.IOException;
public class TestLaunchServerConfigManager implements LaunchServer.LaunchServerConfigManager {
public LaunchServerConfig config;
public LaunchServerRuntimeConfig runtimeConfig;
@Override
public LaunchServerConfig readConfig() throws IOException {
return config;
}
@Override
public LaunchServerRuntimeConfig readRuntimeConfig() throws IOException {
return runtimeConfig;
}
@Override
public void writeConfig(LaunchServerConfig config) throws IOException {
}
@Override
public void writeRuntimeConfig(LaunchServerRuntimeConfig config) throws IOException {
}
public TestLaunchServerConfigManager() {
config = LaunchServerConfig.getDefault(LaunchServer.LaunchServerEnv.TEST);
runtimeConfig = new LaunchServerRuntimeConfig();
runtimeConfig.reset();
}
}