mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-11-15 03:31:15 +03:00
IDEA Code Reformat
This commit is contained in:
parent
f9b8bd2947
commit
874a30eb6b
81 changed files with 740 additions and 697 deletions
|
@ -106,7 +106,7 @@ public static final class Config extends ConfigObject {
|
||||||
private final StringConfigEntry address;
|
private final StringConfigEntry address;
|
||||||
private final String bindAddress;
|
private final String bindAddress;
|
||||||
|
|
||||||
private Config(BlockConfigEntry block, Path coredir,LaunchServer server) {
|
private Config(BlockConfigEntry block, Path coredir, LaunchServer server) {
|
||||||
super(block);
|
super(block);
|
||||||
address = block.getEntry("address", StringConfigEntry.class);
|
address = block.getEntry("address", StringConfigEntry.class);
|
||||||
port = VerifyHelper.verifyInt(block.getEntryValue("port", IntegerConfigEntry.class),
|
port = VerifyHelper.verifyInt(block.getEntryValue("port", IntegerConfigEntry.class),
|
||||||
|
@ -129,7 +129,7 @@ private Config(BlockConfigEntry block, Path coredir,LaunchServer server) {
|
||||||
block.getEntry("authHandlerConfig", BlockConfigEntry.class));
|
block.getEntry("authHandlerConfig", BlockConfigEntry.class));
|
||||||
authProvider = new AuthProvider[1];
|
authProvider = new AuthProvider[1];
|
||||||
authProvider[0] = AuthProvider.newProvider(block.getEntryValue("authProvider", StringConfigEntry.class),
|
authProvider[0] = AuthProvider.newProvider(block.getEntryValue("authProvider", StringConfigEntry.class),
|
||||||
block.getEntry("authProviderConfig", BlockConfigEntry.class),server);
|
block.getEntry("authProviderConfig", BlockConfigEntry.class), server);
|
||||||
textureProvider = TextureProvider.newProvider(block.getEntryValue("textureProvider", StringConfigEntry.class),
|
textureProvider = TextureProvider.newProvider(block.getEntryValue("textureProvider", StringConfigEntry.class),
|
||||||
block.getEntry("textureProviderConfig", BlockConfigEntry.class));
|
block.getEntry("textureProviderConfig", BlockConfigEntry.class));
|
||||||
hwidHandler = HWIDHandler.newHandler(block.getEntryValue("hwidHandler", StringConfigEntry.class),
|
hwidHandler = HWIDHandler.newHandler(block.getEntryValue("hwidHandler", StringConfigEntry.class),
|
||||||
|
@ -137,7 +137,7 @@ private Config(BlockConfigEntry block, Path coredir,LaunchServer server) {
|
||||||
|
|
||||||
// Set misc config
|
// Set misc config
|
||||||
genMappings = block.getEntryValue("proguardPrintMappings", BooleanConfigEntry.class);
|
genMappings = block.getEntryValue("proguardPrintMappings", BooleanConfigEntry.class);
|
||||||
mirrors = block.getEntry("mirrors",ListConfigEntry.class);
|
mirrors = block.getEntry("mirrors", ListConfigEntry.class);
|
||||||
launch4j = new ExeConf(block.getEntry("launch4J", BlockConfigEntry.class));
|
launch4j = new ExeConf(block.getEntry("launch4J", BlockConfigEntry.class));
|
||||||
sign = new SignConf(block.getEntry("signing", BlockConfigEntry.class), coredir);
|
sign = new SignConf(block.getEntry("signing", BlockConfigEntry.class), coredir);
|
||||||
binaryName = block.getEntryValue("binaryName", StringConfigEntry.class);
|
binaryName = block.getEntryValue("binaryName", StringConfigEntry.class);
|
||||||
|
@ -410,7 +410,7 @@ public LaunchServer(Path dir, boolean portable) throws IOException, InvalidKeySp
|
||||||
generateConfigIfNotExists();
|
generateConfigIfNotExists();
|
||||||
LogHelper.info("Reading LaunchServer config file");
|
LogHelper.info("Reading LaunchServer config file");
|
||||||
try (BufferedReader reader = IOHelper.newReader(configFile)) {
|
try (BufferedReader reader = IOHelper.newReader(configFile)) {
|
||||||
config = new Config(TextConfigReader.read(reader, true), dir,this);
|
config = new Config(TextConfigReader.read(reader, true), dir, this);
|
||||||
}
|
}
|
||||||
config.verify();
|
config.verify();
|
||||||
|
|
||||||
|
@ -473,12 +473,12 @@ public void close() {
|
||||||
|
|
||||||
// Close handlers & providers
|
// Close handlers & providers
|
||||||
try {
|
try {
|
||||||
for(AuthHandler h : config.authHandler) h.close();
|
for (AuthHandler h : config.authHandler) h.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
for(AuthProvider p : config.authProvider) p.close();
|
for (AuthProvider p : config.authProvider) p.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
}
|
}
|
||||||
|
@ -501,7 +501,7 @@ private void generateConfigIfNotExists() throws IOException {
|
||||||
LogHelper.info("Creating LaunchServer config");
|
LogHelper.info("Creating LaunchServer config");
|
||||||
Config newConfig;
|
Config newConfig;
|
||||||
try (BufferedReader reader = IOHelper.newReader(IOHelper.getResourceURL("ru/gravit/launchserver/defaults/config.cfg"))) {
|
try (BufferedReader reader = IOHelper.newReader(IOHelper.getResourceURL("ru/gravit/launchserver/defaults/config.cfg"))) {
|
||||||
newConfig = new Config(TextConfigReader.read(reader, false), dir,this);
|
newConfig = new Config(TextConfigReader.read(reader, false), dir, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set server address
|
// Set server address
|
||||||
|
|
|
@ -9,12 +9,13 @@ public ClientPermissions() {
|
||||||
canAdmin = false;
|
canAdmin = false;
|
||||||
canServer = false;
|
canServer = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClientPermissions(long data) {
|
public ClientPermissions(long data) {
|
||||||
canAdmin = (data & (1)) != 0;
|
canAdmin = (data & (1)) != 0;
|
||||||
canServer = (data & (1 << 1)) != 0;
|
canServer = (data & (1 << 1)) != 0;
|
||||||
}
|
}
|
||||||
public static ClientPermissions getSuperuserAccount()
|
|
||||||
{
|
public static ClientPermissions getSuperuserAccount() {
|
||||||
ClientPermissions perm = new ClientPermissions();
|
ClientPermissions perm = new ClientPermissions();
|
||||||
perm.canServer = true;
|
perm.canServer = true;
|
||||||
perm.canAdmin = true;
|
perm.canAdmin = true;
|
||||||
|
|
|
@ -7,8 +7,9 @@
|
||||||
|
|
||||||
public final class AcceptAuthProvider extends AuthProvider {
|
public final class AcceptAuthProvider extends AuthProvider {
|
||||||
private final boolean isAdminAccess;
|
private final boolean isAdminAccess;
|
||||||
|
|
||||||
public AcceptAuthProvider(BlockConfigEntry block, LaunchServer server) {
|
public AcceptAuthProvider(BlockConfigEntry block, LaunchServer server) {
|
||||||
super(block,server);
|
super(block, server);
|
||||||
isAdminAccess = block.hasEntry("admin") ? block.getEntryValue("admin", BooleanConfigEntry.class) : false;
|
isAdminAccess = block.hasEntry("admin") ? block.getEntryValue("admin", BooleanConfigEntry.class) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,11 +23,11 @@ public static AuthProviderResult authError(String message) throws AuthException
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static AuthProvider newProvider(String name, BlockConfigEntry block,LaunchServer server) {
|
public static AuthProvider newProvider(String name, BlockConfigEntry block, LaunchServer server) {
|
||||||
VerifyHelper.verifyIDName(name);
|
VerifyHelper.verifyIDName(name);
|
||||||
ServerAdapter<AuthProvider> authHandlerAdapter = VerifyHelper.getMapValue(AUTH_PROVIDERS, name,
|
ServerAdapter<AuthProvider> authHandlerAdapter = VerifyHelper.getMapValue(AUTH_PROVIDERS, name,
|
||||||
String.format("Unknown auth provider: '%s'", name));
|
String.format("Unknown auth provider: '%s'", name));
|
||||||
return authHandlerAdapter.convert(block,server);
|
return authHandlerAdapter.convert(block, server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,8 +51,8 @@ public static void registerProviders() {
|
||||||
registredProv = true;
|
registredProv = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public AuthHandler getAccociateHandler(int this_position)
|
|
||||||
{
|
public AuthHandler getAccociateHandler(int this_position) {
|
||||||
return server.config.authHandler[this_position];
|
return server.config.authHandler[this_position];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,9 +67,10 @@ protected AuthProvider(BlockConfigEntry block, LaunchServer launchServer) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract void close() throws IOException;
|
public abstract void close() throws IOException;
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface ServerAdapter<O extends ConfigObject> {
|
public interface ServerAdapter<O extends ConfigObject> {
|
||||||
|
|
||||||
O convert(BlockConfigEntry entry,LaunchServer server);
|
O convert(BlockConfigEntry entry, LaunchServer server);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,8 @@ public AuthProviderResult(String username, String accessToken) {
|
||||||
this.accessToken = accessToken;
|
this.accessToken = accessToken;
|
||||||
permissions = ClientPermissions.DEFAULT;
|
permissions = ClientPermissions.DEFAULT;
|
||||||
}
|
}
|
||||||
public AuthProviderResult(String username, String accessToken,ClientPermissions permissions) {
|
|
||||||
|
public AuthProviderResult(String username, String accessToken, ClientPermissions permissions) {
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.accessToken = accessToken;
|
this.accessToken = accessToken;
|
||||||
this.permissions = permissions;
|
this.permissions = permissions;
|
||||||
|
|
|
@ -12,7 +12,7 @@ public abstract class DigestAuthProvider extends AuthProvider {
|
||||||
|
|
||||||
|
|
||||||
protected DigestAuthProvider(BlockConfigEntry block, LaunchServer server) {
|
protected DigestAuthProvider(BlockConfigEntry block, LaunchServer server) {
|
||||||
super(block,server);
|
super(block, server);
|
||||||
digest = DigestAlgorithm.byName(block.getEntryValue("digest", StringConfigEntry.class));
|
digest = DigestAlgorithm.byName(block.getEntryValue("digest", StringConfigEntry.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ private Entry(BlockConfigEntry block) {
|
||||||
private FileTime cacheLastModified;
|
private FileTime cacheLastModified;
|
||||||
|
|
||||||
public FileAuthProvider(BlockConfigEntry block, LaunchServer server) {
|
public FileAuthProvider(BlockConfigEntry block, LaunchServer server) {
|
||||||
super(block,server);
|
super(block, server);
|
||||||
file = IOHelper.toPath(block.getEntryValue("file", StringConfigEntry.class));
|
file = IOHelper.toPath(block.getEntryValue("file", StringConfigEntry.class));
|
||||||
|
|
||||||
// Try to update cache
|
// Try to update cache
|
||||||
|
|
|
@ -26,7 +26,7 @@ public final class JsonAuthProvider extends AuthProvider {
|
||||||
private final String responseErrorKeyName;
|
private final String responseErrorKeyName;
|
||||||
|
|
||||||
JsonAuthProvider(BlockConfigEntry block, LaunchServer server) {
|
JsonAuthProvider(BlockConfigEntry block, LaunchServer server) {
|
||||||
super(block,server);
|
super(block, server);
|
||||||
String configUrl = block.getEntryValue("url", StringConfigEntry.class);
|
String configUrl = block.getEntryValue("url", StringConfigEntry.class);
|
||||||
userKeyName = VerifyHelper.verify(block.getEntryValue("userKeyName", StringConfigEntry.class),
|
userKeyName = VerifyHelper.verify(block.getEntryValue("userKeyName", StringConfigEntry.class),
|
||||||
VerifyHelper.NOT_EMPTY, "Username key name can't be empty");
|
VerifyHelper.NOT_EMPTY, "Username key name can't be empty");
|
||||||
|
@ -54,7 +54,7 @@ public AuthProviderResult auth(String login, String password, String ip) throws
|
||||||
String value;
|
String value;
|
||||||
|
|
||||||
if ((value = response.getString(responseUserKeyName, null)) != null)
|
if ((value = response.getString(responseUserKeyName, null)) != null)
|
||||||
return new AuthProviderResult(value, SecurityHelper.randomStringToken(),new ClientPermissions(response.getLong(responsePermissionKeyName,0)));
|
return new AuthProviderResult(value, SecurityHelper.randomStringToken(), new ClientPermissions(response.getLong(responsePermissionKeyName, 0)));
|
||||||
else if ((value = response.getString(responseErrorKeyName, null)) != null)
|
else if ((value = response.getString(responseErrorKeyName, null)) != null)
|
||||||
return authError(value);
|
return authError(value);
|
||||||
else
|
else
|
||||||
|
|
|
@ -55,7 +55,7 @@ public static JsonObject makeJSONRequest(URL url, JsonObject request) throws IOE
|
||||||
}
|
}
|
||||||
|
|
||||||
public MojangAuthProvider(BlockConfigEntry block, LaunchServer server) {
|
public MojangAuthProvider(BlockConfigEntry block, LaunchServer server) {
|
||||||
super(block,server);
|
super(block, server);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -24,7 +24,7 @@ public final class MySQLAuthProvider extends AuthProvider {
|
||||||
private final boolean usePermission;
|
private final boolean usePermission;
|
||||||
|
|
||||||
public MySQLAuthProvider(BlockConfigEntry block, LaunchServer server) {
|
public MySQLAuthProvider(BlockConfigEntry block, LaunchServer server) {
|
||||||
super(block,server);
|
super(block, server);
|
||||||
mySQLHolder = new MySQLSourceConfig("authProviderPool", block);
|
mySQLHolder = new MySQLSourceConfig("authProviderPool", block);
|
||||||
|
|
||||||
// Read query
|
// Read query
|
||||||
|
|
|
@ -11,7 +11,7 @@ public final class NullAuthProvider extends AuthProvider {
|
||||||
private volatile AuthProvider provider;
|
private volatile AuthProvider provider;
|
||||||
|
|
||||||
public NullAuthProvider(BlockConfigEntry block, LaunchServer server) {
|
public NullAuthProvider(BlockConfigEntry block, LaunchServer server) {
|
||||||
super(block,server);
|
super(block, server);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -10,7 +10,7 @@ public final class RejectAuthProvider extends AuthProvider {
|
||||||
private final String message;
|
private final String message;
|
||||||
|
|
||||||
public RejectAuthProvider(BlockConfigEntry block, LaunchServer server) {
|
public RejectAuthProvider(BlockConfigEntry block, LaunchServer server) {
|
||||||
super(block,server);
|
super(block, server);
|
||||||
message = VerifyHelper.verify(block.getEntryValue("message", StringConfigEntry.class), VerifyHelper.NOT_EMPTY,
|
message = VerifyHelper.verify(block.getEntryValue("message", StringConfigEntry.class), VerifyHelper.NOT_EMPTY,
|
||||||
"Auth error message can't be empty");
|
"Auth error message can't be empty");
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ public final class RequestAuthProvider extends AuthProvider {
|
||||||
private final boolean usePermission;
|
private final boolean usePermission;
|
||||||
|
|
||||||
public RequestAuthProvider(BlockConfigEntry block, LaunchServer server) {
|
public RequestAuthProvider(BlockConfigEntry block, LaunchServer server) {
|
||||||
super(block,server);
|
super(block, server);
|
||||||
url = block.getEntryValue("url", StringConfigEntry.class);
|
url = block.getEntryValue("url", StringConfigEntry.class);
|
||||||
response = Pattern.compile(block.getEntryValue("response", StringConfigEntry.class));
|
response = Pattern.compile(block.getEntryValue("response", StringConfigEntry.class));
|
||||||
usePermission = block.hasEntry("usePermission") ? block.getEntryValue("usePermission", BooleanConfigEntry.class) : false;
|
usePermission = block.hasEntry("usePermission") ? block.getEntryValue("usePermission", BooleanConfigEntry.class) : false;
|
||||||
|
|
|
@ -48,12 +48,13 @@ public CtClass getCtClass() {
|
||||||
public byte[] getBytecode() throws IOException, CannotCompileException {
|
public byte[] getBytecode() throws IOException, CannotCompileException {
|
||||||
return ctClass.toBytecode();
|
return ctClass.toBytecode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void compile() throws CannotCompileException {
|
public void compile() throws CannotCompileException {
|
||||||
body.append("}");
|
body.append("}");
|
||||||
moduleBody.append("}");
|
moduleBody.append("}");
|
||||||
ctConstructor.setBody(body.toString());
|
ctConstructor.setBody(body.toString());
|
||||||
initModuleMethod.insertAfter(moduleBody.toString());
|
initModuleMethod.insertAfter(moduleBody.toString());
|
||||||
if(ctClass.isFrozen()) ctClass.defrost();
|
if (ctClass.isFrozen()) ctClass.defrost();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getZipEntryPath() {
|
public String getZipEntryPath() {
|
||||||
|
@ -83,16 +84,19 @@ public void setPort(int port) {
|
||||||
body.append(port);
|
body.append(port);
|
||||||
body.append(";");
|
body.append(";");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClientPort(int port) {
|
public void setClientPort(int port) {
|
||||||
body.append("this.clientPort = ");
|
body.append("this.clientPort = ");
|
||||||
body.append(port);
|
body.append(port);
|
||||||
body.append(";");
|
body.append(";");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUsingWrapper(boolean b) {
|
public void setUsingWrapper(boolean b) {
|
||||||
body.append("this.isUsingWrapper = ");
|
body.append("this.isUsingWrapper = ");
|
||||||
body.append(b ? "true" : "false");
|
body.append(b ? "true" : "false");
|
||||||
body.append(";");
|
body.append(";");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDownloadJava(boolean b) {
|
public void setDownloadJava(boolean b) {
|
||||||
body.append("this.isDownloadJava = ");
|
body.append("this.isDownloadJava = ");
|
||||||
body.append(b ? "true" : "false");
|
body.append(b ? "true" : "false");
|
||||||
|
|
|
@ -98,6 +98,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
|
||||||
private static ZipEntry newEntry(String fileName) {
|
private static ZipEntry newEntry(String fileName) {
|
||||||
return newZipEntry(Launcher.RUNTIME_DIR + IOHelper.CROSS_SEPARATOR + fileName);
|
return newZipEntry(Launcher.RUNTIME_DIR + IOHelper.CROSS_SEPARATOR + fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ZipEntry newGuardEntry(String fileName) {
|
private static ZipEntry newGuardEntry(String fileName) {
|
||||||
return newZipEntry(Launcher.GUARD_DIR + IOHelper.CROSS_SEPARATOR + fileName);
|
return newZipEntry(Launcher.GUARD_DIR + IOHelper.CROSS_SEPARATOR + fileName);
|
||||||
}
|
}
|
||||||
|
@ -145,13 +146,11 @@ public void build() throws IOException {
|
||||||
} catch (ParseException e1) {
|
} catch (ParseException e1) {
|
||||||
e1.printStackTrace();
|
e1.printStackTrace();
|
||||||
}
|
}
|
||||||
if(server.buildHookManager.isNeedPostProguardHook())
|
if (server.buildHookManager.isNeedPostProguardHook()) {
|
||||||
{
|
|
||||||
Path obfPath = Paths.get(server.config.binaryName + "-obf.jar");
|
Path obfPath = Paths.get(server.config.binaryName + "-obf.jar");
|
||||||
Path tmpPath = Paths.get(server.config.binaryName + "-tmp.jar");
|
Path tmpPath = Paths.get(server.config.binaryName + "-tmp.jar");
|
||||||
IOHelper.move(obfPath,tmpPath);
|
IOHelper.move(obfPath, tmpPath);
|
||||||
try (ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(obfPath)))
|
try (ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(obfPath))) {
|
||||||
{
|
|
||||||
try (ZipInputStream input = new ZipInputStream(
|
try (ZipInputStream input = new ZipInputStream(
|
||||||
IOHelper.newInput(tmpPath))) {
|
IOHelper.newInput(tmpPath))) {
|
||||||
ZipEntry e = input.getNextEntry();
|
ZipEntry e = input.getNextEntry();
|
||||||
|
|
|
@ -43,6 +43,7 @@ public final boolean exists() {
|
||||||
public final DigestBytesHolder getBytes() {
|
public final DigestBytesHolder getBytes() {
|
||||||
return binary;
|
return binary;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final byte[] getSign() {
|
public final byte[] getSign() {
|
||||||
return sign;
|
return sign;
|
||||||
}
|
}
|
||||||
|
@ -51,7 +52,7 @@ public final byte[] getSign() {
|
||||||
public final boolean sync() throws IOException {
|
public final boolean sync() throws IOException {
|
||||||
boolean exists = exists();
|
boolean exists = exists();
|
||||||
binary = exists ? new DigestBytesHolder(IOHelper.read(syncBinaryFile), SecurityHelper.DigestAlgorithm.SHA512) : null;
|
binary = exists ? new DigestBytesHolder(IOHelper.read(syncBinaryFile), SecurityHelper.DigestAlgorithm.SHA512) : null;
|
||||||
sign = exists ? SecurityHelper.sign(IOHelper.read(syncBinaryFile),server.privateKey) : null;
|
sign = exists ? SecurityHelper.sign(IOHelper.read(syncBinaryFile), server.privateKey) : null;
|
||||||
|
|
||||||
return exists;
|
return exists;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ public void invoke(String... args) throws Exception {
|
||||||
String login = args[0];
|
String login = args[0];
|
||||||
String password = args[1];
|
String password = args[1];
|
||||||
int auth_id = 0;
|
int auth_id = 0;
|
||||||
if(args.length >= 3) auth_id = Integer.valueOf(args[3]);
|
if (args.length >= 3) auth_id = Integer.valueOf(args[3]);
|
||||||
|
|
||||||
// Authenticate
|
// Authenticate
|
||||||
AuthProvider provider = server.config.authProvider[auth_id];
|
AuthProvider provider = server.config.authProvider[auth_id];
|
||||||
|
|
|
@ -28,7 +28,7 @@ public void invoke(String... args) throws Exception {
|
||||||
if (handler == null)
|
if (handler == null)
|
||||||
handler = new NettyServerSocketHandler(server);
|
handler = new NettyServerSocketHandler(server);
|
||||||
if (args[0].equals("start")) {
|
if (args[0].equals("start")) {
|
||||||
CommonHelper.newThread("Netty Server",true,handler).start();
|
CommonHelper.newThread("Netty Server", true, handler).start();
|
||||||
}
|
}
|
||||||
if (args[0].equals("stop")) {
|
if (args[0].equals("stop")) {
|
||||||
handler.close();
|
handler.close();
|
||||||
|
|
|
@ -229,7 +229,7 @@ private static void sendListing(ChannelHandlerContext ctx, File dir, String dirP
|
||||||
.append("<ul>")
|
.append("<ul>")
|
||||||
.append("<li><a href=\"../\">..</a></li>\r\n");
|
.append("<li><a href=\"../\">..</a></li>\r\n");
|
||||||
|
|
||||||
for (File f: dir.listFiles()) {
|
for (File f : dir.listFiles()) {
|
||||||
if (f.isHidden() || !f.canRead()) {
|
if (f.isHidden() || !f.canRead()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -275,8 +275,7 @@ private static void sendError(ChannelHandlerContext ctx, HttpResponseStatus stat
|
||||||
/**
|
/**
|
||||||
* When file timestamp is the same as what the browser is sending up, send a "304 Not Modified"
|
* When file timestamp is the same as what the browser is sending up, send a "304 Not Modified"
|
||||||
*
|
*
|
||||||
* @param ctx
|
* @param ctx Context
|
||||||
* Context
|
|
||||||
*/
|
*/
|
||||||
private static void sendNotModified(ChannelHandlerContext ctx) {
|
private static void sendNotModified(ChannelHandlerContext ctx) {
|
||||||
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, NOT_MODIFIED);
|
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, NOT_MODIFIED);
|
||||||
|
@ -289,8 +288,7 @@ private static void sendNotModified(ChannelHandlerContext ctx) {
|
||||||
/**
|
/**
|
||||||
* Sets the Date header for the HTTP response
|
* Sets the Date header for the HTTP response
|
||||||
*
|
*
|
||||||
* @param response
|
* @param response HTTP response
|
||||||
* HTTP response
|
|
||||||
*/
|
*/
|
||||||
private static void setDateHeader(FullHttpResponse response) {
|
private static void setDateHeader(FullHttpResponse response) {
|
||||||
SimpleDateFormat dateFormatter = new SimpleDateFormat(HTTP_DATE_FORMAT, Locale.US);
|
SimpleDateFormat dateFormatter = new SimpleDateFormat(HTTP_DATE_FORMAT, Locale.US);
|
||||||
|
@ -303,10 +301,8 @@ private static void setDateHeader(FullHttpResponse response) {
|
||||||
/**
|
/**
|
||||||
* Sets the Date and Cache headers for the HTTP Response
|
* Sets the Date and Cache headers for the HTTP Response
|
||||||
*
|
*
|
||||||
* @param response
|
* @param response HTTP response
|
||||||
* HTTP response
|
* @param fileToCache file to extract content type
|
||||||
* @param fileToCache
|
|
||||||
* file to extract content type
|
|
||||||
*/
|
*/
|
||||||
private static void setDateAndCacheHeaders(HttpResponse response, File fileToCache) {
|
private static void setDateAndCacheHeaders(HttpResponse response, File fileToCache) {
|
||||||
SimpleDateFormat dateFormatter = new SimpleDateFormat(HTTP_DATE_FORMAT, Locale.US);
|
SimpleDateFormat dateFormatter = new SimpleDateFormat(HTTP_DATE_FORMAT, Locale.US);
|
||||||
|
@ -327,10 +323,8 @@ private static void setDateAndCacheHeaders(HttpResponse response, File fileToCac
|
||||||
/**
|
/**
|
||||||
* Sets the content type header for the HTTP Response
|
* Sets the content type header for the HTTP Response
|
||||||
*
|
*
|
||||||
* @param response
|
* @param response HTTP response
|
||||||
* HTTP response
|
* @param file file to extract content type
|
||||||
* @param file
|
|
||||||
* file to extract content type
|
|
||||||
*/
|
*/
|
||||||
private static void setContentTypeHeader(HttpResponse response, File file) {
|
private static void setContentTypeHeader(HttpResponse response, File file) {
|
||||||
MimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap();
|
MimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap();
|
||||||
|
|
|
@ -64,6 +64,7 @@ public byte[] classTransform(byte[] clazz, CharSequence classname) {
|
||||||
for (Transformer transformer : CLASS_TRANSFORMER) result = transformer.transform(result, classname);
|
for (Transformer transformer : CLASS_TRANSFORMER) result = transformer.transform(result, classname);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] proGuardClassTransform(byte[] clazz, CharSequence classname) {
|
public byte[] proGuardClassTransform(byte[] clazz, CharSequence classname) {
|
||||||
byte[] result = clazz;
|
byte[] result = clazz;
|
||||||
for (Transformer transformer : POST_PROGUARD_HOOKS) result = transformer.transform(result, classname);
|
for (Transformer transformer : POST_PROGUARD_HOOKS) result = transformer.transform(result, classname);
|
||||||
|
@ -109,11 +110,12 @@ public void registerIgnoredClass(String clazz) {
|
||||||
public void registerPostHook(PostBuildHook hook) {
|
public void registerPostHook(PostBuildHook hook) {
|
||||||
POST_HOOKS.add(hook);
|
POST_HOOKS.add(hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerProGuardHook(Transformer hook) {
|
public void registerProGuardHook(Transformer hook) {
|
||||||
POST_PROGUARD_HOOKS.add(hook);
|
POST_PROGUARD_HOOKS.add(hook);
|
||||||
}
|
}
|
||||||
public boolean isNeedPostProguardHook()
|
|
||||||
{
|
public boolean isNeedPostProguardHook() {
|
||||||
return !POST_PROGUARD_HOOKS.isEmpty();
|
return !POST_PROGUARD_HOOKS.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,58 +7,63 @@
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class MirrorManager {
|
public class MirrorManager {
|
||||||
public class Mirror
|
public class Mirror {
|
||||||
{
|
|
||||||
URL url;
|
URL url;
|
||||||
String assetsURLMask;
|
String assetsURLMask;
|
||||||
String clientsURLMask;
|
String clientsURLMask;
|
||||||
boolean enabled;
|
boolean enabled;
|
||||||
Mirror(String url)
|
|
||||||
{
|
Mirror(String url) {
|
||||||
assetsURLMask = url.concat("assets/%s.zip");
|
assetsURLMask = url.concat("assets/%s.zip");
|
||||||
clientsURLMask = url.concat("clients/%s.zip");
|
clientsURLMask = url.concat("clients/%s.zip");
|
||||||
}
|
}
|
||||||
private URL formatArg(String mask,String arg) throws MalformedURLException {
|
|
||||||
|
private URL formatArg(String mask, String arg) throws MalformedURLException {
|
||||||
return new URL(String.format(mask, IOHelper.urlEncode(arg)));
|
return new URL(String.format(mask, IOHelper.urlEncode(arg)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public URL getAssetsURL(String assets) throws MalformedURLException {
|
public URL getAssetsURL(String assets) throws MalformedURLException {
|
||||||
return formatArg(assetsURLMask,assets);
|
return formatArg(assetsURLMask, assets);
|
||||||
}
|
}
|
||||||
|
|
||||||
public URL getClientsURL(String client) throws MalformedURLException {
|
public URL getClientsURL(String client) throws MalformedURLException {
|
||||||
return formatArg(clientsURLMask,client);
|
return formatArg(clientsURLMask, client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ArrayList<Mirror> list = new ArrayList<>();
|
protected ArrayList<Mirror> list = new ArrayList<>();
|
||||||
private Mirror defaultMirror;
|
private Mirror defaultMirror;
|
||||||
|
|
||||||
public void addMirror(String mirror) throws MalformedURLException {
|
public void addMirror(String mirror) throws MalformedURLException {
|
||||||
Mirror m = new Mirror(mirror);
|
Mirror m = new Mirror(mirror);
|
||||||
m.enabled = true;
|
m.enabled = true;
|
||||||
if(defaultMirror == null) defaultMirror = m;
|
if (defaultMirror == null) defaultMirror = m;
|
||||||
}
|
}
|
||||||
public void addMirror(String mirror,boolean enabled) throws MalformedURLException {
|
|
||||||
|
public void addMirror(String mirror, boolean enabled) throws MalformedURLException {
|
||||||
Mirror m = new Mirror(mirror);
|
Mirror m = new Mirror(mirror);
|
||||||
m.url = new URL(mirror);
|
m.url = new URL(mirror);
|
||||||
m.enabled = enabled;
|
m.enabled = enabled;
|
||||||
if(defaultMirror == null && enabled) defaultMirror = m;
|
if (defaultMirror == null && enabled) defaultMirror = m;
|
||||||
}
|
}
|
||||||
public Mirror getDefaultMirror()
|
|
||||||
{
|
public Mirror getDefaultMirror() {
|
||||||
return defaultMirror;
|
return defaultMirror;
|
||||||
}
|
}
|
||||||
public void setDefaultMirror(Mirror m)
|
|
||||||
{
|
public void setDefaultMirror(Mirror m) {
|
||||||
defaultMirror = m;
|
defaultMirror = m;
|
||||||
}
|
}
|
||||||
public void disableMirror(int index)
|
|
||||||
{
|
public void disableMirror(int index) {
|
||||||
list.get(index).enabled = false;
|
list.get(index).enabled = false;
|
||||||
}
|
}
|
||||||
public void enableMirror(int index)
|
|
||||||
{
|
public void enableMirror(int index) {
|
||||||
list.get(index).enabled = true;
|
list.get(index).enabled = true;
|
||||||
}
|
}
|
||||||
public int size()
|
|
||||||
{
|
public int size() {
|
||||||
return list.size();
|
return list.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ public boolean addClient(Client client) {
|
||||||
|
|
||||||
public void garbageCollection() {
|
public void garbageCollection() {
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
clientSet.removeIf(c -> (c.timestamp + SESSION_TIMEOUT < time) && ((c.type == Client.Type.USER) || ((c.type == Client.Type.SERVER) && !NON_GARBAGE_SERVER ) ));
|
clientSet.removeIf(c -> (c.timestamp + SESSION_TIMEOUT < time) && ((c.type == Client.Type.USER) || ((c.type == Client.Type.SERVER) && !NON_GARBAGE_SERVER)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ public static void registerResponses() {
|
||||||
registerResponse(RequestType.PROFILES.getNumber(), ProfilesResponse::new);
|
registerResponse(RequestType.PROFILES.getNumber(), ProfilesResponse::new);
|
||||||
registerResponse(RequestType.SERVERAUTH.getNumber(), AuthServerResponse::new);
|
registerResponse(RequestType.SERVERAUTH.getNumber(), AuthServerResponse::new);
|
||||||
registerResponse(RequestType.SETPROFILE.getNumber(), SetProfileResponse::new);
|
registerResponse(RequestType.SETPROFILE.getNumber(), SetProfileResponse::new);
|
||||||
registerResponse(RequestType.CHANGESERVER.getNumber(),ChangeServerResponse::new);
|
registerResponse(RequestType.CHANGESERVER.getNumber(), ChangeServerResponse::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -42,13 +42,13 @@ public void reply() throws Exception {
|
||||||
String login = input.readString(SerializeLimits.MAX_LOGIN);
|
String login = input.readString(SerializeLimits.MAX_LOGIN);
|
||||||
boolean isClient = input.readBoolean();
|
boolean isClient = input.readBoolean();
|
||||||
String client = null;
|
String client = null;
|
||||||
if(isClient)
|
if (isClient)
|
||||||
client = input.readString(SerializeLimits.MAX_CLIENT);
|
client = input.readString(SerializeLimits.MAX_CLIENT);
|
||||||
int auth_id = input.readInt();
|
int auth_id = input.readInt();
|
||||||
long hwid_hdd = input.readLong();
|
long hwid_hdd = input.readLong();
|
||||||
long hwid_cpu = input.readLong();
|
long hwid_cpu = input.readLong();
|
||||||
long hwid_bios = input.readLong();
|
long hwid_bios = input.readLong();
|
||||||
if(auth_id + 1 > server.config.authProvider.length || auth_id < 0) auth_id = 0;
|
if (auth_id + 1 > server.config.authProvider.length || auth_id < 0) auth_id = 0;
|
||||||
byte[] encryptedPassword = input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH);
|
byte[] encryptedPassword = input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH);
|
||||||
// Decrypt password
|
// Decrypt password
|
||||||
String password;
|
String password;
|
||||||
|
@ -71,8 +71,7 @@ public void reply() throws Exception {
|
||||||
AuthProvider.authError(server.config.authRejectString);
|
AuthProvider.authError(server.config.authRejectString);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!clientData.checkSign)
|
if (!clientData.checkSign) {
|
||||||
{
|
|
||||||
throw new AuthException("You must using checkLauncher");
|
throw new AuthException("You must using checkLauncher");
|
||||||
}
|
}
|
||||||
result = provider.auth(login, password, ip);
|
result = provider.auth(login, password, ip);
|
||||||
|
@ -80,7 +79,7 @@ public void reply() throws Exception {
|
||||||
AuthProvider.authError(String.format("Illegal result: '%s'", result.username));
|
AuthProvider.authError(String.format("Illegal result: '%s'", result.username));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(isClient) {
|
if (isClient) {
|
||||||
Collection<SignedObjectHolder<ClientProfile>> profiles = server.getProfiles();
|
Collection<SignedObjectHolder<ClientProfile>> profiles = server.getProfiles();
|
||||||
for (SignedObjectHolder<ClientProfile> p : profiles) {
|
for (SignedObjectHolder<ClientProfile> p : profiles) {
|
||||||
if (p.object.getTitle().equals(client)) {
|
if (p.object.getTitle().equals(client)) {
|
||||||
|
|
|
@ -38,7 +38,7 @@ public void reply() throws Exception {
|
||||||
String login = input.readString(SerializeLimits.MAX_LOGIN);
|
String login = input.readString(SerializeLimits.MAX_LOGIN);
|
||||||
String client = input.readString(SerializeLimits.MAX_CLIENT);
|
String client = input.readString(SerializeLimits.MAX_CLIENT);
|
||||||
int auth_id = input.readInt();
|
int auth_id = input.readInt();
|
||||||
if(auth_id + 1 > server.config.authProvider.length || auth_id < 0) auth_id = 0;
|
if (auth_id + 1 > server.config.authProvider.length || auth_id < 0) auth_id = 0;
|
||||||
byte[] encryptedPassword = input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH);
|
byte[] encryptedPassword = input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH);
|
||||||
// Decrypt password
|
// Decrypt password
|
||||||
String password;
|
String password;
|
||||||
|
@ -73,7 +73,7 @@ public void reply() throws Exception {
|
||||||
clientData.profile = p.object;
|
clientData.profile = p.object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(clientData.profile == null) {
|
if (clientData.profile == null) {
|
||||||
throw new AuthException("You profile not found");
|
throw new AuthException("You profile not found");
|
||||||
}
|
}
|
||||||
clientData.type = Client.Type.SERVER;
|
clientData.type = Client.Type.SERVER;
|
||||||
|
|
|
@ -19,9 +19,8 @@ public void reply() throws Exception {
|
||||||
writeNoError(output);
|
writeNoError(output);
|
||||||
output.writeBoolean(needChange);
|
output.writeBoolean(needChange);
|
||||||
//if true
|
//if true
|
||||||
if(needChange)
|
if (needChange) {
|
||||||
{
|
output.writeString(address, 255);
|
||||||
output.writeString(address,255);
|
|
||||||
output.writeInt(port);
|
output.writeInt(port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ public SetProfileResponse(LaunchServer server, long session, HInput input, HOutp
|
||||||
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);
|
Client clientData = server.sessionManager.getClient(session);
|
||||||
if(!clientData.isAuth) requestError("You not auth");
|
if (!clientData.isAuth) requestError("You not auth");
|
||||||
Collection<SignedObjectHolder<ClientProfile>> profiles = server.getProfiles();
|
Collection<SignedObjectHolder<ClientProfile>> profiles = server.getProfiles();
|
||||||
for (SignedObjectHolder<ClientProfile> p : profiles) {
|
for (SignedObjectHolder<ClientProfile> p : profiles) {
|
||||||
if (p.object.getTitle().equals(client)) {
|
if (p.object.getTitle().equals(client)) {
|
||||||
|
|
|
@ -26,8 +26,7 @@ public void reply() throws IOException {
|
||||||
}
|
}
|
||||||
Client client = server.sessionManager.getOrNewClient(session);
|
Client client = server.sessionManager.getOrNewClient(session);
|
||||||
byte[] digest = input.readByteArray(0);
|
byte[] digest = input.readByteArray(0);
|
||||||
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);
|
||||||
|
|
|
@ -23,8 +23,8 @@ public void reply() throws IOException {
|
||||||
// Resolve launcher binary
|
// Resolve launcher binary
|
||||||
Client client = server.sessionManager.getClient(session);
|
Client client = server.sessionManager.getClient(session);
|
||||||
input.readBoolean();
|
input.readBoolean();
|
||||||
if(client.type == Client.Type.USER && !client.checkSign) {
|
if (client.type == Client.Type.USER && !client.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("Assess denied");
|
requestError("Assess denied");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,6 @@ public void reply() throws Exception {
|
||||||
// Write all update dirs names
|
// Write all update dirs names
|
||||||
output.writeLength(updateDirs.size(), 0);
|
output.writeLength(updateDirs.size(), 0);
|
||||||
for (Entry<String, SignedObjectHolder<HashedDir>> entry : updateDirs)
|
for (Entry<String, SignedObjectHolder<HashedDir>> entry : updateDirs)
|
||||||
output.writeString(entry.getKey(), 255);
|
output.writeString(entry.getKey(), 255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,12 +38,14 @@ public void reply() throws IOException {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Client clientData = server.sessionManager.getClient(session);
|
Client clientData = server.sessionManager.getClient(session);
|
||||||
if(!clientData.isAuth || clientData.type != Client.Type.USER || clientData.profile == null) { requestError("Assess denied"); return;}
|
if (!clientData.isAuth || clientData.type != Client.Type.USER || clientData.profile == null) {
|
||||||
for(SignedObjectHolder<ClientProfile> p : server.getProfiles())
|
requestError("Assess denied");
|
||||||
{
|
return;
|
||||||
|
}
|
||||||
|
for (SignedObjectHolder<ClientProfile> p : server.getProfiles()) {
|
||||||
ClientProfile profile = p.object;
|
ClientProfile profile = p.object;
|
||||||
if(!clientData.profile.getTitle().equals(profile.getTitle())) continue;
|
if (!clientData.profile.getTitle().equals(profile.getTitle())) continue;
|
||||||
if(!profile.isWhitelistContains(clientData.username)) {
|
if (!profile.isWhitelistContains(clientData.username)) {
|
||||||
requestError("You don't download this folder");
|
requestError("You don't download this folder");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,13 @@ public Client(long session) {
|
||||||
username = "";
|
username = "";
|
||||||
checkSign = false;
|
checkSign = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Данные ваторизации
|
//Данные ваторизации
|
||||||
public void up() {
|
public void up() {
|
||||||
timestamp = System.currentTimeMillis();
|
timestamp = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
public enum Type
|
|
||||||
{
|
public enum Type {
|
||||||
SERVER,
|
SERVER,
|
||||||
USER
|
USER
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,7 +140,7 @@ public void initChannel(NioSocketChannel ch) {
|
||||||
pipeline.addLast(new HttpObjectAggregator(65536));
|
pipeline.addLast(new HttpObjectAggregator(65536));
|
||||||
pipeline.addLast(new WebSocketServerCompressionHandler());
|
pipeline.addLast(new WebSocketServerCompressionHandler());
|
||||||
pipeline.addLast(new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true));
|
pipeline.addLast(new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true));
|
||||||
pipeline.addLast(new FileServerHandler(LaunchServer.server.updatesDir,true));
|
pipeline.addLast(new FileServerHandler(LaunchServer.server.updatesDir, true));
|
||||||
pipeline.addLast(new WebSocketFrameHandler());
|
pipeline.addLast(new WebSocketFrameHandler());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,14 +11,17 @@
|
||||||
import ru.gravit.launchserver.socket.Client;
|
import ru.gravit.launchserver.socket.Client;
|
||||||
import ru.gravit.utils.helper.IOHelper;
|
import ru.gravit.utils.helper.IOHelper;
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
import ru.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
public class WebSocketFrameHandler extends SimpleChannelInboundHandler<WebSocketFrame> {
|
public class WebSocketFrameHandler extends SimpleChannelInboundHandler<WebSocketFrame> {
|
||||||
public static LaunchServer server;
|
public static LaunchServer server;
|
||||||
public static GsonBuilder builder = new GsonBuilder();
|
public static GsonBuilder builder = new GsonBuilder();
|
||||||
public static WebSocketService service = new WebSocketService(new DefaultChannelGroup(GlobalEventExecutor.INSTANCE), LaunchServer.server,builder);
|
public static WebSocketService service = new WebSocketService(new DefaultChannelGroup(GlobalEventExecutor.INSTANCE), LaunchServer.server, builder);
|
||||||
private Client client;
|
private Client client;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
service.registerResponses();
|
service.registerResponses();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void channelActive(ChannelHandlerContext ctx) {
|
public void channelActive(ChannelHandlerContext ctx) {
|
||||||
LogHelper.debug("New client %s", IOHelper.getIP(ctx.channel().remoteAddress()));
|
LogHelper.debug("New client %s", IOHelper.getIP(ctx.channel().remoteAddress()));
|
||||||
|
|
|
@ -25,69 +25,68 @@
|
||||||
|
|
||||||
public class WebSocketService {
|
public class WebSocketService {
|
||||||
public final ChannelGroup channels;
|
public final ChannelGroup channels;
|
||||||
|
|
||||||
public WebSocketService(ChannelGroup channels, LaunchServer server, GsonBuilder gson) {
|
public WebSocketService(ChannelGroup channels, LaunchServer server, GsonBuilder gson) {
|
||||||
this.channels = channels;
|
this.channels = channels;
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.gsonBuiler = gson;
|
this.gsonBuiler = gson;
|
||||||
this.
|
this.
|
||||||
gsonBuiler.registerTypeAdapter(JsonResponseInterface.class,new JsonResponseAdapter(this));
|
gsonBuiler.registerTypeAdapter(JsonResponseInterface.class, new JsonResponseAdapter(this));
|
||||||
gsonBuiler.registerTypeAdapter(HashedEntry.class,new HashedEntryAdapter());
|
gsonBuiler.registerTypeAdapter(HashedEntry.class, new HashedEntryAdapter());
|
||||||
this.gson = gsonBuiler.create();
|
this.gson = gsonBuiler.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final LaunchServer server;
|
private final LaunchServer server;
|
||||||
private static final HashMap<String,Class> responses = new HashMap<>();
|
private static final HashMap<String, Class> responses = new HashMap<>();
|
||||||
private final Gson gson;
|
private final Gson gson;
|
||||||
private final GsonBuilder gsonBuiler;
|
private final GsonBuilder gsonBuiler;
|
||||||
|
|
||||||
void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client client)
|
void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client client) {
|
||||||
{
|
|
||||||
String request = frame.text();
|
String request = frame.text();
|
||||||
JsonResponseInterface response = gson.fromJson(request, JsonResponseInterface.class);
|
JsonResponseInterface response = gson.fromJson(request, JsonResponseInterface.class);
|
||||||
try {
|
try {
|
||||||
response.execute(this,ctx,client);
|
response.execute(this, ctx, client);
|
||||||
} catch (Exception e)
|
} catch (Exception e) {
|
||||||
{
|
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
sendObject(ctx,new ExceptionResult(e));
|
sendObject(ctx, new ExceptionResult(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public Class getResponseClass(String type)
|
|
||||||
{
|
public Class getResponseClass(String type) {
|
||||||
return responses.get(type);
|
return responses.get(type);
|
||||||
}
|
}
|
||||||
public void registerResponse(String key,Class responseInterfaceClass)
|
|
||||||
{
|
public void registerResponse(String key, Class responseInterfaceClass) {
|
||||||
responses.put(key,responseInterfaceClass);
|
responses.put(key, responseInterfaceClass);
|
||||||
}
|
}
|
||||||
public void registerClient(Channel channel)
|
|
||||||
{
|
public void registerClient(Channel channel) {
|
||||||
channels.add(channel);
|
channels.add(channel);
|
||||||
}
|
}
|
||||||
public void registerResponses()
|
|
||||||
{
|
public void registerResponses() {
|
||||||
registerResponse("echo", EchoResponse.class);
|
registerResponse("echo", EchoResponse.class);
|
||||||
registerResponse("auth", AuthResponse.class);
|
registerResponse("auth", AuthResponse.class);
|
||||||
registerResponse("checkServer", CheckServerResponse.class);
|
registerResponse("checkServer", CheckServerResponse.class);
|
||||||
registerResponse("joinServer", JoinServerResponse.class);
|
registerResponse("joinServer", JoinServerResponse.class);
|
||||||
registerResponse("launcherUpdate", LauncherResponse.class);
|
registerResponse("launcherUpdate", LauncherResponse.class);
|
||||||
registerResponse("updateList", UpdateListResponse.class);
|
registerResponse("updateList", UpdateListResponse.class);
|
||||||
registerResponse("cmdExec",UpdateListResponse.class);
|
registerResponse("cmdExec", UpdateListResponse.class);
|
||||||
}
|
}
|
||||||
public void sendObject(ChannelHandlerContext ctx, Object obj)
|
|
||||||
{
|
public void sendObject(ChannelHandlerContext ctx, Object obj) {
|
||||||
ctx.channel().writeAndFlush(new TextWebSocketFrame(gson.toJson(obj)));
|
ctx.channel().writeAndFlush(new TextWebSocketFrame(gson.toJson(obj)));
|
||||||
}
|
}
|
||||||
public void sendObjectAndClose(ChannelHandlerContext ctx, Object obj)
|
|
||||||
{
|
public void sendObjectAndClose(ChannelHandlerContext ctx, Object obj) {
|
||||||
ctx.channel().writeAndFlush(new TextWebSocketFrame(gson.toJson(obj))).addListener(ChannelFutureListener.CLOSE);
|
ctx.channel().writeAndFlush(new TextWebSocketFrame(gson.toJson(obj))).addListener(ChannelFutureListener.CLOSE);
|
||||||
}
|
}
|
||||||
public void sendEvent(EventResult obj)
|
|
||||||
{
|
public void sendEvent(EventResult obj) {
|
||||||
channels.writeAndFlush(new TextWebSocketFrame(gson.toJson(obj)));
|
channels.writeAndFlush(new TextWebSocketFrame(gson.toJson(obj)));
|
||||||
}
|
}
|
||||||
public static class ErrorResult
|
|
||||||
{
|
public static class ErrorResult {
|
||||||
public ErrorResult(String error) {
|
public ErrorResult(String error) {
|
||||||
this.error = error;
|
this.error = error;
|
||||||
this.type = "requestError";
|
this.type = "requestError";
|
||||||
|
@ -96,8 +95,8 @@ public ErrorResult(String error) {
|
||||||
public final String error;
|
public final String error;
|
||||||
public final String type;
|
public final String type;
|
||||||
}
|
}
|
||||||
public static class SuccessResult
|
|
||||||
{
|
public static class SuccessResult {
|
||||||
public SuccessResult(String requesttype) {
|
public SuccessResult(String requesttype) {
|
||||||
this.requesttype = requesttype;
|
this.requesttype = requesttype;
|
||||||
this.type = "success";
|
this.type = "success";
|
||||||
|
@ -106,15 +105,16 @@ public SuccessResult(String requesttype) {
|
||||||
public final String requesttype;
|
public final String requesttype;
|
||||||
public final String type;
|
public final String type;
|
||||||
}
|
}
|
||||||
public static class EventResult
|
|
||||||
{
|
public static class EventResult {
|
||||||
public EventResult() {
|
public EventResult() {
|
||||||
this.type = "event";
|
this.type = "event";
|
||||||
}
|
}
|
||||||
|
|
||||||
public final String type;
|
public final String type;
|
||||||
}
|
}
|
||||||
public static class ExceptionResult
|
|
||||||
{
|
public static class ExceptionResult {
|
||||||
public ExceptionResult(Exception e) {
|
public ExceptionResult(Exception e) {
|
||||||
this.message = e.getMessage();
|
this.message = e.getMessage();
|
||||||
this.clazz = e.getClass().getName();
|
this.clazz = e.getClass().getName();
|
||||||
|
|
|
@ -18,12 +18,12 @@ public String getType() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(WebSocketService service,ChannelHandlerContext ctx, Client client) {
|
public void execute(WebSocketService service, ChannelHandlerContext ctx, Client client) {
|
||||||
LogHelper.info("Echo: %s, isAuth %s",echo,client.isAuth ? "true" : "false");
|
LogHelper.info("Echo: %s, isAuth %s", echo, client.isAuth ? "true" : "false");
|
||||||
service.sendObject(ctx,new Result(echo));
|
service.sendObject(ctx, new Result(echo));
|
||||||
}
|
}
|
||||||
public class Result
|
|
||||||
{
|
public class Result {
|
||||||
String echo;
|
String echo;
|
||||||
|
|
||||||
public Result(String echo) {
|
public Result(String echo) {
|
||||||
|
|
|
@ -6,5 +6,6 @@
|
||||||
|
|
||||||
public interface JsonResponseInterface {
|
public interface JsonResponseInterface {
|
||||||
String getType();
|
String getType();
|
||||||
void execute(WebSocketService service,ChannelHandlerContext ctx, Client client) throws Exception;
|
|
||||||
|
void execute(WebSocketService service, ChannelHandlerContext ctx, Client client) throws Exception;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
public class ExecCommandResponse implements JsonResponseInterface {
|
public class ExecCommandResponse implements JsonResponseInterface {
|
||||||
public String cmd;
|
public String cmd;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return "cmdExec";
|
return "cmdExec";
|
||||||
|
@ -15,9 +16,15 @@ public String getType() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(WebSocketService service, ChannelHandlerContext ctx, Client client) throws Exception {
|
public void execute(WebSocketService service, ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
if(!client.isAuth) {service.sendObject(ctx,new WebSocketService.ErrorResult("Access denied")); return; }
|
if (!client.isAuth) {
|
||||||
if(!client.permissions.canAdmin) {service.sendObject(ctx,new WebSocketService.ErrorResult("Access denied")); return; }
|
service.sendObject(ctx, new WebSocketService.ErrorResult("Access denied"));
|
||||||
LaunchServer.server.commandHandler.eval(cmd,false);
|
return;
|
||||||
service.sendObject(ctx,new WebSocketService.SuccessResult("cmdExec"));
|
}
|
||||||
|
if (!client.permissions.canAdmin) {
|
||||||
|
service.sendObject(ctx, new WebSocketService.ErrorResult("Access denied"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LaunchServer.server.commandHandler.eval(cmd, false);
|
||||||
|
service.sendObject(ctx, new WebSocketService.SuccessResult("cmdExec"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ public AuthResponse(String login, String password, int authid, HWID hwid) {
|
||||||
|
|
||||||
public int authid;
|
public int authid;
|
||||||
public HWID hwid;
|
public HWID hwid;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return "auth";
|
return "auth";
|
||||||
|
@ -45,8 +46,7 @@ public void execute(WebSocketService service, ChannelHandlerContext ctx, Client
|
||||||
AuthProvider.authError(LaunchServer.server.config.authRejectString);
|
AuthProvider.authError(LaunchServer.server.config.authRejectString);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!clientData.checkSign)
|
if (!clientData.checkSign) {
|
||||||
{
|
|
||||||
AuthProvider.authError("Don't skip Launcher Update");
|
AuthProvider.authError("Don't skip Launcher Update");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -65,20 +65,19 @@ public void execute(WebSocketService service, ChannelHandlerContext ctx, Client
|
||||||
clientData.profile = p.object;
|
clientData.profile = p.object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(clientData.profile == null) {
|
if (clientData.profile == null) {
|
||||||
throw new AuthException("You profile not found");
|
throw new AuthException("You profile not found");
|
||||||
}
|
}
|
||||||
LaunchServer.server.config.hwidHandler.check(hwid, result.username);
|
LaunchServer.server.config.hwidHandler.check(hwid, result.username);
|
||||||
clientData.isAuth = true;
|
clientData.isAuth = true;
|
||||||
clientData.permissions = result.permissions;
|
clientData.permissions = result.permissions;
|
||||||
service.sendObject(ctx,new WebSocketService.SuccessResult("auth"));
|
service.sendObject(ctx, new WebSocketService.SuccessResult("auth"));
|
||||||
} catch (AuthException | HWIDException e)
|
} catch (AuthException | HWIDException e) {
|
||||||
{
|
service.sendObject(ctx, new WebSocketService.ErrorResult(e.getMessage()));
|
||||||
service.sendObject(ctx,new WebSocketService.ErrorResult(e.getMessage()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public class Result
|
|
||||||
{
|
public class Result {
|
||||||
public Result() {
|
public Result() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
public class CheckServerResponse implements JsonResponseInterface {
|
public class CheckServerResponse implements JsonResponseInterface {
|
||||||
public String serverID;
|
public String serverID;
|
||||||
public String username;
|
public String username;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return "checkServer";
|
return "checkServer";
|
||||||
|
@ -24,17 +25,17 @@ public void execute(WebSocketService service, ChannelHandlerContext ctx, Client
|
||||||
try {
|
try {
|
||||||
uuid = LaunchServer.server.config.authHandler[0].checkServer(username, serverID);
|
uuid = LaunchServer.server.config.authHandler[0].checkServer(username, serverID);
|
||||||
} catch (AuthException e) {
|
} catch (AuthException e) {
|
||||||
service.sendObject(ctx,new WebSocketService.ErrorResult(e.getMessage()));
|
service.sendObject(ctx, new WebSocketService.ErrorResult(e.getMessage()));
|
||||||
return;
|
return;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
service.sendObject(ctx,new WebSocketService.ErrorResult("Internal authHandler error"));
|
service.sendObject(ctx, new WebSocketService.ErrorResult("Internal authHandler error"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
service.sendObject(ctx,new Result());
|
service.sendObject(ctx, new Result());
|
||||||
}
|
}
|
||||||
public class Result
|
|
||||||
{
|
public class Result {
|
||||||
public String type = "success";
|
public String type = "success";
|
||||||
public String requesttype = "checkServer";
|
public String requesttype = "checkServer";
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ public class JoinServerResponse implements JsonResponseInterface {
|
||||||
public String serverID;
|
public String serverID;
|
||||||
public String accessToken;
|
public String accessToken;
|
||||||
public String username;
|
public String username;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return "joinServer";
|
return "joinServer";
|
||||||
|
@ -21,19 +22,19 @@ public String getType() {
|
||||||
public void execute(WebSocketService service, ChannelHandlerContext ctx, Client client) throws Exception {
|
public void execute(WebSocketService service, ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
boolean success;
|
boolean success;
|
||||||
try {
|
try {
|
||||||
success = LaunchServer.server.config.authHandler[0].joinServer(username,accessToken,serverID);
|
success = LaunchServer.server.config.authHandler[0].joinServer(username, accessToken, serverID);
|
||||||
} catch (AuthException e) {
|
} catch (AuthException e) {
|
||||||
service.sendObject(ctx,new WebSocketService.ErrorResult(e.getMessage()));
|
service.sendObject(ctx, new WebSocketService.ErrorResult(e.getMessage()));
|
||||||
return;
|
return;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
service.sendObject(ctx,new WebSocketService.ErrorResult("Internal authHandler error"));
|
service.sendObject(ctx, new WebSocketService.ErrorResult("Internal authHandler error"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
service.sendObject(ctx,new Result(success));
|
service.sendObject(ctx, new Result(success));
|
||||||
}
|
}
|
||||||
public class Result
|
|
||||||
{
|
public class Result {
|
||||||
public String type = "success";
|
public String type = "success";
|
||||||
public String requesttype = "checkServer";
|
public String requesttype = "checkServer";
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ public class LauncherResponse implements JsonResponseInterface {
|
||||||
//REPLACED TO REAL URL
|
//REPLACED TO REAL URL
|
||||||
public static final String JAR_URL = "http://localhost:9752/Launcher.jar";
|
public static final String JAR_URL = "http://localhost:9752/Launcher.jar";
|
||||||
public static final String EXE_URL = "http://localhost:9752/Launcher.exe";
|
public static final String EXE_URL = "http://localhost:9752/Launcher.exe";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return "launcherUpdate";
|
return "launcherUpdate";
|
||||||
|
@ -25,38 +26,34 @@ public String getType() {
|
||||||
@Override
|
@Override
|
||||||
public void execute(WebSocketService service, ChannelHandlerContext ctx, Client client) throws Exception {
|
public void execute(WebSocketService service, ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
byte[] bytes = Base64.getDecoder().decode(hash);
|
byte[] bytes = Base64.getDecoder().decode(hash);
|
||||||
if(launcher_type == 1) // JAR
|
if (launcher_type == 1) // JAR
|
||||||
{
|
{
|
||||||
byte[] hash = LaunchServer.server.launcherBinary.getBytes().getDigest();
|
byte[] hash = LaunchServer.server.launcherBinary.getBytes().getDigest();
|
||||||
if(hash == null) service.sendObjectAndClose(ctx, new Result(true,JAR_URL));
|
if (hash == null) service.sendObjectAndClose(ctx, new Result(true, JAR_URL));
|
||||||
if(Arrays.equals(bytes, hash))
|
if (Arrays.equals(bytes, hash)) {
|
||||||
{
|
service.sendObject(ctx, new Result(false, JAR_URL));
|
||||||
service.sendObject(ctx, new Result(false,JAR_URL));
|
} else {
|
||||||
} else
|
service.sendObjectAndClose(ctx, new Result(true, JAR_URL));
|
||||||
{
|
|
||||||
service.sendObjectAndClose(ctx, new Result(true,JAR_URL));
|
|
||||||
}
|
}
|
||||||
} else if(launcher_type == 2) //EXE
|
} else if (launcher_type == 2) //EXE
|
||||||
{
|
{
|
||||||
byte[] hash = LaunchServer.server.launcherEXEBinary.getBytes().getDigest();
|
byte[] hash = LaunchServer.server.launcherEXEBinary.getBytes().getDigest();
|
||||||
if(hash == null) service.sendObjectAndClose(ctx, new Result(true,EXE_URL));
|
if (hash == null) service.sendObjectAndClose(ctx, new Result(true, EXE_URL));
|
||||||
if(Arrays.equals(bytes, hash))
|
if (Arrays.equals(bytes, hash)) {
|
||||||
{
|
service.sendObject(ctx, new Result(false, EXE_URL));
|
||||||
service.sendObject(ctx, new Result(false,EXE_URL));
|
} else {
|
||||||
} else
|
service.sendObjectAndClose(ctx, new Result(true, EXE_URL));
|
||||||
{
|
|
||||||
service.sendObjectAndClose(ctx, new Result(true,EXE_URL));
|
|
||||||
}
|
}
|
||||||
} else service.sendObject(ctx, new WebSocketService.ErrorResult("Request launcher type error"));
|
} else service.sendObject(ctx, new WebSocketService.ErrorResult("Request launcher type error"));
|
||||||
|
|
||||||
}
|
}
|
||||||
public class Result
|
|
||||||
{
|
public class Result {
|
||||||
public String type = "success";
|
public String type = "success";
|
||||||
public String requesttype = "launcherUpdate";
|
public String requesttype = "launcherUpdate";
|
||||||
public String url;
|
public String url;
|
||||||
|
|
||||||
public Result(boolean needUpdate,String url) {
|
public Result(boolean needUpdate, String url) {
|
||||||
this.needUpdate = needUpdate;
|
this.needUpdate = needUpdate;
|
||||||
this.url = url;
|
this.url = url;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
public class UpdateListResponse implements JsonResponseInterface {
|
public class UpdateListResponse implements JsonResponseInterface {
|
||||||
public String dir;
|
public String dir;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return "updateList";
|
return "updateList";
|
||||||
|
@ -16,15 +17,15 @@ public String getType() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(WebSocketService service, ChannelHandlerContext ctx, Client client) throws Exception {
|
public void execute(WebSocketService service, ChannelHandlerContext ctx, Client client) throws Exception {
|
||||||
if(!client.isAuth) {
|
if (!client.isAuth) {
|
||||||
service.sendObject(ctx,new WebSocketService.ErrorResult("Access denied"));
|
service.sendObject(ctx, new WebSocketService.ErrorResult("Access denied"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
HashedDir hdir = LaunchServer.server.updatesDirMap.get(dir).object;
|
HashedDir hdir = LaunchServer.server.updatesDirMap.get(dir).object;
|
||||||
service.sendObject(ctx,new Result(hdir));
|
service.sendObject(ctx, new Result(hdir));
|
||||||
}
|
}
|
||||||
class Result
|
|
||||||
{
|
class Result {
|
||||||
public final String type;
|
public final String type;
|
||||||
public final String requesttype;
|
public final String requesttype;
|
||||||
public final HashedDir dir;
|
public final HashedDir dir;
|
||||||
|
|
|
@ -15,11 +15,12 @@
|
||||||
public class AvanguardStarter {
|
public class AvanguardStarter {
|
||||||
static class SecurityThread implements Runnable {
|
static class SecurityThread implements Runnable {
|
||||||
static long macID = GuardBind.avnGetMacId();
|
static long macID = GuardBind.avnGetMacId();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while (!Thread.interrupted()) {
|
while (!Thread.interrupted()) {
|
||||||
try {
|
try {
|
||||||
if(macID != GuardBind.avnGetMacId()) {
|
if (macID != GuardBind.avnGetMacId()) {
|
||||||
LogHelper.error("MacID changed");
|
LogHelper.error("MacID changed");
|
||||||
safeHalt(8);
|
safeHalt(8);
|
||||||
}
|
}
|
||||||
|
@ -43,18 +44,16 @@ public void run() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void safeHalt(int exitcode)
|
|
||||||
{
|
static void safeHalt(int exitcode) {
|
||||||
try {
|
try {
|
||||||
SafeExitJVMLegacy.exit(exitcode);
|
SafeExitJVMLegacy.exit(exitcode);
|
||||||
} catch (Throwable ignored)
|
} catch (Throwable ignored) {
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
SafeExitJVM.exit(exitcode);
|
SafeExitJVM.exit(exitcode);
|
||||||
} catch (Throwable ignored)
|
} catch (Throwable ignored) {
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
NativeJVMHalt halt = new NativeJVMHalt(exitcode);
|
NativeJVMHalt halt = new NativeJVMHalt(exitcode);
|
||||||
|
@ -72,8 +71,7 @@ public static void main(boolean init) {
|
||||||
LogHelper.error("Cheating == crash!");
|
LogHelper.error("Cheating == crash!");
|
||||||
try {
|
try {
|
||||||
SafeExitJVM.exit(threatType + 7000);
|
SafeExitJVM.exit(threatType + 7000);
|
||||||
} catch (Throwable e)
|
} catch (Throwable e) {
|
||||||
{
|
|
||||||
SafeExitJVMLegacy.exit(threatType + 7000);
|
SafeExitJVMLegacy.exit(threatType + 7000);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -82,21 +80,21 @@ public static void main(boolean init) {
|
||||||
GuardBind.avnStartDefence();
|
GuardBind.avnStartDefence();
|
||||||
CommonHelper.newThread("Security Thread", true, new SecurityThread()).start();
|
CommonHelper.newThread("Security Thread", true, new SecurityThread()).start();
|
||||||
}
|
}
|
||||||
public static void load()
|
|
||||||
{
|
public static void load() {
|
||||||
GuardBind.startAbs(avanguard.toString());
|
GuardBind.startAbs(avanguard.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void start(Path path1) throws IOException {
|
public static void start(Path path1) throws IOException {
|
||||||
Path path = path1.resolve("guard");
|
Path path = path1.resolve("guard");
|
||||||
if(!IOHelper.exists(path))
|
if (!IOHelper.exists(path))
|
||||||
Files.createDirectories(path);
|
Files.createDirectories(path);
|
||||||
Path avanguard = path.resolve(JVMHelper.JVM_BITS == 64 ? "Avanguard64.dll" : "Avanguard32.dll");
|
Path avanguard = path.resolve(JVMHelper.JVM_BITS == 64 ? "Avanguard64.dll" : "Avanguard32.dll");
|
||||||
Path wrapper = path.resolve(JVMHelper.JVM_BITS == 64 ? NAME + "64.exe" : NAME + "32.exe");
|
Path wrapper = path.resolve(JVMHelper.JVM_BITS == 64 ? NAME + "64.exe" : NAME + "32.exe");
|
||||||
String avanguardResource = JVMHelper.JVM_BITS == 64 ? "Avanguard64.dll" : "Avanguard32.dll";
|
String avanguardResource = JVMHelper.JVM_BITS == 64 ? "Avanguard64.dll" : "Avanguard32.dll";
|
||||||
String wrapperResource = JVMHelper.JVM_BITS == 64 ? "wrapper64.exe" : "wrapper32.exe";
|
String wrapperResource = JVMHelper.JVM_BITS == 64 ? "wrapper64.exe" : "wrapper32.exe";
|
||||||
UnpackHelper.unpack(Launcher.getResourceURL(avanguardResource,"guard"),avanguard);
|
UnpackHelper.unpack(Launcher.getResourceURL(avanguardResource, "guard"), avanguard);
|
||||||
UnpackHelper.unpack(Launcher.getResourceURL(wrapperResource,"guard"),wrapper);
|
UnpackHelper.unpack(Launcher.getResourceURL(wrapperResource, "guard"), wrapper);
|
||||||
AvanguardStarter.wrapper = wrapper;
|
AvanguardStarter.wrapper = wrapper;
|
||||||
AvanguardStarter.avanguard = avanguard;
|
AvanguardStarter.avanguard = avanguard;
|
||||||
HashedDir guard = new HashedDir(path, null, true, false);
|
HashedDir guard = new HashedDir(path, null, true, false);
|
||||||
|
|
|
@ -36,16 +36,14 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep
|
||||||
LogHelper.debug("Commandline: " + args);
|
LogHelper.debug("Commandline: " + args);
|
||||||
processBuilder.command(args);
|
processBuilder.command(args);
|
||||||
Process process = processBuilder.start();
|
Process process = processBuilder.start();
|
||||||
if(!LogHelper.isDebugEnabled()) {
|
if (!LogHelper.isDebugEnabled()) {
|
||||||
Thread.sleep(3000);
|
Thread.sleep(3000);
|
||||||
if (!process.isAlive()) {
|
if (!process.isAlive()) {
|
||||||
LogHelper.error("Process error code: %d", process.exitValue());
|
LogHelper.error("Process error code: %d", process.exitValue());
|
||||||
} else {
|
} else {
|
||||||
LogHelper.debug("Process started success");
|
LogHelper.debug("Process started success");
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
process.waitFor();
|
process.waitFor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,8 +135,8 @@ public static void addLauncherClassBindings(Map<String, Object> bindings) {
|
||||||
bindings.put("DigestAlgorithmClass", SecurityHelper.DigestAlgorithm.class);
|
bindings.put("DigestAlgorithmClass", SecurityHelper.DigestAlgorithm.class);
|
||||||
bindings.put("VerifyHelperClass", VerifyHelper.class);
|
bindings.put("VerifyHelperClass", VerifyHelper.class);
|
||||||
bindings.put("DirBridgeClass", DirBridge.class);
|
bindings.put("DirBridgeClass", DirBridge.class);
|
||||||
bindings.put("FunctionalBridgeClass",FunctionalBridge.class);
|
bindings.put("FunctionalBridgeClass", FunctionalBridge.class);
|
||||||
bindings.put("LauncherSettingsClass",LauncherSettings.class);
|
bindings.put("LauncherSettingsClass", LauncherSettings.class);
|
||||||
|
|
||||||
// Load JS API if available
|
// Load JS API if available
|
||||||
bindings.put("RingProgressIndicatorClass", RingProgressIndicator.class);
|
bindings.put("RingProgressIndicatorClass", RingProgressIndicator.class);
|
||||||
|
@ -217,8 +217,8 @@ public void start(String... args) throws Throwable {
|
||||||
Launcher.modulesManager.postInitModules();
|
Launcher.modulesManager.postInitModules();
|
||||||
invoker.invokeFunction("start", (Object) args);
|
invoker.invokeFunction("start", (Object) args);
|
||||||
}
|
}
|
||||||
public static LauncherEngine clientInstance()
|
|
||||||
{
|
public static LauncherEngine clientInstance() {
|
||||||
return new LauncherEngine();
|
return new LauncherEngine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,9 +88,8 @@ public Params(byte[] launcherDigest, Path assetDir, Path clientDir, PlayerProfil
|
||||||
boolean autoEnter, boolean fullScreen, int ram, int width, int height) {
|
boolean autoEnter, boolean fullScreen, int ram, int width, int height) {
|
||||||
this.launcherDigest = launcherDigest.clone();
|
this.launcherDigest = launcherDigest.clone();
|
||||||
this.updateOptional = new HashSet<>();
|
this.updateOptional = new HashSet<>();
|
||||||
for(ClientProfile.MarkedString s : Launcher.profile.getOptional())
|
for (ClientProfile.MarkedString s : Launcher.profile.getOptional()) {
|
||||||
{
|
if (s.mark) updateOptional.add(s);
|
||||||
if(s.mark) updateOptional.add(s);
|
|
||||||
}
|
}
|
||||||
// Client paths
|
// Client paths
|
||||||
this.assetDir = assetDir;
|
this.assetDir = assetDir;
|
||||||
|
@ -113,14 +112,13 @@ public Params(HInput input) throws Exception {
|
||||||
clientDir = IOHelper.toPath(input.readString(0));
|
clientDir = IOHelper.toPath(input.readString(0));
|
||||||
updateOptional = new HashSet<>();
|
updateOptional = new HashSet<>();
|
||||||
int len = input.readLength(128);
|
int len = input.readLength(128);
|
||||||
for(int i=0;i<len;++i)
|
for (int i = 0; i < len; ++i) {
|
||||||
{
|
updateOptional.add(new ClientProfile.MarkedString(input.readString(512), true));
|
||||||
updateOptional.add(new ClientProfile.MarkedString(input.readString(512),true));
|
|
||||||
}
|
}
|
||||||
// Client params
|
// Client params
|
||||||
pp = new PlayerProfile(input);
|
pp = new PlayerProfile(input);
|
||||||
byte[] encryptedAccessToken = input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH);
|
byte[] encryptedAccessToken = input.readByteArray(SecurityHelper.CRYPTO_MAX_LENGTH);
|
||||||
String accessTokenD = new String(SecurityHelper.decrypt(Launcher.getConfig().secretKeyClient.getBytes(),encryptedAccessToken));
|
String accessTokenD = new String(SecurityHelper.decrypt(Launcher.getConfig().secretKeyClient.getBytes(), encryptedAccessToken));
|
||||||
accessToken = SecurityHelper.verifyToken(accessTokenD);
|
accessToken = SecurityHelper.verifyToken(accessTokenD);
|
||||||
autoEnter = input.readBoolean();
|
autoEnter = input.readBoolean();
|
||||||
fullScreen = input.readBoolean();
|
fullScreen = input.readBoolean();
|
||||||
|
@ -135,15 +133,14 @@ public void write(HOutput output) throws IOException {
|
||||||
// Client paths
|
// Client paths
|
||||||
output.writeString(assetDir.toString(), 0);
|
output.writeString(assetDir.toString(), 0);
|
||||||
output.writeString(clientDir.toString(), 0);
|
output.writeString(clientDir.toString(), 0);
|
||||||
output.writeLength(updateOptional.size(),128);
|
output.writeLength(updateOptional.size(), 128);
|
||||||
for(ClientProfile.MarkedString s : updateOptional)
|
for (ClientProfile.MarkedString s : updateOptional) {
|
||||||
{
|
output.writeString(s.string, 512);
|
||||||
output.writeString(s.string,512);
|
|
||||||
}
|
}
|
||||||
// Client params
|
// Client params
|
||||||
pp.write(output);
|
pp.write(output);
|
||||||
try {
|
try {
|
||||||
output.writeByteArray(SecurityHelper.encrypt(Launcher.getConfig().secretKeyClient.getBytes(),accessToken.getBytes()), SecurityHelper.CRYPTO_MAX_LENGTH);
|
output.writeByteArray(SecurityHelper.encrypt(Launcher.getConfig().secretKeyClient.getBytes(), accessToken.getBytes()), SecurityHelper.CRYPTO_MAX_LENGTH);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
}
|
}
|
||||||
|
@ -227,6 +224,7 @@ private static void addClientArgs(Collection<String> args, ClientProfile profile
|
||||||
Collections.addAll(args, "--height", Integer.toString(params.height));
|
Collections.addAll(args, "--height", Integer.toString(params.height));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public static void setJavaBinPath(Path javaBinPath) {
|
public static void setJavaBinPath(Path javaBinPath) {
|
||||||
JavaBinPath = javaBinPath;
|
JavaBinPath = javaBinPath;
|
||||||
|
@ -289,7 +287,9 @@ private static void launch(ClientProfile profile, Params params) throws Throwabl
|
||||||
System.setProperty("minecraft.applet.TargetDirectory", params.clientDir.toString()); // For 1.5.2
|
System.setProperty("minecraft.applet.TargetDirectory", params.clientDir.toString()); // For 1.5.2
|
||||||
mainMethod.invoke((Object) args.toArray(EMPTY_ARRAY));
|
mainMethod.invoke((Object) args.toArray(EMPTY_ARRAY));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Process process = null;
|
private static Process process = null;
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public static Process launch(
|
public static Process launch(
|
||||||
SignedObjectHolder<HashedDir> assetHDir, SignedObjectHolder<HashedDir> clientHDir,
|
SignedObjectHolder<HashedDir> assetHDir, SignedObjectHolder<HashedDir> clientHDir,
|
||||||
|
@ -301,26 +301,24 @@ public static Process launch(
|
||||||
try {
|
try {
|
||||||
try (ServerSocket socket = new ServerSocket()) {
|
try (ServerSocket socket = new ServerSocket()) {
|
||||||
|
|
||||||
socket.setReuseAddress(true);
|
socket.setReuseAddress(true);
|
||||||
socket.bind(new InetSocketAddress(SOCKET_HOST, SOCKET_PORT));
|
socket.bind(new InetSocketAddress(SOCKET_HOST, SOCKET_PORT));
|
||||||
Socket client = socket.accept();
|
Socket client = socket.accept();
|
||||||
if(process == null)
|
if (process == null) {
|
||||||
{
|
LogHelper.error("Process is null");
|
||||||
LogHelper.error("Process is null");
|
return;
|
||||||
return;
|
}
|
||||||
}
|
if (!process.isAlive()) {
|
||||||
if(!process.isAlive())
|
LogHelper.error("Process is not alive");
|
||||||
{
|
JOptionPane.showMessageDialog(null, "Client Process crashed", "Launcher", JOptionPane.ERROR_MESSAGE);
|
||||||
LogHelper.error("Process is not alive");
|
return;
|
||||||
JOptionPane.showMessageDialog(null,"Client Process crashed","Launcher",JOptionPane.ERROR_MESSAGE);
|
}
|
||||||
return;
|
try (HOutput output = new HOutput(client.getOutputStream())) {
|
||||||
}
|
params.write(output);
|
||||||
try (HOutput output = new HOutput(client.getOutputStream())) {
|
profile.write(output);
|
||||||
params.write(output);
|
assetHDir.write(output);
|
||||||
profile.write(output);
|
clientHDir.write(output);
|
||||||
assetHDir.write(output);
|
}
|
||||||
clientHDir.write(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -337,15 +335,13 @@ public static Process launch(
|
||||||
boolean wrapper = isUsingWrapper();
|
boolean wrapper = isUsingWrapper();
|
||||||
Path javaBin;
|
Path javaBin;
|
||||||
if (wrapper) javaBin = AvanguardStarter.wrapper;
|
if (wrapper) javaBin = AvanguardStarter.wrapper;
|
||||||
else if(isDownloadJava)
|
else if (isDownloadJava) {
|
||||||
{
|
|
||||||
//Linux и Mac не должны скачивать свою JVM
|
//Linux и Mac не должны скачивать свою JVM
|
||||||
if(JVMHelper.OS_TYPE == OS.MUSTDIE)
|
if (JVMHelper.OS_TYPE == OS.MUSTDIE)
|
||||||
javaBin = IOHelper.resolveJavaBin(JavaBinPath);
|
javaBin = IOHelper.resolveJavaBin(JavaBinPath);
|
||||||
else
|
else
|
||||||
javaBin = IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home")));
|
javaBin = IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home")));
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
javaBin = IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home")));
|
javaBin = IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home")));
|
||||||
args.add(javaBin.toString());
|
args.add(javaBin.toString());
|
||||||
args.add(MAGICAL_INTEL_OPTION);
|
args.add(MAGICAL_INTEL_OPTION);
|
||||||
|
@ -463,9 +459,8 @@ public static void main(String... args) throws Throwable {
|
||||||
// Verify current state of all dirs
|
// Verify current state of all dirs
|
||||||
//verifyHDir(IOHelper.JVM_DIR, jvmHDir.object, null, digest);
|
//verifyHDir(IOHelper.JVM_DIR, jvmHDir.object, null, digest);
|
||||||
HashedDir hdir = clientHDir.object;
|
HashedDir hdir = clientHDir.object;
|
||||||
for(ClientProfile.MarkedString s : Launcher.profile.getOptional())
|
for (ClientProfile.MarkedString s : Launcher.profile.getOptional()) {
|
||||||
{
|
if (params.updateOptional.contains(s)) s.mark = true;
|
||||||
if(params.updateOptional.contains(s)) s.mark = true;
|
|
||||||
else hdir.removeR(s.string);
|
else hdir.removeR(s.string);
|
||||||
}
|
}
|
||||||
verifyHDir(params.assetDir, assetHDir.object, assetMatcher, digest);
|
verifyHDir(params.assetDir, assetHDir.object, assetMatcher, digest);
|
||||||
|
@ -477,6 +472,7 @@ public static void main(String... args) throws Throwable {
|
||||||
launch(profile.object, params);
|
launch(profile.object, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public void launchLocal(SignedObjectHolder<HashedDir> assetHDir, SignedObjectHolder<HashedDir> clientHDir,
|
public void launchLocal(SignedObjectHolder<HashedDir> assetHDir, SignedObjectHolder<HashedDir> clientHDir,
|
||||||
SignedObjectHolder<ClientProfile> profile, Params params) throws Throwable {
|
SignedObjectHolder<ClientProfile> profile, Params params) throws Throwable {
|
||||||
|
@ -502,9 +498,8 @@ public void launchLocal(SignedObjectHolder<HashedDir> assetHDir, SignedObjectHol
|
||||||
// Verify current state of all dirs
|
// Verify current state of all dirs
|
||||||
//verifyHDir(IOHelper.JVM_DIR, jvmHDir.object, null, digest);
|
//verifyHDir(IOHelper.JVM_DIR, jvmHDir.object, null, digest);
|
||||||
HashedDir hdir = clientHDir.object;
|
HashedDir hdir = clientHDir.object;
|
||||||
for(ClientProfile.MarkedString s : Launcher.profile.getOptional())
|
for (ClientProfile.MarkedString s : Launcher.profile.getOptional()) {
|
||||||
{
|
if (params.updateOptional.contains(s)) s.mark = true;
|
||||||
if(params.updateOptional.contains(s)) s.mark = true;
|
|
||||||
else hdir.removeR(s.string);
|
else hdir.removeR(s.string);
|
||||||
}
|
}
|
||||||
verifyHDir(params.assetDir, assetHDir.object, assetMatcher, digest);
|
verifyHDir(params.assetDir, assetHDir.object, assetMatcher, digest);
|
||||||
|
|
|
@ -14,18 +14,18 @@
|
||||||
public class FunctionalBridge {
|
public class FunctionalBridge {
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public static LauncherSettings settings;
|
public static LauncherSettings settings;
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public HashedDirRunnable offlineUpdateRequest(String dirName, Path dir, SignedObjectHolder<HashedDir> hdir, FileNameMatcher matcher, boolean digest) throws Exception
|
public HashedDirRunnable offlineUpdateRequest(String dirName, Path dir, SignedObjectHolder<HashedDir> hdir, FileNameMatcher matcher, boolean digest) throws Exception {
|
||||||
{
|
|
||||||
return () -> {
|
return () -> {
|
||||||
if(hdir == null)
|
if (hdir == null) {
|
||||||
{
|
|
||||||
Request.requestError(java.lang.String.format("Директории '%s' нет в кэше", dirName));
|
Request.requestError(java.lang.String.format("Директории '%s' нет в кэше", dirName));
|
||||||
}
|
}
|
||||||
ClientLauncher.verifyHDir(dir, hdir.object, matcher, digest);
|
ClientLauncher.verifyHDir(dir, hdir.object, matcher, digest);
|
||||||
return hdir;
|
return hdir;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public LegacyLauncherRequest.Result offlineLauncherRequest() throws IOException, SignatureException {
|
public LegacyLauncherRequest.Result offlineLauncherRequest() throws IOException, SignatureException {
|
||||||
if (settings.lastDigest == null || settings.lastProfiles.isEmpty()) {
|
if (settings.lastDigest == null || settings.lastProfiles.isEmpty()) {
|
||||||
|
@ -38,8 +38,9 @@ public LegacyLauncherRequest.Result offlineLauncherRequest() throws IOException,
|
||||||
// settings.lastDigest, Launcher.getConfig().publicKey);
|
// settings.lastDigest, Launcher.getConfig().publicKey);
|
||||||
|
|
||||||
// Return last sign and profiles
|
// Return last sign and profiles
|
||||||
return new LegacyLauncherRequest.Result(null,settings.lastDigest,settings.lastProfiles);
|
return new LegacyLauncherRequest.Result(null, settings.lastDigest, settings.lastProfiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface HashedDirRunnable {
|
public interface HashedDirRunnable {
|
||||||
SignedObjectHolder<HashedDir> run() throws Exception;
|
SignedObjectHolder<HashedDir> run() throws Exception;
|
||||||
|
|
|
@ -46,36 +46,36 @@ public class LauncherSettings {
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public List<SignedObjectHolder<ClientProfile>> lastProfiles = new LinkedList<>();
|
public List<SignedObjectHolder<ClientProfile>> lastProfiles = new LinkedList<>();
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public Map<String,SignedObjectHolder<HashedDir>> lastHDirs = new HashMap<>(16);
|
public Map<String, SignedObjectHolder<HashedDir>> lastHDirs = new HashMap<>(16);
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public void load() throws SignatureException {
|
public void load() throws SignatureException {
|
||||||
LogHelper.debug("Loading settings file");
|
LogHelper.debug("Loading settings file");
|
||||||
try {
|
try {
|
||||||
try(HInput input = new HInput(IOHelper.newInput(file)))
|
try (HInput input = new HInput(IOHelper.newInput(file))) {
|
||||||
{
|
|
||||||
read(input);
|
read(input);
|
||||||
}
|
}
|
||||||
} catch(IOException e) {
|
} catch (IOException e) {
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
setDefault();
|
setDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public void save() throws SignatureException {
|
public void save() throws SignatureException {
|
||||||
LogHelper.debug("Save settings file");
|
LogHelper.debug("Save settings file");
|
||||||
try {
|
try {
|
||||||
try(HOutput output = new HOutput(IOHelper.newOutput(file)))
|
try (HOutput output = new HOutput(IOHelper.newOutput(file))) {
|
||||||
{
|
|
||||||
write(output);
|
write(output);
|
||||||
}
|
}
|
||||||
} catch(IOException e) {
|
} catch (IOException e) {
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
setDefault();
|
setDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public void read(HInput input) throws IOException, SignatureException
|
public void read(HInput input) throws IOException, SignatureException {
|
||||||
{
|
|
||||||
int magic = input.readInt();
|
int magic = input.readInt();
|
||||||
if (magic != settingsMagic) {
|
if (magic != settingsMagic) {
|
||||||
setDefault();
|
setDefault();
|
||||||
|
@ -114,9 +114,10 @@ public void read(HInput input) throws IOException, SignatureException
|
||||||
for (int i = 0; i < lastHDirsCount; i++) {
|
for (int i = 0; i < lastHDirsCount; i++) {
|
||||||
String name = IOHelper.verifyFileName(input.readString(255));
|
String name = IOHelper.verifyFileName(input.readString(255));
|
||||||
VerifyHelper.putIfAbsent(lastHDirs, name, new SignedObjectHolder<>(input, publicKey, HashedDir::new),
|
VerifyHelper.putIfAbsent(lastHDirs, name, new SignedObjectHolder<>(input, publicKey, HashedDir::new),
|
||||||
java.lang.String.format("Duplicate offline hashed dir: '%s'", name));
|
java.lang.String.format("Duplicate offline hashed dir: '%s'", name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public void write(HOutput output) throws IOException {
|
public void write(HOutput output) throws IOException {
|
||||||
output.writeInt(settingsMagic);
|
output.writeInt(settingsMagic);
|
||||||
|
@ -156,14 +157,14 @@ public void write(HOutput output) throws IOException {
|
||||||
entry.getValue().write(output);
|
entry.getValue().write(output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public void setRAM(int ram)
|
public void setRAM(int ram) {
|
||||||
{
|
|
||||||
this.ram = java.lang.Math.min(((ram / 256)) * 256, JVMHelper.RAM);
|
this.ram = java.lang.Math.min(((ram / 256)) * 256, JVMHelper.RAM);
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public void setDefault()
|
public void setDefault() {
|
||||||
{
|
|
||||||
// Auth settings
|
// Auth settings
|
||||||
login = null;
|
login = null;
|
||||||
rsaPassword = null;
|
rsaPassword = null;
|
||||||
|
@ -182,6 +183,7 @@ public void setDefault()
|
||||||
lastProfiles.clear();
|
lastProfiles.clear();
|
||||||
lastHDirs.clear();
|
lastHDirs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public byte[] setPassword(String password) throws BadPaddingException, IllegalBlockSizeException {
|
public byte[] setPassword(String password) throws BadPaddingException, IllegalBlockSizeException {
|
||||||
byte[] encrypted = SecurityHelper.newRSAEncryptCipher(Launcher.getConfig().publicKey).doFinal(IOHelper.encode(password));
|
byte[] encrypted = SecurityHelper.newRSAEncryptCipher(Launcher.getConfig().publicKey).doFinal(IOHelper.encode(password));
|
||||||
|
|
|
@ -41,8 +41,9 @@ public AuthRequest(LauncherConfig config, String login, byte[] encryptedPassword
|
||||||
this.encryptedPassword = encryptedPassword.clone();
|
this.encryptedPassword = encryptedPassword.clone();
|
||||||
auth_id = 0;
|
auth_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public AuthRequest(LauncherConfig config, String login, byte[] encryptedPassword,int auth_id) {
|
public AuthRequest(LauncherConfig config, String login, byte[] encryptedPassword, int auth_id) {
|
||||||
super(config);
|
super(config);
|
||||||
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
|
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
|
||||||
this.encryptedPassword = encryptedPassword.clone();
|
this.encryptedPassword = encryptedPassword.clone();
|
||||||
|
@ -53,9 +54,10 @@ public AuthRequest(LauncherConfig config, String login, byte[] encryptedPassword
|
||||||
public AuthRequest(String login, byte[] encryptedPassword) {
|
public AuthRequest(String login, byte[] encryptedPassword) {
|
||||||
this(null, login, encryptedPassword);
|
this(null, login, encryptedPassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public AuthRequest(String login, byte[] encryptedPassword,int auth_id) {
|
public AuthRequest(String login, byte[] encryptedPassword, int auth_id) {
|
||||||
this(null, login, encryptedPassword,auth_id);
|
this(null, login, encryptedPassword, auth_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -67,7 +69,7 @@ public Integer getType() {
|
||||||
protected Result requestDo(HInput input, HOutput output) throws IOException {
|
protected Result requestDo(HInput input, HOutput output) throws IOException {
|
||||||
output.writeString(login, SerializeLimits.MAX_LOGIN);
|
output.writeString(login, SerializeLimits.MAX_LOGIN);
|
||||||
output.writeBoolean(Launcher.profile != null);
|
output.writeBoolean(Launcher.profile != null);
|
||||||
if(Launcher.profile != null)
|
if (Launcher.profile != null)
|
||||||
output.writeString(Launcher.profile.getTitle(), SerializeLimits.MAX_CLIENT);
|
output.writeString(Launcher.profile.getTitle(), SerializeLimits.MAX_CLIENT);
|
||||||
output.writeInt(auth_id);
|
output.writeInt(auth_id);
|
||||||
output.writeLong(Launcher.isUsingAvanguard() ? GuardBind.avnGetHddId() : 0);
|
output.writeLong(Launcher.isUsingAvanguard() ? GuardBind.avnGetHddId() : 0);
|
||||||
|
|
|
@ -40,6 +40,7 @@ public AuthServerRequest(LauncherConfig config, String login, byte[] encryptedPa
|
||||||
auth_id = 0;
|
auth_id = 0;
|
||||||
title = "";
|
title = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public AuthServerRequest(LauncherConfig config, String login, byte[] encryptedPassword, int auth_id) {
|
public AuthServerRequest(LauncherConfig config, String login, byte[] encryptedPassword, int auth_id) {
|
||||||
super(config);
|
super(config);
|
||||||
|
@ -48,8 +49,9 @@ public AuthServerRequest(LauncherConfig config, String login, byte[] encryptedPa
|
||||||
this.auth_id = auth_id;
|
this.auth_id = auth_id;
|
||||||
title = "";
|
title = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public AuthServerRequest(LauncherConfig config, String login, byte[] encryptedPassword, int auth_id,String title) {
|
public AuthServerRequest(LauncherConfig config, String login, byte[] encryptedPassword, int auth_id, String title) {
|
||||||
super(config);
|
super(config);
|
||||||
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
|
this.login = VerifyHelper.verify(login, VerifyHelper.NOT_EMPTY, "Login can't be empty");
|
||||||
this.encryptedPassword = encryptedPassword.clone();
|
this.encryptedPassword = encryptedPassword.clone();
|
||||||
|
@ -61,9 +63,10 @@ public AuthServerRequest(LauncherConfig config, String login, byte[] encryptedPa
|
||||||
public AuthServerRequest(String login, byte[] encryptedPassword) {
|
public AuthServerRequest(String login, byte[] encryptedPassword) {
|
||||||
this(null, login, encryptedPassword);
|
this(null, login, encryptedPassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public AuthServerRequest(String login, byte[] encryptedPassword, int auth_id) {
|
public AuthServerRequest(String login, byte[] encryptedPassword, int auth_id) {
|
||||||
this(null, login, encryptedPassword,auth_id);
|
this(null, login, encryptedPassword, auth_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -13,28 +13,27 @@ public class ChangeServerRequest extends Request<ChangeServerRequest.Result> {
|
||||||
public Integer getType() {
|
public Integer getType() {
|
||||||
return RequestType.CHANGESERVER.getNumber();
|
return RequestType.CHANGESERVER.getNumber();
|
||||||
}
|
}
|
||||||
public boolean change(Result result)
|
|
||||||
{
|
public boolean change(Result result) {
|
||||||
if(!result.needChange) return false;
|
if (!result.needChange) return false;
|
||||||
Launcher.getConfig().address = InetSocketAddress.createUnresolved( result.address, result.port);
|
Launcher.getConfig().address = InetSocketAddress.createUnresolved(result.address, result.port);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Result requestDo(HInput input, HOutput output) throws Exception {
|
protected Result requestDo(HInput input, HOutput output) throws Exception {
|
||||||
readError(input);
|
readError(input);
|
||||||
Result result = new Result();
|
Result result = new Result();
|
||||||
result.needChange = input.readBoolean();
|
result.needChange = input.readBoolean();
|
||||||
if(result.needChange)
|
if (result.needChange) {
|
||||||
{
|
|
||||||
result.address = input.readString(255);
|
result.address = input.readString(255);
|
||||||
result.port = input.readInt();
|
result.port = input.readInt();
|
||||||
}
|
}
|
||||||
if(result.needChange) change(result);
|
if (result.needChange) change(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Result
|
public class Result {
|
||||||
{
|
|
||||||
public boolean needChange;
|
public boolean needChange;
|
||||||
public String address;
|
public String address;
|
||||||
public int port;
|
public int port;
|
||||||
|
|
|
@ -39,11 +39,10 @@ public Integer getType() {
|
||||||
protected PlayerProfile requestDo(HInput input, HOutput output) throws IOException {
|
protected PlayerProfile requestDo(HInput input, HOutput output) throws IOException {
|
||||||
output.writeString(username, SerializeLimits.MAX_LOGIN);
|
output.writeString(username, SerializeLimits.MAX_LOGIN);
|
||||||
output.writeASCII(serverID, SerializeLimits.MAX_SERVERID); // 1 char for minus sign
|
output.writeASCII(serverID, SerializeLimits.MAX_SERVERID); // 1 char for minus sign
|
||||||
if(Launcher.profile == null) {
|
if (Launcher.profile == null) {
|
||||||
LogHelper.error("Profile is null. Title is not net.");
|
LogHelper.error("Profile is null. Title is not net.");
|
||||||
output.writeString("", SerializeLimits.MAX_CLIENT);
|
output.writeString("", SerializeLimits.MAX_CLIENT);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
output.writeString(Launcher.profile.getTitle(), SerializeLimits.MAX_CLIENT);
|
output.writeString(Launcher.profile.getTitle(), SerializeLimits.MAX_CLIENT);
|
||||||
output.flush();
|
output.flush();
|
||||||
|
|
||||||
|
|
|
@ -86,9 +86,9 @@ public Integer getType() {
|
||||||
@SuppressWarnings("CallToSystemExit")
|
@SuppressWarnings("CallToSystemExit")
|
||||||
protected Result requestDo(HInput input, HOutput output) throws Exception {
|
protected Result requestDo(HInput input, HOutput output) throws Exception {
|
||||||
Path launcherPath = IOHelper.getCodeSource(LauncherRequest.class);
|
Path launcherPath = IOHelper.getCodeSource(LauncherRequest.class);
|
||||||
byte[] digest = SecurityHelper.digest(SecurityHelper.DigestAlgorithm.SHA512,launcherPath);
|
byte[] digest = SecurityHelper.digest(SecurityHelper.DigestAlgorithm.SHA512, launcherPath);
|
||||||
output.writeBoolean(EXE_BINARY);
|
output.writeBoolean(EXE_BINARY);
|
||||||
output.writeByteArray(digest,0);
|
output.writeByteArray(digest, 0);
|
||||||
output.flush();
|
output.flush();
|
||||||
readError(input);
|
readError(input);
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ protected Result requestDo(HInput input, HOutput output) throws Exception {
|
||||||
if (shouldUpdate) {
|
if (shouldUpdate) {
|
||||||
byte[] binary = input.readByteArray(0);
|
byte[] binary = input.readByteArray(0);
|
||||||
Result result = new Result(binary, digest);
|
Result result = new Result(binary, digest);
|
||||||
update(Launcher.getConfig(),result);
|
update(Launcher.getConfig(), result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return request result
|
// Return request result
|
||||||
|
|
|
@ -307,7 +307,7 @@ protected SignedObjectHolder<HashedDir> requestDo(HInput input, HOutput output)
|
||||||
// Get diff between local and remote dir
|
// Get diff between local and remote dir
|
||||||
SignedObjectHolder<HashedDir> remoteHDirHolder = new SignedObjectHolder<>(input, config.publicKey, HashedDir::new);
|
SignedObjectHolder<HashedDir> remoteHDirHolder = new SignedObjectHolder<>(input, config.publicKey, HashedDir::new);
|
||||||
HashedDir hackHackedDir = remoteHDirHolder.object;
|
HashedDir hackHackedDir = remoteHDirHolder.object;
|
||||||
Launcher.profile.pushOptional(hackHackedDir,!Launcher.profile.isUpdateFastCheck());
|
Launcher.profile.pushOptional(hackHackedDir, !Launcher.profile.isUpdateFastCheck());
|
||||||
HashedDir.Diff diff = hackHackedDir.diff(localDir, matcher);
|
HashedDir.Diff diff = hackHackedDir.diff(localDir, matcher);
|
||||||
totalSize = diff.mismatch.size();
|
totalSize = diff.mismatch.size();
|
||||||
boolean compress = input.readBoolean();
|
boolean compress = input.readBoolean();
|
||||||
|
|
|
@ -29,34 +29,34 @@
|
||||||
*/
|
*/
|
||||||
@ClientEndpoint
|
@ClientEndpoint
|
||||||
public class ClientJSONPoint {
|
public class ClientJSONPoint {
|
||||||
public Session session = null;
|
public Session session = null;
|
||||||
private ClientWebSocketService service;
|
private ClientWebSocketService service;
|
||||||
|
|
||||||
public void setService(ClientWebSocketService service) {
|
public void setService(ClientWebSocketService service) {
|
||||||
this.service = service;
|
this.service = service;
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnOpen
|
@OnOpen
|
||||||
public void onOpen(final Session session_r) {
|
public void onOpen(final Session session_r) {
|
||||||
session = session_r;
|
session = session_r;
|
||||||
System.out.println("Connected to endpoint: " + session.getBasicRemote());
|
System.out.println("Connected to endpoint: " + session.getBasicRemote());
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnError
|
@OnError
|
||||||
public void processError(final Throwable t) {
|
public void processError(final Throwable t) {
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnMessage
|
@OnMessage
|
||||||
public void processMessage(Reader message) {
|
public void processMessage(Reader message) {
|
||||||
service.processMessage(message);
|
service.processMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void send(String js) throws IOException {
|
public void send(String js) throws IOException {
|
||||||
session.getBasicRemote().sendText(js);
|
session.getBasicRemote().sendText(js);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendAsync(String js) throws IOException {
|
public void sendAsync(String js) throws IOException {
|
||||||
session.getAsyncRemote().sendText(js);
|
session.getAsyncRemote().sendText(js);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,47 +13,49 @@ public class ClientWebSocketService {
|
||||||
public final GsonBuilder gsonBuilder;
|
public final GsonBuilder gsonBuilder;
|
||||||
public final Gson gson;
|
public final Gson gson;
|
||||||
public final ClientJSONPoint point;
|
public final ClientJSONPoint point;
|
||||||
private HashMap<String,Class> requests;
|
private HashMap<String, Class> requests;
|
||||||
private HashMap<String,Class> results;
|
private HashMap<String, Class> results;
|
||||||
|
|
||||||
public ClientWebSocketService(GsonBuilder gsonBuilder,ClientJSONPoint point) {
|
public ClientWebSocketService(GsonBuilder gsonBuilder, ClientJSONPoint point) {
|
||||||
requests = new HashMap<>();
|
requests = new HashMap<>();
|
||||||
results = new HashMap<>();
|
results = new HashMap<>();
|
||||||
this.gsonBuilder = gsonBuilder;
|
this.gsonBuilder = gsonBuilder;
|
||||||
gsonBuilder.registerTypeAdapter(RequestInterface.class, new JsonRequestAdapter(this));
|
gsonBuilder.registerTypeAdapter(RequestInterface.class, new JsonRequestAdapter(this));
|
||||||
gsonBuilder.registerTypeAdapter(HashedEntry.class,new HashedEntryAdapter());
|
gsonBuilder.registerTypeAdapter(HashedEntry.class, new HashedEntryAdapter());
|
||||||
this.gson = gsonBuilder.create();
|
this.gson = gsonBuilder.create();
|
||||||
this.point = point;
|
this.point = point;
|
||||||
point.setService(this);
|
point.setService(this);
|
||||||
}
|
}
|
||||||
public void processMessage(Reader reader)
|
|
||||||
{
|
public void processMessage(Reader reader) {
|
||||||
ResultInterface result = gson.fromJson(reader,ResultInterface.class);
|
ResultInterface result = gson.fromJson(reader, ResultInterface.class);
|
||||||
result.process();
|
result.process();
|
||||||
}
|
}
|
||||||
public Class getRequestClass(String key)
|
|
||||||
{
|
public Class getRequestClass(String key) {
|
||||||
return requests.get(key);
|
return requests.get(key);
|
||||||
}
|
}
|
||||||
public void registerRequest(String key, Class clazz)
|
|
||||||
{
|
public void registerRequest(String key, Class clazz) {
|
||||||
requests.put(key,clazz);
|
requests.put(key, clazz);
|
||||||
}
|
}
|
||||||
public void registerRequests()
|
|
||||||
{
|
public void registerRequests() {
|
||||||
|
|
||||||
}
|
}
|
||||||
public void registerResult(String key, Class clazz)
|
|
||||||
{
|
public void registerResult(String key, Class clazz) {
|
||||||
results.put(key,clazz);
|
results.put(key, clazz);
|
||||||
}
|
}
|
||||||
public void registerResults()
|
|
||||||
{
|
public void registerResults() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendObjectAsync(Object obj) throws IOException {
|
public void sendObjectAsync(Object obj) throws IOException {
|
||||||
point.sendAsync(gson.toJson(obj));
|
point.sendAsync(gson.toJson(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendObject(Object obj) throws IOException {
|
public void sendObject(Object obj) throws IOException {
|
||||||
point.send(gson.toJson(obj));
|
point.send(gson.toJson(obj));
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,9 @@
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
|
|
||||||
public class ServerAgent {
|
public class ServerAgent {
|
||||||
private static boolean isAgentStarted=false;
|
private static boolean isAgentStarted = false;
|
||||||
public static Instrumentation inst;
|
public static Instrumentation inst;
|
||||||
|
|
||||||
public static final class StarterVisitor extends SimpleFileVisitor<Path> {
|
public static final class StarterVisitor extends SimpleFileVisitor<Path> {
|
||||||
private Instrumentation inst;
|
private Instrumentation inst;
|
||||||
|
|
||||||
|
@ -25,18 +26,21 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
|
||||||
return super.visitFile(file, attrs);
|
return super.visitFile(file, attrs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addJVMClassPath(String path) throws IOException {
|
public static void addJVMClassPath(String path) throws IOException {
|
||||||
LogHelper.debug("Load %s",path);
|
LogHelper.debug("Load %s", path);
|
||||||
inst.appendToSystemClassLoaderSearch(new JarFile(path));
|
inst.appendToSystemClassLoaderSearch(new JarFile(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addJVMClassPath(JarFile file) throws IOException {
|
public static void addJVMClassPath(JarFile file) throws IOException {
|
||||||
LogHelper.debug("Load %s",file.getName());
|
LogHelper.debug("Load %s", file.getName());
|
||||||
inst.appendToSystemClassLoaderSearch(file);
|
inst.appendToSystemClassLoaderSearch(file);
|
||||||
}
|
}
|
||||||
public boolean isAgentStarted()
|
|
||||||
{
|
public boolean isAgentStarted() {
|
||||||
return isAgentStarted;
|
return isAgentStarted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long getObjSize(Object obj) {
|
public static long getObjSize(Object obj) {
|
||||||
return inst.getObjectSize(obj);
|
return inst.getObjectSize(obj);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,10 +33,11 @@ public class ServerWrapper {
|
||||||
public static ModulesManager modulesManager;
|
public static ModulesManager modulesManager;
|
||||||
public static Path configFile;
|
public static Path configFile;
|
||||||
public static Config config;
|
public static Config config;
|
||||||
|
|
||||||
public static boolean auth(ServerWrapper wrapper) {
|
public static boolean auth(ServerWrapper wrapper) {
|
||||||
try {
|
try {
|
||||||
LauncherConfig cfg = Launcher.getConfig();
|
LauncherConfig cfg = Launcher.getConfig();
|
||||||
Boolean auth = new AuthServerRequest(cfg,config.login,SecurityHelper.newRSAEncryptCipher(cfg.publicKey).doFinal(IOHelper.encode(config.password)),0,config.title).request();
|
Boolean auth = new AuthServerRequest(cfg, config.login, SecurityHelper.newRSAEncryptCipher(cfg.publicKey).doFinal(IOHelper.encode(config.password)), 0, config.title).request();
|
||||||
ProfilesRequest.Result result = new ProfilesRequest(cfg).request();
|
ProfilesRequest.Result result = new ProfilesRequest(cfg).request();
|
||||||
for (SignedObjectHolder<ClientProfile> p : result.profiles) {
|
for (SignedObjectHolder<ClientProfile> p : result.profiles) {
|
||||||
LogHelper.debug("Get profile: %s", p.object.getTitle());
|
LogHelper.debug("Get profile: %s", p.object.getTitle());
|
||||||
|
@ -48,21 +49,21 @@ public static boolean auth(ServerWrapper wrapper) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} catch (Throwable e)
|
} catch (Throwable e) {
|
||||||
{
|
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
public static boolean loopAuth(ServerWrapper wrapper,int count,int sleeptime) {
|
|
||||||
if(count == 0) {
|
public static boolean loopAuth(ServerWrapper wrapper, int count, int sleeptime) {
|
||||||
while(true) {
|
if (count == 0) {
|
||||||
if(auth(wrapper)) return true;
|
while (true) {
|
||||||
|
if (auth(wrapper)) return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(int i=0;i<count;++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
if(auth(wrapper)) return true;
|
if (auth(wrapper)) return true;
|
||||||
try {
|
try {
|
||||||
Thread.sleep(sleeptime);
|
Thread.sleep(sleeptime);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
@ -71,6 +72,7 @@ public static boolean loopAuth(ServerWrapper wrapper,int count,int sleeptime) {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Throwable {
|
public static void main(String[] args) throws Throwable {
|
||||||
ServerWrapper wrapper = new ServerWrapper();
|
ServerWrapper wrapper = new ServerWrapper();
|
||||||
modulesManager = new ModulesManager(wrapper);
|
modulesManager = new ModulesManager(wrapper);
|
||||||
|
@ -82,21 +84,21 @@ public static void main(String[] args) throws Throwable {
|
||||||
try (BufferedReader reader = IOHelper.newReader(configFile)) {
|
try (BufferedReader reader = IOHelper.newReader(configFile)) {
|
||||||
config = new Config(TextConfigReader.read(reader, true));
|
config = new Config(TextConfigReader.read(reader, true));
|
||||||
}
|
}
|
||||||
LauncherConfig cfg = new LauncherConfig(config.address, config.port, SecurityHelper.toPublicRSAKey(IOHelper.read(Paths.get("public.key"))),new HashMap<>(),config.projectname);
|
LauncherConfig cfg = new LauncherConfig(config.address, config.port, SecurityHelper.toPublicRSAKey(IOHelper.read(Paths.get("public.key"))), new HashMap<>(), config.projectname);
|
||||||
Launcher.setConfig(cfg);
|
Launcher.setConfig(cfg);
|
||||||
if(config.syncAuth) auth(wrapper);
|
if (config.syncAuth) auth(wrapper);
|
||||||
else CommonHelper.newThread("Server Auth Thread",true,() -> ServerWrapper.loopAuth(wrapper,config.reconnectCount,config.reconnectSleep));
|
else
|
||||||
|
CommonHelper.newThread("Server Auth Thread", true, () -> ServerWrapper.loopAuth(wrapper, config.reconnectCount, config.reconnectSleep));
|
||||||
modulesManager.initModules();
|
modulesManager.initModules();
|
||||||
String classname = config.mainclass.isEmpty() ? args[0] : config.mainclass;
|
String classname = config.mainclass.isEmpty() ? args[0] : config.mainclass;
|
||||||
Class<?> mainClass;
|
Class<?> mainClass;
|
||||||
if(config.customClassLoader) {
|
if (config.customClassLoader) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Class<ClassLoader> classloader_class = (Class<ClassLoader>) Class.forName(config.classloader);
|
Class<ClassLoader> classloader_class = (Class<ClassLoader>) Class.forName(config.classloader);
|
||||||
ClassLoader loader = classloader_class.getConstructor(ClassLoader.class).newInstance(ClassLoader.getSystemClassLoader());
|
ClassLoader loader = classloader_class.getConstructor(ClassLoader.class).newInstance(ClassLoader.getSystemClassLoader());
|
||||||
Thread.currentThread().setContextClassLoader(loader);
|
Thread.currentThread().setContextClassLoader(loader);
|
||||||
mainClass = Class.forName(classname,false,loader);
|
mainClass = Class.forName(classname, false, loader);
|
||||||
}
|
} else mainClass = Class.forName(classname);
|
||||||
else mainClass = Class.forName(classname);
|
|
||||||
MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class));
|
MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class));
|
||||||
String[] real_args = new String[args.length - 1];
|
String[] real_args = new String[args.length - 1];
|
||||||
System.arraycopy(args, 1, real_args, 0, args.length - 1);
|
System.arraycopy(args, 1, real_args, 0, args.length - 1);
|
||||||
|
@ -104,6 +106,7 @@ public static void main(String[] args) throws Throwable {
|
||||||
LogHelper.debug("Invoke main method");
|
LogHelper.debug("Invoke main method");
|
||||||
mainMethod.invoke(real_args);
|
mainMethod.invoke(real_args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void generateConfigIfNotExists() throws IOException {
|
private static void generateConfigIfNotExists() throws IOException {
|
||||||
if (IOHelper.isFile(configFile))
|
if (IOHelper.isFile(configFile))
|
||||||
return;
|
return;
|
||||||
|
@ -123,6 +126,7 @@ private static void generateConfigIfNotExists() throws IOException {
|
||||||
TextConfigWriter.write(newConfig.block, writer, true);
|
TextConfigWriter.write(newConfig.block, writer, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class Config extends ConfigObject {
|
public static final class Config extends ConfigObject {
|
||||||
public String title;
|
public String title;
|
||||||
public String projectname;
|
public String projectname;
|
||||||
|
@ -136,22 +140,24 @@ public static final class Config extends ConfigObject {
|
||||||
public String mainclass;
|
public String mainclass;
|
||||||
public String login;
|
public String login;
|
||||||
public String password;
|
public String password;
|
||||||
|
|
||||||
protected Config(BlockConfigEntry block) {
|
protected Config(BlockConfigEntry block) {
|
||||||
super(block);
|
super(block);
|
||||||
title = block.getEntryValue("title",StringConfigEntry.class);
|
title = block.getEntryValue("title", StringConfigEntry.class);
|
||||||
address = block.getEntryValue("address",StringConfigEntry.class);
|
address = block.getEntryValue("address", StringConfigEntry.class);
|
||||||
projectname = block.getEntryValue("projectName",StringConfigEntry.class);
|
projectname = block.getEntryValue("projectName", StringConfigEntry.class);
|
||||||
login = block.getEntryValue("login",StringConfigEntry.class);
|
login = block.getEntryValue("login", StringConfigEntry.class);
|
||||||
password = block.getEntryValue("password",StringConfigEntry.class);
|
password = block.getEntryValue("password", StringConfigEntry.class);
|
||||||
port = block.getEntryValue("port", IntegerConfigEntry.class);
|
port = block.getEntryValue("port", IntegerConfigEntry.class);
|
||||||
customClassLoader = block.getEntryValue("customClassLoader", BooleanConfigEntry.class);
|
customClassLoader = block.getEntryValue("customClassLoader", BooleanConfigEntry.class);
|
||||||
if(customClassLoader)
|
if (customClassLoader)
|
||||||
classloader = block.getEntryValue("classloader",StringConfigEntry.class);
|
classloader = block.getEntryValue("classloader", StringConfigEntry.class);
|
||||||
mainclass = block.getEntryValue("MainClass",StringConfigEntry.class);
|
mainclass = block.getEntryValue("MainClass", StringConfigEntry.class);
|
||||||
reconnectCount = block.hasEntry("reconnectCount") ? block.getEntryValue("reconnectCount",IntegerConfigEntry.class) : 1;
|
reconnectCount = block.hasEntry("reconnectCount") ? block.getEntryValue("reconnectCount", IntegerConfigEntry.class) : 1;
|
||||||
reconnectSleep = block.hasEntry("reconnectSleep") ? block.getEntryValue("reconnectSleep",IntegerConfigEntry.class) : 30000;
|
reconnectSleep = block.hasEntry("reconnectSleep") ? block.getEntryValue("reconnectSleep", IntegerConfigEntry.class) : 30000;
|
||||||
syncAuth = block.hasEntry("syncAuth") ? block.getEntryValue("syncAuth",BooleanConfigEntry.class) : true;
|
syncAuth = block.hasEntry("syncAuth") ? block.getEntryValue("syncAuth", BooleanConfigEntry.class) : true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClientProfile profile;
|
public ClientProfile profile;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,10 @@
|
||||||
// FMLSecurityManager запрещает делать System.exit из классов
|
// FMLSecurityManager запрещает делать System.exit из классов
|
||||||
// Не входящих в пакеты самого Forge
|
// Не входящих в пакеты самого Forge
|
||||||
public class SafeExitJVMLegacy {
|
public class SafeExitJVMLegacy {
|
||||||
public static void exit(int code)
|
public static void exit(int code) {
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
JVMHelper.RUNTIME.halt(code);
|
JVMHelper.RUNTIME.halt(code);
|
||||||
} catch (Throwable e)
|
} catch (Throwable e) {
|
||||||
{
|
|
||||||
System.exit(code);
|
System.exit(code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,10 @@
|
||||||
// FMLSecurityManager запрещает делать System.exit из классов
|
// FMLSecurityManager запрещает делать System.exit из классов
|
||||||
// Не входящих в пакеты самого Forge
|
// Не входящих в пакеты самого Forge
|
||||||
public class SafeExitJVM {
|
public class SafeExitJVM {
|
||||||
public static void exit(int code)
|
public static void exit(int code) {
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
JVMHelper.RUNTIME.halt(code);
|
JVMHelper.RUNTIME.halt(code);
|
||||||
} catch (Throwable e)
|
} catch (Throwable e) {
|
||||||
{
|
|
||||||
System.exit(code);
|
System.exit(code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,9 +83,9 @@ public static LauncherConfig getConfig() {
|
||||||
}
|
}
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public static void setConfig(LauncherConfig cfg)
|
public static void setConfig(LauncherConfig cfg) {
|
||||||
{
|
|
||||||
CONFIG.set(cfg);
|
CONFIG.set(cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ public static URL getResourceURL(String name) throws IOException {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static URL getResourceURL(String name,String prefix) throws IOException {
|
public static URL getResourceURL(String name, String prefix) throws IOException {
|
||||||
LauncherConfig config = getConfig();
|
LauncherConfig config = getConfig();
|
||||||
byte[] validDigest = config.runtime.get(name);
|
byte[] validDigest = config.runtime.get(name);
|
||||||
if (validDigest == null)
|
if (validDigest == null)
|
||||||
|
|
|
@ -50,8 +50,8 @@ public static void premain(String agentArgument, Instrumentation instrumentation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static boolean isStarted()
|
|
||||||
{
|
public static boolean isStarted() {
|
||||||
return isAgentStarted;
|
return isAgentStarted;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,9 @@
|
||||||
//Набор стандартных событий
|
//Набор стандартных событий
|
||||||
public class ControlEvent implements EventInterface {
|
public class ControlEvent implements EventInterface {
|
||||||
private static final UUID uuid = UUID.fromString("f1051a64-0cd0-4ed8-8430-d856a196e91f");
|
private static final UUID uuid = UUID.fromString("f1051a64-0cd0-4ed8-8430-d856a196e91f");
|
||||||
|
|
||||||
public enum ControlCommand {
|
public enum ControlCommand {
|
||||||
STOP,START,PAUSE,CONTINUE,CRASH
|
STOP, START, PAUSE, CONTINUE, CRASH
|
||||||
}
|
}
|
||||||
|
|
||||||
public ControlEvent(ControlCommand signal) {
|
public ControlEvent(ControlCommand signal) {
|
||||||
|
@ -16,6 +17,7 @@ public ControlEvent(ControlCommand signal) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ControlCommand signal;
|
public ControlCommand signal;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UUID getUUID() {
|
public UUID getUUID() {
|
||||||
return uuid;
|
return uuid;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
//Все обработчики обязаны его игнорировать
|
//Все обработчики обязаны его игнорировать
|
||||||
public final class PingEvent implements EventInterface {
|
public final class PingEvent implements EventInterface {
|
||||||
private static final UUID uuid = UUID.fromString("7c8be7e7-82ce-4c99-84cd-ee8fcce1b509");
|
private static final UUID uuid = UUID.fromString("7c8be7e7-82ce-4c99-84cd-ee8fcce1b509");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UUID getUUID() {
|
public UUID getUUID() {
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,16 @@
|
||||||
import ru.gravit.utils.event.EventInterface;
|
import ru.gravit.utils.event.EventInterface;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
//Используется, что бы послать короткое сообщение, которое вмещается в int
|
//Используется, что бы послать короткое сообщение, которое вмещается в int
|
||||||
public class SignalEvent implements EventInterface {
|
public class SignalEvent implements EventInterface {
|
||||||
private static final UUID uuid = UUID.fromString("edc3afa1-2726-4da3-95c6-7e6994b981e1");
|
private static final UUID uuid = UUID.fromString("edc3afa1-2726-4da3-95c6-7e6994b981e1");
|
||||||
public int signal;
|
public int signal;
|
||||||
|
|
||||||
public SignalEvent(int signal) {
|
public SignalEvent(int signal) {
|
||||||
this.signal = signal;
|
this.signal = signal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UUID getUUID() {
|
public UUID getUUID() {
|
||||||
return uuid;
|
return uuid;
|
||||||
|
|
|
@ -71,14 +71,12 @@ private static void handleError(Throwable e) {
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
try {
|
try {
|
||||||
SafeExitJVMLegacy.exit(-123);
|
SafeExitJVMLegacy.exit(-123);
|
||||||
} catch (Throwable ignored)
|
} catch (Throwable ignored) {
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
SafeExitJVM.exit(-123);
|
SafeExitJVM.exit(-123);
|
||||||
} catch (Throwable ignored)
|
} catch (Throwable ignored) {
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
NativeJVMHalt halt = new NativeJVMHalt(-123);
|
NativeJVMHalt halt = new NativeJVMHalt(-123);
|
||||||
|
|
|
@ -143,45 +143,43 @@ public Diff diff(HashedDir other, FileNameMatcher matcher) {
|
||||||
HashedDir extra = other.sideDiff(this, matcher, new LinkedList<>(), false);
|
HashedDir extra = other.sideDiff(this, matcher, new LinkedList<>(), false);
|
||||||
return new Diff(mismatch, extra);
|
return new Diff(mismatch, extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public Diff compare(HashedDir other, FileNameMatcher matcher) {
|
public Diff compare(HashedDir other, FileNameMatcher matcher) {
|
||||||
HashedDir mismatch = sideDiff(other, matcher, new LinkedList<>(), true);
|
HashedDir mismatch = sideDiff(other, matcher, new LinkedList<>(), true);
|
||||||
HashedDir extra = other.sideDiff(this, matcher, new LinkedList<>(), false);
|
HashedDir extra = other.sideDiff(this, matcher, new LinkedList<>(), false);
|
||||||
return new Diff(mismatch, extra);
|
return new Diff(mismatch, extra);
|
||||||
}
|
}
|
||||||
public void remove(String name)
|
|
||||||
{
|
public void remove(String name) {
|
||||||
map.remove(name);
|
map.remove(name);
|
||||||
}
|
}
|
||||||
public void removeR(String name)
|
|
||||||
{
|
public void removeR(String name) {
|
||||||
LinkedList<String> dirs = new LinkedList<>();
|
LinkedList<String> dirs = new LinkedList<>();
|
||||||
StringTokenizer t = new StringTokenizer(name,"/");
|
StringTokenizer t = new StringTokenizer(name, "/");
|
||||||
while(t.hasMoreTokens())
|
while (t.hasMoreTokens()) {
|
||||||
{
|
|
||||||
dirs.add(t.nextToken());
|
dirs.add(t.nextToken());
|
||||||
}
|
}
|
||||||
Map<String,HashedEntry> current = map;
|
Map<String, HashedEntry> current = map;
|
||||||
for(String s : dirs)
|
for (String s : dirs) {
|
||||||
{
|
|
||||||
HashedEntry e = current.get(s);
|
HashedEntry e = current.get(s);
|
||||||
if(e == null)
|
if (e == null) {
|
||||||
{
|
LogHelper.debug("Null %s", s);
|
||||||
LogHelper.debug("Null %s",s);
|
for (String x : current.keySet()) LogHelper.debug("Contains %s", x);
|
||||||
for(String x : current.keySet()) LogHelper.debug("Contains %s",x);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(e.getType() == Type.DIR)
|
if (e.getType() == Type.DIR) {
|
||||||
{
|
|
||||||
current = ((HashedDir) e).map;
|
current = ((HashedDir) e).map;
|
||||||
LogHelper.debug("Found dir %s",s);
|
LogHelper.debug("Found dir %s", s);
|
||||||
} else {
|
} else {
|
||||||
current.remove(s);
|
current.remove(s);
|
||||||
LogHelper.debug("Found filename %s",s);
|
LogHelper.debug("Found filename %s", s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public HashedEntry getEntry(String name) {
|
public HashedEntry getEntry(String name) {
|
||||||
return map.get(name);
|
return map.get(name);
|
||||||
|
|
|
@ -16,8 +16,8 @@ public HashedEntryAdapter() {
|
||||||
public HashedEntry deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
public HashedEntry deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||||
String typename = json.getAsJsonObject().getAsJsonPrimitive(PROP_NAME).getAsString();
|
String typename = json.getAsJsonObject().getAsJsonPrimitive(PROP_NAME).getAsString();
|
||||||
Class cls = null;
|
Class cls = null;
|
||||||
if(typename.equals("dir")) cls = HashedDir.class;
|
if (typename.equals("dir")) cls = HashedDir.class;
|
||||||
if(typename.equals("file")) cls = HashedFile.class;
|
if (typename.equals("file")) cls = HashedFile.class;
|
||||||
|
|
||||||
|
|
||||||
return (HashedEntry) context.deserialize(json, cls);
|
return (HashedEntry) context.deserialize(json, cls);
|
||||||
|
@ -29,9 +29,9 @@ public JsonElement serialize(HashedEntry src, Type typeOfSrc, JsonSerializationC
|
||||||
JsonObject jo = context.serialize(src).getAsJsonObject();
|
JsonObject jo = context.serialize(src).getAsJsonObject();
|
||||||
|
|
||||||
HashedEntry.Type type = src.getType();
|
HashedEntry.Type type = src.getType();
|
||||||
if(type == HashedEntry.Type.DIR)
|
if (type == HashedEntry.Type.DIR)
|
||||||
jo.add(PROP_NAME, new JsonPrimitive("dir"));
|
jo.add(PROP_NAME, new JsonPrimitive("dir"));
|
||||||
if(type == HashedEntry.Type.FILE)
|
if (type == HashedEntry.Type.FILE)
|
||||||
jo.add(PROP_NAME, new JsonPrimitive("file"));
|
jo.add(PROP_NAME, new JsonPrimitive("file"));
|
||||||
|
|
||||||
return jo;
|
return jo;
|
||||||
|
|
|
@ -75,6 +75,7 @@ public String toString() {
|
||||||
private final StringConfigEntry serverAddress;
|
private final StringConfigEntry serverAddress;
|
||||||
|
|
||||||
private final IntegerConfigEntry serverPort;
|
private final IntegerConfigEntry serverPort;
|
||||||
|
|
||||||
public static class MarkedString {
|
public static class MarkedString {
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public String string;
|
public String string;
|
||||||
|
@ -85,6 +86,7 @@ public MarkedString(String string, boolean mark) {
|
||||||
this.string = string;
|
this.string = string;
|
||||||
this.mark = mark;
|
this.mark = mark;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MarkedString(String string) {
|
public MarkedString(String string) {
|
||||||
this.string = string;
|
this.string = string;
|
||||||
this.mark = false;
|
this.mark = false;
|
||||||
|
@ -103,6 +105,7 @@ public int hashCode() {
|
||||||
return Objects.hash(string);
|
return Objects.hash(string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updater and client watch service
|
// Updater and client watch service
|
||||||
private final List<String> update = new ArrayList<>();
|
private final List<String> update = new ArrayList<>();
|
||||||
private final List<String> updateExclusions = new ArrayList<>();
|
private final List<String> updateExclusions = new ArrayList<>();
|
||||||
|
@ -213,28 +216,34 @@ public String getServerAddress() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public Set<MarkedString> getOptional()
|
public Set<MarkedString> getOptional() {
|
||||||
{
|
|
||||||
return updateOptional;
|
return updateOptional;
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public void markOptional(String opt)
|
public void markOptional(String opt) {
|
||||||
{
|
if (!updateOptional.contains(new MarkedString(opt)))
|
||||||
if(!updateOptional.contains(new MarkedString(opt))) throw new SecurityException(String.format("Optional mod %s not found in optionalList",opt));
|
throw new SecurityException(String.format("Optional mod %s not found in optionalList", opt));
|
||||||
updateOptional.forEach(e -> {if(e.string.equals(opt)) e.mark = true;});
|
updateOptional.forEach(e -> {
|
||||||
|
if (e.string.equals(opt)) e.mark = true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public void unmarkOptional(String opt)
|
public void unmarkOptional(String opt) {
|
||||||
{
|
if (!updateOptional.contains(new MarkedString(opt)))
|
||||||
if(!updateOptional.contains(new MarkedString(opt))) throw new SecurityException(String.format("Optional mod %s not found in optionalList",opt));
|
throw new SecurityException(String.format("Optional mod %s not found in optionalList", opt));
|
||||||
updateOptional.forEach(e -> {if(e.string.equals(opt)) e.mark = false;});
|
updateOptional.forEach(e -> {
|
||||||
|
if (e.string.equals(opt)) e.mark = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
public void pushOptional(HashedDir dir,boolean digest) throws IOException {
|
|
||||||
for(MarkedString opt : updateOptional)
|
public void pushOptional(HashedDir dir, boolean digest) throws IOException {
|
||||||
{
|
for (MarkedString opt : updateOptional) {
|
||||||
if(!opt.mark) dir.removeR(opt.string);
|
if (!opt.mark) dir.removeR(opt.string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public int getServerPort() {
|
public int getServerPort() {
|
||||||
return serverPort.getValue();
|
return serverPort.getValue();
|
||||||
|
|
|
@ -11,7 +11,7 @@ public enum RequestType implements EnumSerializer.Itf {
|
||||||
LEGACYLAUNCHER(1), UPDATE(2), UPDATE_LIST(3), // Update requests
|
LEGACYLAUNCHER(1), UPDATE(2), UPDATE_LIST(3), // Update requests
|
||||||
AUTH(4), JOIN_SERVER(5), CHECK_SERVER(6), // Auth requests
|
AUTH(4), JOIN_SERVER(5), CHECK_SERVER(6), // Auth requests
|
||||||
PROFILE_BY_USERNAME(7), PROFILE_BY_UUID(8), BATCH_PROFILE_BY_USERNAME(9), // Profile requests
|
PROFILE_BY_USERNAME(7), PROFILE_BY_UUID(8), BATCH_PROFILE_BY_USERNAME(9), // Profile requests
|
||||||
PROFILES(10),SERVERAUTH(11), SETPROFILE(12),LAUNCHER(13),CHANGESERVER(14),
|
PROFILES(10), SERVERAUTH(11), SETPROFILE(12), LAUNCHER(13), CHANGESERVER(14),
|
||||||
CUSTOM(255); // Custom requests
|
CUSTOM(255); // Custom requests
|
||||||
private static final EnumSerializer<RequestType> SERIALIZER = new EnumSerializer<>(RequestType.class);
|
private static final EnumSerializer<RequestType> SERIALIZER = new EnumSerializer<>(RequestType.class);
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,8 @@ public class DigestBytesHolder extends StreamObject {
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public DigestBytesHolder(byte[] bytes, byte[] digest, SecurityHelper.DigestAlgorithm algorithm) throws SignatureException {
|
public DigestBytesHolder(byte[] bytes, byte[] digest, SecurityHelper.DigestAlgorithm algorithm) throws SignatureException {
|
||||||
if(Arrays.equals(SecurityHelper.digest(algorithm,bytes),digest)) throw new SignatureException("Invalid digest");
|
if (Arrays.equals(SecurityHelper.digest(algorithm, bytes), digest))
|
||||||
|
throw new SignatureException("Invalid digest");
|
||||||
this.bytes = bytes.clone();
|
this.bytes = bytes.clone();
|
||||||
this.digest = digest.clone();
|
this.digest = digest.clone();
|
||||||
}
|
}
|
||||||
|
@ -24,12 +25,12 @@ public DigestBytesHolder(byte[] bytes, byte[] digest, SecurityHelper.DigestAlgor
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public DigestBytesHolder(byte[] bytes, SecurityHelper.DigestAlgorithm algorithm) {
|
public DigestBytesHolder(byte[] bytes, SecurityHelper.DigestAlgorithm algorithm) {
|
||||||
this.bytes = bytes.clone();
|
this.bytes = bytes.clone();
|
||||||
this.digest = SecurityHelper.digest(algorithm,bytes);
|
this.digest = SecurityHelper.digest(algorithm, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public DigestBytesHolder(HInput input, SecurityHelper.DigestAlgorithm algorithm) throws IOException, SignatureException {
|
public DigestBytesHolder(HInput input, SecurityHelper.DigestAlgorithm algorithm) throws IOException, SignatureException {
|
||||||
this(input.readByteArray(0), input.readByteArray(-SecurityHelper.RSA_KEY_LENGTH),algorithm);
|
this(input.readByteArray(0), input.readByteArray(-SecurityHelper.RSA_KEY_LENGTH), algorithm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
|
|
|
@ -5,10 +5,11 @@
|
||||||
public class NativeJVMHalt {
|
public class NativeJVMHalt {
|
||||||
public NativeJVMHalt(int haltCode) {
|
public NativeJVMHalt(int haltCode) {
|
||||||
this.haltCode = haltCode;
|
this.haltCode = haltCode;
|
||||||
LogHelper.error("JVM exit code %d",haltCode);
|
LogHelper.error("JVM exit code %d", haltCode);
|
||||||
halt();
|
halt();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int haltCode;
|
public int haltCode;
|
||||||
|
|
||||||
public native void halt();
|
public native void halt();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ public class PublicURLClassLoader extends URLClassLoader {
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public static ClassLoader systemclassloader = ClassLoader.getSystemClassLoader();
|
public static ClassLoader systemclassloader = ClassLoader.getSystemClassLoader();
|
||||||
public String nativePath;
|
public String nativePath;
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public static ClassLoader getSystemClassLoader() {
|
public static ClassLoader getSystemClassLoader() {
|
||||||
return systemclassloader;
|
return systemclassloader;
|
||||||
|
@ -62,9 +63,9 @@ public PublicURLClassLoader(URL[] urls) {
|
||||||
public PublicURLClassLoader(URL[] urls, ClassLoader parent) {
|
public PublicURLClassLoader(URL[] urls, ClassLoader parent) {
|
||||||
super(urls, parent);
|
super(urls, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String findLibrary(String name)
|
public String findLibrary(String name) {
|
||||||
{
|
|
||||||
return nativePath.concat(name);
|
return nativePath.concat(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,186 +20,186 @@
|
||||||
import ru.gravit.utils.helper.LogHelper;
|
import ru.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
public class Downloader implements Runnable {
|
public class Downloader implements Runnable {
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface Handler {
|
public interface Handler {
|
||||||
void check(Certificate[] certs) throws IOException;
|
void check(Certificate[] certs) throws IOException;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Map<String, String> requestClient = Collections.singletonMap("User-Agent",
|
public static final Map<String, String> requestClient = Collections.singletonMap("User-Agent",
|
||||||
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11");
|
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11");
|
||||||
public static final int INTERVAL = 300;
|
public static final int INTERVAL = 300;
|
||||||
|
|
||||||
private final File file;
|
private final File file;
|
||||||
private final URL url;
|
private final URL url;
|
||||||
private final String method;
|
private final String method;
|
||||||
public final Map<String, String> requestProps;
|
public final Map<String, String> requestProps;
|
||||||
public AtomicInteger writed = new AtomicInteger(0);
|
public AtomicInteger writed = new AtomicInteger(0);
|
||||||
public final AtomicBoolean interrupt = new AtomicBoolean(false);
|
public final AtomicBoolean interrupt = new AtomicBoolean(false);
|
||||||
public final AtomicBoolean interrupted = new AtomicBoolean(false);
|
public final AtomicBoolean interrupted = new AtomicBoolean(false);
|
||||||
public AtomicReference<Throwable> ex = new AtomicReference<>(null);
|
public AtomicReference<Throwable> ex = new AtomicReference<>(null);
|
||||||
private final int skip;
|
private final int skip;
|
||||||
private final Handler handler;
|
private final Handler handler;
|
||||||
|
|
||||||
public Downloader(URL url, File file) {
|
public Downloader(URL url, File file) {
|
||||||
this.requestProps = new HashMap<>(requestClient);
|
this.requestProps = new HashMap<>(requestClient);
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.skip = 0;
|
this.skip = 0;
|
||||||
this.handler = null;
|
this.handler = null;
|
||||||
this.method = null;
|
this.method = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Downloader(URL url, File file, int skip) {
|
public Downloader(URL url, File file, int skip) {
|
||||||
this.requestProps = new HashMap<>(requestClient);
|
this.requestProps = new HashMap<>(requestClient);
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.skip = skip;
|
this.skip = skip;
|
||||||
this.handler = null;
|
this.handler = null;
|
||||||
this.method = null;
|
this.method = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Downloader(URL url, File file, Handler handler) {
|
public Downloader(URL url, File file, Handler handler) {
|
||||||
this.requestProps = new HashMap<>(requestClient);
|
this.requestProps = new HashMap<>(requestClient);
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.skip = 0;
|
this.skip = 0;
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
this.method = null;
|
this.method = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Downloader(URL url, File file, int skip, Handler handler) {
|
public Downloader(URL url, File file, int skip, Handler handler) {
|
||||||
this.requestProps = new HashMap<>(requestClient);
|
this.requestProps = new HashMap<>(requestClient);
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.skip = skip;
|
this.skip = skip;
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
this.method = null;
|
this.method = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Downloader(URL url, File file, int skip, Handler handler, Map<String, String> requestProps) {
|
|
||||||
this.requestProps = new HashMap<>(requestProps);
|
|
||||||
this.file = file;
|
|
||||||
this.url = url;
|
|
||||||
this.skip = skip;
|
|
||||||
this.handler = handler;
|
|
||||||
this.method = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Downloader(URL url, File file, int skip, Handler handler, Map<String, String> requestProps, String method) {
|
|
||||||
this.requestProps = new HashMap<>(requestProps);
|
|
||||||
this.file = file;
|
|
||||||
this.url = url;
|
|
||||||
this.skip = skip;
|
|
||||||
this.handler = handler;
|
|
||||||
this.method = method;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Downloader(URL url, File file, int skip, Handler handler, String method) {
|
|
||||||
this.requestProps = new HashMap<>(requestClient);
|
|
||||||
this.file = file;
|
|
||||||
this.url = url;
|
|
||||||
this.skip = skip;
|
|
||||||
this.handler = handler;
|
|
||||||
this.method = method;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getProps() {
|
|
||||||
return requestProps;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addProp(String key, String value) {
|
public Downloader(URL url, File file, int skip, Handler handler, Map<String, String> requestProps) {
|
||||||
requestProps.put(key, value);
|
this.requestProps = new HashMap<>(requestProps);
|
||||||
}
|
this.file = file;
|
||||||
|
this.url = url;
|
||||||
public File getFile() {
|
this.skip = skip;
|
||||||
return file;
|
this.handler = handler;
|
||||||
}
|
this.method = null;
|
||||||
|
}
|
||||||
|
|
||||||
public String getMethod() {
|
public Downloader(URL url, File file, int skip, Handler handler, Map<String, String> requestProps, String method) {
|
||||||
return method;
|
this.requestProps = new HashMap<>(requestProps);
|
||||||
}
|
this.file = file;
|
||||||
|
this.url = url;
|
||||||
public Handler getHandler() {
|
this.skip = skip;
|
||||||
return handler;
|
this.handler = handler;
|
||||||
}
|
this.method = method;
|
||||||
|
}
|
||||||
public void downloadFile() throws IOException {
|
|
||||||
if (!(url.getProtocol().equalsIgnoreCase("http") || url.getProtocol().equalsIgnoreCase("https")))
|
|
||||||
throw new IOException("Invalid protocol.");
|
|
||||||
interrupted.set(false);
|
|
||||||
if (url.getProtocol().equalsIgnoreCase("http")) {
|
|
||||||
HttpURLConnection connect = (HttpURLConnection) (url).openConnection();
|
|
||||||
if (method != null) connect.setRequestMethod(method);
|
|
||||||
for (Map.Entry<String, String> ent : requestProps.entrySet()) {
|
|
||||||
connect.setRequestProperty(ent.getKey(), ent.getValue());
|
|
||||||
}
|
|
||||||
connect.setInstanceFollowRedirects(true);
|
|
||||||
if (!(connect.getResponseCode() >= 200 && connect.getResponseCode() < 300))
|
|
||||||
throw new IOException(String.format("Invalid response of http server %d.", connect.getResponseCode()));
|
|
||||||
try (BufferedInputStream in = new BufferedInputStream(connect.getInputStream(), IOHelper.BUFFER_SIZE);
|
|
||||||
FileOutputStream fout = new FileOutputStream(file, skip != 0)) {
|
|
||||||
byte data[] = new byte[IOHelper.BUFFER_SIZE];
|
|
||||||
int count = -1;
|
|
||||||
long timestamp = System.currentTimeMillis();
|
|
||||||
int writed_local = 0;
|
|
||||||
in.skip(skip);
|
|
||||||
while ((count = in.read(data)) != -1) {
|
|
||||||
fout.write(data, 0, count);
|
|
||||||
writed_local += count;
|
|
||||||
if (System.currentTimeMillis() - timestamp > INTERVAL) {
|
|
||||||
writed.set(writed_local);
|
|
||||||
LogHelper.debug("Downloaded %d", writed_local);
|
|
||||||
if (interrupt.get()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LogHelper.debug("Downloaded %d", writed_local);
|
|
||||||
writed.set(writed_local);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
HttpsURLConnection connect = (HttpsURLConnection) (url).openConnection();
|
|
||||||
if (method != null) connect.setRequestMethod(method);
|
|
||||||
for (Map.Entry<String, String> ent : requestProps.entrySet()) {
|
|
||||||
connect.setRequestProperty(ent.getKey(), ent.getValue());
|
|
||||||
}
|
|
||||||
connect.setInstanceFollowRedirects(true);
|
|
||||||
if (handler != null)
|
|
||||||
handler.check(connect.getServerCertificates());
|
|
||||||
if (!(connect.getResponseCode() >= 200 && connect.getResponseCode() < 300))
|
|
||||||
throw new IOException(String.format("Invalid response of http server %d.", connect.getResponseCode()));
|
|
||||||
try (BufferedInputStream in = new BufferedInputStream(connect.getInputStream(), IOHelper.BUFFER_SIZE);
|
|
||||||
FileOutputStream fout = new FileOutputStream(file, skip != 0)) {
|
|
||||||
byte data[] = new byte[IOHelper.BUFFER_SIZE];
|
|
||||||
int count = -1;
|
|
||||||
long timestamp = System.currentTimeMillis();
|
|
||||||
int writed_local = 0;
|
|
||||||
in.skip(skip);
|
|
||||||
while ((count = in.read(data)) != -1) {
|
|
||||||
fout.write(data, 0, count);
|
|
||||||
writed_local += count;
|
|
||||||
if (System.currentTimeMillis() - timestamp > INTERVAL) {
|
|
||||||
writed.set(writed_local);
|
|
||||||
LogHelper.debug("Downloaded %d", writed_local);
|
|
||||||
if (interrupt.get()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LogHelper.debug("Downloaded %d", writed_local);
|
|
||||||
writed.set(writed_local);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
interrupted.set(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public Downloader(URL url, File file, int skip, Handler handler, String method) {
|
||||||
public void run() {
|
this.requestProps = new HashMap<>(requestClient);
|
||||||
try {
|
this.file = file;
|
||||||
downloadFile();
|
this.url = url;
|
||||||
} catch (Throwable ex) {
|
this.skip = skip;
|
||||||
this.ex.set(ex);
|
this.handler = handler;
|
||||||
LogHelper.error(ex);
|
this.method = method;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public Map<String, String> getProps() {
|
||||||
|
return requestProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addProp(String key, String value) {
|
||||||
|
requestProps.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getFile() {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMethod() {
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Handler getHandler() {
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void downloadFile() throws IOException {
|
||||||
|
if (!(url.getProtocol().equalsIgnoreCase("http") || url.getProtocol().equalsIgnoreCase("https")))
|
||||||
|
throw new IOException("Invalid protocol.");
|
||||||
|
interrupted.set(false);
|
||||||
|
if (url.getProtocol().equalsIgnoreCase("http")) {
|
||||||
|
HttpURLConnection connect = (HttpURLConnection) (url).openConnection();
|
||||||
|
if (method != null) connect.setRequestMethod(method);
|
||||||
|
for (Map.Entry<String, String> ent : requestProps.entrySet()) {
|
||||||
|
connect.setRequestProperty(ent.getKey(), ent.getValue());
|
||||||
|
}
|
||||||
|
connect.setInstanceFollowRedirects(true);
|
||||||
|
if (!(connect.getResponseCode() >= 200 && connect.getResponseCode() < 300))
|
||||||
|
throw new IOException(String.format("Invalid response of http server %d.", connect.getResponseCode()));
|
||||||
|
try (BufferedInputStream in = new BufferedInputStream(connect.getInputStream(), IOHelper.BUFFER_SIZE);
|
||||||
|
FileOutputStream fout = new FileOutputStream(file, skip != 0)) {
|
||||||
|
byte data[] = new byte[IOHelper.BUFFER_SIZE];
|
||||||
|
int count = -1;
|
||||||
|
long timestamp = System.currentTimeMillis();
|
||||||
|
int writed_local = 0;
|
||||||
|
in.skip(skip);
|
||||||
|
while ((count = in.read(data)) != -1) {
|
||||||
|
fout.write(data, 0, count);
|
||||||
|
writed_local += count;
|
||||||
|
if (System.currentTimeMillis() - timestamp > INTERVAL) {
|
||||||
|
writed.set(writed_local);
|
||||||
|
LogHelper.debug("Downloaded %d", writed_local);
|
||||||
|
if (interrupt.get()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LogHelper.debug("Downloaded %d", writed_local);
|
||||||
|
writed.set(writed_local);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HttpsURLConnection connect = (HttpsURLConnection) (url).openConnection();
|
||||||
|
if (method != null) connect.setRequestMethod(method);
|
||||||
|
for (Map.Entry<String, String> ent : requestProps.entrySet()) {
|
||||||
|
connect.setRequestProperty(ent.getKey(), ent.getValue());
|
||||||
|
}
|
||||||
|
connect.setInstanceFollowRedirects(true);
|
||||||
|
if (handler != null)
|
||||||
|
handler.check(connect.getServerCertificates());
|
||||||
|
if (!(connect.getResponseCode() >= 200 && connect.getResponseCode() < 300))
|
||||||
|
throw new IOException(String.format("Invalid response of http server %d.", connect.getResponseCode()));
|
||||||
|
try (BufferedInputStream in = new BufferedInputStream(connect.getInputStream(), IOHelper.BUFFER_SIZE);
|
||||||
|
FileOutputStream fout = new FileOutputStream(file, skip != 0)) {
|
||||||
|
byte data[] = new byte[IOHelper.BUFFER_SIZE];
|
||||||
|
int count = -1;
|
||||||
|
long timestamp = System.currentTimeMillis();
|
||||||
|
int writed_local = 0;
|
||||||
|
in.skip(skip);
|
||||||
|
while ((count = in.read(data)) != -1) {
|
||||||
|
fout.write(data, 0, count);
|
||||||
|
writed_local += count;
|
||||||
|
if (System.currentTimeMillis() - timestamp > INTERVAL) {
|
||||||
|
writed.set(writed_local);
|
||||||
|
LogHelper.debug("Downloaded %d", writed_local);
|
||||||
|
if (interrupt.get()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LogHelper.debug("Downloaded %d", writed_local);
|
||||||
|
writed.set(writed_local);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
interrupted.set(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
downloadFile();
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
this.ex.set(ex);
|
||||||
|
LogHelper.error(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,31 +4,31 @@
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
public class DownloadingThread extends Thread {
|
public class DownloadingThread extends Thread {
|
||||||
private final Downloader runnable;
|
private final Downloader runnable;
|
||||||
|
|
||||||
public DownloadingThread(File file, URL url, String name) {
|
public DownloadingThread(File file, URL url, String name) {
|
||||||
super(name);
|
super(name);
|
||||||
runnable = new Downloader(url, file);
|
runnable = new Downloader(url, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Downloader getDownloader() {
|
public Downloader getDownloader() {
|
||||||
return runnable;
|
return runnable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void interrupt() {
|
public void interrupt() {
|
||||||
runnable.interrupt.set(true);
|
runnable.interrupt.set(true);
|
||||||
while (!runnable.interrupted.get()) {
|
while (!runnable.interrupted.get()) {
|
||||||
}
|
}
|
||||||
super.interrupt();
|
super.interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hardInterrupt() {
|
public void hardInterrupt() {
|
||||||
super.interrupt();
|
super.interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
runnable.run();
|
runnable.run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
public class EventManager {
|
public class EventManager {
|
||||||
public static final int QUEUE_MAX_SIZE = 2048;
|
public static final int QUEUE_MAX_SIZE = 2048;
|
||||||
public static final int INITIAL_HANDLERS_SIZE = 16;
|
public static final int INITIAL_HANDLERS_SIZE = 16;
|
||||||
public class Entry
|
|
||||||
{
|
public class Entry {
|
||||||
public Entry(EventHandler<EventInterface> func, UUID[] events) {
|
public Entry(EventHandler<EventInterface> func, UUID[] events) {
|
||||||
this.func = func;
|
this.func = func;
|
||||||
this.events = events;
|
this.events = events;
|
||||||
|
@ -23,8 +23,8 @@ public Entry(EventHandler<EventInterface> func, UUID[] events) {
|
||||||
EventHandler<EventInterface> func;
|
EventHandler<EventInterface> func;
|
||||||
UUID[] events;
|
UUID[] events;
|
||||||
}
|
}
|
||||||
public class QueueEntry
|
|
||||||
{
|
public class QueueEntry {
|
||||||
public QueueEntry(EventInterface event, UUID key) {
|
public QueueEntry(EventInterface event, UUID key) {
|
||||||
this.event = event;
|
this.event = event;
|
||||||
this.key = key;
|
this.key = key;
|
||||||
|
@ -33,61 +33,65 @@ public QueueEntry(EventInterface event, UUID key) {
|
||||||
EventInterface event;
|
EventInterface event;
|
||||||
UUID key;
|
UUID key;
|
||||||
}
|
}
|
||||||
|
|
||||||
private EventExecutor executor;
|
private EventExecutor executor;
|
||||||
private Thread executorThread;
|
private Thread executorThread;
|
||||||
private AtomicBoolean isStarted = new AtomicBoolean(false);
|
private AtomicBoolean isStarted = new AtomicBoolean(false);
|
||||||
public synchronized void start()
|
|
||||||
{
|
public synchronized void start() {
|
||||||
if(isStarted.get()) return;
|
if (isStarted.get()) return;
|
||||||
executor = new EventExecutor();
|
executor = new EventExecutor();
|
||||||
isStarted.set(true);
|
isStarted.set(true);
|
||||||
executorThread = CommonHelper.newThread("EventExecutor",true,executor);
|
executorThread = CommonHelper.newThread("EventExecutor", true, executor);
|
||||||
executorThread.start();
|
executorThread.start();
|
||||||
}
|
}
|
||||||
public synchronized void stop()
|
|
||||||
{
|
public synchronized void stop() {
|
||||||
if(!isStarted.get()) return;
|
if (!isStarted.get()) return;
|
||||||
executorThread.interrupt();
|
executorThread.interrupt();
|
||||||
try {
|
try {
|
||||||
executorThread.join();
|
executorThread.join();
|
||||||
} catch (InterruptedException ignored) {
|
} catch (InterruptedException ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<Entry> handlers = new ArrayList<>(INITIAL_HANDLERS_SIZE);
|
public ArrayList<Entry> handlers = new ArrayList<>(INITIAL_HANDLERS_SIZE);
|
||||||
public BlockingQueue<QueueEntry> queue = new LinkedBlockingQueue<>(QUEUE_MAX_SIZE); //Максимальный размер очереди
|
public BlockingQueue<QueueEntry> queue = new LinkedBlockingQueue<>(QUEUE_MAX_SIZE); //Максимальный размер очереди
|
||||||
public int registerHandler(EventHandler<EventInterface> func, UUID[] events)
|
|
||||||
{
|
public int registerHandler(EventHandler<EventInterface> func, UUID[] events) {
|
||||||
if(isStarted.get()) throw new IllegalThreadStateException("It is forbidden to add a handler during thread operation.");
|
if (isStarted.get())
|
||||||
|
throw new IllegalThreadStateException("It is forbidden to add a handler during thread operation.");
|
||||||
Arrays.sort(events);
|
Arrays.sort(events);
|
||||||
handlers.add(new Entry(func,events));
|
handlers.add(new Entry(func, events));
|
||||||
return handlers.size();
|
return handlers.size();
|
||||||
}
|
}
|
||||||
public void unregisterHandler(EventHandler<EventInterface> func)
|
|
||||||
{
|
public void unregisterHandler(EventHandler<EventInterface> func) {
|
||||||
if(isStarted.get()) throw new IllegalThreadStateException("It is forbidden to remove a handler during thread operation.");
|
if (isStarted.get())
|
||||||
|
throw new IllegalThreadStateException("It is forbidden to remove a handler during thread operation.");
|
||||||
handlers.removeIf(e -> e.func.equals(func));
|
handlers.removeIf(e -> e.func.equals(func));
|
||||||
}
|
}
|
||||||
public void sendEvent(UUID key, EventInterface event, boolean blocking)
|
|
||||||
{
|
public void sendEvent(UUID key, EventInterface event, boolean blocking) {
|
||||||
if(blocking) process(key,event);
|
if (blocking) process(key, event);
|
||||||
else queue.add(new QueueEntry(event,key));
|
else queue.add(new QueueEntry(event, key));
|
||||||
}
|
}
|
||||||
public void process(UUID key, EventInterface event)
|
|
||||||
{
|
public void process(UUID key, EventInterface event) {
|
||||||
for(Entry e : handlers)
|
for (Entry e : handlers) {
|
||||||
{
|
if (Arrays.binarySearch(e.events, key) >= 0) e.func.run(key, event);
|
||||||
if(Arrays.binarySearch(e.events,key) >= 0) e.func.run(key, event);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class EventExecutor implements Runnable {
|
public class EventExecutor implements Runnable {
|
||||||
public boolean enable = true;
|
public boolean enable = true;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while(enable && !Thread.interrupted())
|
while (enable && !Thread.interrupted()) {
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
QueueEntry e = queue.take();
|
QueueEntry e = queue.take();
|
||||||
process(e.key,e.event);
|
process(e.key, e.event);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,32 +4,32 @@
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class EnvHelper {
|
public class EnvHelper {
|
||||||
public static final String[] toTest;
|
public static final String[] toTest;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
toTest = new String[] { "_JAVA_OPTIONS", "_JAVA_OPTS", "JAVA_OPTS", "JAVA_OPTIONS" };
|
toTest = new String[]{"_JAVA_OPTIONS", "_JAVA_OPTS", "JAVA_OPTS", "JAVA_OPTIONS"};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addEnv(ProcessBuilder builder) {
|
public static void addEnv(ProcessBuilder builder) {
|
||||||
Map<String, String> map = builder.environment();
|
Map<String, String> map = builder.environment();
|
||||||
for (String env : toTest) {
|
for (String env : toTest) {
|
||||||
if(map.containsKey(env))
|
if (map.containsKey(env))
|
||||||
map.put(env, "");
|
map.put(env, "");
|
||||||
String lower_env = env.toLowerCase(Locale.US);
|
String lower_env = env.toLowerCase(Locale.US);
|
||||||
if(map.containsKey(lower_env))
|
if (map.containsKey(lower_env))
|
||||||
map.put(lower_env, "");
|
map.put(lower_env, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void checkDangerousParams() {
|
public static void checkDangerousParams() {
|
||||||
for (String t : toTest) {
|
for (String t : toTest) {
|
||||||
String env = System.getenv(t);
|
String env = System.getenv(t);
|
||||||
if (env != null) {
|
if (env != null) {
|
||||||
env = env.toLowerCase(Locale.US);
|
env = env.toLowerCase(Locale.US);
|
||||||
if (env.contains("-cp") || env.contains("-classpath") || env.contains("-javaagent")
|
if (env.contains("-cp") || env.contains("-classpath") || env.contains("-javaagent")
|
||||||
|| env.contains("-agentpath") || env.contains("-agentlib"))
|
|| env.contains("-agentpath") || env.contains("-agentlib"))
|
||||||
throw new SecurityException("JavaAgent in global options not allow");
|
throw new SecurityException("JavaAgent in global options not allow");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,14 +114,13 @@ public static URL[] getClassPathURL() {
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
public static void checkStackTrace(Class mainClass)
|
|
||||||
{
|
public static void checkStackTrace(Class mainClass) {
|
||||||
LogHelper.debug("Testing stacktrace");
|
LogHelper.debug("Testing stacktrace");
|
||||||
Exception e = new Exception("Testing stacktrace");
|
Exception e = new Exception("Testing stacktrace");
|
||||||
StackTraceElement[] list = e.getStackTrace();
|
StackTraceElement[] list = e.getStackTrace();
|
||||||
if(!list[list.length - 1].getClassName().equals(mainClass.getName()))
|
if (!list[list.length - 1].getClassName().equals(mainClass.getName())) {
|
||||||
{
|
throw new SecurityException(String.format("Invalid StackTraceElement: %s", list[list.length - 1].getClassName()));
|
||||||
throw new SecurityException(String.format("Invalid StackTraceElement: %s",list[list.length - 1].getClassName()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
import ru.gravit.launcher.LauncherAPI;
|
import ru.gravit.launcher.LauncherAPI;
|
||||||
|
|
||||||
public final class SecurityHelper {
|
public final class SecurityHelper {
|
||||||
|
|
||||||
public enum DigestAlgorithm {
|
public enum DigestAlgorithm {
|
||||||
PLAIN("plain", -1), MD5("MD5", 128), SHA1("SHA-1", 160), SHA224("SHA-224", 224), SHA256("SHA-256", 256), SHA512("SHA-512", 512);
|
PLAIN("plain", -1), MD5("MD5", 128), SHA1("SHA-1", 160), SHA224("SHA-224", 224), SHA256("SHA-256", 256), SHA512("SHA-512", 512);
|
||||||
private static final Map<String, DigestAlgorithm> ALGORITHMS;
|
private static final Map<String, DigestAlgorithm> ALGORITHMS;
|
||||||
|
@ -78,9 +78,9 @@ public byte[] verify(byte[] digest) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Algorithm constants
|
// Algorithm constants
|
||||||
|
|
||||||
public static final String RSA_ALGO = "RSA";
|
public static final String RSA_ALGO = "RSA";
|
||||||
|
|
||||||
public static final String RSA_SIGN_ALGO = "SHA256withRSA";
|
public static final String RSA_SIGN_ALGO = "SHA256withRSA";
|
||||||
|
|
||||||
|
|
||||||
|
@ -486,6 +486,7 @@ public static String verifyToken(String token) {
|
||||||
|
|
||||||
private SecurityHelper() {
|
private SecurityHelper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//AES
|
//AES
|
||||||
public static byte[] encrypt(String seed, byte[] cleartext) throws Exception {
|
public static byte[] encrypt(String seed, byte[] cleartext) throws Exception {
|
||||||
byte[] rawKey = getRawKey(seed.getBytes());
|
byte[] rawKey = getRawKey(seed.getBytes());
|
||||||
|
@ -520,6 +521,7 @@ public static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
|
||||||
cipher.init(Cipher.DECRYPT_MODE, sKeySpec);
|
cipher.init(Cipher.DECRYPT_MODE, sKeySpec);
|
||||||
return cipher.doFinal(encrypted);
|
return cipher.doFinal(encrypted);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] HexToByte(String hexString) {
|
public static byte[] HexToByte(String hexString) {
|
||||||
int len = hexString.length() / 2;
|
int len = hexString.length() / 2;
|
||||||
byte[] result = new byte[len];
|
byte[] result = new byte[len];
|
||||||
|
|
|
@ -9,15 +9,15 @@ public class UnpackHelper {
|
||||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||||
public static boolean unpack(URL resource, Path target) throws IOException {
|
public static boolean unpack(URL resource, Path target) throws IOException {
|
||||||
byte[] orig = IOHelper.read(resource);
|
byte[] orig = IOHelper.read(resource);
|
||||||
if(IOHelper.exists(target))
|
if (IOHelper.exists(target)) {
|
||||||
{
|
if (matches(target, orig)) return false;
|
||||||
if(matches(target,orig)) return false;
|
|
||||||
}
|
}
|
||||||
if (!IOHelper.exists(target))
|
if (!IOHelper.exists(target))
|
||||||
target.toFile().createNewFile();
|
target.toFile().createNewFile();
|
||||||
IOHelper.transfer(orig,target,false);
|
IOHelper.transfer(orig, target, false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean matches(Path target, byte[] in) {
|
private static boolean matches(Path target, byte[] in) {
|
||||||
try {
|
try {
|
||||||
return Arrays.equals(SecurityHelper.digest(SecurityHelper.DigestAlgorithm.SHA256, in),
|
return Arrays.equals(SecurityHelper.digest(SecurityHelper.DigestAlgorithm.SHA256, in),
|
||||||
|
|
Loading…
Reference in a new issue