mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-12-22 08:31:07 +03:00
Merge branch 'release/5.5.3'
This commit is contained in:
commit
6dadea1b67
35 changed files with 283 additions and 126 deletions
|
@ -108,7 +108,7 @@ public UserSession getUserSessionByOAuthAccessToken(String accessToken) throws O
|
|||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
return new SQLUserSession(user);
|
||||
return createSession(user);
|
||||
} catch (ExpiredJwtException e) {
|
||||
throw new OAuthAccessTokenExpired();
|
||||
} catch (JwtException e) {
|
||||
|
@ -133,13 +133,13 @@ public AuthManager.AuthReport refreshAccessToken(String refreshToken, AuthRespon
|
|||
return null;
|
||||
}
|
||||
var accessToken = LegacySessionHelper.makeAccessJwtTokenFromString(user, LocalDateTime.now(Clock.systemUTC()).plusSeconds(expireSeconds), server.keyAgreementManager.ecdsaPrivateKey);
|
||||
return new AuthManager.AuthReport(null, accessToken, refreshToken, SECONDS.toMillis(expireSeconds), new SQLUserSession(user));
|
||||
return new AuthManager.AuthReport(null, accessToken, refreshToken, SECONDS.toMillis(expireSeconds), createSession(user));
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthManager.AuthReport authorize(String login, AuthResponse.AuthContext context, AuthRequest.AuthPasswordInterface password, boolean minecraftAccess) throws IOException {
|
||||
SQLUser SQLUser = (SQLUser) getUserByLogin(login);
|
||||
if (SQLUser == null) {
|
||||
SQLUser user = (SQLUser) getUserByLogin(login);
|
||||
if (user == null) {
|
||||
throw AuthException.userNotFound();
|
||||
}
|
||||
if (context != null) {
|
||||
|
@ -147,16 +147,16 @@ public AuthManager.AuthReport authorize(String login, AuthResponse.AuthContext c
|
|||
if (plainPassword == null) {
|
||||
throw AuthException.wrongPassword();
|
||||
}
|
||||
if (!passwordVerifier.check(SQLUser.password, plainPassword.password)) {
|
||||
if (!passwordVerifier.check(user.password, plainPassword.password)) {
|
||||
throw AuthException.wrongPassword();
|
||||
}
|
||||
}
|
||||
SQLUserSession session = new SQLUserSession(SQLUser);
|
||||
var accessToken = LegacySessionHelper.makeAccessJwtTokenFromString(SQLUser, LocalDateTime.now(Clock.systemUTC()).plusSeconds(expireSeconds), server.keyAgreementManager.ecdsaPrivateKey);
|
||||
var refreshToken = SQLUser.username.concat(".").concat(LegacySessionHelper.makeRefreshTokenFromPassword(SQLUser.username, SQLUser.password, server.keyAgreementManager.legacySalt));
|
||||
SQLUserSession session = createSession(user);
|
||||
var accessToken = LegacySessionHelper.makeAccessJwtTokenFromString(user, LocalDateTime.now(Clock.systemUTC()).plusSeconds(expireSeconds), server.keyAgreementManager.ecdsaPrivateKey);
|
||||
var refreshToken = user.username.concat(".").concat(LegacySessionHelper.makeRefreshTokenFromPassword(user.username, user.password, server.keyAgreementManager.legacySalt));
|
||||
if (minecraftAccess) {
|
||||
String minecraftAccessToken = SecurityHelper.randomStringToken();
|
||||
updateAuth(SQLUser, minecraftAccessToken);
|
||||
updateAuth(user, minecraftAccessToken);
|
||||
return AuthManager.AuthReport.ofOAuthWithMinecraft(minecraftAccessToken, accessToken, refreshToken, SECONDS.toMillis(expireSeconds), session);
|
||||
} else {
|
||||
return AuthManager.AuthReport.ofOAuth(accessToken, refreshToken, SECONDS.toMillis(expireSeconds), session);
|
||||
|
@ -179,7 +179,7 @@ public User checkServer(Client client, String username, String serverID) throws
|
|||
public boolean joinServer(Client client, String username, UUID uuid, String accessToken, String serverID) throws IOException {
|
||||
SQLUser user = (SQLUser) client.getUser();
|
||||
if (user == null) return false;
|
||||
return user.getUsername().equals(username) && user.getAccessToken().equals(accessToken) && updateServerID(user, serverID);
|
||||
return (uuid == null ? user.getUsername().equals(username) : user.getUUID().equals(uuid)) && user.getAccessToken().equals(accessToken) && updateServerID(user, serverID);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -299,6 +299,10 @@ private List<String> queryPermissions(String sql, String value) throws SQLExcept
|
|||
}
|
||||
}
|
||||
|
||||
protected SQLUserSession createSession(SQLUser user) {
|
||||
return new SQLUserSession(user);
|
||||
}
|
||||
|
||||
public boolean isEnabledPermissions() {
|
||||
return permissionsPermissionColumn != null;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
import pro.gravit.launchserver.auth.core.interfaces.provider.AuthSupportGetAllUsers;
|
||||
import pro.gravit.launchserver.auth.core.interfaces.provider.AuthSupportHardware;
|
||||
import pro.gravit.launchserver.auth.core.interfaces.provider.AuthSupportRegistration;
|
||||
import pro.gravit.launchserver.auth.core.interfaces.user.UserSupportHardware;
|
||||
import pro.gravit.launchserver.manangers.AuthManager;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
||||
|
@ -176,28 +175,6 @@ public void invoke(String... args) throws Exception {
|
|||
}
|
||||
}
|
||||
});
|
||||
map.put("getuserhardware", new SubCommand("[username]", "get hardware by username") {
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
verifyArgs(args, 1);
|
||||
User user = getUserByUUID(UUID.fromString(args[0]));
|
||||
if (user == null) {
|
||||
logger.info("User {} not found", args[0]);
|
||||
}
|
||||
UserSupportHardware hardware = instance.fetchUserHardware(user);
|
||||
if (hardware == null) {
|
||||
logger.error("Method fetchUserHardware return null");
|
||||
return;
|
||||
}
|
||||
UserHardware userHardware = hardware.getHardware();
|
||||
if (userHardware == null) {
|
||||
logger.info("User {} not contains hardware info", args[0]);
|
||||
} else {
|
||||
logger.info("UserHardware: {}", userHardware);
|
||||
logger.info("HardwareInfo(JSON): {}", Launcher.gsonManager.gson.toJson(userHardware.getHardwareInfo()));
|
||||
}
|
||||
}
|
||||
});
|
||||
map.put("findmulti", new SubCommand("[hardware id]", "get all users in one hardware id") {
|
||||
@Override
|
||||
public void invoke(String... args) throws Exception {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import pro.gravit.launchserver.auth.SQLSourceConfig;
|
||||
import pro.gravit.launchserver.auth.core.interfaces.UserHardware;
|
||||
import pro.gravit.launchserver.auth.core.interfaces.provider.AuthSupportHardware;
|
||||
import pro.gravit.launchserver.auth.core.interfaces.user.UserSupportHardware;
|
||||
import pro.gravit.launchserver.auth.core.interfaces.session.UserSessionSupportHardware;
|
||||
import pro.gravit.utils.helper.IOHelper;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
@ -260,6 +260,34 @@ public void unbanHardware(UserHardware hardware) {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SQLUserSession createSession(SQLUser user) {
|
||||
return new MySQLUserSession(user);
|
||||
}
|
||||
|
||||
public class MySQLUserSession extends SQLUserSession implements UserSessionSupportHardware {
|
||||
private transient MySQLUser mySQLUser;
|
||||
protected transient MySQLUserHardware hardware;
|
||||
|
||||
public MySQLUserSession(SQLUser user) {
|
||||
super(user);
|
||||
mySQLUser = (MySQLUser) user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHardwareId() {
|
||||
return mySQLUser.hwidId == 0 ? null : String.valueOf(mySQLUser.hwidId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserHardware getHardware() {
|
||||
if(hardware == null) {
|
||||
hardware = (MySQLUserHardware) getHardwareInfoById(String.valueOf(mySQLUser.hwidId));
|
||||
}
|
||||
return hardware;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MySQLUserHardware implements UserHardware {
|
||||
private final HardwareReportRequest.HardwareInfo hardwareInfo;
|
||||
private final long id;
|
||||
|
@ -304,23 +332,14 @@ public String toString() {
|
|||
}
|
||||
}
|
||||
|
||||
public class MySQLUser extends SQLUser implements UserSupportHardware {
|
||||
public class MySQLUser extends SQLUser {
|
||||
protected long hwidId;
|
||||
protected transient MySQLUserHardware hardware;
|
||||
|
||||
public MySQLUser(UUID uuid, String username, String accessToken, String serverId, String password, ClientPermissions permissions, long hwidId) {
|
||||
super(uuid, username, accessToken, serverId, password, permissions);
|
||||
this.hwidId = hwidId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserHardware getHardware() {
|
||||
if (hardware != null) return hardware;
|
||||
MySQLUserHardware result = (MySQLUserHardware) getHardwareInfoById(String.valueOf(hwidId));
|
||||
hardware = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MySQLUser{" +
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import java.util.Set;
|
||||
|
||||
@Feature(GetAssetUploadUrlRequestEvent.FEATURE_NAME)
|
||||
public interface AuthSupportAssetUpload {
|
||||
public interface AuthSupportAssetUpload extends AuthSupport {
|
||||
String getAssetUploadUrl(String name, User user);
|
||||
|
||||
default AuthRequestEvent.OAuthRequestEvent getAssetUploadToken(String name, User user) {
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package pro.gravit.launchserver.auth.core.interfaces.provider;
|
||||
|
||||
import pro.gravit.launchserver.auth.core.User;
|
||||
import pro.gravit.launchserver.auth.core.UserSession;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface AuthSupportExtendedCheckServer {
|
||||
UserSession extendedCheckServer(Client client, String username, String serverID) throws IOException;
|
||||
}
|
|
@ -4,7 +4,6 @@
|
|||
import pro.gravit.launchserver.auth.core.User;
|
||||
import pro.gravit.launchserver.auth.core.UserSession;
|
||||
import pro.gravit.launchserver.auth.core.interfaces.UserHardware;
|
||||
import pro.gravit.launchserver.auth.core.interfaces.user.UserSupportHardware;
|
||||
import pro.gravit.launchserver.helper.DamerauHelper;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
@ -28,10 +27,6 @@ public interface AuthSupportHardware extends AuthSupport {
|
|||
|
||||
void unbanHardware(UserHardware hardware);
|
||||
|
||||
default UserSupportHardware fetchUserHardware(User user) {
|
||||
return (UserSupportHardware) user;
|
||||
}
|
||||
|
||||
default void normalizeHardwareInfo(HardwareReportRequest.HardwareInfo hardwareInfo) {
|
||||
if (hardwareInfo.baseboardSerialNumber != null)
|
||||
hardwareInfo.baseboardSerialNumber = hardwareInfo.baseboardSerialNumber.trim();
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
package pro.gravit.launchserver.auth.core.interfaces.provider;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface AuthSupportRemoteClientAccess {
|
||||
String getClientApiUrl();
|
||||
|
||||
List<String> getClientApiFeatures();
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package pro.gravit.launchserver.auth.core.interfaces.session;
|
||||
|
||||
import pro.gravit.launchserver.auth.core.interfaces.UserHardware;
|
||||
|
||||
public interface UserSessionSupportHardware {
|
||||
String getHardwareId();
|
||||
UserHardware getHardware();
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package pro.gravit.launchserver.auth.core.interfaces.session;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface UserSessionSupportProperties {
|
||||
Map<String, String> getProperties();
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
package pro.gravit.launchserver.auth.core.interfaces.user;
|
||||
|
||||
import pro.gravit.launchserver.auth.core.interfaces.UserHardware;
|
||||
|
||||
public interface UserSupportHardware {
|
||||
UserHardware getHardware();
|
||||
}
|
|
@ -124,6 +124,10 @@ public static ClientProfile makeProfile(ClientProfile.Version version, String ti
|
|||
builder.setMinJavaVersion(17);
|
||||
builder.setRecommendJavaVersion(17);
|
||||
}
|
||||
if(version.compareTo(ClientProfileVersions.MINECRAFT_1_20_3) >= 0) {
|
||||
builder.setMinJavaVersion(21);
|
||||
builder.setRecommendJavaVersion(21);
|
||||
}
|
||||
jvmArgs.add("-Dfml.ignorePatchDiscrepancies=true");
|
||||
jvmArgs.add("-Dfml.ignoreInvalidMinecraftCertificates=true");
|
||||
builder.setJvmArgs(jvmArgs);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
import pro.gravit.launchserver.auth.core.AuthCoreProvider;
|
||||
import pro.gravit.launchserver.auth.core.User;
|
||||
import pro.gravit.launchserver.auth.core.UserSession;
|
||||
import pro.gravit.launchserver.auth.core.interfaces.provider.AuthSupportExtendedCheckServer;
|
||||
import pro.gravit.launchserver.auth.core.interfaces.session.UserSessionSupportKeys;
|
||||
import pro.gravit.launchserver.auth.core.interfaces.user.UserSupportProperties;
|
||||
import pro.gravit.launchserver.auth.core.interfaces.user.UserSupportTextures;
|
||||
|
@ -161,9 +162,16 @@ public UserSessionSupportKeys.ClientProfileKeys createClientProfileKeys(UUID pla
|
|||
|
||||
public CheckServerReport checkServer(Client client, String username, String serverID) throws IOException {
|
||||
if (client.auth == null) return null;
|
||||
User user = client.auth.core.checkServer(client, username, serverID);
|
||||
if (user == null) return null;
|
||||
else return CheckServerReport.ofUser(user, getPlayerProfile(client.auth, user));
|
||||
var supportExtended = client.auth.core.isSupport(AuthSupportExtendedCheckServer.class);
|
||||
if(supportExtended != null) {
|
||||
var session = supportExtended.extendedCheckServer(client, username, serverID);
|
||||
if(session == null) return null;
|
||||
return CheckServerReport.ofUserSession(session, getPlayerProfile(client.auth, session.getUser()));
|
||||
} else {
|
||||
var user = client.auth.core.checkServer(client, username, serverID);
|
||||
if (user == null) return null;
|
||||
return CheckServerReport.ofUser(user, getPlayerProfile(client.auth, user));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean joinServer(Client client, String username, UUID uuid, String accessToken, String serverID) throws IOException {
|
||||
|
@ -322,20 +330,27 @@ public boolean accept(Client client, AuthProviderPair pair, String extendedToken
|
|||
public static class CheckServerReport {
|
||||
public UUID uuid;
|
||||
public User user;
|
||||
public UserSession session;
|
||||
public PlayerProfile playerProfile;
|
||||
|
||||
public CheckServerReport(UUID uuid, User user, PlayerProfile playerProfile) {
|
||||
public CheckServerReport(UUID uuid, User user, UserSession session, PlayerProfile playerProfile) {
|
||||
this.uuid = uuid;
|
||||
this.user = user;
|
||||
this.session = session;
|
||||
this.playerProfile = playerProfile;
|
||||
}
|
||||
|
||||
public static CheckServerReport ofUser(User user, PlayerProfile playerProfile) {
|
||||
return new CheckServerReport(user.getUUID(), user, playerProfile);
|
||||
return new CheckServerReport(user.getUUID(), user, null, playerProfile);
|
||||
}
|
||||
|
||||
public static CheckServerReport ofUserSession(UserSession session, PlayerProfile playerProfile) {
|
||||
var user = session.getUser();
|
||||
return new CheckServerReport(user.getUUID(), user, session, playerProfile);
|
||||
}
|
||||
|
||||
public static CheckServerReport ofUUID(UUID uuid, PlayerProfile playerProfile) {
|
||||
return new CheckServerReport(uuid, null, playerProfile);
|
||||
return new CheckServerReport(uuid, null, null, playerProfile);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
import org.apache.logging.log4j.Logger;
|
||||
import pro.gravit.launcher.events.request.CheckServerRequestEvent;
|
||||
import pro.gravit.launchserver.auth.AuthException;
|
||||
import pro.gravit.launchserver.auth.core.interfaces.session.UserSessionSupportHardware;
|
||||
import pro.gravit.launchserver.auth.core.interfaces.session.UserSessionSupportProperties;
|
||||
import pro.gravit.launchserver.manangers.AuthManager;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
|
@ -14,7 +16,8 @@ public class CheckServerResponse extends SimpleResponse {
|
|||
private transient final Logger logger = LogManager.getLogger();
|
||||
public String serverID;
|
||||
public String username;
|
||||
public String client;
|
||||
public boolean needHardware;
|
||||
public boolean needProperties;
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
|
@ -37,6 +40,15 @@ public void execute(ChannelHandlerContext ctx, Client pClient) {
|
|||
}
|
||||
result.playerProfile = report.playerProfile;
|
||||
result.uuid = report.uuid;
|
||||
if(report.session != null) {
|
||||
result.sessionId = report.session.getID();
|
||||
if(needProperties && report.session instanceof UserSessionSupportProperties supportProperties) {
|
||||
result.sessionProperties = supportProperties.getProperties();
|
||||
}
|
||||
if(needHardware && report.session instanceof UserSessionSupportHardware supportHardware) {
|
||||
result.hardwareId = supportHardware.getHardwareId();
|
||||
}
|
||||
}
|
||||
server.authHookManager.postCheckServerHook.hook(report, pClient);
|
||||
logger.debug("checkServer: {} uuid: {} serverID: {}", result.playerProfile == null ? null : result.playerProfile.username, result.uuid, serverID);
|
||||
} catch (AuthException | HookException e) {
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
import io.netty.channel.ChannelHandlerContext;
|
||||
import pro.gravit.launcher.events.request.GetAvailabilityAuthRequestEvent;
|
||||
import pro.gravit.launchserver.auth.AuthProviderPair;
|
||||
import pro.gravit.launchserver.auth.core.interfaces.provider.AuthSupportRemoteClientAccess;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.socket.response.SimpleResponse;
|
||||
|
||||
|
|
|
@ -105,7 +105,10 @@ public static boolean contains(String[] array, String value) {
|
|||
|
||||
public static void main(String... args) throws Throwable {
|
||||
JVMHelper.checkStackTrace(LauncherEngineWrapper.class);
|
||||
JVMHelper.verifySystemProperties(Launcher.class, true);
|
||||
JVMHelper.verifySystemProperties(Launcher.class, false);
|
||||
{
|
||||
LauncherEngine.checkClass(LauncherEngine.class.getClassLoader().getClass());
|
||||
}
|
||||
EnvHelper.checkDangerousParams();
|
||||
//if(!LauncherAgent.isStarted()) throw new SecurityException("JavaAgent not set");
|
||||
verifyNoAgent();
|
||||
|
|
|
@ -1,8 +1,42 @@
|
|||
package pro.gravit.launcher;
|
||||
|
||||
import pro.gravit.utils.helper.IOHelper;
|
||||
import pro.gravit.utils.launch.LaunchOptions;
|
||||
import pro.gravit.utils.launch.ModuleLaunch;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@LauncherNetworkAPI
|
||||
public class LauncherEngineWrapper {
|
||||
private static final List<String> modules = new ArrayList<>();
|
||||
|
||||
static {
|
||||
modules.add("javafx.base");
|
||||
modules.add("javafx.graphics");
|
||||
modules.add("javafx.fxml");
|
||||
modules.add("javafx.controls");
|
||||
modules.add("javafx.media");
|
||||
modules.add("javafx.web");
|
||||
}
|
||||
public static void main(String[] args) throws Throwable {
|
||||
LauncherEngine.main(args);
|
||||
ModuleLaunch launch = new ModuleLaunch();
|
||||
LaunchOptions options = new LaunchOptions();
|
||||
options.disablePackageDelegateSupport = true;
|
||||
options.moduleConf = new LaunchOptions.ModuleConf();
|
||||
List<Path> classpath = new ArrayList<>();
|
||||
classpath.add(IOHelper.getCodeSource(LauncherEngine.class));
|
||||
var libDirectory = Path.of(System.getProperty("java.home")).resolve("lib");
|
||||
for(var moduleName : modules) {
|
||||
var path = libDirectory.resolve(moduleName.concat(".jar"));
|
||||
if(Files.exists(path)) {
|
||||
options.moduleConf.modules.add(moduleName);
|
||||
options.moduleConf.modulePath.add(path.toAbsolutePath().toString());
|
||||
}
|
||||
}
|
||||
var control = launch.init(classpath, null, options);
|
||||
launch.launch(LauncherEngine.class.getName(), null, List.of(args));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ public void run(String[] args) {
|
|||
if(uuid == null) {
|
||||
if(accessToken != null) {
|
||||
Request.setOAuth(authId, new AuthRequestEvent.OAuthRequestEvent(accessToken, refreshToken, expire));
|
||||
Request.RequestRestoreReport report = Request.restore(true, false);
|
||||
Request.RequestRestoreReport report = Request.restore(true, false, true);
|
||||
permissions = report.userInfo.permissions;
|
||||
username = report.userInfo.playerProfile.username;
|
||||
uuid = report.userInfo.playerProfile.uuid.toString();
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import pro.gravit.launcher.ClientPermissions;
|
||||
import pro.gravit.launcher.profiles.ClientProfile;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class AuthService {
|
||||
|
@ -14,4 +15,12 @@ public class AuthService {
|
|||
public static boolean hasPermission(String permission) {
|
||||
return permissions.hasPerm(permission);
|
||||
}
|
||||
|
||||
public static boolean hasRole(String role) {
|
||||
return permissions.hasRole(role);
|
||||
}
|
||||
|
||||
public static List<String> getRoles() {
|
||||
return permissions.getRoles();
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package pro.gravit.launcher.api;
|
||||
|
||||
import pro.gravit.launcher.utils.ApiBridgeService;
|
||||
import pro.gravit.utils.helper.IOHelper;
|
||||
import pro.gravit.utils.helper.JVMHelper;
|
||||
import pro.gravit.utils.launch.ClassLoaderControl;
|
|
@ -0,0 +1,11 @@
|
|||
package pro.gravit.launcher.api;
|
||||
|
||||
public class ConfigService {
|
||||
public static boolean disableLogging;
|
||||
public static String serverName;
|
||||
public static CheckServerConfig checkServerConfig = new CheckServerConfig();
|
||||
public static class CheckServerConfig {
|
||||
public boolean needProperties;
|
||||
public boolean needHardware;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
package pro.gravit.launcher.api;
|
||||
|
||||
import java.security.interfaces.ECPublicKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
|
||||
public class KeyService {
|
||||
public static RSAPublicKey serverRsaPublicKey;
|
||||
public static ECPublicKey serverEcPublicKey;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import pro.gravit.launcher.events.RequestEvent;
|
||||
import pro.gravit.launcher.profiles.PlayerProfile;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
|
@ -14,6 +15,12 @@ public class CheckServerRequestEvent extends RequestEvent {
|
|||
public UUID uuid;
|
||||
@LauncherNetworkAPI
|
||||
public PlayerProfile playerProfile;
|
||||
@LauncherNetworkAPI
|
||||
public String sessionId;
|
||||
@LauncherNetworkAPI
|
||||
public String hardwareId;
|
||||
@LauncherNetworkAPI
|
||||
public Map<String, String> sessionProperties;
|
||||
|
||||
public CheckServerRequestEvent(PlayerProfile playerProfile) {
|
||||
this.playerProfile = playerProfile;
|
||||
|
|
|
@ -17,4 +17,5 @@ private ClientProfileVersions() {
|
|||
public static final ClientProfile.Version MINECRAFT_1_19 = ClientProfile.Version.of("1.19");
|
||||
public static final ClientProfile.Version MINECRAFT_1_20 = ClientProfile.Version.of("1.20");
|
||||
public static final ClientProfile.Version MINECRAFT_1_20_2 = ClientProfile.Version.of("1.20.2");
|
||||
public static final ClientProfile.Version MINECRAFT_1_20_3 = ClientProfile.Version.of("1.20.3");
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ public static synchronized void startAutoRefresh() {
|
|||
}
|
||||
executorService.scheduleAtFixedRate(() -> {
|
||||
try {
|
||||
restore(false, true);
|
||||
restore(false, true, false);
|
||||
} catch (Exception e) {
|
||||
LogHelper.error(e);
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ public static void reconnect() throws Exception {
|
|||
}
|
||||
|
||||
public static RequestRestoreReport restore() throws Exception {
|
||||
return restore(false, false);
|
||||
return restore(false, false, false);
|
||||
}
|
||||
|
||||
private synchronized static Map<String, String> getExpiredExtendedTokens() {
|
||||
|
@ -178,16 +178,22 @@ private synchronized static Map<String, String> getExpiredExtendedTokens() {
|
|||
return makeNewTokens(set);
|
||||
}
|
||||
|
||||
public static synchronized RequestRestoreReport restore(boolean needUserInfo, boolean refreshOnly) throws Exception {
|
||||
public static synchronized RequestRestoreReport restore(boolean needUserInfo, boolean refreshOnly, boolean noRefresh) throws Exception {
|
||||
boolean refreshed = false;
|
||||
RestoreRequest request;
|
||||
if (oauth != null) {
|
||||
if (isTokenExpired() || oauth.accessToken == null) {
|
||||
RefreshTokenRequest refreshRequest = new RefreshTokenRequest(authId, oauth.refreshToken);
|
||||
RefreshTokenRequestEvent event = refreshRequest.request();
|
||||
setOAuth(authId, event.oauth);
|
||||
refreshed = true;
|
||||
if(isTokenExpired() || oauth.accessToken == null) {
|
||||
if(noRefresh) {
|
||||
oauth = null;
|
||||
} else {
|
||||
RefreshTokenRequest refreshRequest = new RefreshTokenRequest(authId, oauth.refreshToken);
|
||||
RefreshTokenRequestEvent event = refreshRequest.request();
|
||||
setOAuth(authId, event.oauth);
|
||||
refreshed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (oauth != null) {
|
||||
request = new RestoreRequest(authId, oauth.accessToken, refreshOnly ? getExpiredExtendedTokens() : getStringExtendedTokens(), needUserInfo);
|
||||
} else {
|
||||
request = new RestoreRequest(authId, null, refreshOnly ? getExpiredExtendedTokens() : getStringExtendedTokens(), false);
|
||||
|
|
|
@ -11,6 +11,10 @@ public final class CheckServerRequest extends Request<CheckServerRequestEvent> i
|
|||
public final String username;
|
||||
@LauncherNetworkAPI
|
||||
public final String serverID;
|
||||
@LauncherNetworkAPI
|
||||
public boolean needHardware;
|
||||
@LauncherNetworkAPI
|
||||
public boolean needProperties;
|
||||
|
||||
|
||||
public CheckServerRequest(String username, String serverID) {
|
||||
|
@ -18,6 +22,13 @@ public CheckServerRequest(String username, String serverID) {
|
|||
this.serverID = VerifyHelper.verifyServerID(serverID);
|
||||
}
|
||||
|
||||
public CheckServerRequest(String username, String serverID, boolean needHardware, boolean needProperties) {
|
||||
this.username = username;
|
||||
this.serverID = VerifyHelper.verifyServerID(serverID);
|
||||
this.needHardware = needHardware;
|
||||
this.needProperties = needProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "checkServer";
|
||||
|
|
|
@ -124,7 +124,7 @@ private static void realMain(String[] args) throws Throwable {
|
|||
service = StdWebSocketService.initWebSockets(Launcher.getConfig().address).get();
|
||||
Request.setRequestService(service);
|
||||
LogHelper.debug("Restore sessions");
|
||||
Request.restore();
|
||||
Request.restore(false, false, true);
|
||||
service.registerEventHandler(new BasicLauncherEventHandler());
|
||||
((StdWebSocketService) service).reconnectCallback = () ->
|
||||
{
|
||||
|
@ -173,9 +173,14 @@ private static void realMain(String[] args) throws Throwable {
|
|||
if(profile.hasFlag(ClientProfile.CompatibilityFlags.CLASS_CONTROL_API)) {
|
||||
ClientService.classLoaderControl = classLoaderControl;
|
||||
}
|
||||
if(params.lwjglGlfwWayland) {
|
||||
String glfwPath = ClientService.findLibrary("glfw_wayland");
|
||||
System.setProperty("org.lwjgl.glfw.libname", glfwPath);
|
||||
}
|
||||
AuthService.username = params.playerProfile.username;
|
||||
AuthService.uuid = params.playerProfile.uuid;
|
||||
KeyService.serverRsaPublicKey = Launcher.getConfig().rsaPublicKey;
|
||||
KeyService.serverEcPublicKey = Launcher.getConfig().ecdsaPublicKey;
|
||||
modulesManager.invokeEvent(new ClientProcessReadyEvent(params));
|
||||
LogHelper.debug("Starting JVM and client WatchService");
|
||||
FileNameMatcher assetMatcher = profile.getAssetUpdateMatcher();
|
||||
|
|
|
@ -35,6 +35,7 @@ public class ClientParams {
|
|||
public boolean autoEnter;
|
||||
|
||||
public boolean fullScreen;
|
||||
public boolean lwjglGlfwWayland;
|
||||
|
||||
public int ram;
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ public final class Version implements Comparable<Version> {
|
|||
|
||||
public static final int MAJOR = 5;
|
||||
public static final int MINOR = 5;
|
||||
public static final int PATCH = 2;
|
||||
public static final int PATCH = 3;
|
||||
public static final int BUILD = 1;
|
||||
public static final Version.Type RELEASE = Type.STABLE;
|
||||
public final int major;
|
||||
|
|
|
@ -7,8 +7,13 @@
|
|||
import java.util.function.Consumer;
|
||||
|
||||
public class HackHelper {
|
||||
|
||||
private static native MethodHandles.Lookup createHackLookupNative(Class<?> lookupClass);
|
||||
private static MethodHandles.Lookup createHackLookupImpl(Class<?> lookupClass) {
|
||||
try {
|
||||
return createHackLookupNative(lookupClass);
|
||||
} catch (Throwable ignored) {
|
||||
|
||||
}
|
||||
try {
|
||||
Field trusted = MethodHandles.Lookup.class.getDeclaredField("TRUSTED");
|
||||
trusted.setAccessible(true);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
public class LaunchOptions {
|
||||
public boolean enableHacks;
|
||||
public boolean disablePackageDelegateSupport;
|
||||
public ModuleConf moduleConf;
|
||||
|
||||
|
||||
|
|
|
@ -18,10 +18,7 @@
|
|||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class ModuleLaunch implements Launch {
|
||||
|
@ -31,8 +28,10 @@ public class ModuleLaunch implements Launch {
|
|||
private ModuleFinder moduleFinder;
|
||||
private ModuleLayer layer;
|
||||
private MethodHandles.Lookup hackLookup;
|
||||
private boolean disablePackageDelegateSupport;
|
||||
@Override
|
||||
public ClassLoaderControl init(List<Path> files, String nativePath, LaunchOptions options) {
|
||||
this.disablePackageDelegateSupport = options.disablePackageDelegateSupport;
|
||||
moduleClassLoader = new ModuleClassLoader(files.stream().map((e) -> {
|
||||
try {
|
||||
return e.toUri().toURL();
|
||||
|
@ -121,6 +120,7 @@ public ClassLoaderControl init(List<Path> files, String nativePath, LaunchOption
|
|||
controller.addReads(source, target);
|
||||
}
|
||||
}
|
||||
moduleClassLoader.initializeWithLayer(layer);
|
||||
}
|
||||
}
|
||||
return moduleClassLoader.makeControl();
|
||||
|
@ -160,6 +160,7 @@ private class ModuleClassLoader extends URLClassLoader {
|
|||
private final ClassLoader SYSTEM_CLASS_LOADER = ClassLoader.getSystemClassLoader();
|
||||
private final List<ClassLoaderControl.ClassTransformer> transformers = new ArrayList<>();
|
||||
private final Map<String, Class<?>> classMap = new ConcurrentHashMap<>();
|
||||
private final Map<String, Module> packageToModule = new HashMap<>();
|
||||
private String nativePath;
|
||||
|
||||
private final List<String> packages = new ArrayList<>();
|
||||
|
@ -169,9 +170,17 @@ public ModuleClassLoader(URL[] urls, ClassLoader parent) {
|
|||
packages.add("pro.gravit.utils.");
|
||||
}
|
||||
|
||||
private void initializeWithLayer(ModuleLayer layer) {
|
||||
for(var m : layer.modules()) {
|
||||
for(var p : m.getPackages()) {
|
||||
packageToModule.put(p, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
|
||||
if(name != null) {
|
||||
if(name != null && !disablePackageDelegateSupport) {
|
||||
for(String pkg : packages) {
|
||||
if(name.startsWith(pkg)) {
|
||||
return SYSTEM_CLASS_LOADER.loadClass(name);
|
||||
|
@ -220,6 +229,17 @@ protected Class<?> findClass(String moduleName, String name) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if(clazz == null && layer != null && name != null) {
|
||||
var pkg = getPackageFromClass(name);
|
||||
var module = packageToModule.get(pkg);
|
||||
if(module != null) {
|
||||
try {
|
||||
clazz = module.getClassLoader().loadClass(name);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(clazz == null) {
|
||||
try {
|
||||
clazz = super.findClass(name);
|
||||
|
|
|
@ -129,31 +129,6 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep
|
|||
args.add(context.executePath.toAbsolutePath().toString());
|
||||
args.addAll(context.args);
|
||||
context.jvmProperties.forEach((key, value) -> args.add(String.format("-D%s=%s", key, value)));
|
||||
if (context.javaVersion.version >= 9) {
|
||||
context.javaFXPaths.add(context.javaVersion.jvmDir);
|
||||
context.javaFXPaths.add(context.javaVersion.jvmDir.resolve("jre"));
|
||||
Path openjfxPath = JavaHelper.tryGetOpenJFXPath(context.javaVersion.jvmDir);
|
||||
if (openjfxPath != null) {
|
||||
context.javaFXPaths.add(openjfxPath);
|
||||
}
|
||||
StringBuilder modulesPath = new StringBuilder();
|
||||
StringBuilder modulesAdd = new StringBuilder();
|
||||
for (String moduleName : context.jvmModules) {
|
||||
boolean success = JavaHelper.tryAddModule(context.javaFXPaths, moduleName, modulesPath);
|
||||
if (success) {
|
||||
if (modulesAdd.length() > 0) modulesAdd.append(",");
|
||||
modulesAdd.append(moduleName);
|
||||
}
|
||||
}
|
||||
if (modulesAdd.length() > 0) {
|
||||
args.add("--add-modules");
|
||||
args.add(modulesAdd.toString());
|
||||
}
|
||||
if (modulesPath.length() > 0) {
|
||||
args.add("--module-path");
|
||||
args.add(modulesPath.toString());
|
||||
}
|
||||
}
|
||||
if (context.memoryLimit != 0) {
|
||||
args.add(String.format("-Xmx%dM", context.memoryLimit));
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
import pro.gravit.launcher.ClientPermissions;
|
||||
import pro.gravit.launcher.Launcher;
|
||||
import pro.gravit.launcher.LauncherConfig;
|
||||
import pro.gravit.launcher.api.AuthService;
|
||||
import pro.gravit.launcher.api.ClientService;
|
||||
import pro.gravit.launcher.api.ConfigService;
|
||||
import pro.gravit.launcher.api.KeyService;
|
||||
import pro.gravit.launcher.config.JsonConfigurable;
|
||||
import pro.gravit.launcher.events.request.AuthRequestEvent;
|
||||
|
@ -39,11 +42,7 @@ public class ServerWrapper extends JsonConfigurable<ServerWrapper.Config> {
|
|||
public static ServerWrapper wrapper;
|
||||
public static ClassLoaderControl classLoaderControl;
|
||||
public Config config;
|
||||
public PublicURLClassLoader ucp;
|
||||
public ClassLoader loader;
|
||||
public ClientPermissions permissions;
|
||||
public ClientProfile profile;
|
||||
public PlayerProfile playerProfile;
|
||||
public ClientProfile.ServerProfile serverProfile;
|
||||
|
||||
public ServerWrapper(Type type, Path configPath) {
|
||||
|
@ -69,7 +68,14 @@ public void restore() throws Exception {
|
|||
if(config.extendedTokens != null) {
|
||||
Request.addAllExtendedToken(config.extendedTokens);
|
||||
}
|
||||
Request.restore();
|
||||
Request.RequestRestoreReport report = Request.restore(config.oauth != null, false, false);
|
||||
if(report.userInfo != null) {
|
||||
if(report.userInfo.playerProfile != null) {
|
||||
AuthService.username = report.userInfo.playerProfile.username;
|
||||
AuthService.uuid = report.userInfo.playerProfile.uuid;
|
||||
}
|
||||
AuthService.permissions = report.userInfo.permissions;
|
||||
}
|
||||
}
|
||||
|
||||
public void getProfiles() throws Exception {
|
||||
|
@ -82,6 +88,7 @@ public void getProfiles() throws Exception {
|
|||
this.serverProfile = srv;
|
||||
this.profile = p;
|
||||
Launcher.profile = p;
|
||||
AuthService.profile = p;
|
||||
LogHelper.debug("Found profile: %s", Launcher.profile.getTitle());
|
||||
isFound = true;
|
||||
break;
|
||||
|
@ -144,6 +151,9 @@ public void run(String... args) throws Throwable {
|
|||
if(config.encodedServerRsaPublicKey != null) {
|
||||
KeyService.serverRsaPublicKey = SecurityHelper.toPublicRSAKey(config.encodedServerRsaPublicKey);
|
||||
}
|
||||
if(config.encodedServerEcPublicKey != null) {
|
||||
KeyService.serverEcPublicKey = SecurityHelper.toPublicECDSAKey(config.encodedServerEcPublicKey);
|
||||
}
|
||||
String classname = (config.mainclass == null || config.mainclass.isEmpty()) ? args[0] : config.mainclass;
|
||||
if (classname.length() == 0) {
|
||||
LogHelper.error("MainClass not found. Please set MainClass for ServerWrapper.json or first commandline argument");
|
||||
|
@ -192,6 +202,16 @@ public void run(String... args) throws Throwable {
|
|||
options.enableHacks = config.enableHacks;
|
||||
options.moduleConf = config.moduleConf;
|
||||
classLoaderControl = launch.init(config.classpath.stream().map(Paths::get).collect(Collectors.toCollection(ArrayList::new)), config.nativesDir, options);
|
||||
if(ServerAgent.isAgentStarted()) {
|
||||
ClientService.instrumentation = ServerAgent.inst;
|
||||
}
|
||||
ClientService.classLoaderControl = classLoaderControl;
|
||||
ClientService.baseURLs = classLoaderControl.getURLs();
|
||||
ClientService.nativePath = config.nativesDir;
|
||||
ConfigService.serverName = config.serverName;
|
||||
if(config.configServiceSettings != null) {
|
||||
config.configServiceSettings.apply();
|
||||
}
|
||||
LogHelper.info("Start Minecraft Server");
|
||||
LogHelper.debug("Invoke main method %s with %s", classname, launch.getClass().getName());
|
||||
try {
|
||||
|
@ -267,5 +287,17 @@ public static final class Config {
|
|||
public boolean enableHacks;
|
||||
|
||||
public Map<String, String> properties;
|
||||
public ConfigServiceSettings configServiceSettings = new ConfigServiceSettings();
|
||||
|
||||
public static class ConfigServiceSettings {
|
||||
public boolean disableLogging = false;
|
||||
public boolean checkServerNeedProperties = false;
|
||||
public boolean checkServerNeedHardware = false;
|
||||
public void apply() {
|
||||
ConfigService.disableLogging = disableLogging;
|
||||
ConfigService.checkServerConfig.needHardware = checkServerNeedHardware;
|
||||
ConfigService.checkServerConfig.needProperties = checkServerNeedProperties;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
id 'org.openjfx.javafxplugin' version '0.0.10' apply false
|
||||
}
|
||||
group = 'pro.gravit.launcher'
|
||||
version = '5.5.2'
|
||||
version = '5.5.3'
|
||||
|
||||
apply from: 'props.gradle'
|
||||
|
||||
|
|
2
modules
2
modules
|
@ -1 +1 @@
|
|||
Subproject commit a70de3865daff53f44fb93cb6c80df99e3cdc0a1
|
||||
Subproject commit 7581b6c01470a5ec32ac67170635d10f6f589b0a
|
Loading…
Reference in a new issue