Merge branch 'release/5.2.10'

This commit is contained in:
Gravita 2022-04-11 17:12:11 +07:00
commit 7254a197a1
26 changed files with 309 additions and 106 deletions

View file

@ -75,7 +75,7 @@ task cleanjar(type: Jar, dependsOn: jar) {
dependencies { dependencies {
pack project(':LauncherAPI') pack project(':LauncherAPI')
bundle group: 'me.tongfei', name: 'progressbar', version: '0.9.2' bundle group: 'me.tongfei', name: 'progressbar', version: '0.9.2'
bundle group: 'com.github.Marcono1234', name: 'gson-record-type-adapter-factory', version: 'v0.1.0' bundle group: 'com.github.Marcono1234', name: 'gson-record-type-adapter-factory', version: 'v0.2.0'
bundle group: 'org.fusesource.jansi', name: 'jansi', version: rootProject['verJansi'] bundle group: 'org.fusesource.jansi', name: 'jansi', version: rootProject['verJansi']
bundle group: 'org.jline', name: 'jline', version: rootProject['verJline'] bundle group: 'org.jline', name: 'jline', version: rootProject['verJline']
bundle group: 'org.jline', name: 'jline-reader', version: rootProject['verJline'] bundle group: 'org.jline', name: 'jline-reader', version: rootProject['verJline']
@ -84,8 +84,6 @@ pack project(':LauncherAPI')
bundle group: 'org.ow2.asm', name: 'asm-commons', version: rootProject['verAsm'] bundle group: 'org.ow2.asm', name: 'asm-commons', version: rootProject['verAsm']
bundle group: 'io.netty', name: 'netty-all', version: rootProject['verNetty'] bundle group: 'io.netty', name: 'netty-all', version: rootProject['verNetty']
bundle group: 'org.slf4j', name: 'slf4j-api', version: rootProject['verSlf4j'] bundle group: 'org.slf4j', name: 'slf4j-api', version: rootProject['verSlf4j']
bundle group: 'org.hibernate', name: 'hibernate-core', version: rootProject['verHibernate']
bundle group: 'org.hibernate', name: 'hibernate-hikaricp', version: rootProject['verHibernate']
bundle group: 'mysql', name: 'mysql-connector-java', version: rootProject['verMySQLConn'] bundle group: 'mysql', name: 'mysql-connector-java', version: rootProject['verMySQLConn']
bundle group: 'org.postgresql', name: 'postgresql', version: rootProject['verPostgreSQLConn'] bundle group: 'org.postgresql', name: 'postgresql', version: rootProject['verPostgreSQLConn']
bundle group: 'com.guardsquare', name: 'proguard-base', version: rootProject['verProguard'] bundle group: 'com.guardsquare', name: 'proguard-base', version: rootProject['verProguard']
@ -96,8 +94,8 @@ pack project(':LauncherAPI')
bundle group: 'io.jsonwebtoken', name: 'jjwt-gson', version: rootProject['verJwt'] bundle group: 'io.jsonwebtoken', name: 'jjwt-gson', version: rootProject['verJwt']
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter', version: rootProject['verJunit'] testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter', version: rootProject['verJunit']
hikari 'io.micrometer:micrometer-core:1.7.2' hikari 'io.micrometer:micrometer-core:1.8.4'
hikari('com.zaxxer:HikariCP:5.0.0') { hikari('com.zaxxer:HikariCP:5.0.1') {
exclude group: 'javassist' exclude group: 'javassist'
exclude group: 'io.micrometer' exclude group: 'io.micrometer'
exclude group: 'org.slf4j' exclude group: 'org.slf4j'

View file

@ -363,6 +363,19 @@ public Map<String, String> getProperties() {
} }
return properties; return properties;
} }
@Override
public String toString() {
return "HttpUser{" +
"username='" + username + '\'' +
", uuid=" + uuid +
", serverId='" + serverId + '\'' +
", accessToken='" + accessToken + '\'' +
", permissions=" + permissions +
", assets=" + getAssets() +
", properties=" + properties +
'}';
}
} }
public static class HttpUserSession implements UserSession { public static class HttpUserSession implements UserSession {
@ -393,5 +406,14 @@ public User getUser() {
public long getExpireIn() { public long getExpireIn() {
return expireIn; return expireIn;
} }
@Override
public String toString() {
return "HttpUserSession{" +
"id='" + id + '\'' +
", user=" + user +
", expireIn=" + expireIn +
'}';
}
} }
} }

View file

@ -51,7 +51,7 @@ public boolean allowGetSecureLevelInfo(Client client) {
@Override @Override
public void onHardwareReport(HardwareReportResponse response, Client client) { public void onHardwareReport(HardwareReportResponse response, Client client) {
if (!enableHardwareFeature) { if (!enableHardwareFeature) {
response.sendResult(new HardwareReportRequestEvent(createHardwareToken(client.username, response.hardware))); response.sendResult(new HardwareReportRequestEvent(null));
return; return;
} }
if (!client.isAuth || client.trustLevel == null || client.trustLevel.publicKey == null) { if (!client.isAuth || client.trustLevel == null || client.trustLevel.publicKey == null) {
@ -73,11 +73,14 @@ public void onHardwareReport(HardwareReportResponse response, Client client) {
throw new SecurityException("Your hardware banned"); throw new SecurityException("Your hardware banned");
} }
client.trustLevel.hardwareInfo = hardware.getHardwareInfo(); client.trustLevel.hardwareInfo = hardware.getHardwareInfo();
response.sendResult(new HardwareReportRequestEvent(createHardwareToken(client.username, hardware)));
return;
} else { } else {
logger.error("AuthCoreProvider not supported hardware"); logger.error("AuthCoreProvider not supported hardware");
response.sendError("AuthCoreProvider not supported hardware");
return;
} }
} }
response.sendResult(new HardwareReportRequestEvent(createHardwareToken(client.username, response.hardware)));
} }
@Override @Override
@ -93,10 +96,10 @@ public VerifySecureLevelKeyRequestEvent onSuccessVerify(Client client) {
} }
client.trustLevel.hardwareInfo = hardware.getHardwareInfo(); client.trustLevel.hardwareInfo = hardware.getHardwareInfo();
authSupportHardware.connectUserAndHardware(client.sessionObject, hardware); authSupportHardware.connectUserAndHardware(client.sessionObject, hardware);
return new VerifySecureLevelKeyRequestEvent(false, false, createPublicKeyToken(client.username, client.trustLevel.publicKey), createHardwareToken(client.username, hardware));
} else { } else {
logger.warn("AuthCoreProvider not supported hardware. HardwareInfo not checked!"); logger.warn("AuthCoreProvider not supported hardware. HardwareInfo not checked!");
} }
return new VerifySecureLevelKeyRequestEvent(false, false, createPublicKeyToken(client.username, client.trustLevel.publicKey));
} }
return new VerifySecureLevelKeyRequestEvent(false, false, createPublicKeyToken(client.username, client.trustLevel.publicKey)); return new VerifySecureLevelKeyRequestEvent(false, false, createPublicKeyToken(client.username, client.trustLevel.publicKey));
} }
@ -115,12 +118,12 @@ public void init(LaunchServer server) {
public void close() { public void close() {
} }
public String createHardwareToken(String username, HardwareReportRequest.HardwareInfo info) { public String createHardwareToken(String username, UserHardware hardware) {
return Jwts.builder() return Jwts.builder()
.setIssuer("LaunchServer") .setIssuer("LaunchServer")
.setSubject(username) .setSubject(username)
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 8)) .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 8))
.claim("hardware", info) .claim("hardware", hardware.getId())
.signWith(server.keyAgreementManager.ecdsaPrivateKey) .signWith(server.keyAgreementManager.ecdsaPrivateKey)
.compact(); .compact();
} }
@ -152,10 +155,14 @@ public HardwareInfoTokenVerifier(LaunchServer server) {
public boolean accept(Client client, AuthProviderPair pair, String extendedToken) { public boolean accept(Client client, AuthProviderPair pair, String extendedToken) {
try { try {
var parse = parser.parseClaimsJws(extendedToken); var parse = parser.parseClaimsJws(extendedToken);
HardwareReportRequest.HardwareInfo hardwareInfo = parse.getBody().get("hardware", HardwareReportRequest.HardwareInfo.class); String hardwareInfoId = parse.getBody().get("hardware", String.class);
if (hardwareInfo == null) return false; if (hardwareInfoId == null) return false;
if(client.auth == null) return false;
var hardwareSupport = client.auth.core.isSupport(AuthSupportHardware.class);
if(hardwareSupport == null) return false;
UserHardware hardware = hardwareSupport.getHardwareInfoById(hardwareInfoId);
if (client.trustLevel == null) client.trustLevel = new Client.TrustLevel(); if (client.trustLevel == null) client.trustLevel = new Client.TrustLevel();
client.trustLevel.hardwareInfo = hardwareInfo; client.trustLevel.hardwareInfo = hardware.getHardwareInfo();
return true; return true;
} catch (Throwable e) { } catch (Throwable e) {
logger.error("Hardware JWT error", e); logger.error("Hardware JWT error", e);

View file

@ -152,7 +152,7 @@ public Path process(Path inputFile) throws IOException {
parser.parse(proguard_cfg); parser.parse(proguard_cfg);
ProGuard proGuard = new ProGuard(proguard_cfg); ProGuard proGuard = new ProGuard(proguard_cfg);
proGuard.execute(); proGuard.execute();
} catch (ParseException e) { } catch (Exception e) {
logger.error(e); logger.error(e);
} }
} else } else

View file

@ -84,6 +84,7 @@ public boolean accept(Client client, AuthProviderPair pair, String extendedToken
if(client.permissions == null) client.permissions = new ClientPermissions(); if(client.permissions == null) client.permissions = new ClientPermissions();
client.permissions.addPerm("launchserver.checkserver"); client.permissions.addPerm("launchserver.checkserver");
client.permissions.addPerm(String.format("launchserver.profile.%s.show", info.serverName)); client.permissions.addPerm(String.format("launchserver.profile.%s.show", info.serverName));
client.setSerializableProperty("launchserver.serverName", info.serverName);
return true; return true;
} }
} }

View file

@ -1,5 +1,7 @@
package pro.gravit.launchserver.manangers.hook; package pro.gravit.launchserver.manangers.hook;
import pro.gravit.launchserver.auth.core.User;
import pro.gravit.launchserver.manangers.AuthManager;
import pro.gravit.launchserver.socket.Client; import pro.gravit.launchserver.socket.Client;
import pro.gravit.launchserver.socket.response.auth.AuthResponse; import pro.gravit.launchserver.socket.response.auth.AuthResponse;
import pro.gravit.launchserver.socket.response.auth.CheckServerResponse; import pro.gravit.launchserver.socket.response.auth.CheckServerResponse;
@ -12,6 +14,7 @@ public class AuthHookManager {
public final BiHookSet<AuthResponse.AuthContext, Client> preHook = new BiHookSet<>(); public final BiHookSet<AuthResponse.AuthContext, Client> preHook = new BiHookSet<>();
public final BiHookSet<AuthResponse.AuthContext, Client> postHook = new BiHookSet<>(); public final BiHookSet<AuthResponse.AuthContext, Client> postHook = new BiHookSet<>();
public final BiHookSet<CheckServerResponse, Client> checkServerHook = new BiHookSet<>(); public final BiHookSet<CheckServerResponse, Client> checkServerHook = new BiHookSet<>();
public final BiHookSet<AuthManager.CheckServerReport, Client> postCheckServerHook = new BiHookSet<>();
public final BiHookSet<JoinServerResponse, Client> joinServerHook = new BiHookSet<>(); public final BiHookSet<JoinServerResponse, Client> joinServerHook = new BiHookSet<>();
public final BiHookSet<SetProfileResponse, Client> setProfileHook = new BiHookSet<>(); public final BiHookSet<SetProfileResponse, Client> setProfileHook = new BiHookSet<>();
public final HookSet<RegContext> registraion = new HookSet<>(); public final HookSet<RegContext> registraion = new HookSet<>();

View file

@ -37,6 +37,7 @@ public void execute(ChannelHandlerContext ctx, Client pClient) {
} }
result.playerProfile = report.playerProfile; result.playerProfile = report.playerProfile;
result.uuid = report.uuid; result.uuid = report.uuid;
server.authHookManager.postCheckServerHook.hook(report, pClient);
logger.debug("checkServer: {} uuid: {} serverID: {}", result.playerProfile == null ? null : result.playerProfile.username, result.uuid, serverID); logger.debug("checkServer: {} uuid: {} serverID: {}", result.playerProfile == null ? null : result.playerProfile.username, result.uuid, serverID);
} catch (AuthException | HookException e) { } catch (AuthException | HookException e) {
sendError(e.getMessage()); sendError(e.getMessage());

View file

@ -12,14 +12,4 @@ private SystemService() {
public static void exit(int code) { public static void exit(int code) {
LauncherEngine.exitLauncher(code); LauncherEngine.exitLauncher(code);
} }
public static void setSecurityManager(SecurityManager s) {
LogHelper.debug("Try set security manager %s", s == null ? "null" : s.getClass().getName());
if (AuthService.profile == null || AuthService.profile.getSecurityManagerConfig() == ClientProfile.SecurityManagerConfig.NONE)
return;
if (AuthService.profile.getSecurityManagerConfig() == ClientProfile.SecurityManagerConfig.CLIENT) {
System.setSecurityManager(s);
}
//TODO NEXT
}
} }

View file

@ -349,6 +349,8 @@ private static void launch(ClientProfile profile, ClientLauncherProcess.ClientPa
} }
FMLPatcher.apply(); FMLPatcher.apply();
LauncherEngine.modulesManager.invokeEvent(new ClientProcessPreInvokeMainClassEvent(params, profile, args)); LauncherEngine.modulesManager.invokeEvent(new ClientProcessPreInvokeMainClassEvent(params, profile, args));
// Invoke main method
try {
{ {
List<String> compatClasses = profile.getCompatClasses(); List<String> compatClasses = profile.getCompatClasses();
for (String e : compatClasses) { for (String e : compatClasses) {
@ -360,8 +362,6 @@ private static void launch(ClientProfile profile, ClientLauncherProcess.ClientPa
MethodHandle mainMethod = MethodHandles.lookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class)).asFixedArity(); MethodHandle mainMethod = MethodHandles.lookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class)).asFixedArity();
Launcher.LAUNCHED.set(true); Launcher.LAUNCHED.set(true);
JVMHelper.fullGC(); JVMHelper.fullGC();
// Invoke main method
try {
mainMethod.invokeWithArguments((Object) args.toArray(new String[0])); mainMethod.invokeWithArguments((Object) args.toArray(new String[0]));
LogHelper.debug("Main exit successful"); LogHelper.debug("Main exit successful");
} catch (Throwable e) { } catch (Throwable e) {

View file

@ -20,6 +20,7 @@
import pro.gravit.utils.Version; import pro.gravit.utils.Version;
import pro.gravit.utils.helper.*; import pro.gravit.utils.helper.*;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
@ -33,7 +34,7 @@ public class ClientLauncherProcess {
public final ClientParams params = new ClientParams(); public final ClientParams params = new ClientParams();
public final List<String> jvmArgs = new LinkedList<>(); public final List<String> jvmArgs = new LinkedList<>();
public final List<String> jvmModules = new LinkedList<>(); public final List<String> jvmModules = new LinkedList<>();
public final List<Path> jvmModulesPaths = new LinkedList<>(); public final List<String> jvmModulesPaths = new LinkedList<>();
public final List<String> systemClientArgs = new LinkedList<>(); public final List<String> systemClientArgs = new LinkedList<>();
public final List<String> systemClassPath = new LinkedList<>(); public final List<String> systemClassPath = new LinkedList<>();
public final Map<String, String> systemEnv = new HashMap<>(); public final Map<String, String> systemEnv = new HashMap<>();
@ -127,7 +128,8 @@ private void applyClientProfile() {
this.params.oauthExpiredTime = Request.getTokenExpiredTime(); this.params.oauthExpiredTime = Request.getTokenExpiredTime();
this.params.extendedTokens = Request.getExtendedTokens(); this.params.extendedTokens = Request.getExtendedTokens();
} }
this.jvmModules.addAll(this.params.profile.getModules());
this.jvmModulesPaths.addAll(this.params.profile.getModulePath());
if (this.params.profile.getRuntimeInClientConfig() != ClientProfile.RuntimeInClientConfig.NONE) { if (this.params.profile.getRuntimeInClientConfig() != ClientProfile.RuntimeInClientConfig.NONE) {
jvmModules.add("javafx.base"); jvmModules.add("javafx.base");
jvmModules.add("javafx.graphics"); jvmModules.add("javafx.graphics");
@ -137,6 +139,7 @@ private void applyClientProfile() {
jvmModules.add("javafx.media"); jvmModules.add("javafx.media");
jvmModules.add("javafx.web"); jvmModules.add("javafx.web");
} }
LauncherEngine.modulesManager.invokeEvent(new ClientProcessBuilderCreateEvent(this)); LauncherEngine.modulesManager.invokeEvent(new ClientProcessBuilderCreateEvent(this));
} }
@ -187,20 +190,26 @@ public void start(boolean pipeOutput) throws IOException, InterruptedException {
} }
private void applyJava9Params(List<String> processArgs) { private void applyJava9Params(List<String> processArgs) {
jvmModulesPaths.add(javaVersion.jvmDir); /*jvmModulesPaths.add(javaVersion.jvmDir);
jvmModulesPaths.add(javaVersion.jvmDir.resolve("jre")); jvmModulesPaths.add(javaVersion.jvmDir.resolve("jre"));
Path openjfxPath = JavaHelper.tryGetOpenJFXPath(javaVersion.jvmDir); Path openjfxPath = JavaHelper.tryGetOpenJFXPath(javaVersion.jvmDir);
if (openjfxPath != null) { if (openjfxPath != null) {
jvmModulesPaths.add(openjfxPath); jvmModulesPaths.add(openjfxPath);
} }*/ // TODO: fix runtime in client
StringBuilder modulesPath = new StringBuilder(); StringBuilder modulesPath = new StringBuilder();
StringBuilder modulesAdd = new StringBuilder(); StringBuilder modulesAdd = new StringBuilder();
for (String moduleName : jvmModules) { for (String moduleName : jvmModules) {
boolean success = JavaHelper.tryAddModule(jvmModulesPaths, moduleName, modulesPath); /*boolean success = JavaHelper.tryAddModule(jvmModulesPaths, moduleName, modulesPath);
if (success) { if (success) {
if (modulesAdd.length() > 0) modulesAdd.append(","); if (modulesAdd.length() > 0) modulesAdd.append(",");
modulesAdd.append(moduleName); modulesAdd.append(moduleName);
}*/
if (modulesAdd.length() > 0) modulesAdd.append(",");
modulesAdd.append(moduleName);
} }
for(String modulePath : jvmModulesPaths) {
if (modulesPath.length() > 0) modulesPath.append(File.pathSeparator);
modulesPath.append(modulePath);
} }
if (modulesAdd.length() > 0) { if (modulesAdd.length() > 0) {
processArgs.add("--add-modules"); processArgs.add("--add-modules");

View file

@ -6,6 +6,7 @@ public class VerifySecureLevelKeyRequestEvent extends RequestEvent {
public boolean needHardwareInfo; public boolean needHardwareInfo;
public boolean onlyStatisticInfo; public boolean onlyStatisticInfo;
public String extendedToken; public String extendedToken;
public String hardwareExtendedToken;
public VerifySecureLevelKeyRequestEvent() { public VerifySecureLevelKeyRequestEvent() {
} }
@ -20,6 +21,13 @@ public VerifySecureLevelKeyRequestEvent(boolean needHardwareInfo, boolean onlySt
this.extendedToken = extendedToken; this.extendedToken = extendedToken;
} }
public VerifySecureLevelKeyRequestEvent(boolean needHardwareInfo, boolean onlyStatisticInfo, String extendedToken, String hardwareExtendedToken) {
this.needHardwareInfo = needHardwareInfo;
this.onlyStatisticInfo = onlyStatisticInfo;
this.extendedToken = extendedToken;
this.hardwareExtendedToken = hardwareExtendedToken;
}
@Override @Override
public String getType() { public String getType() {
return "verifySecureLevelKey"; return "verifySecureLevelKey";

View file

@ -48,6 +48,10 @@ public final class ClientProfile implements Comparable<ClientProfile> {
@LauncherNetworkAPI @LauncherNetworkAPI
private List<String> classPath; private List<String> classPath;
@LauncherNetworkAPI @LauncherNetworkAPI
private List<String> modulePath = new ArrayList<>();
@LauncherNetworkAPI
private List<String> modules = new ArrayList<>();
@LauncherNetworkAPI
private List<String> altClassPath; private List<String> altClassPath;
@LauncherNetworkAPI @LauncherNetworkAPI
private List<String> clientArgs; private List<String> clientArgs;
@ -91,6 +95,7 @@ public ClientProfile() {
updateOptional = new HashSet<>(); updateOptional = new HashSet<>();
jvmArgs = new ArrayList<>(); jvmArgs = new ArrayList<>();
classPath = new ArrayList<>(); classPath = new ArrayList<>();
modulePath = new ArrayList<>();
altClassPath = new ArrayList<>(); altClassPath = new ArrayList<>();
clientArgs = new ArrayList<>(); clientArgs = new ArrayList<>();
compatClasses = new ArrayList<>(); compatClasses = new ArrayList<>();
@ -102,7 +107,7 @@ public ClientProfile() {
runtimeInClientConfig = RuntimeInClientConfig.NONE; runtimeInClientConfig = RuntimeInClientConfig.NONE;
} }
public ClientProfile(List<String> update, List<String> updateExclusions, List<String> updateShared, List<String> updateVerify, Set<OptionalFile> updateOptional, List<String> jvmArgs, List<String> classPath, List<String> altClassPath, List<String> clientArgs, List<String> compatClasses, Map<String, String> properties, List<ServerProfile> servers, SecurityManagerConfig securityManagerConfig, ClassLoaderConfig classLoaderConfig, SignedClientConfig signedClientConfig, RuntimeInClientConfig runtimeInClientConfig, String version, String assetIndex, String dir, String assetDir, int recommendJavaVersion, int minJavaVersion, int maxJavaVersion, boolean warnMissJavaVersion, ProfileDefaultSettings settings, int sortIndex, UUID uuid, String title, String info, boolean updateFastCheck, String mainClass) { public ClientProfile(List<String> update, List<String> updateExclusions, List<String> updateShared, List<String> updateVerify, Set<OptionalFile> updateOptional, List<String> jvmArgs, List<String> classPath, List<String> modulePath, List<String> modules, List<String> altClassPath, List<String> clientArgs, List<String> compatClasses, Map<String, String> properties, List<ServerProfile> servers, SecurityManagerConfig securityManagerConfig, ClassLoaderConfig classLoaderConfig, SignedClientConfig signedClientConfig, RuntimeInClientConfig runtimeInClientConfig, String version, String assetIndex, String dir, String assetDir, int recommendJavaVersion, int minJavaVersion, int maxJavaVersion, boolean warnMissJavaVersion, ProfileDefaultSettings settings, int sortIndex, UUID uuid, String title, String info, boolean updateFastCheck, String mainClass) {
this.update = update; this.update = update;
this.updateExclusions = updateExclusions; this.updateExclusions = updateExclusions;
this.updateShared = updateShared; this.updateShared = updateShared;
@ -110,6 +115,8 @@ public ClientProfile(List<String> update, List<String> updateExclusions, List<St
this.updateOptional = updateOptional; this.updateOptional = updateOptional;
this.jvmArgs = jvmArgs; this.jvmArgs = jvmArgs;
this.classPath = classPath; this.classPath = classPath;
this.modulePath = modulePath;
this.modules = modules;
this.altClassPath = altClassPath; this.altClassPath = altClassPath;
this.clientArgs = clientArgs; this.clientArgs = clientArgs;
this.compatClasses = compatClasses; this.compatClasses = compatClasses;
@ -160,6 +167,14 @@ public String[] getClassPath() {
return classPath.toArray(new String[0]); return classPath.toArray(new String[0]);
} }
public List<String> getModulePath() {
return Collections.unmodifiableList(modulePath);
}
public List<String> getModules() {
return Collections.unmodifiableList(modules);
}
public String[] getAlternativeClassPath() { public String[] getAlternativeClassPath() {
return altClassPath.toArray(new String[0]); return altClassPath.toArray(new String[0]);
} }
@ -411,14 +426,6 @@ public int hashCode() {
return Objects.hash(uuid); return Objects.hash(uuid);
} }
public SecurityManagerConfig getSecurityManagerConfig() {
return securityManagerConfig;
}
public void setSecurityManagerConfig(SecurityManagerConfig securityManagerConfig) {
this.securityManagerConfig = securityManagerConfig;
}
public ClassLoaderConfig getClassLoaderConfig() { public ClassLoaderConfig getClassLoaderConfig() {
return classLoaderConfig; return classLoaderConfig;
} }
@ -427,14 +434,6 @@ public void setClassLoaderConfig(ClassLoaderConfig classLoaderConfig) {
this.classLoaderConfig = classLoaderConfig; this.classLoaderConfig = classLoaderConfig;
} }
public SignedClientConfig getSignedClientConfig() {
return signedClientConfig;
}
public void setSignedClientConfig(SignedClientConfig signedClientConfig) {
this.signedClientConfig = signedClientConfig;
}
public RuntimeInClientConfig getRuntimeInClientConfig() { public RuntimeInClientConfig getRuntimeInClientConfig() {
return runtimeInClientConfig; return runtimeInClientConfig;
} }
@ -517,7 +516,7 @@ public enum SecurityManagerConfig {
} }
public enum ClassLoaderConfig { public enum ClassLoaderConfig {
AGENT, LAUNCHER, SYSTEM_ARGS AGENT, LAUNCHER, MODULE, SYSTEM_ARGS
} }
public enum SignedClientConfig { public enum SignedClientConfig {

View file

@ -12,6 +12,8 @@ public class ClientProfileBuilder {
private Set<OptionalFile> updateOptional = new HashSet<>(); private Set<OptionalFile> updateOptional = new HashSet<>();
private List<String> jvmArgs = new ArrayList<>(); private List<String> jvmArgs = new ArrayList<>();
private List<String> classPath = new ArrayList<>(); private List<String> classPath = new ArrayList<>();
private List<String> modulePath = new ArrayList<>();
private List<String> modules = new ArrayList<>();
private List<String> altClassPath = new ArrayList<>(); private List<String> altClassPath = new ArrayList<>();
private List<String> clientArgs = new ArrayList<>(); private List<String> clientArgs = new ArrayList<>();
private List<String> compatClasses = new ArrayList<>(); private List<String> compatClasses = new ArrayList<>();
@ -142,6 +144,16 @@ public ClientProfileBuilder setRecommendJavaVersion(int recommendJavaVersion) {
return this; return this;
} }
public ClientProfileBuilder setModulePath(List<String> modulePath) {
this.modulePath = modulePath;
return this;
}
public ClientProfileBuilder setModules(List<String> modules) {
this.modules = modules;
return this;
}
public ClientProfileBuilder setMinJavaVersion(int minJavaVersion) { public ClientProfileBuilder setMinJavaVersion(int minJavaVersion) {
this.minJavaVersion = minJavaVersion; this.minJavaVersion = minJavaVersion;
return this; return this;
@ -193,6 +205,6 @@ public ClientProfileBuilder setMainClass(String mainClass) {
} }
public ClientProfile createClientProfile() { public ClientProfile createClientProfile() {
return new ClientProfile(update, updateExclusions, updateShared, updateVerify, updateOptional, jvmArgs, classPath, altClassPath, clientArgs, compatClasses, properties, servers, securityManagerConfig, classLoaderConfig, signedClientConfig, runtimeInClientConfig, version, assetIndex, dir, assetDir, recommendJavaVersion, minJavaVersion, maxJavaVersion, warnMissJavaVersion, settings, sortIndex, uuid, title, info, updateFastCheck, mainClass); return new ClientProfile(update, updateExclusions, updateShared, updateVerify, updateOptional, jvmArgs, classPath, modulePath, modules, altClassPath, clientArgs, compatClasses, properties, servers, securityManagerConfig, classLoaderConfig, signedClientConfig, runtimeInClientConfig, version, assetIndex, dir, assetDir, recommendJavaVersion, minJavaVersion, maxJavaVersion, warnMissJavaVersion, settings, sortIndex, uuid, title, info, updateFastCheck, mainClass);
} }
} }

View file

@ -6,7 +6,7 @@ public final class Version implements Comparable<Version> {
public static final int MAJOR = 5; public static final int MAJOR = 5;
public static final int MINOR = 2; public static final int MINOR = 2;
public static final int PATCH = 9; public static final int PATCH = 10;
public static final int BUILD = 1; public static final int BUILD = 1;
public static final Version.Type RELEASE = Type.STABLE; public static final Version.Type RELEASE = Type.STABLE;
public final int major; public final int major;

View file

@ -14,16 +14,37 @@
} }
} }
sourceSets {
java11 {
java {
srcDirs = ['src/main/java11']
}
dependencies {
java11Implementation project(':LauncherAPI')
java11Implementation files(sourceSets.main.output.classesDirs) { builtBy compileJava }
}
}
}
sourceCompatibility = '1.8' sourceCompatibility = '1.8'
targetCompatibility = '1.8' targetCompatibility = '1.8'
compileJava11Java {
sourceCompatibility = 11
targetCompatibility = 11
}
jar { jar {
into('META-INF/versions/11') {
from sourceSets.java11.output
}
archiveClassifier.set('clean') archiveClassifier.set('clean')
manifest.attributes("Main-Class": mainClassName, manifest.attributes("Main-Class": mainClassName,
"Premain-Class": mainAgentName, "Premain-Class": mainAgentName,
"Can-Redefine-Classes": "true", "Can-Redefine-Classes": "true",
"Can-Retransform-Classes": "true", "Can-Retransform-Classes": "true",
"Can-Set-Native-Method-Prefix": "true") "Can-Set-Native-Method-Prefix": "true",
"Multi-Release": "true")
} }
task sourcesJar(type: Jar) { task sourcesJar(type: Jar) {

View file

@ -18,6 +18,10 @@
import pro.gravit.launcher.request.auth.RestoreRequest; import pro.gravit.launcher.request.auth.RestoreRequest;
import pro.gravit.launcher.request.update.ProfilesRequest; import pro.gravit.launcher.request.update.ProfilesRequest;
import pro.gravit.launcher.request.websockets.StdWebSocketService; import pro.gravit.launcher.request.websockets.StdWebSocketService;
import pro.gravit.launcher.server.launch.ClasspathLaunch;
import pro.gravit.launcher.server.launch.Launch;
import pro.gravit.launcher.server.launch.ModuleLaunch;
import pro.gravit.launcher.server.launch.SimpleLaunch;
import pro.gravit.launcher.server.setup.ServerWrapperSetup; import pro.gravit.launcher.server.setup.ServerWrapperSetup;
import pro.gravit.utils.PublicURLClassLoader; import pro.gravit.utils.PublicURLClassLoader;
import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.IOHelper;
@ -139,22 +143,6 @@ public void run(String... args) throws Throwable {
LogHelper.error("Auth not configured. Please use 'java -jar ServerWrapper.jar setup'"); LogHelper.error("Auth not configured. Please use 'java -jar ServerWrapper.jar setup'");
System.exit(-1); System.exit(-1);
} }
Class<?> mainClass;
if (config.classpath != null && !config.classpath.isEmpty()) {
if(config.classLoaderConfig == ClientProfile.ClassLoaderConfig.LAUNCHER) {
URL[] urls = config.classpath.stream().map(Paths::get).map(IOHelper::toURL).toArray(URL[]::new);
ucp = new PublicURLClassLoader(urls);
Thread.currentThread().setContextClassLoader(ucp);
loader = ucp;
} else if(config.classLoaderConfig == ClientProfile.ClassLoaderConfig.AGENT) {
if (!ServerAgent.isAgentStarted()) {
LogHelper.error("JavaAgent not found");
System.exit(-1);
}
for (String c : config.classpath)
ServerAgent.addJVMClassPath(c);
}
}
if (config.autoloadLibraries) { if (config.autoloadLibraries) {
if (!ServerAgent.isAgentStarted()) { if (!ServerAgent.isAgentStarted()) {
throw new UnsupportedOperationException("JavaAgent not found, autoloadLibraries not available"); throw new UnsupportedOperationException("JavaAgent not found, autoloadLibraries not available");
@ -165,24 +153,34 @@ public void run(String... args) throws Throwable {
LogHelper.info("Load libraries"); LogHelper.info("Load libraries");
ServerAgent.loadLibraries(librariesDir); 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));
LogHelper.info("ServerWrapper: LaunchServer address: %s. Title: %s", config.address, Launcher.profile != null ? Launcher.profile.getTitle() : "unknown"); LogHelper.info("ServerWrapper: LaunchServer address: %s. Title: %s", config.address, Launcher.profile != null ? Launcher.profile.getTitle() : "unknown");
LogHelper.info("Minecraft Version (for profile): %s", wrapper.profile == null ? "unknown" : wrapper.profile.getVersion().name); LogHelper.info("Minecraft Version (for profile): %s", wrapper.profile == null ? "unknown" : wrapper.profile.getVersion().name);
LogHelper.info("Start Minecraft Server");
LogHelper.debug("Invoke main method %s", mainClass.getName());
if (config.args == null) {
String[] real_args; String[] real_args;
if (args.length > 0) { if (args.length > 0) {
real_args = new String[args.length - 1]; real_args = new String[args.length - 1];
System.arraycopy(args, 1, real_args, 0, args.length - 1); System.arraycopy(args, 1, real_args, 0, args.length - 1);
} else real_args = args; } else real_args = args;
Launch launch;
mainMethod.invoke(real_args); switch (config.classLoaderConfig) {
} else { case LAUNCHER:
mainMethod.invoke(config.args.toArray(new String[0])); launch = new ClasspathLaunch();
break;
case MODULE:
launch = new ModuleLaunch();
break;
default:
launch = new SimpleLaunch();
break;
} }
LogHelper.info("Start Minecraft Server");
LogHelper.debug("Invoke main method %s with %s", config.mainclass, launch.getClass().getName());
try {
launch.run(config, real_args);
} catch (Throwable e) {
LogHelper.error(e);
System.exit(-1);
}
System.exit(0);
} }
public void updateLauncherConfig() { public void updateLauncherConfig() {
@ -231,8 +229,15 @@ public static final class Config {
public long oauthExpireTime; public long oauthExpireTime;
public Map<String, String> extendedTokens; public Map<String, String> extendedTokens;
public LauncherConfig.LauncherEnvironment env; public LauncherConfig.LauncherEnvironment env;
public ModuleConf moduleConf = new ModuleConf();
} }
public static final class WebSocketConf { public static final class ModuleConf {
public List<String> modules = new ArrayList<>();
public List<String> modulePath = new ArrayList<>();
public String mainModule = "";
public Map<String, String> exports = new HashMap<>();
public Map<String, String> opens = new HashMap<>();
public Map<String, String> reads = new HashMap<>();
} }
} }

View file

@ -0,0 +1,23 @@
package pro.gravit.launcher.server.launch;
import pro.gravit.launcher.server.ServerWrapper;
import pro.gravit.utils.PublicURLClassLoader;
import pro.gravit.utils.helper.IOHelper;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.net.URL;
import java.nio.file.Paths;
public class ClasspathLaunch implements Launch {
@Override
@SuppressWarnings("ConfusingArgumentToVarargsMethod")
public void run(ServerWrapper.Config config, String[] args) throws Throwable {
URL[] urls = config.classpath.stream().map(Paths::get).map(IOHelper::toURL).toArray(URL[]::new);
ClassLoader ucl = new PublicURLClassLoader(urls);
Class<?> mainClass = Class.forName(config.mainclass, true, ucl);
MethodHandle mainMethod = MethodHandles.lookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class));
mainMethod.invoke(args);
}
}

View file

@ -0,0 +1,7 @@
package pro.gravit.launcher.server.launch;
import pro.gravit.launcher.server.ServerWrapper;
public interface Launch {
void run(ServerWrapper.Config config, String[] args) throws Throwable;
}

View file

@ -0,0 +1,10 @@
package pro.gravit.launcher.server.launch;
import pro.gravit.launcher.server.ServerWrapper;
public class ModuleLaunch implements Launch {
@Override
public void run(ServerWrapper.Config config, String[] args) throws Throwable {
throw new UnsupportedOperationException("Module system not supported");
}
}

View file

@ -0,0 +1,17 @@
package pro.gravit.launcher.server.launch;
import pro.gravit.launcher.server.ServerWrapper;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
public class SimpleLaunch implements Launch {
@Override
@SuppressWarnings("ConfusingArgumentToVarargsMethod")
public void run(ServerWrapper.Config config, String[] args) throws Throwable {
Class<?> mainClass = Class.forName(config.mainclass);
MethodHandle mainMethod = MethodHandles.lookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class));
mainMethod.invoke(args);
}
}

View file

@ -0,0 +1,70 @@
package pro.gravit.launcher.server.launch;
import pro.gravit.launcher.server.ServerWrapper;
import pro.gravit.utils.PublicURLClassLoader;
import pro.gravit.utils.helper.IOHelper;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.module.Configuration;
import java.lang.module.ModuleFinder;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
public class ModuleLaunch implements Launch {
@Override
@SuppressWarnings("ConfusingArgumentToVarargsMethod")
public void run(ServerWrapper.Config config, String[] args) throws Throwable {
URL[] urls = config.classpath.stream().map(Paths::get).map(IOHelper::toURL).toArray(URL[]::new);
ClassLoader ucl = new PublicURLClassLoader(urls);
// Create Module Layer
ModuleFinder finder = ModuleFinder.of(config.moduleConf.modulePath.stream().map(Paths::get).toArray(Path[]::new));
ModuleLayer bootLayer = ModuleLayer.boot();
Configuration configuration = bootLayer.configuration()
.resolveAndBind(ModuleFinder.of(), finder, config.moduleConf.modules);
ModuleLayer.Controller controller = ModuleLayer.defineModulesWithOneLoader(configuration, List.of(bootLayer), ucl);
ModuleLayer layer = controller.layer();
// Configure exports / opens
for(var e : config.moduleConf.exports.entrySet()) {
String[] split = e.getKey().split("\\\\");
Module source = layer.findModule(split[0]).orElseThrow();
String pkg = split[1];
Module target = layer.findModule(e.getValue()).orElseThrow();
controller.addExports(source, pkg, target);
}
for(var e : config.moduleConf.opens.entrySet()) {
String[] split = e.getKey().split("\\\\");
Module source = layer.findModule(split[0]).orElseThrow();
String pkg = split[1];
Module target = layer.findModule(e.getValue()).orElseThrow();
controller.addOpens(source, pkg, target);
}
for(var e : config.moduleConf.reads.entrySet()) {
Module source = layer.findModule(e.getKey()).orElseThrow();
Module target = layer.findModule(e.getValue()).orElseThrow();
controller.addReads(source, target);
}
Module mainModule = layer.findModule(config.moduleConf.mainModule).orElseThrow();
Module unnamed = ModuleLaunch.class.getClassLoader().getUnnamedModule();
if(unnamed != null) {
controller.addOpens(mainModule, getPackageFromClass(config.mainclass), unnamed);
}
// Start main class
ClassLoader loader = mainModule.getClassLoader();
Class<?> mainClass = Class.forName(config.mainclass, true, loader);
MethodHandle mainMethod = MethodHandles.lookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class));
mainMethod.invoke(args);
}
private static String getPackageFromClass(String clazz) {
int index = clazz.lastIndexOf(".");
if(index >= 0) {
return clazz.substring(0, index);
}
return clazz;
}
}

