mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-11-15 11:39:11 +03:00
Merge branch 'release/5.4.3'
This commit is contained in:
commit
7fee478552
51 changed files with 311 additions and 223 deletions
86
.gitattributes
vendored
86
.gitattributes
vendored
|
@ -1,26 +1,78 @@
|
||||||
* text eol=lf
|
* text=auto eol=lf
|
||||||
*.bat text eol=crlf
|
*.[cC][mM][dD] text eol=crlf
|
||||||
*.sh text eol=lf
|
*.[bB][aA][tT] text eol=crlf
|
||||||
|
*.[pP][sS]1 text eol=crlf
|
||||||
|
*.[sS][hH] text eol=lf
|
||||||
|
|
||||||
*.patch text eol=lf
|
*.patch text eol=lf
|
||||||
*.java text eol=lf
|
|
||||||
*.scala text eol=lf
|
|
||||||
*.groovy text eol=lf
|
|
||||||
|
|
||||||
*.gradle text eol=crlf
|
|
||||||
gradle.properties text eol=crlf
|
|
||||||
/gradle/wrapper/gradle-wrapper.properties text eol=crlf
|
|
||||||
*.cfg text eol=lf
|
|
||||||
|
|
||||||
*.png binary
|
*.png binary
|
||||||
*.jar binary
|
|
||||||
*.war binary
|
|
||||||
*.lzma binary
|
*.lzma binary
|
||||||
*.zip binary
|
*.zip binary
|
||||||
*.gzip binary
|
*.gzip binary
|
||||||
*.dll binary
|
|
||||||
*.so binary
|
|
||||||
*.exe binary
|
*.exe binary
|
||||||
|
*.ico binary
|
||||||
|
*.eot binary
|
||||||
|
*.ttf binary
|
||||||
|
*.woff binary
|
||||||
|
*.woff2 binary
|
||||||
|
*.a binary
|
||||||
|
*.lib binary
|
||||||
|
*.icns binary
|
||||||
|
*.jpg binary
|
||||||
|
*.jpeg binary
|
||||||
|
*.gif binary
|
||||||
|
*.mov binary
|
||||||
|
*.mp4 binary
|
||||||
|
*.mp3 binary
|
||||||
|
*.flv binary
|
||||||
|
*.fla binary
|
||||||
|
*.swf binary
|
||||||
|
*.gz binary
|
||||||
|
*.tar binary
|
||||||
|
*.tar.gz binary
|
||||||
|
*.7z binary
|
||||||
|
*.pyc binary
|
||||||
|
*.gpg binary
|
||||||
|
*.bin binary
|
||||||
|
|
||||||
*.gitattributes text eol=crlf
|
*.gitattributes text
|
||||||
*.gitignore text eol=crlf
|
.gitignore text
|
||||||
|
|
||||||
|
# Java sources
|
||||||
|
*.java text diff=java
|
||||||
|
*.kt text diff=kotlin
|
||||||
|
*.groovy text diff=java
|
||||||
|
*.scala text diff=java
|
||||||
|
*.gradle text diff=java
|
||||||
|
*.gradle.kts text diff=kotlin
|
||||||
|
|
||||||
|
# These files are text and should be normalized (Convert crlf => lf)
|
||||||
|
*.css text diff=css
|
||||||
|
*.scss text diff=css
|
||||||
|
*.sass text
|
||||||
|
*.df text
|
||||||
|
*.htm text diff=html
|
||||||
|
*.html text diff=html
|
||||||
|
*.js text
|
||||||
|
*.jsp text
|
||||||
|
*.jspf text
|
||||||
|
*.jspx text
|
||||||
|
*.properties text
|
||||||
|
*.tld text
|
||||||
|
*.tag text
|
||||||
|
*.tagx text
|
||||||
|
*.xml text
|
||||||
|
|
||||||
|
# These files are binary and should be left untouched
|
||||||
|
# (binary is a macro for -text -diff)
|
||||||
|
*.class binary
|
||||||
|
*.dll binary
|
||||||
|
*.ear binary
|
||||||
|
*.jar binary
|
||||||
|
*.so binary
|
||||||
|
*.war binary
|
||||||
|
*.jks binary
|
||||||
|
|
||||||
|
mvnw text eol=lf
|
||||||
|
gradlew text eol=lf
|
|
@ -50,7 +50,6 @@
|
||||||
* Not a singletron
|
* Not a singletron
|
||||||
*/
|
*/
|
||||||
public final class LaunchServer implements Runnable, AutoCloseable, Reconfigurable {
|
public final class LaunchServer implements Runnable, AutoCloseable, Reconfigurable {
|
||||||
public static final Class<? extends LauncherBinary> defaultLauncherEXEBinaryClass = null;
|
|
||||||
/**
|
/**
|
||||||
* Working folder path
|
* Working folder path
|
||||||
*/
|
*/
|
||||||
|
@ -95,8 +94,6 @@ public final class LaunchServer implements Runnable, AutoCloseable, Reconfigurab
|
||||||
* Pipeline for building EXE
|
* Pipeline for building EXE
|
||||||
*/
|
*/
|
||||||
public final LauncherBinary launcherEXEBinary;
|
public final LauncherBinary launcherEXEBinary;
|
||||||
//public static LaunchServer server = null;
|
|
||||||
public final Class<? extends LauncherBinary> launcherEXEBinaryClass;
|
|
||||||
// Server config
|
// Server config
|
||||||
public final AuthHookManager authHookManager;
|
public final AuthHookManager authHookManager;
|
||||||
public final LaunchServerModulesManager modulesManager;
|
public final LaunchServerModulesManager modulesManager;
|
||||||
|
@ -148,9 +145,6 @@ public LaunchServer(LaunchServerDirectories directories, LaunchServerEnv env, La
|
||||||
|
|
||||||
// Print keypair fingerprints
|
// Print keypair fingerprints
|
||||||
|
|
||||||
// Load class bindings.
|
|
||||||
launcherEXEBinaryClass = defaultLauncherEXEBinaryClass;
|
|
||||||
|
|
||||||
runtime.verify();
|
runtime.verify();
|
||||||
config.verify();
|
config.verify();
|
||||||
|
|
||||||
|
@ -276,12 +270,10 @@ public void invoke(String... args) throws Exception {
|
||||||
}
|
}
|
||||||
|
|
||||||
private LauncherBinary binary() {
|
private LauncherBinary binary() {
|
||||||
if (launcherEXEBinaryClass != null) {
|
LaunchServerLauncherExeInit event = new LaunchServerLauncherExeInit(this, null);
|
||||||
try {
|
modulesManager.invokeEvent(event);
|
||||||
return (LauncherBinary) MethodHandles.publicLookup().findConstructor(launcherEXEBinaryClass, MethodType.methodType(void.class, LaunchServer.class)).invoke(this);
|
if(event.binary != null) {
|
||||||
} catch (Throwable e) {
|
return event.binary;
|
||||||
logger.error(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Class.forName("net.sf.launch4j.Builder");
|
Class.forName("net.sf.launch4j.Builder");
|
||||||
|
@ -519,7 +511,7 @@ public void collect() {
|
||||||
launcherPackDir = getPath(LAUNCHERPACK_NAME);
|
launcherPackDir = getPath(LAUNCHERPACK_NAME);
|
||||||
if (keyDirectory == null) keyDirectory = getPath(KEY_NAME);
|
if (keyDirectory == null) keyDirectory = getPath(KEY_NAME);
|
||||||
if (tmpDir == null)
|
if (tmpDir == null)
|
||||||
tmpDir = Paths.get(System.getProperty("java.io.tmpdir")).resolve(String.format("launchserver-%s", SecurityHelper.randomStringToken()));
|
tmpDir = Paths.get(System.getProperty("java.io.tmpdir")).resolve("launchserver-%s".formatted(SecurityHelper.randomStringToken()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Path getPath(String dirName) {
|
private Path getPath(String dirName) {
|
||||||
|
|
|
@ -92,7 +92,7 @@ public void visit(final String name, final Object value) {
|
||||||
if ("value".equals(name)) {
|
if ("value".equals(name)) {
|
||||||
if (value.getClass() != String.class)
|
if (value.getClass() != String.class)
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
String.format("Invalid annotation with value class %s", field.getClass().getName()));
|
"Invalid annotation with value class %s".formatted(field.getClass().getName()));
|
||||||
valueName.set(value.toString());
|
valueName.set(value.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ public void visit(final String name, final Object value) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (initMethod == null) {
|
if (initMethod == null) {
|
||||||
throw new IllegalArgumentException(String.format("Not found init in target: %s", classNode.name));
|
throw new IllegalArgumentException("Not found init in target: %s".formatted(classNode.name));
|
||||||
}
|
}
|
||||||
List<FieldInsnNode> putFieldNodes = Arrays.stream(initMethod.instructions.toArray())
|
List<FieldInsnNode> putFieldNodes = Arrays.stream(initMethod.instructions.toArray())
|
||||||
.filter(node -> node instanceof FieldInsnNode && node.getOpcode() == Opcodes.PUTFIELD).map(p -> (FieldInsnNode) p)
|
.filter(node -> node instanceof FieldInsnNode && node.getOpcode() == Opcodes.PUTFIELD).map(p -> (FieldInsnNode) p)
|
||||||
|
@ -173,8 +173,7 @@ private static InsnList serializeValue(Object value) {
|
||||||
return ((Serializer) serializerEntry.getValue()).serialize(value);
|
return ((Serializer) serializerEntry.getValue()).serialize(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new UnsupportedOperationException(String.format("Serialization of type %s is not supported",
|
throw new UnsupportedOperationException("Serialization of type %s is not supported".formatted(value.getClass()));
|
||||||
value.getClass()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSerializableValue(Object value) {
|
public static boolean isSerializableValue(Object value) {
|
||||||
|
|
|
@ -72,11 +72,11 @@ public final void link(LaunchServer srv) {
|
||||||
links.forEach((k, v) -> {
|
links.forEach((k, v) -> {
|
||||||
AuthProviderPair pair = srv.config.getAuthProviderPair(v);
|
AuthProviderPair pair = srv.config.getAuthProviderPair(v);
|
||||||
if (pair == null) {
|
if (pair == null) {
|
||||||
throw new NullPointerException(String.format("Auth %s link failed. Pair %s not found", name, v));
|
throw new NullPointerException("Auth %s link failed. Pair %s not found".formatted(name, v));
|
||||||
}
|
}
|
||||||
if ("core".equals(k)) {
|
if ("core".equals(k)) {
|
||||||
if (pair.core == null)
|
if (pair.core == null)
|
||||||
throw new NullPointerException(String.format("Auth %s link failed. %s.core is null", name, v));
|
throw new NullPointerException("Auth %s link failed. %s.core is null".formatted(name, v));
|
||||||
core = pair.core;
|
core = pair.core;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import static java.util.concurrent.TimeUnit.MINUTES;
|
||||||
|
|
||||||
public final class MySQLSourceConfig implements AutoCloseable, SQLSourceConfig {
|
public final class MySQLSourceConfig implements AutoCloseable, SQLSourceConfig {
|
||||||
|
|
||||||
public static final int TIMEOUT = VerifyHelper.verifyInt(
|
public static final int TIMEOUT = VerifyHelper.verifyInt(
|
||||||
|
@ -33,6 +35,7 @@ public final class MySQLSourceConfig implements AutoCloseable, SQLSourceConfig {
|
||||||
private String password;
|
private String password;
|
||||||
private String database;
|
private String database;
|
||||||
private String timezone;
|
private String timezone;
|
||||||
|
private long hikariMaxLifetime = MINUTES.toMillis(30);
|
||||||
private boolean useHikari;
|
private boolean useHikari;
|
||||||
|
|
||||||
// Cache
|
// Cache
|
||||||
|
@ -108,8 +111,8 @@ public synchronized Connection getConnection() throws SQLException {
|
||||||
hikariConfig.setMaximumPoolSize(MAX_POOL_SIZE);
|
hikariConfig.setMaximumPoolSize(MAX_POOL_SIZE);
|
||||||
hikariConfig.setConnectionTestQuery("SELECT 1");
|
hikariConfig.setConnectionTestQuery("SELECT 1");
|
||||||
hikariConfig.setConnectionTimeout(1000);
|
hikariConfig.setConnectionTimeout(1000);
|
||||||
hikariConfig.setAutoCommit(true);
|
|
||||||
hikariConfig.setLeakDetectionThreshold(2000);
|
hikariConfig.setLeakDetectionThreshold(2000);
|
||||||
|
hikariConfig.setMaxLifetime(hikariMaxLifetime);
|
||||||
// Set HikariCP pool
|
// Set HikariCP pool
|
||||||
// Replace source with hds
|
// Replace source with hds
|
||||||
source = new HikariDataSource(hikariConfig);
|
source = new HikariDataSource(hikariConfig);
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import static java.util.concurrent.TimeUnit.MINUTES;
|
||||||
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
|
|
||||||
public final class PostgreSQLSourceConfig implements AutoCloseable, SQLSourceConfig {
|
public final class PostgreSQLSourceConfig implements AutoCloseable, SQLSourceConfig {
|
||||||
public static final int TIMEOUT = VerifyHelper.verifyInt(
|
public static final int TIMEOUT = VerifyHelper.verifyInt(
|
||||||
Integer.parseUnsignedInt(System.getProperty("launcher.postgresql.idleTimeout", Integer.toString(5000))),
|
Integer.parseUnsignedInt(System.getProperty("launcher.postgresql.idleTimeout", Integer.toString(5000))),
|
||||||
|
@ -27,6 +30,8 @@ public final class PostgreSQLSourceConfig implements AutoCloseable, SQLSourceCon
|
||||||
private String password;
|
private String password;
|
||||||
private String database;
|
private String database;
|
||||||
|
|
||||||
|
private long hikariMaxLifetime = MINUTES.toMillis(30); // 30 minutes
|
||||||
|
|
||||||
// Cache
|
// Cache
|
||||||
private transient DataSource source;
|
private transient DataSource source;
|
||||||
private transient boolean hikari;
|
private transient boolean hikari;
|
||||||
|
@ -65,7 +70,8 @@ public synchronized Connection getConnection() throws SQLException {
|
||||||
hikariSource.setPoolName(poolName);
|
hikariSource.setPoolName(poolName);
|
||||||
hikariSource.setMinimumIdle(0);
|
hikariSource.setMinimumIdle(0);
|
||||||
hikariSource.setMaximumPoolSize(MAX_POOL_SIZE);
|
hikariSource.setMaximumPoolSize(MAX_POOL_SIZE);
|
||||||
hikariSource.setIdleTimeout(TIMEOUT * 1000L);
|
hikariSource.setIdleTimeout(SECONDS.toMillis(TIMEOUT));
|
||||||
|
hikariSource.setMaxLifetime(hikariMaxLifetime);
|
||||||
|
|
||||||
// Replace source with hds
|
// Replace source with hds
|
||||||
source = hikariSource;
|
source = hikariSource;
|
||||||
|
|
|
@ -28,9 +28,12 @@
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static java.util.concurrent.TimeUnit.HOURS;
|
||||||
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
|
|
||||||
public abstract class AbstractSQLCoreProvider extends AuthCoreProvider {
|
public abstract class AbstractSQLCoreProvider extends AuthCoreProvider {
|
||||||
public final transient Logger logger = LogManager.getLogger();
|
public final transient Logger logger = LogManager.getLogger();
|
||||||
public int expireSeconds = 3600;
|
public long expireSeconds = HOURS.toSeconds(1);
|
||||||
public String uuidColumn;
|
public String uuidColumn;
|
||||||
public String usernameColumn;
|
public String usernameColumn;
|
||||||
public String accessTokenColumn;
|
public String accessTokenColumn;
|
||||||
|
@ -129,7 +132,7 @@ public AuthManager.AuthReport refreshAccessToken(String refreshToken, AuthRespon
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var accessToken = LegacySessionHelper.makeAccessJwtTokenFromString(user, LocalDateTime.now(Clock.systemUTC()).plusSeconds(expireSeconds), server.keyAgreementManager.ecdsaPrivateKey);
|
var accessToken = LegacySessionHelper.makeAccessJwtTokenFromString(user, LocalDateTime.now(Clock.systemUTC()).plusSeconds(expireSeconds), server.keyAgreementManager.ecdsaPrivateKey);
|
||||||
return new AuthManager.AuthReport(null, accessToken, refreshToken, expireSeconds * 1000L, new SQLUserSession(user));
|
return new AuthManager.AuthReport(null, accessToken, refreshToken, SECONDS.toMillis(expireSeconds), new SQLUserSession(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -153,9 +156,9 @@ public AuthManager.AuthReport authorize(String login, AuthResponse.AuthContext c
|
||||||
if (minecraftAccess) {
|
if (minecraftAccess) {
|
||||||
String minecraftAccessToken = SecurityHelper.randomStringToken();
|
String minecraftAccessToken = SecurityHelper.randomStringToken();
|
||||||
updateAuth(SQLUser, minecraftAccessToken);
|
updateAuth(SQLUser, minecraftAccessToken);
|
||||||
return AuthManager.AuthReport.ofOAuthWithMinecraft(minecraftAccessToken, accessToken, refreshToken, expireSeconds * 1000L, session);
|
return AuthManager.AuthReport.ofOAuthWithMinecraft(minecraftAccessToken, accessToken, refreshToken, SECONDS.toMillis(expireSeconds), session);
|
||||||
} else {
|
} else {
|
||||||
return AuthManager.AuthReport.ofOAuth(accessToken, refreshToken, expireSeconds * 1000L, session);
|
return AuthManager.AuthReport.ofOAuth(accessToken, refreshToken, SECONDS.toMillis(expireSeconds), session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,20 +173,20 @@ public void init(LaunchServer server) {
|
||||||
if (table == null) logger.error("table cannot be null");
|
if (table == null) logger.error("table cannot be null");
|
||||||
// Prepare SQL queries
|
// Prepare SQL queries
|
||||||
String userInfoCols = makeUserCols();
|
String userInfoCols = makeUserCols();
|
||||||
queryByUUIDSQL = customQueryByUUIDSQL != null ? customQueryByUUIDSQL : String.format("SELECT %s FROM %s WHERE %s=? LIMIT 1", userInfoCols,
|
queryByUUIDSQL = customQueryByUUIDSQL != null ? customQueryByUUIDSQL :
|
||||||
table, uuidColumn);
|
"SELECT %s FROM %s WHERE %s=? LIMIT 1".formatted(userInfoCols, table, uuidColumn);
|
||||||
queryByUsernameSQL = customQueryByUsernameSQL != null ? customQueryByUsernameSQL : String.format("SELECT %s FROM %s WHERE %s=? LIMIT 1",
|
queryByUsernameSQL = customQueryByUsernameSQL != null ? customQueryByUsernameSQL :
|
||||||
userInfoCols, table, usernameColumn);
|
"SELECT %s FROM %s WHERE %s=? LIMIT 1".formatted(userInfoCols, table, usernameColumn);
|
||||||
queryByLoginSQL = customQueryByLoginSQL != null ? customQueryByLoginSQL : queryByUsernameSQL;
|
queryByLoginSQL = customQueryByLoginSQL != null ? customQueryByLoginSQL : queryByUsernameSQL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
updateAuthSQL = customUpdateAuthSQL != null ? customUpdateAuthSQL : String.format("UPDATE %s SET %s=?, %s=NULL WHERE %s=?",
|
updateAuthSQL = customUpdateAuthSQL != null ? customUpdateAuthSQL :
|
||||||
table, accessTokenColumn, serverIDColumn, uuidColumn);
|
"UPDATE %s SET %s=?, %s=NULL WHERE %s=?".formatted(table, accessTokenColumn, serverIDColumn, uuidColumn);
|
||||||
updateServerIDSQL = customUpdateServerIdSQL != null ? customUpdateServerIdSQL : String.format("UPDATE %s SET %s=? WHERE %s=?",
|
updateServerIDSQL = customUpdateServerIdSQL != null ? customUpdateServerIdSQL :
|
||||||
table, serverIDColumn, uuidColumn);
|
"UPDATE %s SET %s=? WHERE %s=?".formatted(table, serverIDColumn, uuidColumn);
|
||||||
if (isEnabledPermissions()) {
|
if (isEnabledPermissions()) {
|
||||||
if(isEnabledRoles()) {
|
if(isEnabledRoles()) {
|
||||||
queryPermissionsByUUIDSQL = customQueryPermissionsByUUIDSQL != null ? customQueryPermissionsByUUIDSQL :
|
queryPermissionsByUUIDSQL = customQueryPermissionsByUUIDSQL != null ? customQueryPermissionsByUUIDSQL :
|
||||||
|
@ -198,14 +201,14 @@ public void init(LaunchServer server) {
|
||||||
"INNER JOIN " + permissionsTable + " pr ON r." + rolesUUIDColumn + "=substring(pr." + permissionsPermissionColumn + " from 6) or r." + rolesNameColumn + "=substring(pr." + permissionsPermissionColumn + " from 6)\n" +
|
"INNER JOIN " + permissionsTable + " pr ON r." + rolesUUIDColumn + "=substring(pr." + permissionsPermissionColumn + " from 6) or r." + rolesNameColumn + "=substring(pr." + permissionsPermissionColumn + " from 6)\n" +
|
||||||
"WHERE pr." + permissionsUUIDColumn + " = ?";
|
"WHERE pr." + permissionsUUIDColumn + " = ?";
|
||||||
} else {
|
} else {
|
||||||
queryPermissionsByUUIDSQL = customQueryPermissionsByUUIDSQL != null ? customQueryPermissionsByUUIDSQL : String.format("SELECT (%s) FROM %s WHERE %s=?",
|
queryPermissionsByUUIDSQL = customQueryPermissionsByUUIDSQL != null ? customQueryPermissionsByUUIDSQL :
|
||||||
permissionsPermissionColumn, permissionsTable, permissionsUUIDColumn);
|
"SELECT (%s) FROM %s WHERE %s=?".formatted(permissionsPermissionColumn, permissionsTable, permissionsUUIDColumn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String makeUserCols() {
|
protected String makeUserCols() {
|
||||||
return String.format("%s, %s, %s, %s, %s", uuidColumn, usernameColumn, accessTokenColumn, serverIDColumn, passwordColumn);
|
return "%s, %s, %s, %s, %s".formatted(uuidColumn, usernameColumn, accessTokenColumn, serverIDColumn, passwordColumn);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateAuth(User user, String accessToken) throws IOException {
|
protected void updateAuth(User user, String accessToken) throws IOException {
|
||||||
|
|
|
@ -46,21 +46,21 @@ public void init(LaunchServer server) {
|
||||||
String userInfoCols = makeUserCols();
|
String userInfoCols = makeUserCols();
|
||||||
String hardwareInfoCols = "id, hwDiskId, baseboardSerialNumber, displayId, bitness, totalMemory, logicalProcessors, physicalProcessors, processorMaxFreq, battery, id, graphicCard, banned, publicKey";
|
String hardwareInfoCols = "id, hwDiskId, baseboardSerialNumber, displayId, bitness, totalMemory, logicalProcessors, physicalProcessors, processorMaxFreq, battery, id, graphicCard, banned, publicKey";
|
||||||
if (sqlFindHardwareByPublicKey == null)
|
if (sqlFindHardwareByPublicKey == null)
|
||||||
sqlFindHardwareByPublicKey = String.format("SELECT %s FROM %s WHERE `publicKey` = ?", hardwareInfoCols, tableHWID);
|
sqlFindHardwareByPublicKey = "SELECT %s FROM %s WHERE `publicKey` = ?".formatted(hardwareInfoCols, tableHWID);
|
||||||
if (sqlFindHardwareById == null)
|
if (sqlFindHardwareById == null)
|
||||||
sqlFindHardwareById = String.format("SELECT %s FROM %s WHERE `id` = ?", hardwareInfoCols, tableHWID);
|
sqlFindHardwareById = "SELECT %s FROM %s WHERE `id` = ?".formatted(hardwareInfoCols, tableHWID);
|
||||||
if (sqlUsersByHwidId == null)
|
if (sqlUsersByHwidId == null)
|
||||||
sqlUsersByHwidId = String.format("SELECT %s FROM %s WHERE `%s` = ?", userInfoCols, table, hardwareIdColumn);
|
sqlUsersByHwidId = "SELECT %s FROM %s WHERE `%s` = ?".formatted(userInfoCols, table, hardwareIdColumn);
|
||||||
if (sqlFindHardwareByData == null)
|
if (sqlFindHardwareByData == null)
|
||||||
sqlFindHardwareByData = String.format("SELECT %s FROM %s", hardwareInfoCols, tableHWID);
|
sqlFindHardwareByData = "SELECT %s FROM %s".formatted(hardwareInfoCols, tableHWID);
|
||||||
if (sqlCreateHardware == null)
|
if (sqlCreateHardware == null)
|
||||||
sqlCreateHardware = String.format("INSERT INTO `%s` (`publickey`, `hwDiskId`, `baseboardSerialNumber`, `displayId`, `bitness`, `totalMemory`, `logicalProcessors`, `physicalProcessors`, `processorMaxFreq`, `graphicCard`, `battery`, `banned`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, '0')", tableHWID);
|
sqlCreateHardware = "INSERT INTO `%s` (`publickey`, `hwDiskId`, `baseboardSerialNumber`, `displayId`, `bitness`, `totalMemory`, `logicalProcessors`, `physicalProcessors`, `processorMaxFreq`, `graphicCard`, `battery`, `banned`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, '0')".formatted(tableHWID);
|
||||||
if (sqlCreateHWIDLog == null)
|
if (sqlCreateHWIDLog == null)
|
||||||
sqlCreateHWIDLog = String.format("INSERT INTO %s (`hwidId`, `newPublicKey`) VALUES (?, ?)", tableHWIDLog);
|
sqlCreateHWIDLog = "INSERT INTO %s (`hwidId`, `newPublicKey`) VALUES (?, ?)".formatted(tableHWIDLog);
|
||||||
if (sqlUpdateHardwarePublicKey == null)
|
if (sqlUpdateHardwarePublicKey == null)
|
||||||
sqlUpdateHardwarePublicKey = String.format("UPDATE %s SET `publicKey` = ? WHERE `id` = ?", tableHWID);
|
sqlUpdateHardwarePublicKey = "UPDATE %s SET `publicKey` = ? WHERE `id` = ?".formatted(tableHWID);
|
||||||
sqlUpdateHardwareBanned = String.format("UPDATE %s SET `banned` = ? WHERE `id` = ?", tableHWID);
|
sqlUpdateHardwareBanned = "UPDATE %s SET `banned` = ? WHERE `id` = ?".formatted(tableHWID);
|
||||||
sqlUpdateUsers = String.format("UPDATE %s SET `%s` = ? WHERE `%s` = ?", table, hardwareIdColumn, uuidColumn);
|
sqlUpdateUsers = "UPDATE %s SET `%s` = ? WHERE `%s` = ?".formatted(table, hardwareIdColumn, uuidColumn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
|
|
||||||
public class AdvancedProtectHandler extends StdProtectHandler implements SecureProtectHandler, HardwareProtectHandler, JoinServerProtectHandler {
|
public class AdvancedProtectHandler extends StdProtectHandler implements SecureProtectHandler, HardwareProtectHandler, JoinServerProtectHandler {
|
||||||
private transient final Logger logger = LogManager.getLogger();
|
private transient final Logger logger = LogManager.getLogger();
|
||||||
public boolean enableHardwareFeature;
|
public boolean enableHardwareFeature;
|
||||||
|
@ -104,7 +106,7 @@ public String createHardwareToken(String username, UserHardware hardware) {
|
||||||
return Jwts.builder()
|
return Jwts.builder()
|
||||||
.setIssuer("LaunchServer")
|
.setIssuer("LaunchServer")
|
||||||
.setSubject(username)
|
.setSubject(username)
|
||||||
.setExpiration(new Date(System.currentTimeMillis() + 1000 * server.config.netty.security.hardwareTokenExpire))
|
.setExpiration(new Date(System.currentTimeMillis() + SECONDS.toMillis(server.config.netty.security.hardwareTokenExpire)))
|
||||||
.claim("hardware", hardware.getId())
|
.claim("hardware", hardware.getId())
|
||||||
.signWith(server.keyAgreementManager.ecdsaPrivateKey)
|
.signWith(server.keyAgreementManager.ecdsaPrivateKey)
|
||||||
.compact();
|
.compact();
|
||||||
|
@ -114,7 +116,7 @@ public String createPublicKeyToken(String username, byte[] publicKey) {
|
||||||
return Jwts.builder()
|
return Jwts.builder()
|
||||||
.setIssuer("LaunchServer")
|
.setIssuer("LaunchServer")
|
||||||
.setSubject(username)
|
.setSubject(username)
|
||||||
.setExpiration(new Date(System.currentTimeMillis() + 1000 * server.config.netty.security.publicKeyTokenExpire))
|
.setExpiration(new Date(System.currentTimeMillis() + SECONDS.toMillis(server.config.netty.security.publicKeyTokenExpire)))
|
||||||
.claim("publicKey", Base64.getEncoder().encodeToString(publicKey))
|
.claim("publicKey", Base64.getEncoder().encodeToString(publicKey))
|
||||||
.signWith(server.keyAgreementManager.ecdsaPrivateKey)
|
.signWith(server.keyAgreementManager.ecdsaPrivateKey)
|
||||||
.compact();
|
.compact();
|
||||||
|
|
|
@ -44,11 +44,11 @@ public boolean canGetUpdates(String updatesDirName, Client client) {
|
||||||
|
|
||||||
private boolean isWhitelisted(String property, ClientProfile profile, Client client) {
|
private boolean isWhitelisted(String property, ClientProfile profile, Client client) {
|
||||||
if (client.permissions != null) {
|
if (client.permissions != null) {
|
||||||
String permByUUID = String.format(property, profile.getUUID());
|
String permByUUID = property.formatted(profile.getUUID());
|
||||||
if (client.permissions.hasPerm(permByUUID)) {
|
if (client.permissions.hasPerm(permByUUID)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
String permByTitle = String.format(property, profile.getTitle().toLowerCase(Locale.ROOT));
|
String permByTitle = property.formatted(profile.getTitle().toLowerCase(Locale.ROOT));
|
||||||
if (client.permissions.hasPerm(permByTitle)) {
|
if (client.permissions.hasPerm(permByTitle)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ public void build(Path target, boolean deleteTempFiles) throws IOException {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String nextName(String taskName) {
|
public String nextName(String taskName) {
|
||||||
return String.format(nameFormat, taskName, count.getAndIncrement());
|
return nameFormat.formatted(taskName, count.getAndIncrement());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Path nextPath(String taskName) {
|
public Path nextPath(String taskName) {
|
||||||
|
|
|
@ -27,7 +27,7 @@ public Launch4JTask(LaunchServer launchServer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String formatVars(String mask) {
|
public static String formatVars(String mask) {
|
||||||
return String.format(mask, VERSION, BUILD);
|
return mask.formatted(VERSION, BUILD);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -59,7 +59,7 @@ protected Downloader downloadWithProgressBar(String taskName, List<AsyncDownload
|
||||||
.setStyle(ProgressBarStyle.COLORFUL_UNICODE_BLOCK)
|
.setStyle(ProgressBarStyle.COLORFUL_UNICODE_BLOCK)
|
||||||
.setUnit("MB", 1024 * 1024)
|
.setUnit("MB", 1024 * 1024)
|
||||||
.build();
|
.build();
|
||||||
bar.setExtraMessage(String.format(" [0/%d]", totalFiles));
|
bar.setExtraMessage(" [0/%d]".formatted(totalFiles));
|
||||||
Downloader downloader = Downloader.downloadList(list, baseUrl, targetDir, new Downloader.DownloadCallback() {
|
Downloader downloader = Downloader.downloadList(list, baseUrl, targetDir, new Downloader.DownloadCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void apply(long fullDiff) {
|
public void apply(long fullDiff) {
|
||||||
|
@ -69,7 +69,7 @@ public void apply(long fullDiff) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onComplete(Path path) {
|
public void onComplete(Path path) {
|
||||||
bar.setExtraMessage(String.format(" [%d/%d]", currentFiles.incrementAndGet(), totalFiles));
|
bar.setExtraMessage(" [%d/%d]".formatted(currentFiles.incrementAndGet(), totalFiles));
|
||||||
}
|
}
|
||||||
}, null, 4);
|
}, null, 4);
|
||||||
downloader.getFuture().handle((v, e) -> {
|
downloader.getFuture().handle((v, e) -> {
|
||||||
|
|
|
@ -86,7 +86,7 @@ public void invoke(String... args) throws IOException, CommandException {
|
||||||
if (version.compareTo(ClientProfileVersions.MINECRAFT_1_7_10) <= 0) {
|
if (version.compareTo(ClientProfileVersions.MINECRAFT_1_7_10) <= 0) {
|
||||||
logger.warn("Minecraft 1.7.9 and below not supported. Use at your own risk");
|
logger.warn("Minecraft 1.7.9 and below not supported. Use at your own risk");
|
||||||
}
|
}
|
||||||
MakeProfileHelper.MakeProfileOption[] options = MakeProfileHelper.getMakeProfileOptionsFromDir(clientDir, version, Files.exists(server.updatesDir.resolve("assets")));
|
MakeProfileHelper.MakeProfileOption[] options = MakeProfileHelper.getMakeProfileOptionsFromDir(clientDir, version);
|
||||||
for (MakeProfileHelper.MakeProfileOption option : options) {
|
for (MakeProfileHelper.MakeProfileOption option : options) {
|
||||||
logger.debug("Detected option {}", option.getClass().getSimpleName());
|
logger.debug("Detected option {}", option.getClass().getSimpleName());
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ public String getUsageDescription() {
|
||||||
public void invoke(String... args) throws Exception {
|
public void invoke(String... args) throws Exception {
|
||||||
verifyArgs(args, 3);
|
verifyArgs(args, 3);
|
||||||
ClientProfile.Version version = parseClientVersion(args[1]);
|
ClientProfile.Version version = parseClientVersion(args[1]);
|
||||||
MakeProfileHelper.MakeProfileOption[] options = MakeProfileHelper.getMakeProfileOptionsFromDir(server.updatesDir.resolve(args[2]), version, Files.exists(server.updatesDir.resolve("assets")));
|
MakeProfileHelper.MakeProfileOption[] options = MakeProfileHelper.getMakeProfileOptionsFromDir(server.updatesDir.resolve(args[2]), version);
|
||||||
for (MakeProfileHelper.MakeProfileOption option : options) {
|
for (MakeProfileHelper.MakeProfileOption option : options) {
|
||||||
logger.info("Detected option {}", option);
|
logger.info("Detected option {}", option);
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,8 +60,8 @@ public void invoke(String... args) throws Exception {
|
||||||
logger.error("Component {} not found", componentName);
|
logger.error("Component {} not found", componentName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (component instanceof AutoCloseable) {
|
if (component instanceof AutoCloseable autoCloseable) {
|
||||||
((AutoCloseable) component).close();
|
autoCloseable.close();
|
||||||
}
|
}
|
||||||
server.unregisterObject("component." + componentName, component);
|
server.unregisterObject("component." + componentName, component);
|
||||||
server.config.components.remove(componentName);
|
server.config.components.remove(componentName);
|
||||||
|
|
|
@ -38,11 +38,11 @@ public SecurityCheckCommand(LaunchServer server) {
|
||||||
|
|
||||||
public static void printCheckResult(String module, String comment, Boolean status) {
|
public static void printCheckResult(String module, String comment, Boolean status) {
|
||||||
if (status == null) {
|
if (status == null) {
|
||||||
logger.warn(String.format("[%s] %s", module, comment));
|
logger.warn("[%s] %s".formatted(module, comment));
|
||||||
} else if (status) {
|
} else if (status) {
|
||||||
logger.info(String.format("[%s] %s OK", module, comment));
|
logger.info("[%s] %s OK".formatted(module, comment));
|
||||||
} else {
|
} else {
|
||||||
logger.error(String.format("[%s] %s", module, comment));
|
logger.error("[%s] %s".formatted(module, comment));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,11 +153,11 @@ public void invoke(String... args) {
|
||||||
//Profiles
|
//Profiles
|
||||||
for (ClientProfile profile : server.getProfiles()) {
|
for (ClientProfile profile : server.getProfiles()) {
|
||||||
boolean bad = false;
|
boolean bad = false;
|
||||||
String profileModuleName = String.format("profiles.%s", profile.getTitle());
|
String profileModuleName = "profiles.%s".formatted(profile.getTitle());
|
||||||
for (String exc : profile.getUpdateExclusions()) {
|
for (String exc : profile.getUpdateExclusions()) {
|
||||||
StringTokenizer tokenizer = new StringTokenizer(exc, "/");
|
StringTokenizer tokenizer = new StringTokenizer(exc, "/");
|
||||||
if (exc.endsWith(".jar")) {
|
if (exc.endsWith(".jar")) {
|
||||||
printCheckResult(profileModuleName, String.format("updateExclusions %s not safe. Cheats may be injected very easy!", exc), false);
|
printCheckResult(profileModuleName, "updateExclusions %s not safe. Cheats may be injected very easy!".formatted(exc), false);
|
||||||
bad = true;
|
bad = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -165,12 +165,12 @@ public void invoke(String... args) {
|
||||||
String nextToken = tokenizer.nextToken();
|
String nextToken = tokenizer.nextToken();
|
||||||
if (!tokenizer.hasMoreTokens()) {
|
if (!tokenizer.hasMoreTokens()) {
|
||||||
if (!exc.endsWith("/")) {
|
if (!exc.endsWith("/")) {
|
||||||
printCheckResult(profileModuleName, String.format("updateExclusions %s not safe. Cheats may be injected very easy!", exc), false);
|
printCheckResult(profileModuleName, "updateExclusions %s not safe. Cheats may be injected very easy!".formatted(exc), false);
|
||||||
bad = true;
|
bad = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (nextToken.equals("memory_repo") || nextToken.equals(profile.getVersion().toString())) {
|
if (nextToken.equals("memory_repo") || nextToken.equals(profile.getVersion().toString())) {
|
||||||
printCheckResult(profileModuleName, String.format("updateExclusions %s not safe. Cheats may be injected very easy!", exc), false);
|
printCheckResult(profileModuleName, "updateExclusions %s not safe. Cheats may be injected very easy!".formatted(exc), false);
|
||||||
bad = true;
|
bad = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ public void invoke(String... args) throws Exception {
|
||||||
verifyArgs(args, 1);
|
verifyArgs(args, 1);
|
||||||
Path targetDir = Paths.get(args[0]);
|
Path targetDir = Paths.get(args[0]);
|
||||||
if (!IOHelper.isDir(targetDir))
|
if (!IOHelper.isDir(targetDir))
|
||||||
throw new IllegalArgumentException(String.format("%s not directory", targetDir));
|
throw new IllegalArgumentException("%s not directory".formatted(targetDir));
|
||||||
Optional<SignJarTask> task = server.launcherBinary.getTaskByClass(SignJarTask.class);
|
Optional<SignJarTask> task = server.launcherBinary.getTaskByClass(SignJarTask.class);
|
||||||
if (task.isEmpty()) throw new IllegalStateException("SignJarTask not found");
|
if (task.isEmpty()) throw new IllegalStateException("SignJarTask not found");
|
||||||
IOHelper.walk(targetDir, new SignJarVisitor(task.get()), true);
|
IOHelper.walk(targetDir, new SignJarVisitor(task.get()), true);
|
||||||
|
|
|
@ -16,7 +16,7 @@ public abstract class AbstractLimiter<T> extends Component implements Reconfigur
|
||||||
protected final transient Map<T, LimitEntry> map = new HashMap<>();
|
protected final transient Map<T, LimitEntry> map = new HashMap<>();
|
||||||
private transient final Logger logger = LogManager.getLogger();
|
private transient final Logger logger = LogManager.getLogger();
|
||||||
public int rateLimit;
|
public int rateLimit;
|
||||||
public int rateLimitMillis;
|
public long rateLimitMillis;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Command> getCommands() {
|
public Map<String, Command> getCommands() {
|
||||||
|
|
|
@ -133,7 +133,7 @@ public Path process(Path inputFile) throws IOException {
|
||||||
if (component.enabled) {
|
if (component.enabled) {
|
||||||
Configuration proguard_cfg = new Configuration();
|
Configuration proguard_cfg = new Configuration();
|
||||||
if (!checkJMods(IOHelper.JVM_DIR.resolve("jmods"))) {
|
if (!checkJMods(IOHelper.JVM_DIR.resolve("jmods"))) {
|
||||||
throw new RuntimeException(String.format("Java path: %s is not JDK! Please install JDK", IOHelper.JVM_DIR));
|
throw new RuntimeException("Java path: %s is not JDK! Please install JDK".formatted(IOHelper.JVM_DIR));
|
||||||
}
|
}
|
||||||
Path jfxPath = tryFindOpenJFXPath(IOHelper.JVM_DIR);
|
Path jfxPath = tryFindOpenJFXPath(IOHelper.JVM_DIR);
|
||||||
if (checkFXJMods(IOHelper.JVM_DIR.resolve("jmods"))) {
|
if (checkFXJMods(IOHelper.JVM_DIR.resolve("jmods"))) {
|
||||||
|
@ -212,7 +212,7 @@ public String[] buildConfig(Path inputJar, Path outputJar, Path[] jfxPath) {
|
||||||
Collections.addAll(confStrs, JAVA9_OPTS);
|
Collections.addAll(confStrs, JAVA9_OPTS);
|
||||||
if (jfxPath != null) {
|
if (jfxPath != null) {
|
||||||
for (Path path : jfxPath) {
|
for (Path path : jfxPath) {
|
||||||
confStrs.add(String.format("-libraryjars '%s'", path.toAbsolutePath()));
|
confStrs.add("-libraryjars '%s'".formatted(path.toAbsolutePath()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
srv.launcherBinary.coreLibs.stream()
|
srv.launcherBinary.coreLibs.stream()
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import static java.util.concurrent.TimeUnit.HOURS;
|
||||||
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
|
|
||||||
public final class LaunchServerConfig {
|
public final class LaunchServerConfig {
|
||||||
private final static List<String> oldMirrorList = List.of("https://mirror.gravit.pro/5.2.x/", "https://mirror.gravit.pro/5.3.x/", "https://mirror.gravitlauncher.com/5.2.x/", "https://mirror.gravitlauncher.com/5.3.x/");
|
private final static List<String> oldMirrorList = List.of("https://mirror.gravit.pro/5.2.x/", "https://mirror.gravit.pro/5.3.x/", "https://mirror.gravitlauncher.com/5.2.x/", "https://mirror.gravitlauncher.com/5.3.x/");
|
||||||
private transient final Logger logger = LogManager.getLogger();
|
private transient final Logger logger = LogManager.getLogger();
|
||||||
|
@ -94,12 +97,12 @@ public static LaunchServerConfig getDefault(LaunchServer.LaunchServerEnv env) {
|
||||||
newConfig.components = new HashMap<>();
|
newConfig.components = new HashMap<>();
|
||||||
AuthLimiterComponent authLimiterComponent = new AuthLimiterComponent();
|
AuthLimiterComponent authLimiterComponent = new AuthLimiterComponent();
|
||||||
authLimiterComponent.rateLimit = 3;
|
authLimiterComponent.rateLimit = 3;
|
||||||
authLimiterComponent.rateLimitMillis = 8000;
|
authLimiterComponent.rateLimitMillis = SECONDS.toMillis(8);
|
||||||
authLimiterComponent.message = "Превышен лимит авторизаций";
|
authLimiterComponent.message = "Превышен лимит авторизаций";
|
||||||
newConfig.components.put("authLimiter", authLimiterComponent);
|
newConfig.components.put("authLimiter", authLimiterComponent);
|
||||||
RegLimiterComponent regLimiterComponent = new RegLimiterComponent();
|
RegLimiterComponent regLimiterComponent = new RegLimiterComponent();
|
||||||
regLimiterComponent.rateLimit = 3;
|
regLimiterComponent.rateLimit = 3;
|
||||||
regLimiterComponent.rateLimitMillis = 1000 * 60 * 60 * 10; //Блок на 10 часов
|
regLimiterComponent.rateLimitMillis = HOURS.toMillis(10);
|
||||||
regLimiterComponent.message = "Превышен лимит регистраций";
|
regLimiterComponent.message = "Превышен лимит регистраций";
|
||||||
newConfig.components.put("regLimiter", regLimiterComponent);
|
newConfig.components.put("regLimiter", regLimiterComponent);
|
||||||
ProGuardComponent proGuardComponent = new ProGuardComponent();
|
ProGuardComponent proGuardComponent = new ProGuardComponent();
|
||||||
|
@ -209,9 +212,9 @@ public void close(LaunchServer.ReloadType type) {
|
||||||
if (type.equals(LaunchServer.ReloadType.FULL)) {
|
if (type.equals(LaunchServer.ReloadType.FULL)) {
|
||||||
components.forEach((k, component) -> {
|
components.forEach((k, component) -> {
|
||||||
server.unregisterObject("component.".concat(k), component);
|
server.unregisterObject("component.".concat(k), component);
|
||||||
if (component instanceof AutoCloseable) {
|
if (component instanceof AutoCloseable autoCloseable) {
|
||||||
try {
|
try {
|
||||||
((AutoCloseable) component).close();
|
autoCloseable.close();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error(e);
|
logger.error(e);
|
||||||
}
|
}
|
||||||
|
@ -310,9 +313,9 @@ public NettyBindAddress(String address, int port) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class NettySecurityConfig {
|
public static class NettySecurityConfig {
|
||||||
public long hardwareTokenExpire = 60 * 60 * 8;
|
public long hardwareTokenExpire = HOURS.toSeconds(8);
|
||||||
public long publicKeyTokenExpire = 60 * 60 * 8;
|
public long publicKeyTokenExpire = HOURS.toSeconds(8);
|
||||||
|
|
||||||
public long launcherTokenExpire = 60 * 60 * 8;
|
public long launcherTokenExpire = HOURS.toSeconds(8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ public T getOrThrow() throws RequestException {
|
||||||
if (isSuccessful()) {
|
if (isSuccessful()) {
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
throw new RequestException(error == null ? String.format("statusCode %d", statusCode) : error.toString());
|
throw new RequestException(error == null ? "statusCode %d".formatted(statusCode) : error.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ public static String makeRefreshTokenFromPassword(String username, String rawPas
|
||||||
rawPassword = "";
|
rawPassword = "";
|
||||||
}
|
}
|
||||||
return SecurityHelper.toHex(SecurityHelper.digest(SecurityHelper.DigestAlgorithm.SHA256,
|
return SecurityHelper.toHex(SecurityHelper.digest(SecurityHelper.DigestAlgorithm.SHA256,
|
||||||
String.format("%s.%s.%s.%s", secretSalt, username, rawPassword, secretSalt)));
|
"%s.%s.%s.%s".formatted(secretSalt, username, rawPassword, secretSalt)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public record JwtTokenInfo(String username, UUID uuid) {
|
public record JwtTokenInfo(String username, UUID uuid) {
|
||||||
|
|
|
@ -19,13 +19,9 @@ public static ClientProfile makeProfile(ClientProfile.Version version, String ti
|
||||||
ClientProfileBuilder builder = new ClientProfileBuilder();
|
ClientProfileBuilder builder = new ClientProfileBuilder();
|
||||||
builder.setVersion(version);
|
builder.setVersion(version);
|
||||||
builder.setDir(title);
|
builder.setDir(title);
|
||||||
if (findOption(options, MakeProfileOptionGlobalAssets.class).isPresent()) {
|
builder.setAssetDir("assets");
|
||||||
builder.setAssetDir("assets");
|
|
||||||
} else {
|
|
||||||
builder.setAssetDir("asset" + version.toCleanString());
|
|
||||||
}
|
|
||||||
builder.setAssetIndex(version.toString());
|
builder.setAssetIndex(version.toString());
|
||||||
builder.setInfo("Информация о сервере");
|
builder.setInfo("Server description");
|
||||||
builder.setTitle(title);
|
builder.setTitle(title);
|
||||||
builder.setUuid(UUID.randomUUID());
|
builder.setUuid(UUID.randomUUID());
|
||||||
builder.setMainClass(getMainClassByVersion(version, options));
|
builder.setMainClass(getMainClassByVersion(version, options));
|
||||||
|
@ -209,7 +205,7 @@ private static String getLog4jVersion(Path dir) throws IOException {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MakeProfileOption[] getMakeProfileOptionsFromDir(Path dir, ClientProfile.Version version, boolean globalAssets) throws IOException {
|
public static MakeProfileOption[] getMakeProfileOptionsFromDir(Path dir, ClientProfile.Version version) throws IOException {
|
||||||
List<MakeProfileOption> options = new ArrayList<>(2);
|
List<MakeProfileOption> options = new ArrayList<>(2);
|
||||||
if (Files.exists(dir.resolve("forge.jar"))) {
|
if (Files.exists(dir.resolve("forge.jar"))) {
|
||||||
options.add(new MakeProfileOptionForge());
|
options.add(new MakeProfileOptionForge());
|
||||||
|
@ -247,9 +243,6 @@ public static MakeProfileOption[] getMakeProfileOptionsFromDir(Path dir, ClientP
|
||||||
if (Files.exists(dir.resolve("libraries/forge/launchwrapper-1.12-launcherfixed.jar.jar")) || Files.exists(dir.resolve("libraries/net/minecraft/launchwrapper"))) {
|
if (Files.exists(dir.resolve("libraries/forge/launchwrapper-1.12-launcherfixed.jar.jar")) || Files.exists(dir.resolve("libraries/net/minecraft/launchwrapper"))) {
|
||||||
options.add(new MakeProfileOptionLaunchWrapper());
|
options.add(new MakeProfileOptionLaunchWrapper());
|
||||||
}
|
}
|
||||||
if (globalAssets) {
|
|
||||||
options.add(new MakeProfileOptionGlobalAssets());
|
|
||||||
}
|
|
||||||
return options.toArray(new MakeProfileOption[0]);
|
return options.toArray(new MakeProfileOption[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,10 +318,6 @@ public static class MakeProfileOptionLaunchWrapper implements MakeProfileOption
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class MakeProfileOptionGlobalAssets implements MakeProfileOption {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class MakeProfileOptionFabric implements MakeProfileOption {
|
public static class MakeProfileOptionFabric implements MakeProfileOption {
|
||||||
public String jimfsPath;
|
public String jimfsPath;
|
||||||
public String guavaPath;
|
public String guavaPath;
|
||||||
|
|
|
@ -133,7 +133,7 @@ public AuthReport auth(AuthResponse.AuthContext context, AuthRequest.AuthPasswor
|
||||||
internalAuth(context.client, context.authType, context.pair, user.getUsername(), user.getUUID(), user.getPermissions(), result.isUsingOAuth());
|
internalAuth(context.client, context.authType, context.pair, user.getUsername(), user.getUUID(), user.getPermissions(), result.isUsingOAuth());
|
||||||
return result;
|
return result;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
if (e instanceof AuthException) throw (AuthException) e;
|
if (e instanceof AuthException authException) throw authException;
|
||||||
logger.error(e);
|
logger.error(e);
|
||||||
throw new AuthException("Internal Auth Error");
|
throw new AuthException("Internal Auth Error");
|
||||||
}
|
}
|
||||||
|
@ -272,19 +272,19 @@ public AuthRequest.AuthPasswordInterface decryptPassword(AuthRequest.AuthPasswor
|
||||||
}
|
}
|
||||||
|
|
||||||
private AuthRequest.AuthPasswordInterface tryDecryptPasswordPlain(AuthRequest.AuthPasswordInterface password) throws AuthException {
|
private AuthRequest.AuthPasswordInterface tryDecryptPasswordPlain(AuthRequest.AuthPasswordInterface password) throws AuthException {
|
||||||
if (password instanceof AuthAESPassword) {
|
if (password instanceof AuthAESPassword authAESPassword) {
|
||||||
try {
|
try {
|
||||||
return new AuthPlainPassword(IOHelper.decode(SecurityHelper.decrypt(server.runtime.passwordEncryptKey
|
return new AuthPlainPassword(IOHelper.decode(SecurityHelper.decrypt(server.runtime.passwordEncryptKey
|
||||||
, ((AuthAESPassword) password).password)));
|
, authAESPassword.password)));
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
throw new AuthException("Password decryption error");
|
throw new AuthException("Password decryption error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (password instanceof AuthRSAPassword) {
|
if (password instanceof AuthRSAPassword authRSAPassword) {
|
||||||
try {
|
try {
|
||||||
Cipher cipher = SecurityHelper.newRSADecryptCipher(server.keyAgreementManager.rsaPrivateKey);
|
Cipher cipher = SecurityHelper.newRSADecryptCipher(server.keyAgreementManager.rsaPrivateKey);
|
||||||
return new AuthPlainPassword(
|
return new AuthPlainPassword(
|
||||||
IOHelper.decode(cipher.doFinal(((AuthRSAPassword) password).password))
|
IOHelper.decode(cipher.doFinal(authRSAPassword.password))
|
||||||
);
|
);
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
throw new AuthException("Password decryption error");
|
throw new AuthException("Password decryption error");
|
||||||
|
@ -313,7 +313,7 @@ public boolean accept(Client client, AuthProviderPair pair, String extendedToken
|
||||||
client.auth = server.config.getAuthProviderPair(info.authId);
|
client.auth = server.config.getAuthProviderPair(info.authId);
|
||||||
if (client.permissions == null) client.permissions = new ClientPermissions();
|
if (client.permissions == null) client.permissions = new ClientPermissions();
|
||||||
client.permissions.addPerm("launchserver.checkserver");
|
client.permissions.addPerm("launchserver.checkserver");
|
||||||
client.permissions.addPerm(String.format("launchserver.profile.%s.show", info.serverName));
|
client.permissions.addPerm("launchserver.profile.%s.show".formatted(info.serverName));
|
||||||
client.setProperty("launchserver.serverName", info.serverName);
|
client.setProperty("launchserver.serverName", info.serverName);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ public void downloadZip(Path path, String mask, Object... args) throws IOExcepti
|
||||||
if (downloadZip(mirror, path, mask, args)) return;
|
if (downloadZip(mirror, path, mask, args)) return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new IOException(String.format("Error download %s. All mirrors return error", path.toString()));
|
throw new IOException("Error download %s. All mirrors return error".formatted(path.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonElement jsonRequest(Mirror mirror, JsonElement request, String method, String mask, Object... args) throws IOException {
|
public JsonElement jsonRequest(Mirror mirror, JsonElement request, String method, String mask, Object... args) throws IOException {
|
||||||
|
@ -111,7 +111,7 @@ public static class Mirror {
|
||||||
|
|
||||||
private URL formatArgs(String mask, Object... args) throws MalformedURLException {
|
private URL formatArgs(String mask, Object... args) throws MalformedURLException {
|
||||||
Object[] data = Arrays.stream(args).map(e -> IOHelper.urlEncode(e.toString())).toArray();
|
Object[] data = Arrays.stream(args).map(e -> IOHelper.urlEncode(e.toString())).toArray();
|
||||||
return new URL(baseUrl.concat(String.format(mask, data)));
|
return new URL(baseUrl.concat(mask.formatted(data)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public URL getURL(String mask, Object... args) throws MalformedURLException {
|
public URL getURL(String mask, Object... args) throws MalformedURLException {
|
||||||
|
|
|
@ -14,7 +14,7 @@ public class ReconfigurableManager {
|
||||||
|
|
||||||
public void registerReconfigurable(String name, Reconfigurable reconfigurable) {
|
public void registerReconfigurable(String name, Reconfigurable reconfigurable) {
|
||||||
VerifyHelper.putIfAbsent(RECONFIGURABLE, name.toLowerCase(), new ReconfigurableVirtualCommand(reconfigurable.getCommands()),
|
VerifyHelper.putIfAbsent(RECONFIGURABLE, name.toLowerCase(), new ReconfigurableVirtualCommand(reconfigurable.getCommands()),
|
||||||
String.format("Reconfigurable has been already registered: '%s'", name));
|
"Reconfigurable has been already registered: '%s'".formatted(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unregisterReconfigurable(String name) {
|
public void unregisterReconfigurable(String name) {
|
||||||
|
@ -23,15 +23,15 @@ public void unregisterReconfigurable(String name) {
|
||||||
|
|
||||||
public void call(String name, String action, String[] args) throws Exception {
|
public void call(String name, String action, String[] args) throws Exception {
|
||||||
Command commands = RECONFIGURABLE.get(name);
|
Command commands = RECONFIGURABLE.get(name);
|
||||||
if (commands == null) throw new CommandException(String.format("Reconfigurable %s not found", name));
|
if (commands == null) throw new CommandException("Reconfigurable %s not found".formatted(name));
|
||||||
Command command = commands.childCommands.get(action);
|
Command command = commands.childCommands.get(action);
|
||||||
if (command == null) throw new CommandException(String.format("Action %s.%s not found", name, action));
|
if (command == null) throw new CommandException("Action %s.%s not found".formatted(name, action));
|
||||||
command.invoke(args);
|
command.invoke(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void printHelp(String name) throws CommandException {
|
public void printHelp(String name) throws CommandException {
|
||||||
Command commands = RECONFIGURABLE.get(name);
|
Command commands = RECONFIGURABLE.get(name);
|
||||||
if (commands == null) throw new CommandException(String.format("Reconfigurable %s not found", name));
|
if (commands == null) throw new CommandException("Reconfigurable %s not found".formatted(name));
|
||||||
HelpCommand.printSubCommandsHelp(name, commands);
|
HelpCommand.printSubCommandsHelp(name, commands);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package pro.gravit.launchserver.modules.events;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.modules.LauncherModule;
|
||||||
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
|
import pro.gravit.launchserver.binary.LauncherBinary;
|
||||||
|
|
||||||
|
public class LaunchServerLauncherExeInit extends LauncherModule.Event {
|
||||||
|
public final LaunchServer server;
|
||||||
|
public LauncherBinary binary;
|
||||||
|
|
||||||
|
public LaunchServerLauncherExeInit(LaunchServer server, LauncherBinary binary) {
|
||||||
|
this.server = server;
|
||||||
|
this.binary = binary;
|
||||||
|
}
|
||||||
|
}
|
|
@ -145,9 +145,7 @@ void process(WebSocketRequestContext context, WebSocketServerResponse response,
|
||||||
logger.error("WebSocket request processing failed", e);
|
logger.error("WebSocket request processing failed", e);
|
||||||
RequestEvent event;
|
RequestEvent event;
|
||||||
event = new ErrorRequestEvent("Fatal server error. Contact administrator");
|
event = new ErrorRequestEvent("Fatal server error. Contact administrator");
|
||||||
if (response instanceof SimpleResponse) {
|
if (response instanceof SimpleResponse simpleResponse) event.requestUUID = simpleResponse.requestUUID;
|
||||||
event.requestUUID = ((SimpleResponse) response).requestUUID;
|
|
||||||
}
|
|
||||||
sendObject(ctx.channel(), event);
|
sendObject(ctx.channel(), event);
|
||||||
}
|
}
|
||||||
hookComplete.hook(context);
|
hookComplete.hook(context);
|
||||||
|
|
|
@ -19,8 +19,8 @@ public NettyIpForwardHandler(NettyConnectContext context) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void decode(ChannelHandlerContext ctx, HttpRequest msg, List<Object> out) {
|
protected void decode(ChannelHandlerContext ctx, HttpRequest msg, List<Object> out) {
|
||||||
if (msg instanceof ReferenceCounted) {
|
if (msg instanceof ReferenceCounted referenceCounted) {
|
||||||
((ReferenceCounted) msg).retain();
|
referenceCounted.retain();
|
||||||
}
|
}
|
||||||
if (context.ip != null) {
|
if (context.ip != null) {
|
||||||
out.add(msg);
|
out.add(msg);
|
||||||
|
|
|
@ -63,16 +63,16 @@ protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) {
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
logger.error("WebSocket frame handler hook error", ex);
|
logger.error("WebSocket frame handler hook error", ex);
|
||||||
}
|
}
|
||||||
if (frame instanceof TextWebSocketFrame) {
|
if (frame instanceof TextWebSocketFrame textWebSocketFrame) {
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace("Message from {}: {}", context.ip == null ? IOHelper.getIP(ctx.channel().remoteAddress()) : context.ip, ((TextWebSocketFrame) frame).text());
|
logger.trace("Message from {}: {}", context.ip == null ? IOHelper.getIP(ctx.channel().remoteAddress()) : context.ip, textWebSocketFrame.text());
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
service.process(ctx, (TextWebSocketFrame) frame, client, context.ip);
|
service.process(ctx, textWebSocketFrame, client, context.ip);
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
logger.warn("Client {} send invalid request. Connection force closed.", context.ip == null ? IOHelper.getIP(ctx.channel().remoteAddress()) : context.ip);
|
logger.warn("Client {} send invalid request. Connection force closed.", context.ip == null ? IOHelper.getIP(ctx.channel().remoteAddress()) : context.ip);
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace("Client message: {}", ((TextWebSocketFrame) frame).text());
|
logger.trace("Client message: {}", textWebSocketFrame.text());
|
||||||
logger.error("Process websockets request failed", ex);
|
logger.error("Process websockets request failed", ex);
|
||||||
}
|
}
|
||||||
ctx.channel().close();
|
ctx.channel().close();
|
||||||
|
@ -81,10 +81,10 @@ protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) {
|
||||||
frame.content().retain();
|
frame.content().retain();
|
||||||
ctx.channel().writeAndFlush(new PongWebSocketFrame(frame.content()));
|
ctx.channel().writeAndFlush(new PongWebSocketFrame(frame.content()));
|
||||||
//return;
|
//return;
|
||||||
} else if ((frame instanceof PongWebSocketFrame)) {
|
} else if (frame instanceof PongWebSocketFrame) {
|
||||||
logger.trace("WebSocket Client received pong");
|
logger.trace("WebSocket Client received pong");
|
||||||
} else if ((frame instanceof CloseWebSocketFrame)) {
|
} else if (frame instanceof CloseWebSocketFrame closeWebSocketFrame) {
|
||||||
int statusCode = ((CloseWebSocketFrame) frame).statusCode();
|
int statusCode = closeWebSocketFrame.statusCode();
|
||||||
ctx.channel().close();
|
ctx.channel().close();
|
||||||
} else {
|
} else {
|
||||||
String message = "unsupported frame type: " + frame.getClass().getName();
|
String message = "unsupported frame type: " + frame.getClass().getName();
|
||||||
|
@ -93,11 +93,11 @@ protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
public void channelInactive(ChannelHandlerContext channelHandlerContext) throws Exception {
|
||||||
if (future != null) future.cancel(true);
|
if (future != null) future.cancel(true);
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace("Client {} disconnected", IOHelper.getIP(ctx.channel().remoteAddress()));
|
logger.trace("Client {} disconnected", IOHelper.getIP(channelHandlerContext.channel().remoteAddress()));
|
||||||
}
|
}
|
||||||
super.channelInactive(ctx);
|
super.channelInactive(channelHandlerContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,8 @@ public void execute(ChannelHandlerContext ctx, Client client) {
|
||||||
boolean success;
|
boolean success;
|
||||||
try {
|
try {
|
||||||
server.authHookManager.joinServerHook.hook(this, client);
|
server.authHookManager.joinServerHook.hook(this, client);
|
||||||
if (server.config.protectHandler instanceof JoinServerProtectHandler) {
|
if (server.config.protectHandler instanceof JoinServerProtectHandler joinServerProtectHandler) {
|
||||||
success = ((JoinServerProtectHandler) server.config.protectHandler).onJoinServer(serverID, username, client);
|
success = joinServerProtectHandler.onJoinServer(serverID, username, client);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
sendResult(new JoinServerRequestEvent(false));
|
sendResult(new JoinServerRequestEvent(false));
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -36,7 +36,7 @@ public String getType() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
public void execute(ChannelHandlerContext ctx, Client client) {
|
||||||
if (server.config.protectHandler instanceof ProfilesProtectHandler && !((ProfilesProtectHandler) server.config.protectHandler).canGetProfiles(client)) {
|
if (server.config.protectHandler instanceof ProfilesProtectHandler profilesProtectHandler && !profilesProtectHandler.canGetProfiles(client)) {
|
||||||
sendError("Access denied");
|
sendError("Access denied");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,8 @@ public void execute(ChannelHandlerContext ctx, Client client) {
|
||||||
Collection<ClientProfile> profiles = server.getProfiles();
|
Collection<ClientProfile> profiles = server.getProfiles();
|
||||||
for (ClientProfile p : profiles) {
|
for (ClientProfile p : profiles) {
|
||||||
if (p.getTitle().equals(this.client)) {
|
if (p.getTitle().equals(this.client)) {
|
||||||
if (server.config.protectHandler instanceof ProfilesProtectHandler &&
|
if (server.config.protectHandler instanceof ProfilesProtectHandler profilesProtectHandler &&
|
||||||
!((ProfilesProtectHandler) server.config.protectHandler).canChangeProfile(p, client)) {
|
!profilesProtectHandler.canChangeProfile(p, client)) {
|
||||||
sendError("Access denied");
|
sendError("Access denied");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,9 @@ public void execute(ChannelHandlerContext ctx, Client client) {
|
||||||
sendError("Invalid request");
|
sendError("Invalid request");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (server.config.protectHandler instanceof HardwareProtectHandler) {
|
if (server.config.protectHandler instanceof HardwareProtectHandler hardwareProtectHandler) {
|
||||||
try {
|
try {
|
||||||
((HardwareProtectHandler) server.config.protectHandler).onHardwareReport(this, client);
|
hardwareProtectHandler.onHardwareReport(this, client);
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
sendError(e.getMessage());
|
sendError(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,12 +21,12 @@ public String getType() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
public void execute(ChannelHandlerContext ctx, Client client) {
|
||||||
if (!(server.config.protectHandler instanceof SecureProtectHandler)) {
|
if (!(server.config.protectHandler instanceof SecureProtectHandler secureProtectHandler)) {
|
||||||
sendError("Method not allowed");
|
sendError("Method not allowed");
|
||||||
|
} else {
|
||||||
|
SecurityReportRequestEvent event = secureProtectHandler.onSecurityReport(this, client);
|
||||||
|
server.modulesManager.invokeEvent(new SecurityReportModuleEvent(event, this, client));
|
||||||
|
sendResult(event);
|
||||||
}
|
}
|
||||||
SecureProtectHandler secureProtectHandler = (SecureProtectHandler) server.config.protectHandler;
|
|
||||||
SecurityReportRequestEvent event = secureProtectHandler.onSecurityReport(this, client);
|
|
||||||
server.modulesManager.invokeEvent(new SecurityReportModuleEvent(event, this, client));
|
|
||||||
sendResult(event);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ public String getType() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(ChannelHandlerContext ctx, Client client) {
|
public void execute(ChannelHandlerContext ctx, Client client) {
|
||||||
if (server.config.protectHandler instanceof ProfilesProtectHandler && !((ProfilesProtectHandler) server.config.protectHandler).canGetUpdates(dirName, client)) {
|
if (server.config.protectHandler instanceof ProfilesProtectHandler profilesProtectHandler && !profilesProtectHandler.canGetUpdates(dirName, client)) {
|
||||||
sendError("Access denied");
|
sendError("Access denied");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ public void execute(ChannelHandlerContext ctx, Client client) {
|
||||||
}
|
}
|
||||||
HashedDir dir = server.updatesManager.getUpdate(dirName);
|
HashedDir dir = server.updatesManager.getUpdate(dirName);
|
||||||
if (dir == null) {
|
if (dir == null) {
|
||||||
sendError(String.format("Directory %s not found", dirName));
|
sendError("Directory %s not found".formatted(dirName));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String url = server.config.netty.downloadURL.replace("%dirname%", IOHelper.urlEncode(dirName));
|
String url = server.config.netty.downloadURL.replace("%dirname%", IOHelper.urlEncode(dirName));
|
||||||
|
|
|
@ -77,25 +77,7 @@ protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundE
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String findLibrary(String name) {
|
public String findLibrary(String name) {
|
||||||
return nativePath.concat(IOHelper.PLATFORM_SEPARATOR).concat(getNativePrefix()).concat(name).concat(getNativeEx());
|
return nativePath.concat(IOHelper.PLATFORM_SEPARATOR).concat(JVMHelper.NATIVE_PREFIX).concat(name).concat(JVMHelper.NATIVE_EXTENSION);
|
||||||
}
|
|
||||||
|
|
||||||
public String getNativeEx() {
|
|
||||||
if (JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE)
|
|
||||||
return ".dll";
|
|
||||||
else if (JVMHelper.OS_TYPE == JVMHelper.OS.LINUX)
|
|
||||||
return ".so";
|
|
||||||
else if (JVMHelper.OS_TYPE == JVMHelper.OS.MACOSX)
|
|
||||||
return ".dylib";
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNativePrefix() {
|
|
||||||
if (JVMHelper.OS_TYPE == JVMHelper.OS.LINUX)
|
|
||||||
return "lib";
|
|
||||||
else if (JVMHelper.OS_TYPE == JVMHelper.OS.MACOSX)
|
|
||||||
return "lib";
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addAllowedPackage(String pkg) {
|
public void addAllowedPackage(String pkg) {
|
||||||
|
|
|
@ -65,13 +65,13 @@ private void injectCertificates() {
|
||||||
// добавление стандартных сертификатов в новый KeyStore
|
// добавление стандартных сертификатов в новый KeyStore
|
||||||
jdkTrustStore.keySet().forEach(key -> setCertificateEntry(mergedTrustStore, key, jdkTrustStore.get(key)));
|
jdkTrustStore.keySet().forEach(key -> setCertificateEntry(mergedTrustStore, key, jdkTrustStore.get(key)));
|
||||||
|
|
||||||
// Инициализация контекста. В случае неудачи допустимо прерывание процесса, но сертификаты добавлены не будут
|
// Context initialization. In case of failure, the process is allowed to be interrupted, but certificates will not be added
|
||||||
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||||
trustManagerFactory.init(mergedTrustStore);
|
trustManagerFactory.init(mergedTrustStore);
|
||||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||||
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
|
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
|
||||||
|
|
||||||
// Установка контекста по умолчанию
|
// Setting the default context
|
||||||
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
|
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
|
||||||
LogHelper.info("Successfully injected certificates to truststore");
|
LogHelper.info("Successfully injected certificates to truststore");
|
||||||
} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | IOException | CertificateException e) {
|
} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | IOException | CertificateException e) {
|
||||||
|
@ -99,7 +99,7 @@ private static Map<String, Certificate> getDefaultKeyStore() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Извлечение существующих сертификатов из стандартного KeyStore текущий сессии JVM. Процесс не должен прерываться в случае неудачи
|
* Retrieve existing certificates from the standard KeyStore of the current JVM session. The process should not be interrupted in case of failure
|
||||||
*/
|
*/
|
||||||
private static void extractAllCertsAndPutInMap(KeyStore keyStore, Map<String, Certificate> placeToExport) {
|
private static void extractAllCertsAndPutInMap(KeyStore keyStore, Map<String, Certificate> placeToExport) {
|
||||||
try {
|
try {
|
||||||
|
@ -121,7 +121,7 @@ private static void setCertificateEntry(KeyStore keyStore, String name, Certific
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Извлечение существующего сертификата из стандартного KeyStore текущий сессии JVM. Процесс не должен прерываться в случае неудачи
|
* Retrieve an existing certificate from the standard KeyStore of the current JVM session. The process should not be interrupted in case of failure
|
||||||
*/
|
*/
|
||||||
private static void extractCertAndPutInMap(KeyStore keyStoreFromExtract, String key, Map<String, Certificate> placeToExtract) {
|
private static void extractCertAndPutInMap(KeyStore keyStoreFromExtract, String key, Map<String, Certificate> placeToExtract) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public final class HashedFile extends HashedEntry {
|
public final class HashedFile extends HashedEntry {
|
||||||
public static final DigestAlgorithm DIGEST_ALGO = DigestAlgorithm.MD5;
|
public static final DigestAlgorithm DIGEST_ALGO = DigestAlgorithm.SHA1;
|
||||||
|
|
||||||
// Instance
|
// Instance
|
||||||
@LauncherNetworkAPI
|
@LauncherNetworkAPI
|
||||||
|
|
|
@ -6,7 +6,7 @@ public final class Version implements Comparable<Version> {
|
||||||
|
|
||||||
public static final int MAJOR = 5;
|
public static final int MAJOR = 5;
|
||||||
public static final int MINOR = 4;
|
public static final int MINOR = 4;
|
||||||
public static final int PATCH = 2;
|
public static final int PATCH = 3;
|
||||||
public static final int BUILD = 1;
|
public static final int BUILD = 1;
|
||||||
public static final Version.Type RELEASE = Type.STABLE;
|
public static final Version.Type RELEASE = Type.STABLE;
|
||||||
public final int major;
|
public final int major;
|
||||||
|
|
|
@ -4,11 +4,11 @@
|
||||||
import pro.gravit.utils.Version;
|
import pro.gravit.utils.Version;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Nashorn при инициализации LogHelper пытается инициализировтаь все доступные в нем методы.
|
* Nashorn when initializing LogHelper tries to initialize all methods available in it.
|
||||||
* При попытке инициализировать rawAnsiFormat он пытается найти класс org.fusesource.jansi.Ansi
|
* When trying to initialize rawAnsiFormat , it tries to find the org.fusesource.jansi.Ansi class
|
||||||
* И есстественно крашится с ClassNotFound
|
* And naturally crashes with ClassNotFound
|
||||||
* В итоге любой вызов LogHelper.* приводит к ClassNotFound org.fusesource.jansi.Ansi
|
* As a result, any call to LogHelper.* results in ClassNotFound org.fusesource.jansi.Ansi
|
||||||
* Поэтому rawAnsiFormat вынесен в отдельный Helper
|
* Therefore, rawAnsiFormat is moved to a separate Helper
|
||||||
*/
|
*/
|
||||||
public class FormatHelper {
|
public class FormatHelper {
|
||||||
public static Ansi rawAnsiFormat(LogHelper.Level level, String dateTime, boolean sub) {
|
public static Ansi rawAnsiFormat(LogHelper.Level level, String dateTime, boolean sub) {
|
||||||
|
|
|
@ -24,6 +24,8 @@ public final class JVMHelper {
|
||||||
// System properties
|
// System properties
|
||||||
public static final String OS_VERSION = OPERATING_SYSTEM_MXBEAN.getVersion();
|
public static final String OS_VERSION = OPERATING_SYSTEM_MXBEAN.getVersion();
|
||||||
public static final ARCH ARCH_TYPE = getArch(System.getProperty("os.arch"));
|
public static final ARCH ARCH_TYPE = getArch(System.getProperty("os.arch"));
|
||||||
|
public static final String NATIVE_EXTENSION = getNativeExtension(OS_TYPE);
|
||||||
|
public static final String NATIVE_PREFIX = getNativePrefix(OS_TYPE);
|
||||||
public static final int JVM_BITS = Integer.parseInt(System.getProperty("sun.arch.data.model"));
|
public static final int JVM_BITS = Integer.parseInt(System.getProperty("sun.arch.data.model"));
|
||||||
// Public static fields
|
// Public static fields
|
||||||
public static final Runtime RUNTIME = Runtime.getRuntime();
|
public static final Runtime RUNTIME = Runtime.getRuntime();
|
||||||
|
@ -82,6 +84,29 @@ public static int getBuild() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getNativeExtension(JVMHelper.OS OS_TYPE) {
|
||||||
|
switch (OS_TYPE) {
|
||||||
|
case MUSTDIE:
|
||||||
|
return ".dll";
|
||||||
|
case LINUX:
|
||||||
|
return ".so";
|
||||||
|
case MACOSX:
|
||||||
|
return ".dylib";
|
||||||
|
default:
|
||||||
|
throw new InternalError(String.format("Unsupported OS TYPE '%s'", OS_TYPE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getNativePrefix(JVMHelper.OS OS_TYPE) {
|
||||||
|
switch (OS_TYPE) {
|
||||||
|
case LINUX:
|
||||||
|
case MACOSX:
|
||||||
|
return "lib";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void appendVars(ProcessBuilder builder, Map<String, String> vars) {
|
public static void appendVars(ProcessBuilder builder, Map<String, String> vars) {
|
||||||
builder.environment().putAll(vars);
|
builder.environment().putAll(vars);
|
||||||
}
|
}
|
||||||
|
@ -179,7 +204,6 @@ public static void verifySystemProperties(Class<?> mainClass, boolean requireSys
|
||||||
LogHelper.debug("Verifying JVM architecture");
|
LogHelper.debug("Verifying JVM architecture");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public enum ARCH {
|
public enum ARCH {
|
||||||
X86("x86"), X86_64("x86-64"), ARM64("arm64"), ARM32("arm32");
|
X86("x86"), X86_64("x86-64"), ARM64("arm64"), ARM32("arm32");
|
||||||
|
|
||||||
|
|
|
@ -20,13 +20,12 @@ public final class JVMHelper {
|
||||||
public static final OperatingSystemMXBean OPERATING_SYSTEM_MXBEAN =
|
public static final OperatingSystemMXBean OPERATING_SYSTEM_MXBEAN =
|
||||||
ManagementFactory.getOperatingSystemMXBean();
|
ManagementFactory.getOperatingSystemMXBean();
|
||||||
public static final OS OS_TYPE = OS.byName(OPERATING_SYSTEM_MXBEAN.getName());
|
public static final OS OS_TYPE = OS.byName(OPERATING_SYSTEM_MXBEAN.getName());
|
||||||
|
public static final int OS_BITS = getCorrectOSArch();
|
||||||
// System properties
|
// System properties
|
||||||
public static final String OS_VERSION = OPERATING_SYSTEM_MXBEAN.getVersion();
|
public static final String OS_VERSION = OPERATING_SYSTEM_MXBEAN.getVersion();
|
||||||
|
|
||||||
public static final int OS_BITS = getCorrectOSArch();
|
|
||||||
|
|
||||||
public static final ARCH ARCH_TYPE = getArch(System.getProperty("os.arch"));
|
public static final ARCH ARCH_TYPE = getArch(System.getProperty("os.arch"));
|
||||||
|
public static final String NATIVE_EXTENSION = getNativeExtension(OS_TYPE);
|
||||||
|
public static final String NATIVE_PREFIX = getNativePrefix(OS_TYPE);
|
||||||
public static final int JVM_BITS = Integer.parseInt(System.getProperty("sun.arch.data.model"));
|
public static final int JVM_BITS = Integer.parseInt(System.getProperty("sun.arch.data.model"));
|
||||||
// Public static fields
|
// Public static fields
|
||||||
public static final Runtime RUNTIME = Runtime.getRuntime();
|
public static final Runtime RUNTIME = Runtime.getRuntime();
|
||||||
|
@ -45,21 +44,11 @@ public final class JVMHelper {
|
||||||
private JVMHelper() {
|
private JVMHelper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ARCH {
|
|
||||||
X86("x86"), X86_64("x86-64"), ARM64("arm64"), ARM32("arm32");
|
|
||||||
|
|
||||||
public final String name;
|
|
||||||
|
|
||||||
ARCH(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ARCH getArch(String arch) {
|
public static ARCH getArch(String arch) {
|
||||||
if(arch.equals("amd64") || arch.equals("x86-64") || arch.equals("x86_64")) return ARCH.X86_64;
|
if (arch.equals("amd64") || arch.equals("x86-64") || arch.equals("x86_64")) return ARCH.X86_64;
|
||||||
if(arch.equals("i386") || arch.equals("i686") || arch.equals("x86")) return ARCH.X86;
|
if (arch.equals("i386") || arch.equals("i686") || arch.equals("x86")) return ARCH.X86;
|
||||||
if(arch.startsWith("armv8") || arch.startsWith("aarch64")) return ARCH.ARM64;
|
if (arch.startsWith("armv8") || arch.startsWith("aarch64")) return ARCH.ARM64;
|
||||||
if(arch.startsWith("arm") || arch.startsWith("aarch32")) return ARCH.ARM32;
|
if (arch.startsWith("arm") || arch.startsWith("aarch32")) return ARCH.ARM32;
|
||||||
throw new InternalError(String.format("Unsupported arch '%s'", arch));
|
throw new InternalError(String.format("Unsupported arch '%s'", arch));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +61,29 @@ public static int getBuild() {
|
||||||
return Runtime.version().update();
|
return Runtime.version().update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getNativeExtension(JVMHelper.OS OS_TYPE) {
|
||||||
|
switch (OS_TYPE) {
|
||||||
|
case MUSTDIE:
|
||||||
|
return ".dll";
|
||||||
|
case LINUX:
|
||||||
|
return ".so";
|
||||||
|
case MACOSX:
|
||||||
|
return ".dylib";
|
||||||
|
default:
|
||||||
|
throw new InternalError(String.format("Unsupported OS TYPE '%s'", OS_TYPE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getNativePrefix(JVMHelper.OS OS_TYPE) {
|
||||||
|
switch (OS_TYPE) {
|
||||||
|
case LINUX:
|
||||||
|
case MACOSX:
|
||||||
|
return "lib";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void appendVars(ProcessBuilder builder, Map<String, String> vars) {
|
public static void appendVars(ProcessBuilder builder, Map<String, String> vars) {
|
||||||
builder.environment().putAll(vars);
|
builder.environment().putAll(vars);
|
||||||
}
|
}
|
||||||
|
@ -86,19 +98,16 @@ public static Class<?> firstClass(String... names) throws ClassNotFoundException
|
||||||
throw new ClassNotFoundException(Arrays.toString(names));
|
throw new ClassNotFoundException(Arrays.toString(names));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void fullGC() {
|
public static void fullGC() {
|
||||||
RUNTIME.gc();
|
RUNTIME.gc();
|
||||||
RUNTIME.runFinalization();
|
RUNTIME.runFinalization();
|
||||||
LogHelper.debug("Used heap: %d MiB", RUNTIME.totalMemory() - RUNTIME.freeMemory() >> 20);
|
LogHelper.debug("Used heap: %d MiB", RUNTIME.totalMemory() - RUNTIME.freeMemory() >> 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String[] getClassPath() {
|
public static String[] getClassPath() {
|
||||||
return System.getProperty("java.class.path").split(File.pathSeparator);
|
return System.getProperty("java.class.path").split(File.pathSeparator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static URL[] getClassPathURL() {
|
public static URL[] getClassPathURL() {
|
||||||
String[] cp = System.getProperty("java.class.path").split(File.pathSeparator);
|
String[] cp = System.getProperty("java.class.path").split(File.pathSeparator);
|
||||||
URL[] list = new URL[cp.length];
|
URL[] list = new URL[cp.length];
|
||||||
|
@ -139,34 +148,28 @@ private static int getCorrectOSArch() {
|
||||||
return System.getProperty("os.arch").contains("64") ? 64 : 32;
|
return System.getProperty("os.arch").contains("64") ? 64 : 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String getEnvPropertyCaseSensitive(String name) {
|
public static String getEnvPropertyCaseSensitive(String name) {
|
||||||
return System.getenv().get(name);
|
return System.getenv().get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static boolean isJVMMatchesSystemArch() {
|
public static boolean isJVMMatchesSystemArch() {
|
||||||
return JVM_BITS == OS_BITS;
|
return JVM_BITS == OS_BITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String jvmProperty(String name, String value) {
|
public static String jvmProperty(String name, String value) {
|
||||||
return String.format("-D%s=%s", name, value);
|
return String.format("-D%s=%s", name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String systemToJvmProperty(String name) {
|
public static String systemToJvmProperty(String name) {
|
||||||
return String.format("-D%s=%s", name, System.getProperties().getProperty(name));
|
return String.format("-D%s=%s", name, System.getProperties().getProperty(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void addSystemPropertyToArgs(Collection<String> args, String name) {
|
public static void addSystemPropertyToArgs(Collection<String> args, String name) {
|
||||||
String property = System.getProperty(name);
|
String property = System.getProperty(name);
|
||||||
if (property != null)
|
if (property != null)
|
||||||
args.add(String.format("-D%s=%s", name, property));
|
args.add(String.format("-D%s=%s", name, property));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void verifySystemProperties(Class<?> mainClass, boolean requireSystem) {
|
public static void verifySystemProperties(Class<?> mainClass, boolean requireSystem) {
|
||||||
Locale.setDefault(Locale.US);
|
Locale.setDefault(Locale.US);
|
||||||
// Verify class loader
|
// Verify class loader
|
||||||
|
@ -178,6 +181,16 @@ public static void verifySystemProperties(Class<?> mainClass, boolean requireSys
|
||||||
LogHelper.debug("Verifying JVM architecture");
|
LogHelper.debug("Verifying JVM architecture");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum ARCH {
|
||||||
|
X86("x86"), X86_64("x86-64"), ARM64("arm64"), ARM32("arm32");
|
||||||
|
|
||||||
|
public final String name;
|
||||||
|
|
||||||
|
ARCH(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public enum OS {
|
public enum OS {
|
||||||
MUSTDIE("mustdie"), LINUX("linux"), MACOSX("macosx");
|
MUSTDIE("mustdie"), LINUX("linux"), MACOSX("macosx");
|
||||||
|
|
||||||
|
|
|
@ -98,14 +98,14 @@ public void run(String... args) throws Throwable {
|
||||||
GetAvailabilityAuthRequest.registerProviders();
|
GetAvailabilityAuthRequest.registerProviders();
|
||||||
OptionalAction.registerProviders();
|
OptionalAction.registerProviders();
|
||||||
OptionalTrigger.registerProviders();
|
OptionalTrigger.registerProviders();
|
||||||
if (args.length > 0 && args[0].equals("setup") && !disableSetup) {
|
if (args.length > 0 && args[0].equalsIgnoreCase("setup") && !disableSetup) {
|
||||||
LogHelper.debug("Read ServerWrapperConfig.json");
|
LogHelper.debug("Read ServerWrapperConfig.json");
|
||||||
loadConfig();
|
loadConfig();
|
||||||
ServerWrapperSetup setup = new ServerWrapperSetup();
|
ServerWrapperSetup setup = new ServerWrapperSetup();
|
||||||
setup.run();
|
setup.run();
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
if (args.length > 1 && args[0].equals("installAuthlib") && !disableSetup) {
|
if (args.length > 1 && args[0].equalsIgnoreCase("installAuthlib") && !disableSetup) {
|
||||||
LogHelper.debug("Read ServerWrapperConfig.json");
|
LogHelper.debug("Read ServerWrapperConfig.json");
|
||||||
loadConfig();
|
loadConfig();
|
||||||
InstallAuthlib command = new InstallAuthlib();
|
InstallAuthlib command = new InstallAuthlib();
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
id 'org.openjfx.javafxplugin' version '0.0.10' apply false
|
id 'org.openjfx.javafxplugin' version '0.0.10' apply false
|
||||||
}
|
}
|
||||||
group = 'pro.gravit.launcher'
|
group = 'pro.gravit.launcher'
|
||||||
version = '5.4.2'
|
version = '5.4.3'
|
||||||
|
|
||||||
apply from: 'props.gradle'
|
apply from: 'props.gradle'
|
||||||
|
|
||||||
|
@ -48,6 +48,8 @@
|
||||||
options.encoding = "UTF-8"
|
options.encoding = "UTF-8"
|
||||||
options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
|
options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
|
||||||
options.incremental = true // one flag, and things will get MUCH faster
|
options.incremental = true // one flag, and things will get MUCH faster
|
||||||
|
compileJava.options.encoding = 'UTF-8'
|
||||||
|
compileTestJava.options.encoding = 'UTF-8'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,7 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-all.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|
12
gradlew
vendored
12
gradlew
vendored
|
@ -85,9 +85,6 @@ done
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
|
|
||||||
|
@ -133,10 +130,13 @@ location of your Java installation."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
JAVACMD=java
|
JAVACMD=java
|
||||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
if ! command -v java >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
location of your Java installation."
|
location of your Java installation."
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
# Increase the maximum file descriptors if we can.
|
||||||
|
@ -197,6 +197,10 @@ if "$cygwin" || "$msys" ; then
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# Collect all arguments for the java command;
|
# Collect all arguments for the java command;
|
||||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||||
# shell script including quotes and variable substitutions, so put them in
|
# shell script including quotes and variable substitutions, so put them in
|
||||||
|
|
2
modules
2
modules
|
@ -1 +1 @@
|
||||||
Subproject commit bade21a21b1fb9525c017b9f27a80a2276ff95e3
|
Subproject commit d20723ae0e41c7580560a4f9f402699dbce2ae4c
|
14
props.gradle
14
props.gradle
|
@ -1,11 +1,11 @@
|
||||||
project.ext {
|
project.ext {
|
||||||
verAsm = '9.4'
|
verAsm = '9.5'
|
||||||
verNetty = '4.1.87.Final'
|
verNetty = '4.1.94.Final'
|
||||||
verOshiCore = '6.4.0'
|
verOshiCore = '6.4.4'
|
||||||
verJunit = '5.9.2'
|
verJunit = '5.9.3'
|
||||||
verGuavaC = '30.1.1-jre'
|
verGuavaC = '30.1.1-jre'
|
||||||
verJansi = '2.4.0'
|
verJansi = '2.4.0'
|
||||||
verJline = '3.22.0'
|
verJline = '3.23.0'
|
||||||
verJwt = '0.11.5'
|
verJwt = '0.11.5'
|
||||||
verBcprov = '1.70'
|
verBcprov = '1.70'
|
||||||
verGson = '2.10.1'
|
verGson = '2.10.1'
|
||||||
|
@ -13,8 +13,8 @@
|
||||||
verSlf4j = '1.7.36'
|
verSlf4j = '1.7.36'
|
||||||
verLog4j = '2.19.0'
|
verLog4j = '2.19.0'
|
||||||
verMySQLConn = '8.0.33'
|
verMySQLConn = '8.0.33'
|
||||||
verPostgreSQLConn = '42.5.1'
|
verPostgreSQLConn = '42.6.0'
|
||||||
verProguard = '7.3.1'
|
verProguard = '7.3.2'
|
||||||
verLaunch4j = '3.50'
|
verLaunch4j = '3.50'
|
||||||
verHibernate = '5.5.6.Final'
|
verHibernate = '5.5.6.Final'
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue