Merge branch 'master' into fixesWriter1

This commit is contained in:
zaxar163 2018-12-19 17:11:33 +03:00
commit 43d6d40d94
15 changed files with 160 additions and 39 deletions

View file

@ -32,6 +32,7 @@
import java.util.zip.CRC32;
import ru.gravit.launcher.Launcher;
import ru.gravit.launcher.LauncherConfig;
import ru.gravit.launcher.hasher.HashedDir;
import ru.gravit.launcher.managers.GarbageManager;
import ru.gravit.launcher.profiles.ClientProfile;
@ -48,10 +49,7 @@
import ru.gravit.launchserver.auth.handler.AuthHandler;
import ru.gravit.launchserver.auth.hwid.HWIDHandler;
import ru.gravit.launchserver.auth.provider.AuthProvider;
import ru.gravit.launchserver.binary.EXEL4JLauncherBinary;
import ru.gravit.launchserver.binary.EXELauncherBinary;
import ru.gravit.launchserver.binary.JARLauncherBinary;
import ru.gravit.launchserver.binary.LauncherBinary;
import ru.gravit.launchserver.binary.*;
import ru.gravit.launchserver.command.handler.CommandHandler;
import ru.gravit.launchserver.command.handler.JLineCommandHandler;
import ru.gravit.launchserver.command.handler.StdCommandHandler;
@ -112,6 +110,7 @@ public static final class Config extends ConfigObject {
public final String binaryName;
private final StringConfigEntry address;
private final String bindAddress;
public final LauncherConfig.LauncherEnvironment env;
private Config(BlockConfigEntry block, Path coredir, LaunchServer server) {
super(block);
@ -157,6 +156,7 @@ private Config(BlockConfigEntry block, Path coredir, LaunchServer server) {
isUsingWrapper = block.getEntryValue("isUsingWrapper", BooleanConfigEntry.class);
isDownloadJava = block.getEntryValue("isDownloadJava", BooleanConfigEntry.class);
env = LauncherConfig.LauncherEnvironment.STD;
}

View file

@ -105,19 +105,13 @@ public synchronized Connection getConnection() throws SQLException {
Class.forName("com.zaxxer.hikari.HikariDataSource");
hikari = true; // Used for shutdown. Not instanceof because of possible classpath error
HikariConfig cfg = new HikariConfig();
cfg.setUsername(username);
cfg.setPassword(password);
cfg.setDataSource(mysqlSource);
cfg.setPoolName(poolName);
cfg.setMinimumIdle(0);
cfg.setMaximumPoolSize(MAX_POOL_SIZE);
cfg.setIdleTimeout(TIMEOUT * 1000L);
// Set HikariCP pool
HikariDataSource hikariSource = new HikariDataSource(cfg);
// Replace source with hds
source = hikariSource;
source = new HikariDataSource(cfg);
LogHelper.info("HikariCP pooling enabled for '%s'", poolName);
return hikariSource.getConnection();
} catch (ClassNotFoundException ignored) {
LogHelper.warning("HikariCP isn't in classpath for '%s'", poolName);
}

View file

@ -8,8 +8,9 @@
import javassist.CtConstructor;
import javassist.CtMethod;
import javassist.NotFoundException;
import ru.gravit.launcher.LauncherConfig;
public class JAConfigurator implements AutoCloseable {
public class JAConfigurator implements AutoCloseable {
public ClassPool pool;
public CtClass ctClass;
public CtConstructor ctConstructor;
@ -92,6 +93,28 @@ public void setPort(int port) {
body.append(port);
body.append(";");
}
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;
}
body.append("this.env = ");
body.append(i);
body.append(";");
}
public void setClientPort(int port) {
body.append("this.clientPort = ");

View file

@ -216,6 +216,7 @@ private void stdBuild() throws IOException {
jaConfigurator.setClientPort(32148 + SecurityHelper.newRandom().nextInt(512));
jaConfigurator.setUsingWrapper(server.config.isUsingWrapper);
jaConfigurator.setDownloadJava(server.config.isDownloadJava);
jaConfigurator.setEnv(server.config.env);
server.buildHookManager.registerAllClientModuleClass(jaConfigurator);
try (ZipInputStream input = new ZipInputStream(IOHelper.newInput(cleanJar))) {
ZipEntry e = input.getNextEntry();

View file

@ -1,9 +1,13 @@
package ru.gravit.launcher.server;
import ru.gravit.utils.helper.IOHelper;
import ru.gravit.utils.helper.LogHelper;
import java.io.IOException;
import java.lang.instrument.Instrumentation;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Collections;
@ -31,21 +35,42 @@ public static void addJVMClassPath(JarFile file) throws IOException {
inst.appendToSystemClassLoaderSearch(file);
}
public boolean isAgentStarted() {
public static boolean isAgentStarted() {
return isAgentStarted;
}
public static long getObjSize(Object obj) {
return inst.getObjectSize(obj);
}
public static Boolean isAutoloadLibraries = Boolean.getBoolean(System.getProperty("serverwrapper,agentlibrariesload","false"));
public static Boolean isAgentProxy = Boolean.getBoolean(System.getProperty("serverwrapper,agentproxy","false"));
public static void premain(String agentArgument, Instrumentation instrumentation) {
LogHelper.debug("Server Agent");
inst = instrumentation;
isAgentStarted = true;
if(isAutoloadLibraries)
{
Path libraries = Paths.get("libraries");
if(IOHelper.exists(libraries)) loadLibraries(libraries);
}
if(isAgentProxy)
{
String proxyClassName = System.getProperty("serverwrapper,agentproxyclass");
Class proxyClass;
try {
proxyClass = Class.forName(proxyClassName);
MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(proxyClass, "premain", MethodType.methodType(void.class, String.class, Instrumentation.class));
Object[] args = {agentArgument,instrumentation};
mainMethod.invoke(args);
} catch (Throwable e) {
e.printStackTrace();
}
}
}
public static void loadLibraries(Path dir)
{
try {
Files.walkFileTree(Paths.get("libraries"), Collections.singleton(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new StarterVisitor());
Files.walkFileTree(dir, Collections.singleton(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new StarterVisitor());
} catch (IOException e) {
e.printStackTrace(System.err);
}

View file

@ -7,8 +7,10 @@
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
import ru.gravit.launcher.Launcher;
@ -21,6 +23,7 @@
import ru.gravit.launcher.serialize.config.entry.BooleanConfigEntry;
import ru.gravit.launcher.serialize.config.entry.IntegerConfigEntry;
import ru.gravit.launcher.serialize.config.entry.StringConfigEntry;
import ru.gravit.utils.PublicURLClassLoader;
import ru.gravit.utils.helper.CommonHelper;
import ru.gravit.utils.helper.IOHelper;
import ru.gravit.utils.helper.LogHelper;
@ -31,8 +34,13 @@
public class ServerWrapper {
public static ModulesManager modulesManager;
public static Path configFile;
public static Config config;
public static PublicURLClassLoader ucp;
public static ClassLoader loader;
public static Path modulesDir = Paths.get(System.getProperty("serverwrapper.modulesDir","modules"));
public static Path configFile = Paths.get(System.getProperty("serverwrapper.configFile","ServerWrapper.cfg"));
public static Path publicKeyFile = Paths.get(System.getProperty("serverwrapper.publicKeyFile","public.key"));
public static boolean auth(ServerWrapper wrapper) {
try {
@ -79,15 +87,14 @@ public static void main(String[] args) throws Throwable {
LogHelper.printVersion("ServerWrapper");
LogHelper.printLicense("ServerWrapper");
modulesManager = new ModulesManager(wrapper);
modulesManager.autoload(Paths.get("srv_modules")); //BungeeCord using modules dir
modulesManager.autoload(modulesDir);
Launcher.modulesManager = modulesManager;
configFile = Paths.get("ServerWrapper.cfg");
modulesManager.preInitModules();
generateConfigIfNotExists();
try (BufferedReader reader = IOHelper.newReader(configFile)) {
config = new Config(TextConfigReader.read(reader, true));
}
LauncherConfig cfg = new LauncherConfig(config.address, config.port, SecurityHelper.toPublicRSAKey(IOHelper.read(Paths.get("public.key"))), new HashMap<>(), config.projectname);
LauncherConfig cfg = new LauncherConfig(config.address, config.port, SecurityHelper.toPublicRSAKey(IOHelper.read(publicKeyFile)), new HashMap<>(), config.projectname);
Launcher.setConfig(cfg);
if (config.syncAuth) auth(wrapper);
else
@ -99,19 +106,43 @@ public static void main(String[] args) throws Throwable {
LogHelper.error("MainClass not found. Please set MainClass for ServerWrapper.cfg or first commandline argument");
}
Class<?> mainClass;
if (config.customClassLoader) {
@SuppressWarnings("unchecked")
Class<ClassLoader> classloader_class = (Class<ClassLoader>) Class.forName(config.classloader);
ClassLoader loader = classloader_class.getConstructor(ClassLoader.class).newInstance(ClassLoader.getSystemClassLoader());
Thread.currentThread().setContextClassLoader(loader);
mainClass = Class.forName(classname, false, loader);
} else mainClass = Class.forName(classname);
if(config.customClassPath)
{
String[] cp = config.classpath.split(":");
if(!ServerAgent.isAgentStarted())
{
LogHelper.warning("JavaAgent not found. Using URLClassLoader");
URL[] urls = Arrays.stream(cp).map(Paths::get).map(IOHelper::toURL).toArray(URL[]::new);
ucp = new PublicURLClassLoader(urls);
Thread.currentThread().setContextClassLoader(ucp);
loader = ucp;
}
else
{
LogHelper.info("Found %d custom classpath elements",cp.length);
for(String c : cp)
ServerAgent.addJVMClassPath(c);
}
}
if(config.autoloadLibraries)
{
if(!ServerAgent.isAgentStarted())
{
throw new UnsupportedOperationException("JavaAgent not found, autoloadLibraries not available");
}
Path librariesDir = Paths.get(config.librariesDir);
LogHelper.info("Load libraries");
ServerAgent.loadLibraries(librariesDir);
}
if(loader != null) mainClass = Class.forName(classname,true, loader);
else mainClass = Class.forName(classname);
MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class));
String[] real_args = new String[args.length - 1];
System.arraycopy(args, 1, real_args, 0, args.length - 1);
modulesManager.postInitModules();
LogHelper.info("ServerWrapper: Project %s, LaunchServer address: %s port %d. Title: %s",config.projectname,config.address,config.port,config.title);
LogHelper.info("Minecraft Version (for profile): %s",wrapper.profile.getVersion().name);
LogHelper.info("Start Minecraft Server");
LogHelper.debug("Invoke main method %s", mainClass.getName());
mainMethod.invoke(real_args);
}
@ -143,9 +174,11 @@ public static final class Config extends ConfigObject {
public int port;
public int reconnectCount;
public int reconnectSleep;
public boolean customClassLoader;
public boolean customClassPath;
public boolean autoloadLibraries;
public boolean syncAuth;
public String classloader;
public String classpath;
public String librariesDir;
public String mainclass;
public String login;
public String password;
@ -158,9 +191,12 @@ protected Config(BlockConfigEntry block) {
login = block.getEntryValue("login", StringConfigEntry.class);
password = block.getEntryValue("password", StringConfigEntry.class);
port = block.getEntryValue("port", IntegerConfigEntry.class);
customClassLoader = block.getEntryValue("customClassLoader", BooleanConfigEntry.class);
if (customClassLoader)
classloader = block.getEntryValue("classloader", StringConfigEntry.class);
customClassPath = block.getEntryValue("customClassPath", BooleanConfigEntry.class);
autoloadLibraries = block.getEntryValue("autoloadLibraries", BooleanConfigEntry.class);
if (customClassPath)
classpath = block.getEntryValue("classpath", StringConfigEntry.class);
if (autoloadLibraries)
librariesDir = block.getEntryValue("librariesDir", StringConfigEntry.class);
mainclass = block.getEntryValue("MainClass", StringConfigEntry.class);
reconnectCount = block.hasEntry("reconnectCount") ? block.getEntryValue("reconnectCount", IntegerConfigEntry.class) : 1;
reconnectSleep = block.hasEntry("reconnectSleep") ? block.getEntryValue("reconnectSleep", IntegerConfigEntry.class) : 30000;

View file

@ -1,6 +1,11 @@
title: "xxxx";
customClassLoader: false;
classloader: "ru.gravit.utils.PublicURLClassLoader";
autoloadLibraries: false;
librariesDir: "libraries";
customClassPath: false;
classpath: "server.jar";
MainClass: "";
address: "localhost";
port: 7240;

Binary file not shown.

View file

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-5.0-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

2
gradlew vendored
View file

@ -28,7 +28,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
DEFAULT_JVM_OPTS='"-Xmx64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

2
gradlew.bat vendored
View file

@ -14,7 +14,7 @@ set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DEFAULT_JVM_OPTS="-Xmx64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

View file

@ -9,6 +9,11 @@ public class AutogenConfig {
public boolean isUsingWrapper;
public boolean isDownloadJava; //Выставление этого флага требует модификации runtime части
public String secretKeyClient;
public int env;
// 0 - Dev (дебаг включен по умолчанию, все сообщения)
// 1 - Debug (дебаг включен по умолчанию, основные сообщения)
// 2 - Std (дебаг выключен по умолчанию, основные сообщения)
// 3 - Production (дебаг выключен, минимальный объем сообщений, stacktrace не выводится)
AutogenConfig() {

View file

@ -59,7 +59,7 @@ public final class Launcher {
public static int MAJOR = 4;
public static int MINOR = 1;
public static int PATCH = 0;
public static int BUILD = 1;
public static int BUILD = 3;
public static Version.Type RELEASE = Version.Type.DEV;
@LauncherAPI

View file

@ -56,6 +56,20 @@ public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException
secretKeyClient = config.secretKeyClient;
isDownloadJava = config.isDownloadJava;
isUsingWrapper = config.isUsingWrapper;
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;
else env = LauncherEnvironment.STD;
if(env == LauncherEnvironment.PROD) {
LogHelper.setStacktraceEnabled(false);
LogHelper.setDebugEnabled(false);
}
if(env == LauncherEnvironment.DEV || env == LauncherEnvironment.DEBUG)
{
LogHelper.setDebugEnabled(true);
}
// Read signed runtime
int count = input.readLength(0);
Map<String, byte[]> localResources = new HashMap<>(count);
@ -108,4 +122,9 @@ public void write(HOutput output) throws IOException {
output.writeByteArray(entry.getValue(), SecurityHelper.CRYPTO_MAX_LENGTH);
}
}
public enum LauncherEnvironment
{
DEV,DEBUG,STD,PROD
}
}

View file

@ -27,6 +27,8 @@ public final class LogHelper {
@LauncherAPI
public static final String DEBUG_PROPERTY = "launcher.debug";
@LauncherAPI
public static final String STACKTRACE_PROPERTY = "launcher.stacktrace";
@LauncherAPI
public static final String NO_JANSI_PROPERTY = "launcher.noJAnsi";
@LauncherAPI
public static final boolean JANSI;
@ -34,6 +36,7 @@ public final class LogHelper {
// Output settings
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss", Locale.US);
private static final AtomicBoolean DEBUG_ENABLED = new AtomicBoolean(Boolean.getBoolean(DEBUG_PROPERTY));
private static final AtomicBoolean STACKTRACE_ENABLED = new AtomicBoolean(Boolean.getBoolean(STACKTRACE_PROPERTY));
private static final Set<Output> OUTPUTS = Collections.newSetFromMap(new ConcurrentHashMap<>(2));
private static final Output STD_OUTPUT;
@ -73,7 +76,7 @@ public static void debug(String format, Object... args) {
@LauncherAPI
public static void error(Throwable exc) {
error(isDebugEnabled() ? toString(exc) : exc.toString());
error(isStacktraceEnabled() ? toString(exc) : exc.toString());
}
@LauncherAPI
@ -106,6 +109,16 @@ public static void setDebugEnabled(boolean debugEnabled) {
DEBUG_ENABLED.set(debugEnabled);
}
@LauncherAPI
public static boolean isStacktraceEnabled() {
return STACKTRACE_ENABLED.get();
}
@LauncherAPI
public static void setStacktraceEnabled(boolean stacktraceEnabled) {
STACKTRACE_ENABLED.set(stacktraceEnabled);
}
@LauncherAPI
public static void log(Level level, String message, boolean sub) {
String dateTime = DATE_TIME_FORMATTER.format(LocalDateTime.now());