mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-12-22 08:31:07 +03:00
Merge branch 'release/5.6.2'
This commit is contained in:
commit
79fc42e86a
30 changed files with 1199 additions and 257 deletions
|
@ -70,20 +70,23 @@
|
|||
|
||||
dependencies {
|
||||
pack project(':LauncherAPI')
|
||||
bundle group: 'me.tongfei', name: 'progressbar', version: '0.9.2'
|
||||
bundle group: 'com.github.Marcono1234', name: 'gson-record-type-adapter-factory', version: 'v0.2.0'
|
||||
bundle group: 'me.tongfei', name: 'progressbar', version: '0.10.1'
|
||||
bundle group: 'com.github.Marcono1234', name: 'gson-record-type-adapter-factory', version: 'v0.3.0'
|
||||
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-reader', version: rootProject['verJline']
|
||||
bundle group: 'org.jline', name: 'jline-terminal', version: rootProject['verJline']
|
||||
bundle group: 'org.bouncycastle', name: 'bcpkix-jdk15on', version: rootProject['verBcpkix']
|
||||
bundle group: 'org.bouncycastle', name: 'bcprov-jdk18on', version: rootProject['verBcpkix']
|
||||
bundle group: 'org.bouncycastle', name: 'bcpkix-jdk18on', version: rootProject['verBcpkix']
|
||||
bundle group: 'org.ow2.asm', name: 'asm-commons', version: rootProject['verAsm']
|
||||
bundle group: 'io.netty', name: 'netty-codec-http', version: rootProject['verNetty']
|
||||
bundle group: 'io.netty', name: 'netty-transport-classes-epoll', version: rootProject['verNetty']
|
||||
bundle group: 'io.netty', name: 'netty-transport-native-epoll', version: rootProject['verNetty'], classifier: 'linux-x86_64'
|
||||
bundle group: 'org.slf4j', name: 'slf4j-api', version: rootProject['verSlf4j']
|
||||
bundle group: 'com.mysql', name: 'mysql-connector-j', version: rootProject['verMySQLConn']
|
||||
bundle group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: rootProject['verMariaDBConn']
|
||||
bundle group: 'org.postgresql', name: 'postgresql', version: rootProject['verPostgreSQLConn']
|
||||
bundle group: 'com.h2database', name: 'h2', version: rootProject['verH2Conn']
|
||||
bundle group: 'com.guardsquare', name: 'proguard-base', version: rootProject['verProguard']
|
||||
bundle group: 'org.apache.logging.log4j', name: 'log4j-core', version: rootProject['verLog4j']
|
||||
bundle group: 'org.apache.logging.log4j', name: 'log4j-slf4j2-impl', version: rootProject['verLog4j']
|
||||
|
|
|
@ -18,8 +18,9 @@
|
|||
import java.util.stream.Stream;
|
||||
|
||||
public class Main {
|
||||
private static final List<String> classpathOnly = List.of("proguard", "jline", "kotlin", "epoll");
|
||||
private static final List<String> classpathOnly = List.of("proguard", "jline", "progressbar", "kotlin", "epoll");
|
||||
private static final String LOG4J_PROPERTY = "log4j2.configurationFile";
|
||||
private static final String DEBUG_PROPERTY = "launchserver.main.debug";
|
||||
private static boolean isClasspathOnly(Path path) {
|
||||
var fileName = path.getFileName().toString();
|
||||
for(var e : classpathOnly) {
|
||||
|
@ -78,6 +79,14 @@ public static void main(String[] args) throws Throwable {
|
|||
ModuleLayer.Controller controller = (ModuleLayer.Controller) control.getJava9ModuleController();
|
||||
LaunchServerControlHolder.setControl(control);
|
||||
LaunchServerControlHolder.setController(controller);
|
||||
if(Boolean.getBoolean(DEBUG_PROPERTY)) {
|
||||
for(var e : controller.layer().modules()) {
|
||||
System.out.printf("Module %s\n", e.getName());
|
||||
for(var p : e.getPackages()) {
|
||||
System.out.printf("Package %s\n", p);
|
||||
}
|
||||
}
|
||||
}
|
||||
launch.launch("pro.gravit.launchserver.LaunchServerStarter", null, Arrays.asList(args));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,10 @@ public AuthException(String message) {
|
|||
super(message);
|
||||
}
|
||||
|
||||
public AuthException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public static AuthException need2FA() {
|
||||
return new AuthException(AuthRequestEvent.TWO_FACTOR_NEED_ERROR_MESSAGE);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package pro.gravit.launchserver.auth;
|
||||
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Properties;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class HikariSQLSourceConfig implements SQLSourceConfig {
|
||||
private transient HikariDataSource dataSource;
|
||||
private String dsClass;
|
||||
private Properties dsProps;
|
||||
private String driverClass;
|
||||
private String jdbcUrl;
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
public void init() {
|
||||
if (dataSource != null) {
|
||||
return;
|
||||
}
|
||||
HikariConfig config = new HikariConfig();
|
||||
consumeIfNotNull(config::setDataSourceClassName, dsClass);
|
||||
consumeIfNotNull(config::setDataSourceProperties, dsProps);
|
||||
consumeIfNotNull(config::setDriverClassName, driverClass);
|
||||
consumeIfNotNull(config::setJdbcUrl, jdbcUrl);
|
||||
consumeIfNotNull(config::setUsername, username);
|
||||
consumeIfNotNull(config::setPassword, password);
|
||||
|
||||
this.dataSource = new HikariDataSource(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() throws SQLException {
|
||||
return dataSource.getConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
dataSource.close();
|
||||
}
|
||||
|
||||
private static <T> void consumeIfNotNull(Consumer<T> consumer, T val) {
|
||||
if (val != null) {
|
||||
consumer.accept(val);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,6 +21,7 @@
|
|||
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.provider.AuthSupportSudo;
|
||||
import pro.gravit.launchserver.auth.core.openid.OpenIDAuthCoreProvider;
|
||||
import pro.gravit.launchserver.manangers.AuthManager;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
||||
|
@ -53,6 +54,8 @@ public static void registerProviders() {
|
|||
providers.register("postgresql", PostgresSQLCoreProvider.class);
|
||||
providers.register("memory", MemoryAuthCoreProvider.class);
|
||||
providers.register("merge", MergeAuthCoreProvider.class);
|
||||
providers.register("openid", OpenIDAuthCoreProvider.class);
|
||||
providers.register("sql", SQLCoreProvider.class);
|
||||
registredProviders = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package pro.gravit.launchserver.auth.core;
|
||||
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.auth.AuthProviderPair;
|
||||
import pro.gravit.launchserver.auth.HikariSQLSourceConfig;
|
||||
import pro.gravit.launchserver.auth.SQLSourceConfig;
|
||||
|
||||
public class SQLCoreProvider extends AbstractSQLCoreProvider {
|
||||
public HikariSQLSourceConfig holder;
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
super.close();
|
||||
holder.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(LaunchServer server, AuthProviderPair pair) {
|
||||
holder.init();
|
||||
super.init(server, pair);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLSourceConfig getSQLConfig() {
|
||||
return holder;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package pro.gravit.launchserver.auth.core.openid;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public record AccessTokenResponse(@SerializedName("access_token") String accessToken,
|
||||
@SerializedName("expires_in") Long expiresIn,
|
||||
@SerializedName("refresh_expires_in") Long refreshExpiresIn,
|
||||
@SerializedName("refresh_token") String refreshToken,
|
||||
@SerializedName("token_type") String tokenType,
|
||||
@SerializedName("id_token") String idToken,
|
||||
@SerializedName("not-before-policy") Integer notBeforePolicy,
|
||||
@SerializedName("session_state") String sessionState,
|
||||
@SerializedName("scope") String scope) {
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
package pro.gravit.launchserver.auth.core.openid;
|
||||
|
||||
import io.jsonwebtoken.JwtException;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import pro.gravit.launcher.base.ClientPermissions;
|
||||
import pro.gravit.launcher.base.events.request.GetAvailabilityAuthRequestEvent;
|
||||
import pro.gravit.launcher.base.request.auth.AuthRequest;
|
||||
import pro.gravit.launcher.base.request.auth.password.AuthCodePassword;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.auth.AuthException;
|
||||
import pro.gravit.launchserver.auth.AuthProviderPair;
|
||||
import pro.gravit.launchserver.auth.HikariSQLSourceConfig;
|
||||
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.manangers.AuthManager;
|
||||
import pro.gravit.launchserver.socket.Client;
|
||||
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class OpenIDAuthCoreProvider extends AuthCoreProvider {
|
||||
private transient SQLUserStore sqlUserStore;
|
||||
private transient SQLServerSessionStore sqlSessionStore;
|
||||
private transient OpenIDAuthenticator openIDAuthenticator;
|
||||
|
||||
private OpenIDConfig openIDConfig;
|
||||
private HikariSQLSourceConfig sqlSourceConfig;
|
||||
|
||||
@Override
|
||||
public List<GetAvailabilityAuthRequestEvent.AuthAvailabilityDetails> getDetails(Client client) {
|
||||
return openIDAuthenticator.getDetails();
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUserByUsername(String username) {
|
||||
return sqlUserStore.getByUsername(username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUserByUUID(UUID uuid) {
|
||||
return sqlUserStore.getUserByUUID(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserSession getUserSessionByOAuthAccessToken(String accessToken) throws OAuthAccessTokenExpired {
|
||||
return openIDAuthenticator.getUserSessionByOAuthAccessToken(accessToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthManager.AuthReport refreshAccessToken(String oldRefreshToken, AuthResponse.AuthContext context) {
|
||||
var tokens = openIDAuthenticator.refreshAccessToken(oldRefreshToken);
|
||||
var accessToken = tokens.accessToken();
|
||||
var refreshToken = tokens.refreshToken();
|
||||
long expiresIn = TimeUnit.SECONDS.toMillis(tokens.accessTokenExpiresIn());
|
||||
|
||||
UserSession session;
|
||||
try {
|
||||
session = openIDAuthenticator.getUserSessionByOAuthAccessToken(accessToken);
|
||||
} catch (OAuthAccessTokenExpired e) {
|
||||
throw new RuntimeException("invalid token", e);
|
||||
}
|
||||
|
||||
|
||||
return AuthManager.AuthReport.ofOAuth(accessToken, refreshToken,
|
||||
expiresIn, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthManager.AuthReport authorize(String login, AuthResponse.AuthContext context, AuthRequest.AuthPasswordInterface password, boolean minecraftAccess) throws IOException {
|
||||
if (password == null) {
|
||||
throw AuthException.wrongPassword();
|
||||
}
|
||||
var authCodePassword = (AuthCodePassword) password;
|
||||
|
||||
var tokens = openIDAuthenticator.authorize(authCodePassword);
|
||||
|
||||
var accessToken = tokens.accessToken();
|
||||
var refreshToken = tokens.refreshToken();
|
||||
var user = openIDAuthenticator.createUserFromToken(accessToken);
|
||||
long expiresIn = TimeUnit.SECONDS.toMillis(tokens.accessTokenExpiresIn());
|
||||
|
||||
sqlUserStore.createOrUpdateUser(user);
|
||||
|
||||
UserSession session;
|
||||
try {
|
||||
session = openIDAuthenticator.getUserSessionByOAuthAccessToken(accessToken);
|
||||
} catch (OAuthAccessTokenExpired e) {
|
||||
throw new AuthException("invalid token", e);
|
||||
}
|
||||
|
||||
if (minecraftAccess) {
|
||||
var minecraftToken = generateMinecraftToken(user);
|
||||
return AuthManager.AuthReport.ofOAuthWithMinecraft(minecraftToken, accessToken, refreshToken,
|
||||
expiresIn, session);
|
||||
} else {
|
||||
return AuthManager.AuthReport.ofOAuth(accessToken, refreshToken,
|
||||
expiresIn, session);
|
||||
}
|
||||
}
|
||||
|
||||
private String generateMinecraftToken(User user) {
|
||||
return Jwts.builder()
|
||||
.issuer("LaunchServer")
|
||||
.subject(user.getUUID().toString())
|
||||
.claim("preferred_username", user.getUsername())
|
||||
.expiration(Date.from(Instant.now().plus(24, ChronoUnit.HOURS)))
|
||||
.signWith(server.keyAgreementManager.ecdsaPrivateKey)
|
||||
.compact();
|
||||
}
|
||||
|
||||
private User createUserFromMinecraftToken(String accessToken) throws AuthException {
|
||||
try {
|
||||
var parser = Jwts.parser()
|
||||
.requireIssuer("LaunchServer")
|
||||
.verifyWith(server.keyAgreementManager.ecdsaPublicKey)
|
||||
.build();
|
||||
var claims = parser.parseSignedClaims(accessToken);
|
||||
var username = claims.getPayload().get("preferred_username", String.class);
|
||||
var uuid = UUID.fromString(claims.getPayload().getSubject());
|
||||
return new UserEntity(username, uuid, new ClientPermissions());
|
||||
} catch (JwtException e) {
|
||||
throw new AuthException("Bad minecraft token", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(LaunchServer server, AuthProviderPair pair) {
|
||||
super.init(server, pair);
|
||||
this.sqlSourceConfig.init();
|
||||
this.sqlUserStore = new SQLUserStore(sqlSourceConfig);
|
||||
this.sqlUserStore.init();
|
||||
this.sqlSessionStore = new SQLServerSessionStore(sqlSourceConfig);
|
||||
this.sqlSessionStore.init();
|
||||
this.openIDAuthenticator = new OpenIDAuthenticator(openIDConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User checkServer(Client client, String username, String serverID) throws IOException {
|
||||
var savedServerId = sqlSessionStore.getServerIdByUsername(username);
|
||||
if (!serverID.equals(savedServerId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return sqlUserStore.getByUsername(username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean joinServer(Client client, String username, UUID uuid, String accessToken, String serverID) throws IOException {
|
||||
User user;
|
||||
try {
|
||||
user = createUserFromMinecraftToken(accessToken);
|
||||
} catch (AuthException e) {
|
||||
LogHelper.error(e);
|
||||
return false;
|
||||
}
|
||||
if (!user.getUUID().equals(uuid)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sqlUserStore.createOrUpdateUser(user);
|
||||
|
||||
return sqlSessionStore.joinServer(user.getUUID(), user.getUsername(), serverID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
sqlSourceConfig.close();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,232 @@
|
|||
package pro.gravit.launchserver.auth.core.openid;
|
||||
|
||||
import io.jsonwebtoken.*;
|
||||
import io.jsonwebtoken.security.Jwk;
|
||||
import io.jsonwebtoken.security.JwkSet;
|
||||
import io.jsonwebtoken.security.Jwks;
|
||||
import pro.gravit.launcher.base.ClientPermissions;
|
||||
import pro.gravit.launcher.base.Launcher;
|
||||
import pro.gravit.launcher.base.events.request.GetAvailabilityAuthRequestEvent;
|
||||
import pro.gravit.launcher.base.request.auth.details.AuthWebViewDetails;
|
||||
import pro.gravit.launcher.base.request.auth.password.AuthCodePassword;
|
||||
import pro.gravit.launchserver.auth.AuthException;
|
||||
import pro.gravit.launchserver.auth.core.AuthCoreProvider;
|
||||
import pro.gravit.launchserver.auth.core.User;
|
||||
import pro.gravit.launchserver.auth.core.UserSession;
|
||||
import pro.gravit.utils.helper.CommonHelper;
|
||||
import pro.gravit.utils.helper.QueryHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.security.Key;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class OpenIDAuthenticator {
|
||||
private static final HttpClient CLIENT = HttpClient.newBuilder().build();
|
||||
private final OpenIDConfig openIDConfig;
|
||||
private final JwtParser jwtParser;
|
||||
|
||||
public OpenIDAuthenticator(OpenIDConfig openIDConfig) {
|
||||
this.openIDConfig = openIDConfig;
|
||||
var keyLocator = loadKeyLocator(openIDConfig);
|
||||
this.jwtParser = Jwts.parser()
|
||||
.keyLocator(keyLocator)
|
||||
.requireIssuer(openIDConfig.issuer())
|
||||
.require("azp", openIDConfig.clientId())
|
||||
.build();
|
||||
}
|
||||
|
||||
public List<GetAvailabilityAuthRequestEvent.AuthAvailabilityDetails> getDetails() {
|
||||
var state = UUID.randomUUID().toString();
|
||||
var uri = QueryBuilder.get(openIDConfig.authorizationEndpoint())
|
||||
.addQuery("response_type", "code")
|
||||
.addQuery("client_id", openIDConfig.clientId())
|
||||
.addQuery("redirect_uri", openIDConfig.redirectUri())
|
||||
.addQuery("scope", openIDConfig.scopes())
|
||||
.addQuery("state", state)
|
||||
.toUriString();
|
||||
|
||||
return List.of(new AuthWebViewDetails(uri, openIDConfig.redirectUri()));
|
||||
}
|
||||
|
||||
public TokenResponse refreshAccessToken(String oldRefreshToken) {
|
||||
var postBody = QueryBuilder.post()
|
||||
.addQuery("grant_type", "refresh_token")
|
||||
.addQuery("refresh_token", oldRefreshToken)
|
||||
.addQuery("client_id", openIDConfig.clientId())
|
||||
.addQuery("client_secret", openIDConfig.clientSecret())
|
||||
.toString();
|
||||
|
||||
var accessTokenResponse = requestToken(postBody);
|
||||
var accessToken = accessTokenResponse.accessToken();
|
||||
var refreshToken = accessTokenResponse.refreshToken();
|
||||
|
||||
try {
|
||||
readAndVerifyToken(accessToken);
|
||||
} catch (AuthException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
var accessTokenExpiresIn = Objects.requireNonNullElse(accessTokenResponse.expiresIn(), 0L);
|
||||
var refreshTokenExpiresIn = Objects.requireNonNullElse(accessTokenResponse.refreshExpiresIn(), 0L);
|
||||
|
||||
return new TokenResponse(accessToken, accessTokenExpiresIn,
|
||||
refreshToken, refreshTokenExpiresIn);
|
||||
}
|
||||
|
||||
public UserSession getUserSessionByOAuthAccessToken(String accessToken) throws AuthCoreProvider.OAuthAccessTokenExpired {
|
||||
Jws<Claims> token;
|
||||
try {
|
||||
token = readAndVerifyToken(accessToken);
|
||||
} catch (AuthException e) {
|
||||
throw new AuthCoreProvider.OAuthAccessTokenExpired("Can't read token", e);
|
||||
}
|
||||
var user = createUserFromToken(token);
|
||||
long expiresIn = 0;
|
||||
var expDate = token.getPayload().getExpiration();
|
||||
if (expDate != null) {
|
||||
expiresIn = expDate.toInstant().toEpochMilli();
|
||||
}
|
||||
|
||||
return new OpenIDUserSession(user, accessToken, expiresIn);
|
||||
}
|
||||
|
||||
public TokenResponse authorize(AuthCodePassword authCode) throws IOException {
|
||||
var uri = URI.create(authCode.uri);
|
||||
var queries = QueryHelper.splitUriQuery(uri);
|
||||
|
||||
String code = CommonHelper.multimapFirstOrNullValue("code", queries);
|
||||
String error = CommonHelper.multimapFirstOrNullValue("error", queries);
|
||||
String errorDescription = CommonHelper.multimapFirstOrNullValue("error_description", queries);
|
||||
|
||||
if (error != null && !error.isBlank()) {
|
||||
throw new AuthException("Auth error. Error: %s, description: %s".formatted(error, errorDescription));
|
||||
}
|
||||
|
||||
|
||||
var postBody = QueryBuilder.post()
|
||||
.addQuery("grant_type", "authorization_code")
|
||||
.addQuery("code", code)
|
||||
.addQuery("redirect_uri", openIDConfig.redirectUri())
|
||||
.addQuery("client_id", openIDConfig.clientId())
|
||||
.addQuery("client_secret", openIDConfig.clientSecret())
|
||||
.toString();
|
||||
|
||||
var accessTokenResponse = requestToken(postBody);
|
||||
var accessToken = accessTokenResponse.accessToken();
|
||||
var refreshToken = accessTokenResponse.refreshToken();
|
||||
|
||||
readAndVerifyToken(accessToken);
|
||||
|
||||
var accessTokenExpiresIn = Objects.requireNonNullElse(accessTokenResponse.expiresIn(), 0L);
|
||||
var refreshTokenExpiresIn = Objects.requireNonNullElse(accessTokenResponse.refreshExpiresIn(), 0L);
|
||||
|
||||
return new TokenResponse(accessToken, accessTokenExpiresIn,
|
||||
refreshToken, refreshTokenExpiresIn);
|
||||
}
|
||||
|
||||
public User createUserFromToken(String accessToken) throws AuthException {
|
||||
return createUserFromToken(readAndVerifyToken(accessToken));
|
||||
}
|
||||
|
||||
private Jws<Claims> readAndVerifyToken(String accessToken) throws AuthException {
|
||||
if (accessToken == null) {
|
||||
throw new AuthException("Token is null");
|
||||
}
|
||||
|
||||
try {
|
||||
return jwtParser.parseSignedClaims(accessToken);
|
||||
} catch (JwtException e) {
|
||||
throw new AuthException("Bad token", e);
|
||||
}
|
||||
}
|
||||
|
||||
private User createUserFromToken(Jws<Claims> token) {
|
||||
var username = token.getPayload().get(openIDConfig.extractorConfig().usernameClaim(), String.class);
|
||||
var uuidStr = token.getPayload().get(openIDConfig.extractorConfig().uuidClaim(), String.class);
|
||||
var uuid = UUID.fromString(uuidStr);
|
||||
return new UserEntity(username, uuid, new ClientPermissions());
|
||||
}
|
||||
|
||||
private AccessTokenResponse requestToken(String postBody) {
|
||||
var request = HttpRequest.newBuilder()
|
||||
.uri(openIDConfig.tokenUri())
|
||||
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||
.header("Accept", "application/json")
|
||||
.POST(HttpRequest.BodyPublishers.ofString(postBody))
|
||||
.build();
|
||||
|
||||
HttpResponse<String> resp;
|
||||
try {
|
||||
resp = CLIENT.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
} catch (IOException | InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return Launcher.gsonManager.gson.fromJson(resp.body(), AccessTokenResponse.class);
|
||||
}
|
||||
|
||||
private static KeyLocator loadKeyLocator(OpenIDConfig openIDConfig) {
|
||||
var request = HttpRequest.newBuilder(openIDConfig.jwksUri()).GET().build();
|
||||
HttpResponse<String> response;
|
||||
try {
|
||||
response = CLIENT.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
} catch (IOException | InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
var jwks = Jwks.setParser().build().parse(response.body());
|
||||
return new KeyLocator(jwks);
|
||||
}
|
||||
|
||||
private static class KeyLocator extends LocatorAdapter<Key> {
|
||||
private final Map<String, Key> keys;
|
||||
|
||||
public KeyLocator(JwkSet jwks) {
|
||||
this.keys = jwks.getKeys().stream().collect(
|
||||
Collectors.toMap(jwk -> String.valueOf(jwk.get("kid")), Jwk::toKey));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Key locate(JweHeader header) {
|
||||
return super.locate(header);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Key locate(JwsHeader header) {
|
||||
return keys.get(header.getKeyId());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Key doLocate(Header header) {
|
||||
return super.doLocate(header);
|
||||
}
|
||||
}
|
||||
|
||||
record OpenIDUserSession(User user, String token, long expiresIn) implements UserSession {
|
||||
@Override
|
||||
public String getID() {
|
||||
return user.getUsername();
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMinecraftAccessToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getExpireIn() {
|
||||
return expiresIn;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package pro.gravit.launchserver.auth.core.openid;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
public record OpenIDConfig(URI tokenUri, String authorizationEndpoint, String clientId, String clientSecret,
|
||||
String redirectUri, URI jwksUri, String scopes, String issuer,
|
||||
ClaimExtractorConfig extractorConfig) {
|
||||
|
||||
public record ClaimExtractorConfig(String usernameClaim, String uuidClaim) {}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package pro.gravit.launchserver.auth.core.openid;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author Xakep_SDK
|
||||
*/
|
||||
public class QueryBuilder {
|
||||
private final String uri;
|
||||
private final StringBuilder query = new StringBuilder();
|
||||
|
||||
public QueryBuilder(String uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
public static QueryBuilder get(String uri) {
|
||||
Objects.requireNonNull(uri, "uri");
|
||||
if (uri.endsWith("/")) {
|
||||
uri = uri.substring(0, uri.length() - 1);
|
||||
}
|
||||
return new QueryBuilder(uri);
|
||||
}
|
||||
|
||||
public static QueryBuilder post() {
|
||||
return new QueryBuilder(null);
|
||||
}
|
||||
|
||||
public QueryBuilder addQuery(String key, String value) {
|
||||
if (!query.isEmpty()) {
|
||||
query.append('&');
|
||||
}
|
||||
query.append(URLEncoder.encode(key, StandardCharsets.UTF_8))
|
||||
.append('=')
|
||||
.append(URLEncoder.encode(value, StandardCharsets.UTF_8));
|
||||
return this;
|
||||
}
|
||||
|
||||
public String toUriString() {
|
||||
if (uri != null) {
|
||||
if (query. isEmpty()) {
|
||||
return uri;
|
||||
}
|
||||
return uri + '?' + query;
|
||||
}
|
||||
return toQueryString();
|
||||
}
|
||||
|
||||
public String toQueryString() {
|
||||
return query.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toUriString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
package pro.gravit.launchserver.auth.core.openid;
|
||||
|
||||
import pro.gravit.launchserver.auth.SQLSourceConfig;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.sql.SQLException;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SQLServerSessionStore implements ServerSessionStore {
|
||||
private static final String CREATE_TABLE = """
|
||||
create table if not exists `gravit_server_session` (
|
||||
id int auto_increment,
|
||||
uuid varchar(36),
|
||||
username varchar(255),
|
||||
server_id varchar(41),
|
||||
primary key (id),
|
||||
unique (uuid),
|
||||
unique (username)
|
||||
);
|
||||
""";
|
||||
private static final String DELETE_SERVER_ID = """
|
||||
delete from `gravit_server_session` where uuid = ?
|
||||
""";
|
||||
private static final String INSERT_SERVER_ID = """
|
||||
insert into `gravit_server_session` (uuid, username, server_id) values (?, ?, ?)
|
||||
""";
|
||||
private static final String SELECT_SERVER_ID_BY_USERNAME = """
|
||||
select server_id from `gravit_server_session` where username = ?
|
||||
""";
|
||||
|
||||
private final SQLSourceConfig sqlSourceConfig;
|
||||
|
||||
public SQLServerSessionStore(SQLSourceConfig sqlSourceConfig) {
|
||||
this.sqlSourceConfig = sqlSourceConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean joinServer(UUID uuid, String username, String serverId) {
|
||||
try (var connection = sqlSourceConfig.getConnection()) {
|
||||
connection.setAutoCommit(false);
|
||||
var savepoint = connection.setSavepoint();
|
||||
try (var deleteServerIdStmt = connection.prepareStatement(DELETE_SERVER_ID);
|
||||
var insertServerIdStmt = connection.prepareStatement(INSERT_SERVER_ID)) {
|
||||
deleteServerIdStmt.setString(1, uuid.toString());
|
||||
deleteServerIdStmt.execute();
|
||||
insertServerIdStmt.setString(1, uuid.toString());
|
||||
insertServerIdStmt.setString(2, username);
|
||||
insertServerIdStmt.setString(3, serverId);
|
||||
insertServerIdStmt.execute();
|
||||
connection.commit();
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
connection.rollback(savepoint);
|
||||
throw e;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
LogHelper.debug("Can't join server. Username: %s".formatted(username));
|
||||
LogHelper.error(e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerIdByUsername(String username) {
|
||||
try (var connection = sqlSourceConfig.getConnection();
|
||||
var selectServerId = connection.prepareStatement(SELECT_SERVER_ID_BY_USERNAME)) {
|
||||
selectServerId.setString(1, username);
|
||||
try (var rs = selectServerId.executeQuery()) {
|
||||
if (!rs.next()) {
|
||||
return null;
|
||||
}
|
||||
return rs.getString("server_id");
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
LogHelper.debug("Can't find server id by username. Username: %s".formatted(username));
|
||||
LogHelper.error(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
try (var connection = sqlSourceConfig.getConnection()) {
|
||||
connection.setAutoCommit(false);
|
||||
var savepoint = connection.setSavepoint();
|
||||
try (var createTableStmt = connection.prepareStatement(CREATE_TABLE)) {
|
||||
createTableStmt.execute();
|
||||
connection.commit();
|
||||
} catch (Exception e) {
|
||||
connection.rollback(savepoint);
|
||||
throw e;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
package pro.gravit.launchserver.auth.core.openid;
|
||||
|
||||
import pro.gravit.launcher.base.ClientPermissions;
|
||||
import pro.gravit.launchserver.auth.HikariSQLSourceConfig;
|
||||
import pro.gravit.launchserver.auth.core.User;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SQLUserStore implements UserStore {
|
||||
private static final String CREATE_USER_TABLE = """
|
||||
create table if not exists `gravit_user` (
|
||||
id int auto_increment,
|
||||
uuid varchar(36),
|
||||
username varchar(255),
|
||||
primary key (id),
|
||||
unique (uuid),
|
||||
unique (username)
|
||||
)
|
||||
""";
|
||||
private static final String INSERT_USER = """
|
||||
insert into `gravit_user` (uuid, username) values (?, ?)
|
||||
""";
|
||||
private static final String DELETE_USER_BY_NAME = """
|
||||
delete `gravit_user` where username = ?
|
||||
""";
|
||||
private static final String SELECT_USER_BY_NAME = """
|
||||
select uuid, username from `gravit_user` where username = ?
|
||||
""";
|
||||
private static final String SELECT_USER_BY_UUID = """
|
||||
select uuid, username from `gravit_user` where uuid = ?
|
||||
""";
|
||||
|
||||
private final HikariSQLSourceConfig sqlSourceConfig;
|
||||
|
||||
public SQLUserStore(HikariSQLSourceConfig sqlSourceConfig) {
|
||||
this.sqlSourceConfig = sqlSourceConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getByUsername(String username) {
|
||||
try (var connection = sqlSourceConfig.getConnection();
|
||||
var selectUserStmt = connection.prepareStatement(SELECT_USER_BY_NAME)) {
|
||||
selectUserStmt.setString(1, username);
|
||||
try (var rs = selectUserStmt.executeQuery()) {
|
||||
if (!rs.next()) {
|
||||
LogHelper.debug("User not found, username: %s".formatted(username));
|
||||
return null;
|
||||
}
|
||||
return new UserEntity(rs.getString("username"),
|
||||
UUID.fromString(rs.getString("uuid")),
|
||||
new ClientPermissions());
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
LogHelper.error(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUserByUUID(UUID uuid) {
|
||||
try (var connection = sqlSourceConfig.getConnection();
|
||||
var selectUserStmt = connection.prepareStatement(SELECT_USER_BY_UUID)) {
|
||||
selectUserStmt.setString(1, uuid.toString());
|
||||
try (var rs = selectUserStmt.executeQuery()) {
|
||||
if (!rs.next()) {
|
||||
LogHelper.debug("User not found, UUID: %s".formatted(uuid));
|
||||
return null;
|
||||
}
|
||||
return new UserEntity(rs.getString("username"),
|
||||
UUID.fromString(rs.getString("uuid")),
|
||||
new ClientPermissions());
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
LogHelper.error(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createOrUpdateUser(User user) {
|
||||
try (var connection = sqlSourceConfig.getConnection()) {
|
||||
connection.setAutoCommit(false);
|
||||
var savepoint = connection.setSavepoint();
|
||||
try (var deleteUserStmt = connection.prepareStatement(DELETE_USER_BY_NAME);
|
||||
var insertUserStmt = connection.prepareStatement(INSERT_USER)) {
|
||||
deleteUserStmt.setString(1, user.getUsername());
|
||||
deleteUserStmt.execute();
|
||||
insertUserStmt.setString(1, user.getUUID().toString());
|
||||
insertUserStmt.setString(2, user.getUsername());
|
||||
insertUserStmt.execute();
|
||||
connection.commit();
|
||||
LogHelper.debug("User saved. UUID: %s, username: %s".formatted(user.getUUID(), user.getUsername()));
|
||||
} catch (Exception e) {
|
||||
connection.rollback(savepoint);
|
||||
throw e;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
LogHelper.debug("Failed to save user");
|
||||
LogHelper.error(e);
|
||||
throw new RuntimeException("Failed to save user", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void init() {
|
||||
try (var connection = sqlSourceConfig.getConnection()) {
|
||||
connection.setAutoCommit(false);
|
||||
var savepoint = connection.setSavepoint();
|
||||
try (var createUserTableStmt = connection.prepareStatement(CREATE_USER_TABLE)) {
|
||||
createUserTableStmt.execute();
|
||||
connection.commit();
|
||||
} catch (Exception e) {
|
||||
connection.rollback(savepoint);
|
||||
throw e;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package pro.gravit.launchserver.auth.core.openid;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface ServerSessionStore {
|
||||
boolean joinServer(UUID uuid, String username, String serverId);
|
||||
String getServerIdByUsername(String username);
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package pro.gravit.launchserver.auth.core.openid;
|
||||
|
||||
public record TokenResponse(String accessToken, long accessTokenExpiresIn,
|
||||
String refreshToken, long refreshTokenExpiresIn) {
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package pro.gravit.launchserver.auth.core.openid;
|
||||
|
||||
import pro.gravit.launcher.base.ClientPermissions;
|
||||
import pro.gravit.launchserver.auth.core.User;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
record UserEntity(String username, UUID uuid, ClientPermissions permissions) implements User {
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUUID() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientPermissions getPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package pro.gravit.launchserver.auth.core.openid;
|
||||
|
||||
import pro.gravit.launchserver.auth.core.User;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface UserStore {
|
||||
User getByUsername(String username);
|
||||
|
||||
User getUserByUUID(UUID uuid);
|
||||
|
||||
void createOrUpdateUser(User user);
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
import org.apache.logging.log4j.Logger;
|
||||
import pro.gravit.launcher.base.Launcher;
|
||||
import pro.gravit.launcher.base.profiles.ClientProfile;
|
||||
import pro.gravit.launcher.base.profiles.ClientProfileBuilder;
|
||||
import pro.gravit.launcher.base.profiles.ClientProfileVersions;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.command.Command;
|
||||
|
@ -61,9 +62,11 @@ public void invoke(String... args) throws IOException, CommandException {
|
|||
try {
|
||||
JsonElement clientJson = server.mirrorManager.jsonRequest(null, "GET", "clients/%s.json", versionName);
|
||||
clientProfile = Launcher.gsonManager.configGson.fromJson(clientJson, ClientProfile.class);
|
||||
clientProfile.setTitle(dirName);
|
||||
clientProfile.setDir(dirName);
|
||||
clientProfile.setUUID(UUID.randomUUID());
|
||||
var builder = new ClientProfileBuilder(clientProfile);
|
||||
builder.setTitle(dirName);
|
||||
builder.setDir(dirName);
|
||||
builder.setUuid(UUID.randomUUID());
|
||||
clientProfile = builder.createClientProfile();
|
||||
if (clientProfile.getServers() != null) {
|
||||
ClientProfile.ServerProfile serverProfile = clientProfile.getDefaultServerProfile();
|
||||
if (serverProfile != null) {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import org.apache.logging.log4j.Logger;
|
||||
import pro.gravit.launcher.base.Launcher;
|
||||
import pro.gravit.launcher.base.profiles.ClientProfile;
|
||||
import pro.gravit.launcher.base.profiles.ClientProfileBuilder;
|
||||
import pro.gravit.launchserver.LaunchServer;
|
||||
import pro.gravit.launchserver.command.Command;
|
||||
import pro.gravit.utils.helper.IOHelper;
|
||||
|
@ -44,8 +45,9 @@ public void invoke(String... args) throws Exception {
|
|||
try(Reader reader = IOHelper.newReader(profilePath)) {
|
||||
profile = Launcher.gsonManager.gson.fromJson(reader, ClientProfile.class);
|
||||
}
|
||||
profile.setTitle(args[1]);
|
||||
profile.setUUID(UUID.randomUUID());
|
||||
var builder = new ClientProfileBuilder(profile);
|
||||
builder.setTitle(args[1]);
|
||||
builder.setUuid(UUID.randomUUID());
|
||||
if(profile.getServers().size() == 1) {
|
||||
profile.getServers().getFirst().name = args[1];
|
||||
}
|
||||
|
@ -61,7 +63,8 @@ public void invoke(String... args) throws Exception {
|
|||
}
|
||||
});
|
||||
}
|
||||
profile.setDir(args[1]);
|
||||
builder.setDir(args[1]);
|
||||
profile = builder.createClientProfile();
|
||||
var targetPath = server.profilesDir.resolve(args[1].concat(".json"));
|
||||
try(Writer writer = IOHelper.newWriter(targetPath)) {
|
||||
Launcher.gsonManager.gson.toJson(profile, writer);
|
||||
|
|
|
@ -23,7 +23,6 @@ public SaveProfilesCommand(LaunchServer server) {
|
|||
}
|
||||
|
||||
public static void saveProfile(ClientProfile profile, Path path) throws IOException {
|
||||
if (profile.getUUID() == null) profile.setUUID(UUID.randomUUID());
|
||||
if (profile.getServers().isEmpty()) {
|
||||
ClientProfile.ServerProfile serverProfile = new ClientProfile.ServerProfile();
|
||||
serverProfile.isDefault = true;
|
||||
|
|
|
@ -109,14 +109,14 @@ public static String getPathSeparator() {
|
|||
|
||||
private void applyClientProfile() {
|
||||
this.systemClassPath.add(IOHelper.getCodeSource(ClientLauncherEntryPoint.class).toAbsolutePath().toString());
|
||||
Collections.addAll(this.jvmArgs, this.params.profile.getJvmArgs());
|
||||
this.jvmArgs.addAll(this.params.profile.getJvmArgs());
|
||||
for (OptionalAction a : this.params.actions) {
|
||||
if (a instanceof OptionalActionJvmArgs) {
|
||||
this.jvmArgs.addAll(((OptionalActionJvmArgs) a).args);
|
||||
}
|
||||
}
|
||||
this.systemEnv.put("JAVA_HOME", javaVersion.jvmDir.toString());
|
||||
Collections.addAll(this.systemClassPath, this.params.profile.getAlternativeClassPath());
|
||||
this.systemClassPath.addAll(this.params.profile.getAlternativeClassPath());
|
||||
if (params.ram > 0) {
|
||||
this.jvmArgs.add("-Xmx" + params.ram + 'M');
|
||||
}
|
||||
|
@ -128,8 +128,6 @@ private void applyClientProfile() {
|
|||
this.params.oauthExpiredTime = Request.getTokenExpiredTime();
|
||||
this.params.extendedTokens = Request.getExtendedTokens();
|
||||
}
|
||||
this.jvmModules.addAll(this.params.profile.getModules());
|
||||
this.jvmModulesPaths.addAll(this.params.profile.getModulePath());
|
||||
LauncherEngine.modulesManager.invokeEvent(new ClientProcessBuilderCreateEvent(this));
|
||||
}
|
||||
|
||||
|
@ -148,7 +146,6 @@ public void start(boolean pipeOutput) throws IOException, InterruptedException {
|
|||
processArgs.add("-javaagent:".concat(IOHelper.getCodeSource(ClientLauncherEntryPoint.class).toAbsolutePath().toString()));
|
||||
} else if (params.profile.getClassLoaderConfig() == ClientProfile.ClassLoaderConfig.SYSTEM_ARGS) {
|
||||
systemClassPath.addAll(ClientLauncherEntryPoint.resolveClassPath(new HashSet<>(), workDir, params.actions, params.profile)
|
||||
.filter(x -> !params.profile.getModulePath().contains(workDir.relativize(x).toString()))
|
||||
.map(Path::toString)
|
||||
.toList());
|
||||
}
|
||||
|
|
|
@ -41,8 +41,6 @@ public final class ClientProfile implements Comparable<ClientProfile> {
|
|||
@LauncherNetworkAPI
|
||||
private List<String> updateExclusions;
|
||||
@LauncherNetworkAPI
|
||||
private List<String> updateShared;
|
||||
@LauncherNetworkAPI
|
||||
private List<String> updateVerify;
|
||||
@LauncherNetworkAPI
|
||||
private Set<OptionalFile> updateOptional;
|
||||
|
@ -51,10 +49,6 @@ public final class ClientProfile implements Comparable<ClientProfile> {
|
|||
@LauncherNetworkAPI
|
||||
private List<String> classPath;
|
||||
@LauncherNetworkAPI
|
||||
private List<String> modulePath = new ArrayList<>();
|
||||
@LauncherNetworkAPI
|
||||
private List<String> modules = new ArrayList<>();
|
||||
@LauncherNetworkAPI
|
||||
private List<String> altClassPath;
|
||||
@LauncherNetworkAPI
|
||||
private List<String> clientArgs;
|
||||
|
@ -89,54 +83,37 @@ public final class ClientProfile implements Comparable<ClientProfile> {
|
|||
@LauncherNetworkAPI
|
||||
private LaunchOptions.ModuleConf moduleConf;
|
||||
|
||||
public ClientProfile() {
|
||||
update = new ArrayList<>();
|
||||
updateExclusions = new ArrayList<>();
|
||||
updateShared = new ArrayList<>();
|
||||
updateVerify = new ArrayList<>();
|
||||
updateOptional = new HashSet<>();
|
||||
jvmArgs = new ArrayList<>();
|
||||
classPath = new ArrayList<>();
|
||||
modulePath = new ArrayList<>();
|
||||
altClassPath = new ArrayList<>();
|
||||
clientArgs = new ArrayList<>();
|
||||
compatClasses = new ArrayList<>();
|
||||
properties = new HashMap<>();
|
||||
servers = new ArrayList<>(1);
|
||||
classLoaderConfig = ClassLoaderConfig.LAUNCHER;
|
||||
flags = new ArrayList<>();
|
||||
}
|
||||
|
||||
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, ClassLoaderConfig classLoaderConfig, List<CompatibilityFlags> flags, Version version, String assetIndex, String dir, String assetDir, int recommendJavaVersion, int minJavaVersion, int maxJavaVersion, ProfileDefaultSettings settings, int sortIndex, UUID uuid, String title, String info, String mainClass) {
|
||||
public ClientProfile(String title, UUID uuid, Version version, String info, String dir, int sortIndex, String assetIndex, String assetDir, List<String> update, List<String> updateExclusions, List<String> updateVerify, Set<OptionalFile> updateOptional, List<String> jvmArgs, List<String> classPath, List<String> altClassPath, List<String> clientArgs, List<String> compatClasses, List<String> loadNatives, Map<String, String> properties, List<ServerProfile> servers, ClassLoaderConfig classLoaderConfig, List<CompatibilityFlags> flags, int recommendJavaVersion, int minJavaVersion, int maxJavaVersion, ProfileDefaultSettings settings, boolean limited, String mainClass, String mainModule, LaunchOptions.ModuleConf moduleConf) {
|
||||
this.title = title;
|
||||
this.uuid = uuid;
|
||||
this.version = version;
|
||||
this.info = info;
|
||||
this.dir = dir;
|
||||
this.sortIndex = sortIndex;
|
||||
this.assetIndex = assetIndex;
|
||||
this.assetDir = assetDir;
|
||||
this.update = update;
|
||||
this.updateExclusions = updateExclusions;
|
||||
this.updateShared = updateShared;
|
||||
this.updateVerify = updateVerify;
|
||||
this.updateOptional = updateOptional;
|
||||
this.jvmArgs = jvmArgs;
|
||||
this.classPath = classPath;
|
||||
this.modulePath = modulePath;
|
||||
this.modules = modules;
|
||||
this.altClassPath = altClassPath;
|
||||
this.clientArgs = clientArgs;
|
||||
this.compatClasses = compatClasses;
|
||||
this.loadNatives = loadNatives;
|
||||
this.properties = properties;
|
||||
this.servers = servers;
|
||||
this.classLoaderConfig = classLoaderConfig;
|
||||
this.version = version;
|
||||
this.assetIndex = assetIndex;
|
||||
this.dir = dir;
|
||||
this.assetDir = assetDir;
|
||||
this.flags = flags;
|
||||
this.recommendJavaVersion = recommendJavaVersion;
|
||||
this.minJavaVersion = minJavaVersion;
|
||||
this.maxJavaVersion = maxJavaVersion;
|
||||
this.settings = settings;
|
||||
this.sortIndex = sortIndex;
|
||||
this.uuid = uuid;
|
||||
this.title = title;
|
||||
this.info = info;
|
||||
this.limited = limited;
|
||||
this.mainClass = mainClass;
|
||||
this.flags = flags;
|
||||
this.mainModule = mainModule;
|
||||
this.moduleConf = moduleConf;
|
||||
}
|
||||
|
||||
public ServerProfile getDefaultServerProfile() {
|
||||
|
@ -159,34 +136,22 @@ public FileNameMatcher getAssetUpdateMatcher() {
|
|||
return getVersion().compareTo(ClientProfileVersions.MINECRAFT_1_7_10) >= 0 ? ASSET_MATCHER : null;
|
||||
}
|
||||
|
||||
public String[] getClassPath() {
|
||||
return classPath.toArray(new String[0]);
|
||||
public List<String> getClassPath() {
|
||||
return Collections.unmodifiableList(classPath);
|
||||
}
|
||||
|
||||
public List<String> getModulePath() {
|
||||
return Collections.unmodifiableList(modulePath);
|
||||
public List<String> getAlternativeClassPath() {
|
||||
return Collections.unmodifiableList(altClassPath);
|
||||
}
|
||||
|
||||
public List<String> getModules() {
|
||||
return Collections.unmodifiableList(modules);
|
||||
}
|
||||
|
||||
public String[] getAlternativeClassPath() {
|
||||
return altClassPath.toArray(new String[0]);
|
||||
}
|
||||
|
||||
public String[] getClientArgs() {
|
||||
return clientArgs.toArray(new String[0]);
|
||||
public List<String> getClientArgs() {
|
||||
return Collections.unmodifiableList(clientArgs);
|
||||
}
|
||||
|
||||
public String getDir() {
|
||||
return dir;
|
||||
}
|
||||
|
||||
public void setDir(String dir) {
|
||||
this.dir = dir;
|
||||
}
|
||||
|
||||
public String getAssetDir() {
|
||||
return assetDir;
|
||||
}
|
||||
|
@ -195,24 +160,25 @@ public List<String> getUpdateExclusions() {
|
|||
return Collections.unmodifiableList(updateExclusions);
|
||||
}
|
||||
|
||||
public FileNameMatcher getClientUpdateMatcher(/*boolean excludeOptional*/) {
|
||||
public List<String> getUpdate() {
|
||||
return Collections.unmodifiableList(update);
|
||||
}
|
||||
|
||||
public List<String> getUpdateVerify() {
|
||||
return Collections.unmodifiableList(updateVerify);
|
||||
}
|
||||
|
||||
public FileNameMatcher getClientUpdateMatcher() {
|
||||
String[] updateArray = update.toArray(new String[0]);
|
||||
String[] verifyArray = updateVerify.toArray(new String[0]);
|
||||
List<String> excludeList;
|
||||
//if(excludeOptional)
|
||||
//{
|
||||
// excludeList = new ArrayList<>();
|
||||
// excludeList.addAll(updateExclusions);
|
||||
// excludeList.addAll(updateOptional);
|
||||
//}
|
||||
//else
|
||||
excludeList = updateExclusions;
|
||||
String[] exclusionsArray = excludeList.toArray(new String[0]);
|
||||
return new FileNameMatcher(updateArray, verifyArray, exclusionsArray);
|
||||
}
|
||||
|
||||
public String[] getJvmArgs() {
|
||||
return jvmArgs.toArray(new String[0]);
|
||||
public List<String> getJvmArgs() {
|
||||
return Collections.unmodifiableList(jvmArgs);
|
||||
}
|
||||
|
||||
public String getMainClass() {
|
||||
|
@ -289,10 +255,6 @@ public OptionalFile getOptionalFile(String file) {
|
|||
return null;
|
||||
}
|
||||
|
||||
public Collection<String> getShared() {
|
||||
return updateShared;
|
||||
}
|
||||
|
||||
public int getServerPort() {
|
||||
ServerProfile profile = getDefaultServerProfile();
|
||||
return profile == null ? 25565 : profile.serverPort;
|
||||
|
@ -306,26 +268,14 @@ public String getTitle() {
|
|||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getInfo() {
|
||||
return info;
|
||||
}
|
||||
|
||||
public void setInfo(String info) {
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public Version getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(Version version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean isUpdateFastCheck() {
|
||||
return true;
|
||||
|
@ -340,10 +290,6 @@ public UUID getUUID() {
|
|||
return uuid;
|
||||
}
|
||||
|
||||
public void setUUID(UUID uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public boolean hasFlag(CompatibilityFlags flag) {
|
||||
return flags.contains(flag);
|
||||
}
|
||||
|
@ -413,18 +359,6 @@ public String getProperty(String name) {
|
|||
return properties.get(name);
|
||||
}
|
||||
|
||||
public void putProperty(String name, String value) {
|
||||
properties.put(name, value);
|
||||
}
|
||||
|
||||
public boolean containsProperty(String name) {
|
||||
return properties.containsKey(name);
|
||||
}
|
||||
|
||||
public void clearProperties() {
|
||||
properties.clear();
|
||||
}
|
||||
|
||||
public Map<String, String> getProperties() {
|
||||
return Collections.unmodifiableMap(properties);
|
||||
}
|
||||
|
@ -450,10 +384,6 @@ public ClassLoaderConfig getClassLoaderConfig() {
|
|||
return classLoaderConfig;
|
||||
}
|
||||
|
||||
public void setClassLoaderConfig(ClassLoaderConfig classLoaderConfig) {
|
||||
this.classLoaderConfig = classLoaderConfig;
|
||||
}
|
||||
|
||||
public boolean isLimited() {
|
||||
return limited;
|
||||
}
|
||||
|
|
|
@ -1,136 +1,117 @@
|
|||
package pro.gravit.launcher.base.profiles;
|
||||
|
||||
import pro.gravit.launcher.base.profiles.optional.OptionalFile;
|
||||
import pro.gravit.utils.launch.LaunchOptions;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ClientProfileBuilder {
|
||||
private List<String> update = new ArrayList<>();
|
||||
private List<String> updateExclusions = new ArrayList<>();
|
||||
private List<String> updateShared = new ArrayList<>();
|
||||
private List<String> updateVerify = new ArrayList<>();
|
||||
private Set<OptionalFile> updateOptional = new HashSet<>();
|
||||
private List<String> jvmArgs = 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> clientArgs = new ArrayList<>();
|
||||
private List<String> compatClasses = new ArrayList<>();
|
||||
private Map<String, String> properties = new HashMap<>();
|
||||
private List<ClientProfile.ServerProfile> servers = new ArrayList<>();
|
||||
private ClientProfile.ClassLoaderConfig classLoaderConfig = ClientProfile.ClassLoaderConfig.LAUNCHER;
|
||||
private List<ClientProfile.CompatibilityFlags> flags = new ArrayList<>();
|
||||
private ClientProfile.Version version;
|
||||
private String assetIndex;
|
||||
private String dir;
|
||||
private String assetDir;
|
||||
private int recommendJavaVersion = 8;
|
||||
private int minJavaVersion = 8;
|
||||
private int maxJavaVersion = 999;
|
||||
private ClientProfile.ProfileDefaultSettings settings = new ClientProfile.ProfileDefaultSettings();
|
||||
private int sortIndex;
|
||||
private UUID uuid;
|
||||
private String title;
|
||||
private UUID uuid;
|
||||
private ClientProfile.Version version;
|
||||
private String info;
|
||||
private String dir;
|
||||
private int sortIndex;
|
||||
private String assetIndex;
|
||||
private String assetDir;
|
||||
private List<String> update;
|
||||
private List<String> updateExclusions;
|
||||
private List<String> updateVerify;
|
||||
private Set<OptionalFile> updateOptional;
|
||||
private List<String> jvmArgs;
|
||||
private List<String> classPath;
|
||||
private List<String> altClassPath;
|
||||
private List<String> clientArgs;
|
||||
private List<String> compatClasses;
|
||||
private List<String> loadNatives;
|
||||
private Map<String, String> properties;
|
||||
private List<ClientProfile.ServerProfile> servers;
|
||||
private ClientProfile.ClassLoaderConfig classLoaderConfig;
|
||||
private List<ClientProfile.CompatibilityFlags> flags;
|
||||
private int recommendJavaVersion;
|
||||
private int minJavaVersion;
|
||||
private int maxJavaVersion;
|
||||
private ClientProfile.ProfileDefaultSettings settings;
|
||||
private boolean limited;
|
||||
private String mainClass;
|
||||
private String mainModule;
|
||||
private LaunchOptions.ModuleConf moduleConf;
|
||||
|
||||
public void setUpdate(List<String> update) {
|
||||
this.update = update;
|
||||
public ClientProfileBuilder() {
|
||||
this.update = new ArrayList<>();
|
||||
this.updateExclusions = new ArrayList<>();
|
||||
this.updateVerify = new ArrayList<>();
|
||||
this.updateOptional = new HashSet<>();
|
||||
this.jvmArgs = new ArrayList<>();
|
||||
this.classPath = new ArrayList<>();
|
||||
this.altClassPath = new ArrayList<>();
|
||||
this.clientArgs = new ArrayList<>();
|
||||
this.compatClasses = new ArrayList<>();
|
||||
this.loadNatives = new ArrayList<>();
|
||||
this.properties = new HashMap<>();
|
||||
this.servers = new ArrayList<>();
|
||||
this.flags = new ArrayList<>();
|
||||
this.settings = new ClientProfile.ProfileDefaultSettings();
|
||||
this.recommendJavaVersion = 21;
|
||||
this.minJavaVersion = 17;
|
||||
this.maxJavaVersion = 999;
|
||||
this.classLoaderConfig = ClientProfile.ClassLoaderConfig.LAUNCHER;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setUpdateExclusions(List<String> updateExclusions) {
|
||||
this.updateExclusions = updateExclusions;
|
||||
public ClientProfileBuilder(ClientProfile profile) {
|
||||
this.title = profile.getTitle();
|
||||
this.uuid = profile.getUUID();
|
||||
this.version = profile.getVersion();
|
||||
this.info = profile.getInfo();
|
||||
this.dir = profile.getDir();
|
||||
this.sortIndex = profile.getSortIndex();
|
||||
this.assetIndex = profile.getAssetIndex();
|
||||
this.assetDir = profile.getAssetDir();
|
||||
this.update = new ArrayList<>(profile.getUpdate());
|
||||
this.updateExclusions = new ArrayList<>(profile.getUpdateExclusions());
|
||||
this.updateVerify = new ArrayList<>(profile.getUpdateVerify());
|
||||
this.updateOptional = new HashSet<>(profile.getOptional());
|
||||
this.jvmArgs = new ArrayList<>(profile.getJvmArgs());
|
||||
this.classPath = new ArrayList<>(profile.getClassPath());
|
||||
this.altClassPath = new ArrayList<>(profile.getAlternativeClassPath());
|
||||
this.clientArgs = new ArrayList<>(profile.getClientArgs());
|
||||
this.compatClasses = new ArrayList<>(profile.getCompatClasses());
|
||||
this.loadNatives = new ArrayList<>(profile.getLoadNatives());
|
||||
this.properties = new HashMap<>(profile.getProperties());
|
||||
this.servers = new ArrayList<>(profile.getServers());
|
||||
this.flags = new ArrayList<>(profile.getFlags());
|
||||
this.recommendJavaVersion = profile.getRecommendJavaVersion();
|
||||
this.minJavaVersion = profile.getMinJavaVersion();
|
||||
this.maxJavaVersion = profile.getMaxJavaVersion();
|
||||
this.settings = profile.getSettings();
|
||||
this.limited = profile.isLimited();
|
||||
this.mainClass = profile.getMainClass();
|
||||
this.mainModule = profile.getMainModule();
|
||||
this.moduleConf = profile.getModuleConf();
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setTitle(String title) {
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setUpdateShared(List<String> updateShared) {
|
||||
this.updateShared = updateShared;
|
||||
public ClientProfileBuilder setUuid(UUID uuid) {
|
||||
this.uuid = uuid;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setUpdateVerify(List<String> updateVerify) {
|
||||
this.updateVerify = updateVerify;
|
||||
}
|
||||
|
||||
public void setUpdateOptional(Set<OptionalFile> updateOptional) {
|
||||
this.updateOptional = updateOptional;
|
||||
}
|
||||
|
||||
public void setJvmArgs(List<String> jvmArgs) {
|
||||
this.jvmArgs = jvmArgs;
|
||||
}
|
||||
|
||||
public void setClassPath(List<String> classPath) {
|
||||
this.classPath = classPath;
|
||||
}
|
||||
|
||||
public void setAltClassPath(List<String> altClassPath) {
|
||||
this.altClassPath = altClassPath;
|
||||
}
|
||||
|
||||
public void setClientArgs(List<String> clientArgs) {
|
||||
this.clientArgs = clientArgs;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setCompatClasses(List<String> compatClasses) {
|
||||
this.compatClasses = compatClasses;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setProperties(Map<String, String> properties) {
|
||||
this.properties = properties;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setServers(List<ClientProfile.ServerProfile> servers) {
|
||||
this.servers = servers;
|
||||
}
|
||||
|
||||
public void setClassLoaderConfig(ClientProfile.ClassLoaderConfig classLoaderConfig) {
|
||||
this.classLoaderConfig = classLoaderConfig;
|
||||
}
|
||||
|
||||
public void setVersion(ClientProfile.Version version) {
|
||||
public ClientProfileBuilder setVersion(ClientProfile.Version version) {
|
||||
this.version = version;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setAssetIndex(String assetIndex) {
|
||||
this.assetIndex = assetIndex;
|
||||
public ClientProfileBuilder setInfo(String info) {
|
||||
this.info = info;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setDir(String dir) {
|
||||
public ClientProfileBuilder setDir(String dir) {
|
||||
this.dir = dir;
|
||||
}
|
||||
|
||||
public void setAssetDir(String assetDir) {
|
||||
this.assetDir = assetDir;
|
||||
}
|
||||
|
||||
public void setRecommendJavaVersion(int recommendJavaVersion) {
|
||||
this.recommendJavaVersion = recommendJavaVersion;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setModulePath(List<String> modulePath) {
|
||||
this.modulePath = modulePath;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setModules(List<String> modules) {
|
||||
this.modules = modules;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setMinJavaVersion(int minJavaVersion) {
|
||||
this.minJavaVersion = minJavaVersion;
|
||||
}
|
||||
|
||||
public void setMaxJavaVersion(int maxJavaVersion) {
|
||||
this.maxJavaVersion = maxJavaVersion;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setSettings(ClientProfile.ProfileDefaultSettings settings) {
|
||||
this.settings = settings;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -139,20 +120,140 @@ public ClientProfileBuilder setSortIndex(int sortIndex) {
|
|||
return this;
|
||||
}
|
||||
|
||||
public void setUuid(UUID uuid) {
|
||||
this.uuid = uuid;
|
||||
public ClientProfileBuilder setAssetIndex(String assetIndex) {
|
||||
this.assetIndex = assetIndex;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
public ClientProfileBuilder setAssetDir(String assetDir) {
|
||||
this.assetDir = assetDir;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setInfo(String info) {
|
||||
this.info = info;
|
||||
public ClientProfileBuilder setUpdate(List<String> update) {
|
||||
this.update = update;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setMainClass(String mainClass) {
|
||||
this.mainClass = mainClass;
|
||||
public ClientProfileBuilder update(String value) {
|
||||
this.update.add(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setUpdateExclusions(List<String> updateExclusions) {
|
||||
this.updateExclusions = updateExclusions;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder updateExclusions(String value) {
|
||||
this.updateExclusions.add(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setUpdateVerify(List<String> updateVerify) {
|
||||
this.updateVerify = updateVerify;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder updateVerify(String value) {
|
||||
this.updateVerify.add(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setUpdateOptional(Set<OptionalFile> updateOptional) {
|
||||
this.updateOptional = updateOptional;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder updateOptional(OptionalFile value) {
|
||||
this.updateOptional.add(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setJvmArgs(List<String> jvmArgs) {
|
||||
this.jvmArgs = jvmArgs;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder jvmArg(String value) {
|
||||
this.jvmArgs.add(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public ClientProfileBuilder setClassPath(List<String> classPath) {
|
||||
this.classPath = classPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder classPath(String value) {
|
||||
this.classPath.add(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setAltClassPath(List<String> altClassPath) {
|
||||
this.altClassPath = altClassPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder altClassPath(String value) {
|
||||
this.altClassPath.add(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setClientArgs(List<String> clientArgs) {
|
||||
this.clientArgs = clientArgs;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder clientArg(String value) {
|
||||
this.clientArgs.add(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setCompatClasses(List<String> compatClasses) {
|
||||
this.compatClasses = compatClasses;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder compatClass(String value) {
|
||||
this.compatClasses.add(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setLoadNatives(List<String> loadNatives) {
|
||||
this.loadNatives = loadNatives;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder loadNatives(String value) {
|
||||
this.loadNatives.add(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setProperties(Map<String, String> properties) {
|
||||
this.properties = properties;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder property(String name, String value) {
|
||||
this.properties.put(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setServers(List<ClientProfile.ServerProfile> servers) {
|
||||
this.servers = servers;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder server(ClientProfile.ServerProfile value) {
|
||||
this.servers.add(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setClassLoaderConfig(ClientProfile.ClassLoaderConfig classLoaderConfig) {
|
||||
this.classLoaderConfig = classLoaderConfig;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setFlags(List<ClientProfile.CompatibilityFlags> flags) {
|
||||
|
@ -160,7 +261,52 @@ public ClientProfileBuilder setFlags(List<ClientProfile.CompatibilityFlags> flag
|
|||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder flag(ClientProfile.CompatibilityFlags value) {
|
||||
this.flags.add(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setRecommendJavaVersion(int recommendJavaVersion) {
|
||||
this.recommendJavaVersion = recommendJavaVersion;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setMinJavaVersion(int minJavaVersion) {
|
||||
this.minJavaVersion = minJavaVersion;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setMaxJavaVersion(int maxJavaVersion) {
|
||||
this.maxJavaVersion = maxJavaVersion;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setSettings(ClientProfile.ProfileDefaultSettings settings) {
|
||||
this.settings = settings;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setLimited(boolean limited) {
|
||||
this.limited = limited;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setMainClass(String mainClass) {
|
||||
this.mainClass = mainClass;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setMainModule(String mainModule) {
|
||||
this.mainModule = mainModule;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfileBuilder setModuleConf(LaunchOptions.ModuleConf moduleConf) {
|
||||
this.moduleConf = moduleConf;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClientProfile createClientProfile() {
|
||||
return new ClientProfile(update, updateExclusions, updateShared, updateVerify, updateOptional, jvmArgs, classPath, modulePath, modules, altClassPath, clientArgs, compatClasses, properties, servers, classLoaderConfig, flags, version, assetIndex, dir, assetDir, recommendJavaVersion, minJavaVersion, maxJavaVersion, settings, sortIndex, uuid, title, info, mainClass);
|
||||
return new ClientProfile(title, uuid, version, info, dir, sortIndex, assetIndex, assetDir, update, updateExclusions, updateVerify, updateOptional, jvmArgs, classPath, altClassPath, clientArgs, compatClasses, loadNatives, properties, servers, classLoaderConfig, flags, recommendJavaVersion, minJavaVersion, maxJavaVersion, settings, limited, mainClass, mainModule, moduleConf);
|
||||
}
|
||||
}
|
|
@ -18,4 +18,5 @@ private ClientProfileVersions() {
|
|||
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");
|
||||
public static final ClientProfile.Version MINECRAFT_1_20_5 = ClientProfile.Version.of("1.20.5");
|
||||
}
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
package pro.gravit.launcher.base.profiles.optional.actions;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class OptionalActionClassPath extends OptionalAction {
|
||||
public String[] args;
|
||||
public List<String> args;
|
||||
public boolean useAltClasspath = false;
|
||||
|
||||
public OptionalActionClassPath() {
|
||||
}
|
||||
|
||||
public OptionalActionClassPath(String[] args) {
|
||||
public OptionalActionClassPath(List<String> args) {
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
public OptionalActionClassPath(String[] args, boolean useAltClasspath) {
|
||||
public OptionalActionClassPath(List<String> args, boolean useAltClasspath) {
|
||||
this.args = args;
|
||||
this.useAltClasspath = useAltClasspath;
|
||||
}
|
||||
|
|
|
@ -120,7 +120,6 @@ private static void realMain(String[] args) throws Throwable {
|
|||
LogHelper.debug("Verifying ClientLauncher sign and classpath");
|
||||
Set<Path> ignoredPath = new HashSet<>();
|
||||
List<Path> classpath = resolveClassPath(ignoredPath, clientDir, params.actions, params.profile)
|
||||
.filter(x -> !profile.getModulePath().contains(clientDir.relativize(x).toString()))
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
if(LogHelper.isDevEnabled()) {
|
||||
for(var e : classpath) {
|
||||
|
@ -253,11 +252,11 @@ public static void verifyHDir(Path dir, HashedDir hdir, FileNameMatcher matcher,
|
|||
}
|
||||
}
|
||||
|
||||
private static LinkedList<Path> resolveClassPathList(Set<Path> ignorePaths, Path clientDir, String... classPath) throws IOException {
|
||||
private static LinkedList<Path> resolveClassPathList(Set<Path> ignorePaths, Path clientDir, List<String> classPath) throws IOException {
|
||||
return resolveClassPathStream(ignorePaths, clientDir, classPath).collect(Collectors.toCollection(LinkedList::new));
|
||||
}
|
||||
|
||||
private static Stream<Path> resolveClassPathStream(Set<Path> ignorePaths, Path clientDir, String... classPath) throws IOException {
|
||||
private static Stream<Path> resolveClassPathStream(Set<Path> ignorePaths, Path clientDir, List<String> classPath) throws IOException {
|
||||
Stream.Builder<Path> builder = Stream.builder();
|
||||
for (String classPathEntry : classPath) {
|
||||
Path path = clientDir.resolve(IOHelper.toPath(classPathEntry.replace(IOHelper.CROSS_SEPARATOR, IOHelper.PLATFORM_SEPARATOR)));
|
||||
|
@ -301,7 +300,7 @@ private static void launch(ClientProfile profile, ClientParams params) throws Th
|
|||
params.addClientLegacyArgs(args);
|
||||
System.setProperty("minecraft.applet.TargetDirectory", params.clientDir);
|
||||
}
|
||||
Collections.addAll(args, profile.getClientArgs());
|
||||
args.addAll(profile.getClientArgs());
|
||||
for (OptionalAction action : params.actions) {
|
||||
if (action instanceof OptionalActionClientArgs) {
|
||||
args.addAll(((OptionalActionClientArgs) action).args);
|
||||
|
|
|
@ -6,7 +6,7 @@ public final class Version implements Comparable<Version> {
|
|||
|
||||
public static final int MAJOR = 5;
|
||||
public static final int MINOR = 6;
|
||||
public static final int PATCH = 1;
|
||||
public static final int PATCH = 2;
|
||||
public static final int BUILD = 1;
|
||||
public static final Version.Type RELEASE = Type.STABLE;
|
||||
public final int major;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
id 'org.openjfx.javafxplugin' version '0.1.0' apply false
|
||||
}
|
||||
group = 'pro.gravit.launcher'
|
||||
version = '5.6.1'
|
||||
version = '5.6.2'
|
||||
|
||||
apply from: 'props.gradle'
|
||||
|
||||
|
|
2
modules
2
modules
|
@ -1 +1 @@
|
|||
Subproject commit dba18b58312a92e465ad17d78ea3504a8b3c1818
|
||||
Subproject commit a52b9cc8552445167b95e8933f4289bbaa70677d
|
27
props.gradle
27
props.gradle
|
@ -1,19 +1,20 @@
|
|||
project.ext {
|
||||
verAsm = '9.6'
|
||||
verNetty = '4.1.99.Final'
|
||||
verOshiCore = '6.4.11'
|
||||
verJunit = '5.9.3'
|
||||
verAsm = '9.7'
|
||||
verNetty = '4.1.110.Final'
|
||||
verOshiCore = '6.6.1'
|
||||
verJunit = '5.10.2'
|
||||
verGuavaC = '30.1.1-jre'
|
||||
verJansi = '2.4.1'
|
||||
verJline = '3.25.0'
|
||||
verJline = '3.26.1'
|
||||
verJwt = '0.12.5'
|
||||
verBcprov = '1.70'
|
||||
verGson = '2.10.1'
|
||||
verBcpkix = '1.70'
|
||||
verSlf4j = '2.0.9'
|
||||
verLog4j = '2.20.0'
|
||||
verMySQLConn = '8.3.0'
|
||||
verPostgreSQLConn = '42.7.1'
|
||||
verProguard = '7.4.1'
|
||||
verLaunch4j = '3.50'
|
||||
verGson = '2.11.0'
|
||||
verBcpkix = '1.78.1'
|
||||
verSlf4j = '2.0.13'
|
||||
verLog4j = '2.23.1'
|
||||
verMySQLConn = '8.4.0'
|
||||
verMariaDBConn = '3.4.0'
|
||||
verPostgreSQLConn = '42.7.3'
|
||||
verH2Conn = '2.2.224'
|
||||
verProguard = '7.5.0'
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue