mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-11-15 11:39:11 +03:00
Merge branch 'release/4.4.2'
This commit is contained in:
commit
c658a85c35
42 changed files with 202 additions and 166 deletions
|
@ -53,7 +53,22 @@
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.zip.CRC32;
|
import java.util.zip.CRC32;
|
||||||
|
|
||||||
public final class LaunchServer implements Runnable {
|
public final class LaunchServer implements Runnable, AutoCloseable, Reloadable {
|
||||||
|
@Override
|
||||||
|
public void reload() throws Exception {
|
||||||
|
config.close();
|
||||||
|
LogHelper.info("Reading LaunchServer config file");
|
||||||
|
try (BufferedReader reader = IOHelper.newReader(configFile)) {
|
||||||
|
config = Launcher.gson.fromJson(reader, Config.class);
|
||||||
|
}
|
||||||
|
config.verify();
|
||||||
|
Launcher.applyLauncherEnv(config.env);
|
||||||
|
for (AuthProvider provider : config.authProvider) {
|
||||||
|
provider.init();
|
||||||
|
}
|
||||||
|
config.authHandler.init();
|
||||||
|
}
|
||||||
|
|
||||||
public static final class Config {
|
public static final class Config {
|
||||||
public int port;
|
public int port;
|
||||||
|
|
||||||
|
@ -170,6 +185,34 @@ public void verify() {
|
||||||
throw new NullPointerException("Netty must not be null");
|
throw new NullPointerException("Netty must not be null");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public void close()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
authHandler.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LogHelper.error(e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
for (AuthProvider p : authProvider) p.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LogHelper.error(e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
textureProvider.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LogHelper.error(e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
hwidHandler.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogHelper.error(e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
permissionsHandler.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogHelper.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ExeConf {
|
public static class ExeConf {
|
||||||
|
@ -233,7 +276,7 @@ public static void main(String... args) throws Throwable {
|
||||||
LogHelper.printLicense("LaunchServer");
|
LogHelper.printLicense("LaunchServer");
|
||||||
|
|
||||||
// Start LaunchServer
|
// Start LaunchServer
|
||||||
Instant start = Instant.now();
|
long startTime = System.currentTimeMillis();
|
||||||
try {
|
try {
|
||||||
LaunchServer launchserver = new LaunchServer(IOHelper.WORKING_DIR, args);
|
LaunchServer launchserver = new LaunchServer(IOHelper.WORKING_DIR, args);
|
||||||
if(args.length == 0) launchserver.run();
|
if(args.length == 0) launchserver.run();
|
||||||
|
@ -244,8 +287,8 @@ public static void main(String... args) throws Throwable {
|
||||||
LogHelper.error(exc);
|
LogHelper.error(exc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Instant end = Instant.now();
|
long endTime = System.currentTimeMillis();
|
||||||
LogHelper.debug("LaunchServer started in %dms", Duration.between(start, end).toMillis());
|
LogHelper.debug("LaunchServer started in %dms", endTime - startTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constant paths
|
// Constant paths
|
||||||
|
@ -269,7 +312,7 @@ public static void main(String... args) throws Throwable {
|
||||||
public final Path profilesDir;
|
public final Path profilesDir;
|
||||||
// Server config
|
// Server config
|
||||||
|
|
||||||
public final Config config;
|
public Config config;
|
||||||
|
|
||||||
|
|
||||||
public final RSAPublicKey publicKey;
|
public final RSAPublicKey publicKey;
|
||||||
|
@ -417,6 +460,7 @@ public LaunchServer(Path dir, String[] args) throws IOException, InvalidKeySpecE
|
||||||
authHookManager = new AuthHookManager();
|
authHookManager = new AuthHookManager();
|
||||||
GarbageManager.registerNeedGC(sessionManager);
|
GarbageManager.registerNeedGC(sessionManager);
|
||||||
GarbageManager.registerNeedGC(limiter);
|
GarbageManager.registerNeedGC(limiter);
|
||||||
|
reloadManager.registerReloadable("launchServer", this);
|
||||||
if (config.permissionsHandler instanceof Reloadable)
|
if (config.permissionsHandler instanceof Reloadable)
|
||||||
reloadManager.registerReloadable("permissionsHandler", (Reloadable) config.permissionsHandler);
|
reloadManager.registerReloadable("permissionsHandler", (Reloadable) config.permissionsHandler);
|
||||||
if (config.authHandler instanceof Reloadable)
|
if (config.authHandler instanceof Reloadable)
|
||||||
|
@ -521,22 +565,7 @@ public void close() {
|
||||||
serverSocketHandler.close();
|
serverSocketHandler.close();
|
||||||
|
|
||||||
// Close handlers & providers
|
// Close handlers & providers
|
||||||
try {
|
config.close();
|
||||||
config.authHandler.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
for (AuthProvider p : config.authProvider) p.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
config.textureProvider.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
LogHelper.error(e);
|
|
||||||
}
|
|
||||||
config.hwidHandler.close();
|
|
||||||
modulesManager.close();
|
modulesManager.close();
|
||||||
// Print last message before death :(
|
// Print last message before death :(
|
||||||
LogHelper.info("LaunchServer stopped");
|
LogHelper.info("LaunchServer stopped");
|
||||||
|
|
|
@ -31,6 +31,7 @@ public final class MySQLSourceConfig implements AutoCloseable {
|
||||||
private String password;
|
private String password;
|
||||||
private String database;
|
private String database;
|
||||||
private String timeZone;
|
private String timeZone;
|
||||||
|
private boolean enableHikari;
|
||||||
|
|
||||||
// Cache
|
// Cache
|
||||||
private transient DataSource source;
|
private transient DataSource source;
|
||||||
|
@ -79,20 +80,24 @@ public synchronized Connection getConnection() throws SQLException {
|
||||||
hikari = false;
|
hikari = false;
|
||||||
// Try using HikariCP
|
// Try using HikariCP
|
||||||
source = mysqlSource;
|
source = mysqlSource;
|
||||||
try {
|
if(enableHikari)
|
||||||
Class.forName("com.zaxxer.hikari.HikariDataSource");
|
{
|
||||||
hikari = true; // Used for shutdown. Not instanceof because of possible classpath error
|
try {
|
||||||
HikariConfig cfg = new HikariConfig();
|
Class.forName("com.zaxxer.hikari.HikariDataSource");
|
||||||
cfg.setDataSource(mysqlSource);
|
hikari = true; // Used for shutdown. Not instanceof because of possible classpath error
|
||||||
cfg.setPoolName(poolName);
|
HikariConfig cfg = new HikariConfig();
|
||||||
cfg.setMaximumPoolSize(MAX_POOL_SIZE);
|
cfg.setDataSource(mysqlSource);
|
||||||
// Set HikariCP pool
|
cfg.setPoolName(poolName);
|
||||||
// Replace source with hds
|
cfg.setMaximumPoolSize(MAX_POOL_SIZE);
|
||||||
source = new HikariDataSource(cfg);
|
// Set HikariCP pool
|
||||||
LogHelper.warning("HikariCP pooling enabled for '%s'", poolName);
|
// Replace source with hds
|
||||||
} catch (ClassNotFoundException ignored) {
|
source = new HikariDataSource(cfg);
|
||||||
LogHelper.debug("HikariCP isn't in classpath for '%s'", poolName);
|
LogHelper.warning("HikariCP pooling enabled for '%s'", poolName);
|
||||||
|
} catch (ClassNotFoundException ignored) {
|
||||||
|
LogHelper.debug("HikariCP isn't in classpath for '%s'", poolName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return source.getConnection();
|
return source.getConnection();
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ public void check(HWID hwid, String username) throws HWIDException {
|
||||||
public abstract void check0(HWID hwid, String username) throws HWIDException;
|
public abstract void check0(HWID hwid, String username) throws HWIDException;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract void close();
|
public abstract void close() throws Exception;
|
||||||
|
|
||||||
public abstract List<HWID> getHwid(String username) throws HWIDException;
|
public abstract List<HWID> getHwid(String username) throws HWIDException;
|
||||||
|
|
||||||
|
|
|
@ -151,6 +151,7 @@ public void onCheckInfo(OshiHWID hwid, String username, Connection c) throws HWI
|
||||||
db_hwid.processorID = set.getString(hwidFieldProcessorID);
|
db_hwid.processorID = set.getString(hwidFieldProcessorID);
|
||||||
db_hwid.HWDiskSerial = set.getString(hwidFieldHWDiskSerial);
|
db_hwid.HWDiskSerial = set.getString(hwidFieldHWDiskSerial);
|
||||||
db_hwid.totalMemory = Long.valueOf(set.getString(hwidFieldTotalMemory));
|
db_hwid.totalMemory = Long.valueOf(set.getString(hwidFieldTotalMemory));
|
||||||
|
db_hwid.macAddr = "";
|
||||||
LogHelper.dev("Compare HWID: %s vs %s", hwid.getSerializeString(), db_hwid.getSerializeString());
|
LogHelper.dev("Compare HWID: %s vs %s", hwid.getSerializeString(), db_hwid.getSerializeString());
|
||||||
int compare_point = hwid.compare(db_hwid);
|
int compare_point = hwid.compare(db_hwid);
|
||||||
if(compare_point < compare) continue;
|
if(compare_point < compare) continue;
|
||||||
|
|
|
@ -13,4 +13,9 @@ public ClientPermissions getPermissions(String username) {
|
||||||
permissions.canAdmin = isAdmin;
|
permissions.canAdmin = isAdmin;
|
||||||
return permissions;
|
return permissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,4 +7,9 @@ public class DefaultPermissionsHandler extends PermissionsHandler {
|
||||||
public ClientPermissions getPermissions(String username) {
|
public ClientPermissions getPermissions(String username) {
|
||||||
return ClientPermissions.DEFAULT;
|
return ClientPermissions.DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws Exception {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,11 @@ public void reload() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws Exception {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public static class Enity {
|
public static class Enity {
|
||||||
public String username;
|
public String username;
|
||||||
public ClientPermissions permissions;
|
public ClientPermissions permissions;
|
||||||
|
|
|
@ -34,6 +34,11 @@ public void reload() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws Exception {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public static class Enity {
|
public static class Enity {
|
||||||
public String username;
|
public String username;
|
||||||
public ClientPermissions permissions;
|
public ClientPermissions permissions;
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
public abstract class PermissionsHandler {
|
public abstract class PermissionsHandler implements AutoCloseable {
|
||||||
private static final Map<String, Class<? extends PermissionsHandler>> PERMISSIONS_HANDLERS = new ConcurrentHashMap<>(4);
|
private static final Map<String, Class<? extends PermissionsHandler>> PERMISSIONS_HANDLERS = new ConcurrentHashMap<>(4);
|
||||||
private static boolean registredHandl = false;
|
private static boolean registredHandl = false;
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,12 @@ public class ProguardConf {
|
||||||
private static final String charsFirst = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ";
|
private static final String charsFirst = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ";
|
||||||
private static final String chars = "1aAbBcC2dDeEfF3gGhHiI4jJkKl5mMnNoO6pPqQrR7sStT8uUvV9wWxX0yYzZ";
|
private static final String chars = "1aAbBcC2dDeEfF3gGhHiI4jJkKl5mMnNoO6pPqQrR7sStT8uUvV9wWxX0yYzZ";
|
||||||
|
|
||||||
private static String generateString(SecureRandom rand, int il) {
|
private static String generateString(SecureRandom rand, String lowString, String upString, int il) {
|
||||||
StringBuilder sb = new StringBuilder(il);
|
StringBuilder sb = new StringBuilder(il + lowString.length());
|
||||||
sb.append(charsFirst.charAt(rand.nextInt(charsFirst.length())));
|
for(int i = 0;i<lowString.length();++i)
|
||||||
|
{
|
||||||
|
sb.append(rand.nextBoolean() ? lowString.charAt(i) : upString.charAt(i));
|
||||||
|
}
|
||||||
for (int i = 0; i < il - 1; i++) sb.append(chars.charAt(rand.nextInt(chars.length())));
|
for (int i = 0; i < il - 1; i++) sb.append(chars.charAt(rand.nextInt(chars.length())));
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
@ -66,7 +69,10 @@ public void genWords(boolean force) throws IOException {
|
||||||
SecureRandom rand = SecurityHelper.newRandom();
|
SecureRandom rand = SecurityHelper.newRandom();
|
||||||
rand.setSeed(SecureRandom.getSeed(32));
|
rand.setSeed(SecureRandom.getSeed(32));
|
||||||
try (PrintWriter out = new PrintWriter(new OutputStreamWriter(IOHelper.newOutput(words), IOHelper.UNICODE_CHARSET))) {
|
try (PrintWriter out = new PrintWriter(new OutputStreamWriter(IOHelper.newOutput(words), IOHelper.UNICODE_CHARSET))) {
|
||||||
for (int i = 0; i < Short.MAX_VALUE; i++) out.println(generateString(rand, 24));
|
String projectName = LaunchServer.server.config.projectName.replaceAll("\\W", "");
|
||||||
|
String lowName = projectName.toLowerCase();
|
||||||
|
String upName = projectName.toUpperCase();
|
||||||
|
for (int i = 0; i < Short.MAX_VALUE; i++) out.println(generateString(rand, lowName, upName, 3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,13 @@
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
import ru.gravit.launcher.serialize.HOutput;
|
||||||
import ru.gravit.launcher.serialize.SerializeLimits;
|
import ru.gravit.launcher.serialize.SerializeLimits;
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
import ru.gravit.launchserver.LaunchServer;
|
||||||
|
import ru.gravit.launchserver.socket.Client;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public final class PingResponse extends Response {
|
public final class PingResponse extends Response {
|
||||||
public PingResponse(LaunchServer server, long id, HInput input, HOutput output, String ip) {
|
public PingResponse(LaunchServer server, long id, HInput input, HOutput output, String ip, Client clientData) {
|
||||||
super(server, id, input, output, ip);
|
super(server, id, input, output, ip, clientData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
import ru.gravit.launchserver.response.profile.ProfileByUUIDResponse;
|
import ru.gravit.launchserver.response.profile.ProfileByUUIDResponse;
|
||||||
import ru.gravit.launchserver.response.profile.ProfileByUsernameResponse;
|
import ru.gravit.launchserver.response.profile.ProfileByUsernameResponse;
|
||||||
import ru.gravit.launchserver.response.update.*;
|
import ru.gravit.launchserver.response.update.*;
|
||||||
|
import ru.gravit.launchserver.socket.Client;
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
import ru.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -21,13 +22,13 @@ public abstract class Response {
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface Factory<R> {
|
public interface Factory<R> {
|
||||||
|
|
||||||
Response newResponse(LaunchServer server, long id, HInput input, HOutput output, String ip);
|
Response newResponse(LaunchServer server, long id, HInput input, HOutput output, String ip, Client clientData);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Map<Integer, Factory<?>> RESPONSES = new ConcurrentHashMap<>(8);
|
private static final Map<Integer, Factory<?>> RESPONSES = new ConcurrentHashMap<>(8);
|
||||||
|
|
||||||
public static Response getResponse(int type, LaunchServer server, long session, HInput input, HOutput output, String ip) {
|
public static Response getResponse(int type, LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
||||||
return RESPONSES.get(type).newResponse(server, session, input, output, ip);
|
return RESPONSES.get(type).newResponse(server, session, input, output, ip, clientData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void registerResponse(int type, Factory<?> factory) {
|
public static void registerResponse(int type, Factory<?> factory) {
|
||||||
|
@ -72,15 +73,18 @@ public static void requestError(String message) throws RequestException {
|
||||||
|
|
||||||
protected final String ip;
|
protected final String ip;
|
||||||
|
|
||||||
|
protected final Client clientData;
|
||||||
|
|
||||||
|
|
||||||
protected final long session;
|
protected final long session;
|
||||||
|
|
||||||
protected Response(LaunchServer server, long session, HInput input, HOutput output, String ip) {
|
protected Response(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.input = input;
|
this.input = input;
|
||||||
this.output = output;
|
this.output = output;
|
||||||
this.ip = ip;
|
this.ip = ip;
|
||||||
this.session = session;
|
this.session = session;
|
||||||
|
this.clientData = clientData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class ExecCommandResponse extends Response {
|
public class ExecCommandResponse extends Response {
|
||||||
public ExecCommandResponse(LaunchServer server, long session, HInput input, HOutput output, String ip) {
|
public ExecCommandResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
||||||
super(server, session, input, output, ip);
|
super(server, session, input, output, ip, clientData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -31,8 +31,8 @@ private static String echo(int length) {
|
||||||
return new String(chars);
|
return new String(chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuthResponse(LaunchServer server, long session, HInput input, HOutput output, String ip) {
|
public AuthResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
||||||
super(server, session, input, output, ip);
|
super(server, session, input, output, ip, clientData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AuthContext {
|
public static class AuthContext {
|
||||||
|
@ -81,7 +81,6 @@ public void reply() throws Exception {
|
||||||
debug("Login: '%s', Password: '%s'", login, echo(password.length()));
|
debug("Login: '%s', Password: '%s'", login, echo(password.length()));
|
||||||
AuthProviderResult result;
|
AuthProviderResult result;
|
||||||
AuthProvider provider = server.config.authProvider[auth_id];
|
AuthProvider provider = server.config.authProvider[auth_id];
|
||||||
Client clientData = server.sessionManager.getClient(session);
|
|
||||||
clientData.type = Client.Type.USER;
|
clientData.type = Client.Type.USER;
|
||||||
AuthContext context = new AuthContext(session, login, password.length(), customText, client, hwid_str, false);
|
AuthContext context = new AuthContext(session, login, password.length(), customText, client, hwid_str, false);
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -28,8 +28,8 @@ private static String echo(int length) {
|
||||||
return new String(chars);
|
return new String(chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuthServerResponse(LaunchServer server, long session, HInput input, HOutput output, String ip) {
|
public AuthServerResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
||||||
super(server, session, input, output, ip);
|
super(server, session, input, output, ip, clientData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -52,7 +52,6 @@ public void reply() throws Exception {
|
||||||
debug("ServerLogin: '%s', Password: '%s'", login, echo(password.length()));
|
debug("ServerLogin: '%s', Password: '%s'", login, echo(password.length()));
|
||||||
AuthProviderResult result;
|
AuthProviderResult result;
|
||||||
AuthProvider provider = server.config.authProvider[auth_id];
|
AuthProvider provider = server.config.authProvider[auth_id];
|
||||||
Client clientData = server.sessionManager.getClient(session);
|
|
||||||
try {
|
try {
|
||||||
if (server.limiter.isLimit(ip)) {
|
if (server.limiter.isLimit(ip)) {
|
||||||
AuthProvider.authError(server.config.authRejectString);
|
AuthProvider.authError(server.config.authRejectString);
|
||||||
|
|
|
@ -4,14 +4,15 @@
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
import ru.gravit.launcher.serialize.HOutput;
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
import ru.gravit.launchserver.LaunchServer;
|
||||||
import ru.gravit.launchserver.response.Response;
|
import ru.gravit.launchserver.response.Response;
|
||||||
|
import ru.gravit.launchserver.socket.Client;
|
||||||
|
|
||||||
public class ChangeServerResponse extends Response {
|
public class ChangeServerResponse extends Response {
|
||||||
public static boolean needChange = false;
|
public static boolean needChange = false;
|
||||||
public static String address;
|
public static String address;
|
||||||
public static int port;
|
public static int port;
|
||||||
|
|
||||||
public ChangeServerResponse(LaunchServer server, long session, HInput input, HOutput output, String ip) {
|
public ChangeServerResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
||||||
super(server, session, input, output, ip);
|
super(server, session, input, output, ip, clientData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
|
|
||||||
public final class CheckServerResponse extends Response {
|
public final class CheckServerResponse extends Response {
|
||||||
|
|
||||||
public CheckServerResponse(LaunchServer server, long session, HInput input, HOutput output, String ip) {
|
public CheckServerResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
||||||
super(server, session, input, output, ip);
|
super(server, session, input, output, ip, clientData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,7 +26,6 @@ public void reply() throws IOException {
|
||||||
String serverID = VerifyHelper.verifyServerID(input.readASCII(41)); // With minus sign
|
String serverID = VerifyHelper.verifyServerID(input.readASCII(41)); // With minus sign
|
||||||
String client = input.readString(SerializeLimits.MAX_CLIENT);
|
String client = input.readString(SerializeLimits.MAX_CLIENT);
|
||||||
debug("Username: %s, Server ID: %s", username, serverID);
|
debug("Username: %s, Server ID: %s", username, serverID);
|
||||||
Client clientData = server.sessionManager.getClient(session);
|
|
||||||
if (!clientData.isAuth || clientData.type != Client.Type.SERVER) {
|
if (!clientData.isAuth || clientData.type != Client.Type.SERVER) {
|
||||||
requestError("Access denied");
|
requestError("Access denied");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
|
|
||||||
public final class JoinServerResponse extends Response {
|
public final class JoinServerResponse extends Response {
|
||||||
|
|
||||||
public JoinServerResponse(LaunchServer server, long session, HInput input, HOutput output, String ip) {
|
public JoinServerResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
||||||
super(server, session, input, output, ip);
|
super(server, session, input, output, ip, clientData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -24,7 +24,6 @@ public void reply() throws IOException {
|
||||||
String username = VerifyHelper.verifyUsername(input.readString(SerializeLimits.MAX_LOGIN));
|
String username = VerifyHelper.verifyUsername(input.readString(SerializeLimits.MAX_LOGIN));
|
||||||
String accessToken = SecurityHelper.verifyToken(input.readASCII(-SecurityHelper.TOKEN_STRING_LENGTH));
|
String accessToken = SecurityHelper.verifyToken(input.readASCII(-SecurityHelper.TOKEN_STRING_LENGTH));
|
||||||
String serverID = VerifyHelper.verifyServerID(input.readASCII(SerializeLimits.MAX_SERVERID)); // With minus sign
|
String serverID = VerifyHelper.verifyServerID(input.readASCII(SerializeLimits.MAX_SERVERID)); // With minus sign
|
||||||
Client clientData = server.sessionManager.getClient(session);
|
|
||||||
if (!clientData.isAuth || clientData.type != Client.Type.USER) {
|
if (!clientData.isAuth || clientData.type != Client.Type.USER) {
|
||||||
requestError("Access denied");
|
requestError("Access denied");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -11,14 +11,13 @@
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
public class SetProfileResponse extends Response {
|
public class SetProfileResponse extends Response {
|
||||||
public SetProfileResponse(LaunchServer server, long session, HInput input, HOutput output, String ip) {
|
public SetProfileResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
||||||
super(server, session, input, output, ip);
|
super(server, session, input, output, ip, clientData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reply() throws Exception {
|
public void reply() throws Exception {
|
||||||
String client = input.readString(SerializeLimits.MAX_CLIENT);
|
String client = input.readString(SerializeLimits.MAX_CLIENT);
|
||||||
Client clientData = server.sessionManager.getClient(session);
|
|
||||||
if (!clientData.isAuth) requestError("You not auth");
|
if (!clientData.isAuth) requestError("You not auth");
|
||||||
Collection<ClientProfile> profiles = server.getProfiles();
|
Collection<ClientProfile> profiles = server.getProfiles();
|
||||||
for (ClientProfile p : profiles) {
|
for (ClientProfile p : profiles) {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
import ru.gravit.launcher.serialize.SerializeLimits;
|
import ru.gravit.launcher.serialize.SerializeLimits;
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
import ru.gravit.launchserver.LaunchServer;
|
||||||
import ru.gravit.launchserver.response.Response;
|
import ru.gravit.launchserver.response.Response;
|
||||||
|
import ru.gravit.launchserver.socket.Client;
|
||||||
import ru.gravit.utils.helper.VerifyHelper;
|
import ru.gravit.utils.helper.VerifyHelper;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -12,8 +13,8 @@
|
||||||
|
|
||||||
public final class BatchProfileByUsernameResponse extends Response {
|
public final class BatchProfileByUsernameResponse extends Response {
|
||||||
|
|
||||||
public BatchProfileByUsernameResponse(LaunchServer server, long session, HInput input, HOutput output, String ip) {
|
public BatchProfileByUsernameResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
||||||
super(server, session, input, output, ip);
|
super(server, session, input, output, ip, clientData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
import ru.gravit.launcher.serialize.SerializeLimits;
|
import ru.gravit.launcher.serialize.SerializeLimits;
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
import ru.gravit.launchserver.LaunchServer;
|
||||||
import ru.gravit.launchserver.response.Response;
|
import ru.gravit.launchserver.response.Response;
|
||||||
|
import ru.gravit.launchserver.socket.Client;
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
import ru.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -37,8 +38,8 @@ public static PlayerProfile getProfile(LaunchServer server, UUID uuid, String us
|
||||||
return new PlayerProfile(uuid, username, skin, cloak);
|
return new PlayerProfile(uuid, username, skin, cloak);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileByUUIDResponse(LaunchServer server, long session, HInput input, HOutput output, String ip) {
|
public ProfileByUUIDResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
||||||
super(server, session, input, output, ip);
|
super(server, session, input, output, ip, clientData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
import ru.gravit.launcher.serialize.SerializeLimits;
|
import ru.gravit.launcher.serialize.SerializeLimits;
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
import ru.gravit.launchserver.LaunchServer;
|
||||||
import ru.gravit.launchserver.response.Response;
|
import ru.gravit.launchserver.response.Response;
|
||||||
|
import ru.gravit.launchserver.socket.Client;
|
||||||
import ru.gravit.utils.helper.VerifyHelper;
|
import ru.gravit.utils.helper.VerifyHelper;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -24,8 +25,8 @@ public static void writeProfile(LaunchServer server, HOutput output, String user
|
||||||
ProfileByUUIDResponse.getProfile(server, uuid, username, client).write(output);
|
ProfileByUUIDResponse.getProfile(server, uuid, username, client).write(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileByUsernameResponse(LaunchServer server, long session, HInput input, HOutput output, String ip) {
|
public ProfileByUsernameResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
||||||
super(server, session, input, output, ip);
|
super(server, session, input, output, ip, clientData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
|
|
||||||
public final class LauncherResponse extends Response {
|
public final class LauncherResponse extends Response {
|
||||||
|
|
||||||
public LauncherResponse(LaunchServer server, long session, HInput input, HOutput output, String ip) {
|
public LauncherResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
||||||
super(server, session, input, output, ip);
|
super(server, session, input, output, ip, clientData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -25,17 +25,16 @@ public void reply() throws IOException {
|
||||||
requestError("Missing launcher binary");
|
requestError("Missing launcher binary");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Client client = server.sessionManager.getOrNewClient(session);
|
|
||||||
byte[] digest = input.readByteArray(SerializeLimits.MAX_DIGEST);
|
byte[] digest = input.readByteArray(SerializeLimits.MAX_DIGEST);
|
||||||
if (!Arrays.equals(bytes.getDigest(), digest)) {
|
if (!Arrays.equals(bytes.getDigest(), digest)) {
|
||||||
writeNoError(output);
|
writeNoError(output);
|
||||||
output.writeBoolean(true);
|
output.writeBoolean(true);
|
||||||
output.writeByteArray(bytes.getBytes(), 0);
|
output.writeByteArray(bytes.getBytes(), 0);
|
||||||
client.checkSign = false;
|
clientData.checkSign = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
writeNoError(output);
|
writeNoError(output);
|
||||||
output.writeBoolean(false);
|
output.writeBoolean(false);
|
||||||
client.checkSign = true;
|
clientData.checkSign = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,14 +5,15 @@
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
import ru.gravit.launchserver.LaunchServer;
|
||||||
import ru.gravit.launchserver.binary.LauncherBinary;
|
import ru.gravit.launchserver.binary.LauncherBinary;
|
||||||
import ru.gravit.launchserver.response.Response;
|
import ru.gravit.launchserver.response.Response;
|
||||||
|
import ru.gravit.launchserver.socket.Client;
|
||||||
import ru.gravit.utils.helper.SecurityHelper;
|
import ru.gravit.utils.helper.SecurityHelper;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public final class LegacyLauncherResponse extends Response {
|
public final class LegacyLauncherResponse extends Response {
|
||||||
|
|
||||||
public LegacyLauncherResponse(LaunchServer server, long session, HInput input, HOutput output, String ip) {
|
public LegacyLauncherResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
||||||
super(server, session, input, output, ip);
|
super(server, session, input, output, ip, clientData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -14,16 +14,15 @@
|
||||||
|
|
||||||
public final class ProfilesResponse extends Response {
|
public final class ProfilesResponse extends Response {
|
||||||
|
|
||||||
public ProfilesResponse(LaunchServer server, long session, HInput input, HOutput output, String ip) {
|
public ProfilesResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
||||||
super(server, session, input, output, ip);
|
super(server, session, input, output, ip, clientData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reply() throws IOException {
|
public void reply() throws IOException {
|
||||||
// Resolve launcher binary
|
// Resolve launcher binary
|
||||||
Client client = server.sessionManager.getClient(session);
|
|
||||||
input.readBoolean();
|
input.readBoolean();
|
||||||
if (client.type == Client.Type.USER && !client.checkSign) {
|
if (clientData.type == Client.Type.USER && !clientData.checkSign) {
|
||||||
LogHelper.warning("User session: %d ip %s try get profiles", session, ip);
|
LogHelper.warning("User session: %d ip %s try get profiles", session, ip);
|
||||||
requestError("Access denied");
|
requestError("Access denied");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -6,14 +6,15 @@
|
||||||
import ru.gravit.launcher.serialize.signed.SignedObjectHolder;
|
import ru.gravit.launcher.serialize.signed.SignedObjectHolder;
|
||||||
import ru.gravit.launchserver.LaunchServer;
|
import ru.gravit.launchserver.LaunchServer;
|
||||||
import ru.gravit.launchserver.response.Response;
|
import ru.gravit.launchserver.response.Response;
|
||||||
|
import ru.gravit.launchserver.socket.Client;
|
||||||
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public final class UpdateListResponse extends Response {
|
public final class UpdateListResponse extends Response {
|
||||||
|
|
||||||
public UpdateListResponse(LaunchServer server, long session, HInput input, HOutput output, String ip) {
|
public UpdateListResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
||||||
super(server, session, input, output, ip);
|
super(server, session, input, output, ip, clientData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
|
|
||||||
public final class UpdateResponse extends Response {
|
public final class UpdateResponse extends Response {
|
||||||
|
|
||||||
public UpdateResponse(LaunchServer server, long session, HInput input, HOutput output, String ip) {
|
public UpdateResponse(LaunchServer server, long session, HInput input, HOutput output, String ip, Client clientData) {
|
||||||
super(server, session, input, output, ip);
|
super(server, session, input, output, ip, clientData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -37,7 +37,6 @@ public void reply() throws IOException {
|
||||||
requestError(String.format("Unknown update dir: %s", updateDirName));
|
requestError(String.format("Unknown update dir: %s", updateDirName));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Client clientData = server.sessionManager.getClient(session);
|
|
||||||
if (!clientData.isAuth || clientData.type != Client.Type.USER || clientData.profile == null) {
|
if (!clientData.isAuth || clientData.type != Client.Type.USER || clientData.profile == null) {
|
||||||
requestError("Access denied");
|
requestError("Access denied");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -82,12 +82,12 @@ private Handshake readHandshake(HInput input, HOutput output) throws IOException
|
||||||
return new Handshake(type, session);
|
return new Handshake(type, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void respond(Integer type, HInput input, HOutput output, long session, String ip) throws Exception {
|
private void respond(Integer type, HInput input, HOutput output, long session, String ip, Client clientData) throws Exception {
|
||||||
if (server.serverSocketHandler.logConnections)
|
if (server.serverSocketHandler.logConnections)
|
||||||
LogHelper.info("Connection #%d from %s", session, ip);
|
LogHelper.info("Connection #%d from %s", session, ip);
|
||||||
|
|
||||||
// Choose response based on type
|
// Choose response based on type
|
||||||
Response response = Response.getResponse(type, server, session, input, output, ip);
|
Response response = Response.getResponse(type, server, session, input, output, ip, clientData);
|
||||||
|
|
||||||
// Reply
|
// Reply
|
||||||
response.reply();
|
response.reply();
|
||||||
|
@ -115,11 +115,13 @@ public void run() {
|
||||||
context.ip = IOHelper.getIP(socket.getRemoteSocketAddress());
|
context.ip = IOHelper.getIP(socket.getRemoteSocketAddress());
|
||||||
context.session = handshake.session;
|
context.session = handshake.session;
|
||||||
context.type = handshake.type;
|
context.type = handshake.type;
|
||||||
|
Client clientData = server.sessionManager.getOrNewClient(context.session);
|
||||||
|
context.client = clientData;
|
||||||
|
|
||||||
// Start response
|
// Start response
|
||||||
if (socketHookManager.preHook(context)) {
|
if (socketHookManager.preHook(context)) {
|
||||||
try {
|
try {
|
||||||
respond(handshake.type, input, output, handshake.session, context.ip);
|
respond(handshake.type, input, output, handshake.session, context.ip, clientData);
|
||||||
socketHookManager.postHook(context);
|
socketHookManager.postHook(context);
|
||||||
} catch (RequestException e) {
|
} catch (RequestException e) {
|
||||||
if (server.socketHookManager.errorHook(context, e)) {
|
if (server.socketHookManager.errorHook(context, e)) {
|
||||||
|
|
|
@ -4,9 +4,10 @@
|
||||||
import ru.gravit.launcher.serialize.HOutput;
|
import ru.gravit.launcher.serialize.HOutput;
|
||||||
|
|
||||||
public class SocketContext {
|
public class SocketContext {
|
||||||
HInput input;
|
public HInput input;
|
||||||
HOutput output;
|
public HOutput output;
|
||||||
long session;
|
public long session;
|
||||||
String ip;
|
public String ip;
|
||||||
Integer type;
|
public Integer type;
|
||||||
|
public Client client;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package ru.gravit.launcher;
|
package ru.gravit.launcher;
|
||||||
|
|
||||||
import ru.gravit.launcher.client.ClientLauncher;
|
import ru.gravit.launcher.client.ClientLauncher;
|
||||||
|
import ru.gravit.launcher.client.DirBridge;
|
||||||
import ru.gravit.utils.helper.EnvHelper;
|
import ru.gravit.utils.helper.EnvHelper;
|
||||||
import ru.gravit.utils.helper.IOHelper;
|
import ru.gravit.utils.helper.IOHelper;
|
||||||
import ru.gravit.utils.helper.JVMHelper;
|
import ru.gravit.utils.helper.JVMHelper;
|
||||||
|
@ -19,18 +20,22 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep
|
||||||
LogHelper.printLicense("Launcher");
|
LogHelper.printLicense("Launcher");
|
||||||
LogHelper.info("Restart Launcher with JavaAgent...");
|
LogHelper.info("Restart Launcher with JavaAgent...");
|
||||||
LogHelper.info("If need debug output use -Dlauncher.debug=true");
|
LogHelper.info("If need debug output use -Dlauncher.debug=true");
|
||||||
|
LogHelper.info("If need stacktrace output use -Dlauncher.stacktrace=true");
|
||||||
JVMHelper.checkStackTrace(ClientLauncherWrapper.class);
|
JVMHelper.checkStackTrace(ClientLauncherWrapper.class);
|
||||||
JVMHelper.verifySystemProperties(Launcher.class, true);
|
JVMHelper.verifySystemProperties(Launcher.class, true);
|
||||||
EnvHelper.checkDangerousParams();
|
EnvHelper.checkDangerousParams();
|
||||||
LogHelper.debug("Restart Launcher");
|
LogHelper.debug("Restart Launcher");
|
||||||
ProcessBuilder processBuilder = new ProcessBuilder();
|
ProcessBuilder processBuilder = new ProcessBuilder();
|
||||||
processBuilder.inheritIO();
|
if (LogHelper.isDebugEnabled()) processBuilder.inheritIO();
|
||||||
Path javaBin = IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home")));
|
Path javaBin = IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home")));
|
||||||
List<String> args = new LinkedList<>();
|
List<String> args = new LinkedList<>();
|
||||||
args.add(javaBin.toString());
|
args.add(javaBin.toString());
|
||||||
String pathLauncher = IOHelper.getCodeSource(ClientLauncher.class).toString();
|
String pathLauncher = IOHelper.getCodeSource(ClientLauncher.class).toString();
|
||||||
args.add(JVMHelper.jvmProperty(LogHelper.DEBUG_PROPERTY, Boolean.toString(LogHelper.isDebugEnabled())));
|
args.add(JVMHelper.jvmProperty(LogHelper.DEBUG_PROPERTY, Boolean.toString(LogHelper.isDebugEnabled())));
|
||||||
args.add(JVMHelper.jvmProperty(LogHelper.STACKTRACE_PROPERTY, Boolean.toString(LogHelper.isStacktraceEnabled())));
|
args.add(JVMHelper.jvmProperty(LogHelper.STACKTRACE_PROPERTY, Boolean.toString(LogHelper.isStacktraceEnabled())));
|
||||||
|
JVMHelper.addSystemPropertyToArgs(args, DirBridge.CUSTOMDIR_PROPERTY);
|
||||||
|
JVMHelper.addSystemPropertyToArgs(args, DirBridge.USE_CUSTOMDIR_PROPERTY);
|
||||||
|
JVMHelper.addSystemPropertyToArgs(args, DirBridge.USE_OPTDIR_PROPERTY);
|
||||||
Collections.addAll(args, "-javaagent:".concat(pathLauncher));
|
Collections.addAll(args, "-javaagent:".concat(pathLauncher));
|
||||||
Collections.addAll(args, "-cp");
|
Collections.addAll(args, "-cp");
|
||||||
Collections.addAll(args, pathLauncher);
|
Collections.addAll(args, pathLauncher);
|
||||||
|
|
|
@ -30,15 +30,15 @@ public static void main(String... args) throws Throwable {
|
||||||
// Start Launcher
|
// Start Launcher
|
||||||
initGson();
|
initGson();
|
||||||
LogHelper.setStacktraceEnabled(true);
|
LogHelper.setStacktraceEnabled(true);
|
||||||
Instant start = Instant.now();
|
long startTime = System.currentTimeMillis();
|
||||||
try {
|
try {
|
||||||
new LauncherEngine().start(args);
|
new LauncherEngine().start(args);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Instant end = Instant.now();
|
long endTime = System.currentTimeMillis();
|
||||||
LogHelper.debug("Launcher started in %dms", Duration.between(start, end).toMillis());
|
LogHelper.debug("Launcher started in %dms", endTime - startTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void initGson() {
|
public static void initGson() {
|
||||||
|
@ -58,7 +58,6 @@ private LauncherEngine() {
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public void start(String... args) throws Throwable {
|
public void start(String... args) throws Throwable {
|
||||||
LogHelper.debug("%d", LauncherSettings.settingsMagic);
|
|
||||||
Launcher.modulesManager = new ClientModuleManager(this);
|
Launcher.modulesManager = new ClientModuleManager(this);
|
||||||
LauncherConfig.getAutogenConfig().initModules();
|
LauncherConfig.getAutogenConfig().initModules();
|
||||||
Launcher.modulesManager.preInitModules();
|
Launcher.modulesManager.preInitModules();
|
||||||
|
|
|
@ -347,8 +347,9 @@ public static Process launch(
|
||||||
context.args.add(JVMHelper.jvmProperty(LogHelper.DEBUG_PROPERTY, Boolean.toString(LogHelper.isDebugEnabled())));
|
context.args.add(JVMHelper.jvmProperty(LogHelper.DEBUG_PROPERTY, Boolean.toString(LogHelper.isDebugEnabled())));
|
||||||
context.args.add(JVMHelper.jvmProperty(LogHelper.STACKTRACE_PROPERTY, Boolean.toString(LogHelper.isStacktraceEnabled())));
|
context.args.add(JVMHelper.jvmProperty(LogHelper.STACKTRACE_PROPERTY, Boolean.toString(LogHelper.isStacktraceEnabled())));
|
||||||
context.args.add(JVMHelper.jvmProperty(LogHelper.DEV_PROPERTY, Boolean.toString(LogHelper.isDevEnabled())));
|
context.args.add(JVMHelper.jvmProperty(LogHelper.DEV_PROPERTY, Boolean.toString(LogHelper.isDevEnabled())));
|
||||||
if (LauncherConfig.ADDRESS_OVERRIDE != null)
|
JVMHelper.addSystemPropertyToArgs(context.args, DirBridge.CUSTOMDIR_PROPERTY);
|
||||||
context.args.add(JVMHelper.jvmProperty(LauncherConfig.ADDRESS_OVERRIDE_PROPERTY, LauncherConfig.ADDRESS_OVERRIDE));
|
JVMHelper.addSystemPropertyToArgs(context.args, DirBridge.USE_CUSTOMDIR_PROPERTY);
|
||||||
|
JVMHelper.addSystemPropertyToArgs(context.args, DirBridge.USE_OPTDIR_PROPERTY);
|
||||||
if (JVMHelper.OS_TYPE == OS.MUSTDIE) {
|
if (JVMHelper.OS_TYPE == OS.MUSTDIE) {
|
||||||
if (JVMHelper.OS_VERSION.startsWith("10.")) {
|
if (JVMHelper.OS_VERSION.startsWith("10.")) {
|
||||||
LogHelper.debug("MustDie 10 fix is applied");
|
LogHelper.debug("MustDie 10 fix is applied");
|
||||||
|
@ -474,46 +475,6 @@ public static void main(String... args) throws Throwable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
|
||||||
public void launchLocal(HashedDir assetHDir, HashedDir clientHDir,
|
|
||||||
ClientProfile profile, Params params) throws Throwable {
|
|
||||||
RSAPublicKey publicKey = Launcher.getConfig().publicKey;
|
|
||||||
LogHelper.debug("Verifying ClientLauncher sign and classpath");
|
|
||||||
SecurityHelper.verifySign(LegacyLauncherRequest.BINARY_PATH, params.launcherDigest, publicKey);
|
|
||||||
LinkedList<Path> classPath = resolveClassPathList(params.clientDir, profile.getClassPath());
|
|
||||||
for (Path classpathURL : classPath) {
|
|
||||||
LauncherAgent.addJVMClassPath(classpathURL.toAbsolutePath().toString());
|
|
||||||
}
|
|
||||||
URL[] classpathurls = resolveClassPath(params.clientDir, profile.getClassPath());
|
|
||||||
classLoader = new PublicURLClassLoader(classpathurls, ClassLoader.getSystemClassLoader());
|
|
||||||
Thread.currentThread().setContextClassLoader(classLoader);
|
|
||||||
classLoader.nativePath = params.clientDir.resolve(NATIVES_DIR).toString();
|
|
||||||
PublicURLClassLoader.systemclassloader = classLoader;
|
|
||||||
// Start client with WatchService monitoring
|
|
||||||
boolean digest = !profile.isUpdateFastCheck();
|
|
||||||
LogHelper.debug("Starting JVM and client WatchService");
|
|
||||||
FileNameMatcher assetMatcher = profile.getAssetUpdateMatcher();
|
|
||||||
FileNameMatcher clientMatcher = profile.getClientUpdateMatcher();
|
|
||||||
try (DirWatcher assetWatcher = new DirWatcher(params.assetDir, assetHDir, assetMatcher, digest);
|
|
||||||
DirWatcher clientWatcher = new DirWatcher(params.clientDir, clientHDir, clientMatcher, digest)) {
|
|
||||||
// Verify current state of all dirs
|
|
||||||
//verifyHDir(IOHelper.JVM_DIR, jvmHDir.object, null, digest);
|
|
||||||
HashedDir hdir = clientHDir;
|
|
||||||
//for (OptionalFile s : Launcher.profile.getOptional()) {
|
|
||||||
// if (params.updateOptional.contains(s)) s.mark = true;
|
|
||||||
// else hdir.removeR(s.file);
|
|
||||||
//}
|
|
||||||
Launcher.profile.pushOptionalFile(hdir,false);
|
|
||||||
verifyHDir(params.assetDir, assetHDir, assetMatcher, digest);
|
|
||||||
verifyHDir(params.clientDir, hdir, clientMatcher, digest);
|
|
||||||
Launcher.modulesManager.postInitModules();
|
|
||||||
// Start WatchService, and only then client
|
|
||||||
CommonHelper.newThread("Asset Directory Watcher", true, assetWatcher).start();
|
|
||||||
CommonHelper.newThread("Client Directory Watcher", true, clientWatcher).start();
|
|
||||||
launch(profile, params);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static URL[] resolveClassPath(Path clientDir, String... classPath) throws IOException {
|
private static URL[] resolveClassPath(Path clientDir, String... classPath) throws IOException {
|
||||||
Collection<Path> result = new LinkedList<>();
|
Collection<Path> result = new LinkedList<>();
|
||||||
for (String classPathEntry : classPath) {
|
for (String classPathEntry : classPath) {
|
||||||
|
|
|
@ -10,6 +10,11 @@
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
public class DirBridge {
|
public class DirBridge {
|
||||||
|
|
||||||
|
public static final String USE_CUSTOMDIR_PROPERTY = "launcher.usecustomdir";
|
||||||
|
public static final String CUSTOMDIR_PROPERTY = "launcher.customdir";
|
||||||
|
public static final String USE_OPTDIR_PROPERTY = "launcher.useoptdir";
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public static Path dir;
|
public static Path dir;
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
|
@ -27,12 +32,12 @@ public static void move(Path newDir) throws IOException {
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public static Path getAppDataDir() throws IOException {
|
public static Path getAppDataDir() throws IOException {
|
||||||
Boolean isCustomDir = Boolean.getBoolean(System.getProperty("launcher.usecustomdir", "false"));
|
boolean isCustomDir = Boolean.getBoolean(System.getProperty(USE_CUSTOMDIR_PROPERTY, "false"));
|
||||||
if (isCustomDir) {
|
if (isCustomDir) {
|
||||||
return Paths.get(System.getProperty("launcher.customdir"));
|
return Paths.get(System.getProperty(CUSTOMDIR_PROPERTY));
|
||||||
}
|
}
|
||||||
if (JVMHelper.OS_TYPE == JVMHelper.OS.LINUX) {
|
if (JVMHelper.OS_TYPE == JVMHelper.OS.LINUX) {
|
||||||
Boolean isOpt = Boolean.getBoolean(System.getProperty("launcher.useoptdir", "false"));
|
boolean isOpt = Boolean.getBoolean(System.getProperty(USE_OPTDIR_PROPERTY, "false"));
|
||||||
if (isOpt) {
|
if (isOpt) {
|
||||||
Path opt = Paths.get("/").resolve("opt");
|
Path opt = Paths.get("/").resolve("opt");
|
||||||
if (!IOHelper.isDir(opt)) Files.createDirectories(opt);
|
if (!IOHelper.isDir(opt)) Files.createDirectories(opt);
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
import ru.gravit.launcher.OshiHWID;
|
import ru.gravit.launcher.OshiHWID;
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
import ru.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
|
import java.net.NetworkInterface;
|
||||||
|
|
||||||
public class OshiHWIDProvider implements LauncherHWIDInterface {
|
public class OshiHWIDProvider implements LauncherHWIDInterface {
|
||||||
public SystemInfo systemInfo;
|
public SystemInfo systemInfo;
|
||||||
public HardwareAbstractionLayer hardware;
|
public HardwareAbstractionLayer hardware;
|
||||||
|
@ -111,6 +113,9 @@ public void printHardwareInformation() {
|
||||||
for(NetworkIF networkIF : hardware.getNetworkIFs())
|
for(NetworkIF networkIF : hardware.getNetworkIFs())
|
||||||
{
|
{
|
||||||
LogHelper.debug("Network Interface: %s mac: %s", networkIF.getName(), networkIF.getMacaddr());
|
LogHelper.debug("Network Interface: %s mac: %s", networkIF.getName(), networkIF.getMacaddr());
|
||||||
|
NetworkInterface network = networkIF.getNetworkInterface();
|
||||||
|
if(network.isLoopback() || network.isVirtual()) continue;
|
||||||
|
LogHelper.debug("Network Interface display: %s name: %s", network.getDisplayName(), network.getName());
|
||||||
for(String ipv4 : networkIF.getIPv4addr())
|
for(String ipv4 : networkIF.getIPv4addr())
|
||||||
{
|
{
|
||||||
if(ipv4.startsWith("127.")) continue;
|
if(ipv4.startsWith("127.")) continue;
|
||||||
|
|
|
@ -41,8 +41,6 @@ public static void update(LauncherConfig config, LauncherRequestEvent result) th
|
||||||
args.add(IOHelper.resolveJavaBin(null).toString());
|
args.add(IOHelper.resolveJavaBin(null).toString());
|
||||||
if (LogHelper.isDebugEnabled())
|
if (LogHelper.isDebugEnabled())
|
||||||
args.add(JVMHelper.jvmProperty(LogHelper.DEBUG_PROPERTY, Boolean.toString(LogHelper.isDebugEnabled())));
|
args.add(JVMHelper.jvmProperty(LogHelper.DEBUG_PROPERTY, Boolean.toString(LogHelper.isDebugEnabled())));
|
||||||
if (LauncherConfig.ADDRESS_OVERRIDE != null)
|
|
||||||
args.add(JVMHelper.jvmProperty(LauncherConfig.ADDRESS_OVERRIDE_PROPERTY, LauncherConfig.ADDRESS_OVERRIDE));
|
|
||||||
args.add("-jar");
|
args.add("-jar");
|
||||||
args.add(BINARY_PATH.toString());
|
args.add(BINARY_PATH.toString());
|
||||||
ProcessBuilder builder = new ProcessBuilder(args.toArray(new String[0]));
|
ProcessBuilder builder = new ProcessBuilder(args.toArray(new String[0]));
|
||||||
|
|
|
@ -61,8 +61,6 @@ public static void update(LauncherConfig config, Result result) throws Signature
|
||||||
args.add(IOHelper.resolveJavaBin(null).toString());
|
args.add(IOHelper.resolveJavaBin(null).toString());
|
||||||
if (LogHelper.isDebugEnabled())
|
if (LogHelper.isDebugEnabled())
|
||||||
args.add(JVMHelper.jvmProperty(LogHelper.DEBUG_PROPERTY, Boolean.toString(LogHelper.isDebugEnabled())));
|
args.add(JVMHelper.jvmProperty(LogHelper.DEBUG_PROPERTY, Boolean.toString(LogHelper.isDebugEnabled())));
|
||||||
if (LauncherConfig.ADDRESS_OVERRIDE != null)
|
|
||||||
args.add(JVMHelper.jvmProperty(LauncherConfig.ADDRESS_OVERRIDE_PROPERTY, LauncherConfig.ADDRESS_OVERRIDE));
|
|
||||||
args.add("-jar");
|
args.add("-jar");
|
||||||
args.add(BINARY_PATH.toString());
|
args.add(BINARY_PATH.toString());
|
||||||
ProcessBuilder builder = new ProcessBuilder(args.toArray(new String[0]));
|
ProcessBuilder builder = new ProcessBuilder(args.toArray(new String[0]));
|
||||||
|
|
|
@ -60,7 +60,7 @@ public final class Launcher {
|
||||||
private static final Pattern UUID_PATTERN = Pattern.compile("-", Pattern.LITERAL);
|
private static final Pattern UUID_PATTERN = Pattern.compile("-", Pattern.LITERAL);
|
||||||
public static final int MAJOR = 4;
|
public static final int MAJOR = 4;
|
||||||
public static final int MINOR = 4;
|
public static final int MINOR = 4;
|
||||||
public static final int PATCH = 1;
|
public static final int PATCH = 2;
|
||||||
public static final int BUILD = 1;
|
public static final int BUILD = 1;
|
||||||
public static final Version.Type RELEASE = Version.Type.STABLE;
|
public static final Version.Type RELEASE = Version.Type.STABLE;
|
||||||
public static GsonBuilder gsonBuilder;
|
public static GsonBuilder gsonBuilder;
|
||||||
|
|
|
@ -14,10 +14,6 @@
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public final class LauncherConfig extends StreamObject {
|
public final class LauncherConfig extends StreamObject {
|
||||||
@LauncherAPI
|
|
||||||
public static final String ADDRESS_OVERRIDE_PROPERTY = "launcher.addressOverride";
|
|
||||||
@LauncherAPI
|
|
||||||
public static final String ADDRESS_OVERRIDE = System.getProperty(ADDRESS_OVERRIDE_PROPERTY, null);
|
|
||||||
private static final AutogenConfig config = new AutogenConfig();
|
private static final AutogenConfig config = new AutogenConfig();
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,9 +47,7 @@ public static AutogenConfig getAutogenConfig() {
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException {
|
public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException {
|
||||||
String localAddress = config.address;
|
address = InetSocketAddress.createUnresolved( config.address, config.port);
|
||||||
address = InetSocketAddress.createUnresolved(
|
|
||||||
ADDRESS_OVERRIDE == null ? localAddress : ADDRESS_OVERRIDE, config.port);
|
|
||||||
publicKey = SecurityHelper.toPublicRSAKey(input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH));
|
publicKey = SecurityHelper.toPublicRSAKey(input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH));
|
||||||
projectname = config.projectname;
|
projectname = config.projectname;
|
||||||
clientPort = config.clientPort;
|
clientPort = config.clientPort;
|
||||||
|
@ -84,10 +78,6 @@ public LauncherConfig(HInput input) throws IOException, InvalidKeySpecException
|
||||||
String.format("Duplicate runtime resource: '%s'", name));
|
String.format("Duplicate runtime resource: '%s'", name));
|
||||||
}
|
}
|
||||||
runtime = Collections.unmodifiableMap(localResources);
|
runtime = Collections.unmodifiableMap(localResources);
|
||||||
|
|
||||||
// Print warning if address override is enabled
|
|
||||||
if (ADDRESS_OVERRIDE != null)
|
|
||||||
LogHelper.warning("Address override is enabled: '%s'", ADDRESS_OVERRIDE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
|
|
|
@ -43,7 +43,7 @@ public int compare(HWID hwid) {
|
||||||
if(oshi.HWDiskSerial.equals(HWDiskSerial)) rate+=45;
|
if(oshi.HWDiskSerial.equals(HWDiskSerial)) rate+=45;
|
||||||
if(oshi.processorID.equals(processorID)) rate+=18;
|
if(oshi.processorID.equals(processorID)) rate+=18;
|
||||||
if(oshi.serialNumber.equals(serialNumber)) rate+=15;
|
if(oshi.serialNumber.equals(serialNumber)) rate+=15;
|
||||||
if(oshi.macAddr.equals(macAddr)) rate+=19;
|
if(!oshi.macAddr.isEmpty() && oshi.macAddr.equals(macAddr)) rate+=19;
|
||||||
return rate;
|
return rate;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -122,7 +122,6 @@ private void processKey(WatchKey key) throws IOException {
|
||||||
// Resolve paths and verify is not exclusion
|
// Resolve paths and verify is not exclusion
|
||||||
Path path = watchDir.resolve((Path) event.context());
|
Path path = watchDir.resolve((Path) event.context());
|
||||||
Deque<String> stringPath = toPath(dir.relativize(path));
|
Deque<String> stringPath = toPath(dir.relativize(path));
|
||||||
LogHelper.debug("DirWatcher event %s", String.join("/", stringPath));
|
|
||||||
if (matcher != null && !matcher.shouldVerify(stringPath))
|
if (matcher != null && !matcher.shouldVerify(stringPath))
|
||||||
continue; // Exclusion; should not be verified
|
continue; // Exclusion; should not be verified
|
||||||
// Verify is REALLY modified (not just attributes)
|
// Verify is REALLY modified (not just attributes)
|
||||||
|
|
|
@ -38,7 +38,7 @@ public void eval(String[] args, boolean bell) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Measure start time and invoke command
|
// Measure start time and invoke command
|
||||||
Instant startTime = Instant.now();
|
long startTime = System.currentTimeMillis();
|
||||||
try {
|
try {
|
||||||
lookup(args[0]).invoke(Arrays.copyOfRange(args, 1, args.length));
|
lookup(args[0]).invoke(Arrays.copyOfRange(args, 1, args.length));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -46,8 +46,8 @@ public void eval(String[] args, boolean bell) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bell if invocation took > 1s
|
// Bell if invocation took > 1s
|
||||||
Instant endTime = Instant.now();
|
long endTime = System.currentTimeMillis();
|
||||||
if (bell && Duration.between(startTime, endTime).getSeconds() >= 5)
|
if (bell && endTime - startTime >= 5000)
|
||||||
try {
|
try {
|
||||||
bell();
|
bell();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -155,6 +156,14 @@ 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@LauncherAPI
|
||||||
|
public static void addSystemPropertyToArgs(Collection<String> args, String name)
|
||||||
|
{
|
||||||
|
String property = System.getProperty(name);
|
||||||
|
if(property != null)
|
||||||
|
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);
|
||||||
|
|
Loading…
Reference in a new issue