View file

@ -5,7 +5,7 @@
id 'org.openjfx.javafxplugin' version '0.0.10' apply false id 'org.openjfx.javafxplugin' version '0.0.10' apply false
} }
group = 'pro.gravit.launcher' group = 'pro.gravit.launcher'
version = '5.2.9' version = '5.2.10'
apply from: 'props.gradle' apply from: 'props.gradle'

Binary file not shown.

View file

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

@ -1 +1 @@
Subproject commit aea93d6803e4770f23ff4a2ea4b5f8752d053d8b Subproject commit 4319cabbeb0abbb1c6bc76f23c16b7902b2be500

View file

@ -1,20 +1,20 @@
project.ext { project.ext {
verAsm = '9.2' verAsm = '9.2'
verNetty = '4.1.70.Final' verNetty = '4.1.75.Final'
verOshiCore = '6.0.0' verOshiCore = '6.1.5'
verJunit = '5.8.2' verJunit = '5.8.2'
verGuavaC = '30.1.1-jre' verGuavaC = '30.1.1-jre'
verJansi = '2.3.4' verJansi = '2.4.0'
verJline = '3.21.0' verJline = '3.21.0'
verJwt = '0.11.2' verJwt = '0.11.2'
verBcprov = '1.70' verBcprov = '1.70'
verGson = '2.8.9' verGson = '2.9.0'
verBcpkix = '1.70' verBcpkix = '1.70'
verSlf4j = '1.7.32' verSlf4j = '1.7.36'
verLog4j = '2.17.1' verLog4j = '2.17.2'
verMySQLConn = '8.0.27' verMySQLConn = '8.0.28'
verPostgreSQLConn = '42.3.1' verPostgreSQLConn = '42.3.3'
verProguard = '7.2.0-beta2' verProguard = '7.2.1'
verLaunch4j = '3.14' verLaunch4j = '3.14'
verHibernate = '5.5.6.Final' verHibernate = '5.5.6.Final'
} }