Merge branch 'dev' into feature/design

This commit is contained in:
Dmitriy Leo 2019-05-19 22:28:25 +03:00 committed by GitHub
commit 405caef0f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
123 changed files with 1018 additions and 920 deletions

37
.gitlab-ci.yml Normal file
View file

@ -0,0 +1,37 @@
image: java:8-jdk
stages:
- build
- test
- deploy
before_script:
# - echo `pwd` # debug
# - echo "$CI_BUILD_NAME, $CI_BUILD_REF_NAME $CI_BUILD_STAGE" # debug
- export GRADLE_USER_HOME=`pwd`/.gradle
cache:
paths:
- .gradle/wrapper
- .gradle/caches
build:
stage: build
script:
- sed -i 's/git@github.com:/https:\/\/github.com\//' .gitmodules
- git submodule sync
- git submodule update --init --recursive
- ./gradlew assemble
artifacts:
paths:
- LaunchServer/build/libs/*
- ServerWrapper/build/libs/*.jar
expire_in: 1 week
test:
stage: test
script:
- ./gradlew check
after_script:
- echo "End CI"

View file

@ -44,13 +44,15 @@
pack project(':libLauncher') pack project(':libLauncher')
pack project(':LauncherAPI') pack project(':LauncherAPI')
bundle project(':Radon') bundle project(':Radon')
bundle 'mysql:mysql-connector-java:8.0.13' bundle 'mysql:mysql-connector-java:8.0.16'
bundle 'jline:jline:2.14.6' bundle 'org.jline:jline:3.11.0'
bundle 'net.sf.proguard:proguard-base:6.0.3' bundle 'org.jline:jline-reader:3.11.0'
bundle 'org.fusesource.jansi:jansi:1.17.1' bundle 'org.jline:jline-terminal:3.11.0'
bundle 'net.sf.proguard:proguard-base:6.1.0'
bundle 'org.fusesource.jansi:jansi:1.18'
bundle 'commons-io:commons-io:2.6' bundle 'commons-io:commons-io:2.6'
bundle 'commons-codec:commons-codec:1.11' bundle 'commons-codec:commons-codec:1.12'
bundle 'org.javassist:javassist:3.24.1-GA' bundle 'org.javassist:javassist:3.25.0-GA'
bundle 'io.netty:netty-all:4.1.36.Final' bundle 'io.netty:netty-all:4.1.36.Final'
bundle 'org.slf4j:slf4j-simple:1.7.25' bundle 'org.slf4j:slf4j-simple:1.7.25'

View file

@ -4,6 +4,7 @@
import ru.gravit.launcher.Launcher; import ru.gravit.launcher.Launcher;
import ru.gravit.launcher.LauncherConfig; import ru.gravit.launcher.LauncherConfig;
import ru.gravit.launcher.NeedGarbageCollection; import ru.gravit.launcher.NeedGarbageCollection;
import ru.gravit.launcher.config.JsonConfigurable;
import ru.gravit.launcher.hasher.HashedDir; import ru.gravit.launcher.hasher.HashedDir;
import ru.gravit.launcher.managers.ConfigManager; import ru.gravit.launcher.managers.ConfigManager;
import ru.gravit.launcher.managers.GarbageManager; import ru.gravit.launcher.managers.GarbageManager;
@ -38,7 +39,6 @@
import ru.gravit.utils.command.CommandHandler; import ru.gravit.utils.command.CommandHandler;
import ru.gravit.utils.command.JLineCommandHandler; import ru.gravit.utils.command.JLineCommandHandler;
import ru.gravit.utils.command.StdCommandHandler; import ru.gravit.utils.command.StdCommandHandler;
import ru.gravit.launcher.config.JsonConfigurable;
import ru.gravit.utils.helper.*; import ru.gravit.utils.helper.*;
import java.io.*; import java.io.*;
@ -200,8 +200,8 @@ public void verify() {
throw new NullPointerException("Netty must not be null"); throw new NullPointerException("Netty must not be null");
} }
} }
public void init()
{ public void init() {
Launcher.applyLauncherEnv(env); Launcher.applyLauncherEnv(env);
for (AuthProviderPair provider : auth) { for (AuthProviderPair provider : auth) {
provider.init(); provider.init();
@ -212,8 +212,7 @@ public void init()
protectHandler.checkLaunchServerLicense(); protectHandler.checkLaunchServerLicense();
} }
LaunchServer.server.registerObject("permissionsHandler", permissionsHandler); LaunchServer.server.registerObject("permissionsHandler", permissionsHandler);
for (int i = 0; i < auth.length; ++i) { for (AuthProviderPair pair : auth) {
AuthProviderPair pair = auth[i];
LaunchServer.server.registerObject("auth.".concat(pair.name).concat(".provider"), pair.provider); LaunchServer.server.registerObject("auth.".concat(pair.name).concat(".provider"), pair.provider);
LaunchServer.server.registerObject("auth.".concat(pair.name).concat(".handler"), pair.handler); LaunchServer.server.registerObject("auth.".concat(pair.name).concat(".handler"), pair.handler);
LaunchServer.server.registerObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider); LaunchServer.server.registerObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider);
@ -225,14 +224,12 @@ public void init()
public void close() { public void close() {
try { try {
LaunchServer.server.unregisterObject("permissionsHandler", permissionsHandler); LaunchServer.server.unregisterObject("permissionsHandler", permissionsHandler);
for (int i = 0; i < auth.length; ++i) { for (AuthProviderPair pair : auth) {
AuthProviderPair pair = auth[i];
LaunchServer.server.unregisterObject("auth.".concat(pair.name).concat(".provider"), pair.provider); LaunchServer.server.unregisterObject("auth.".concat(pair.name).concat(".provider"), pair.provider);
LaunchServer.server.unregisterObject("auth.".concat(pair.name).concat(".handler"), pair.handler); LaunchServer.server.unregisterObject("auth.".concat(pair.name).concat(".handler"), pair.handler);
LaunchServer.server.unregisterObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider); LaunchServer.server.unregisterObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider);
} }
} catch (Exception e) } catch (Exception e) {
{
LogHelper.error(e); LogHelper.error(e);
} }
try { try {
@ -266,10 +263,15 @@ public static class ExeConf {
public String txtFileVersion; public String txtFileVersion;
public String txtProductVersion; public String txtProductVersion;
} }
public static class NettyUpdatesBind
public class LauncherConf
{ {
public String url;
public boolean zip;
}
public class LauncherConf {
public String guardType; public String guardType;
public boolean attachLibraryBeforeProGuard;
} }
public class NettyConfig { public class NettyConfig {
@ -280,19 +282,19 @@ public class NettyConfig {
public String downloadURL; public String downloadURL;
public String launcherEXEURL; public String launcherEXEURL;
public String address; public String address;
public Map<String, String> bindings = new HashMap<>(); public Map<String, NettyUpdatesBind> bindings = new HashMap<>();
public NettyPerformanceConfig performance; public NettyPerformanceConfig performance;
public NettyBindAddress[] binds; public NettyBindAddress[] binds;
public LogLevel logLevel = LogLevel.DEBUG; public LogLevel logLevel = LogLevel.DEBUG;
public NettyProxyConfig proxy = new NettyProxyConfig(); public NettyProxyConfig proxy = new NettyProxyConfig();
} }
public class NettyPerformanceConfig
{ public class NettyPerformanceConfig {
public int bossThread; public int bossThread;
public int workerThread; public int workerThread;
} }
public class NettyProxyConfig
{ public class NettyProxyConfig {
public boolean enabled; public boolean enabled;
public String address = "ws://localhost:9275/api"; public String address = "ws://localhost:9275/api";
public String login = "login"; public String login = "login";
@ -300,8 +302,8 @@ public class NettyProxyConfig
public String auth_id = "std"; public String auth_id = "std";
public ArrayList<String> requests = new ArrayList<>(); public ArrayList<String> requests = new ArrayList<>();
} }
public class NettyBindAddress
{ public class NettyBindAddress {
public String address; public String address;
public int port; public int port;
@ -481,7 +483,7 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException
localCommandHandler = new StdCommandHandler(false); localCommandHandler = new StdCommandHandler(false);
else else
try { try {
Class.forName("jline.Terminal"); Class.forName("org.jline.terminal.Terminal");
// JLine2 available // JLine2 available
localCommandHandler = new JLineCommandHandler(); localCommandHandler = new JLineCommandHandler();
@ -532,14 +534,11 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException
try (BufferedReader reader = IOHelper.newReader(configFile)) { try (BufferedReader reader = IOHelper.newReader(configFile)) {
config = Launcher.gsonManager.gson.fromJson(reader, Config.class); config = Launcher.gsonManager.gson.fromJson(reader, Config.class);
} }
if(!Files.exists(runtimeConfigFile)) if (!Files.exists(runtimeConfigFile)) {
{
LogHelper.info("Reset LaunchServer runtime config file"); LogHelper.info("Reset LaunchServer runtime config file");
runtime = new LaunchServerRuntimeConfig(); runtime = new LaunchServerRuntimeConfig();
runtime.reset(); runtime.reset();
} } else {
else
{
LogHelper.info("Reading LaunchServer runtime config file"); LogHelper.info("Reading LaunchServer runtime config file");
try (BufferedReader reader = IOHelper.newReader(runtimeConfigFile)) { try (BufferedReader reader = IOHelper.newReader(runtimeConfigFile)) {
runtime = Launcher.gsonManager.gson.fromJson(reader, LaunchServerRuntimeConfig.class); runtime = Launcher.gsonManager.gson.fromJson(reader, LaunchServerRuntimeConfig.class);
@ -674,10 +673,8 @@ public void close() {
config.close(); config.close();
modulesManager.close(); modulesManager.close();
LogHelper.info("Save LaunchServer runtime config"); LogHelper.info("Save LaunchServer runtime config");
try(Writer writer = IOHelper.newWriter(runtimeConfigFile)) try (Writer writer = IOHelper.newWriter(runtimeConfigFile)) {
{ if (Launcher.gsonManager.configGson != null) {
if(Launcher.gsonManager.configGson != null)
{
Launcher.gsonManager.configGson.toJson(runtime, writer); Launcher.gsonManager.configGson.toJson(runtime, writer);
} else { } else {
LogHelper.error("Error writing LaunchServer runtime config file. Gson is null"); LogHelper.error("Error writing LaunchServer runtime config file. Gson is null");
@ -726,7 +723,7 @@ private void generateConfigIfNotExists(boolean testEnv) throws IOException {
newConfig.netty = new NettyConfig(); newConfig.netty = new NettyConfig();
newConfig.netty.fileServerEnabled = true; newConfig.netty.fileServerEnabled = true;
newConfig.netty.binds = new NettyBindAddress[]{ new NettyBindAddress("0.0.0.0", 9274) }; newConfig.netty.binds = new NettyBindAddress[]{new NettyBindAddress("0.0.0.0", 9274)};
newConfig.netty.performance = new NettyPerformanceConfig(); newConfig.netty.performance = new NettyPerformanceConfig();
newConfig.netty.performance.bossThread = 2; newConfig.netty.performance.bossThread = 2;
newConfig.netty.performance.workerThread = 8; newConfig.netty.performance.workerThread = 8;
@ -762,13 +759,11 @@ private void generateConfigIfNotExists(boolean testEnv) throws IOException {
System.out.println("LaunchServer projectName: "); System.out.println("LaunchServer projectName: ");
newConfig.setProjectName(commandHandler.readLine()); newConfig.setProjectName(commandHandler.readLine());
} }
if(address == null || address.isEmpty()) if (address == null || address.isEmpty()) {
{
LogHelper.error("Address null. Using localhost"); LogHelper.error("Address null. Using localhost");
address = "localhost"; address = "localhost";
} }
if(newConfig.projectName == null || newConfig.projectName.isEmpty()) if (newConfig.projectName == null || newConfig.projectName.isEmpty()) {
{
LogHelper.error("ProjectName null. Using MineCraft"); LogHelper.error("ProjectName null. Using MineCraft");
newConfig.projectName = "MineCraft"; newConfig.projectName = "MineCraft";
} }
@ -869,7 +864,8 @@ public void syncUpdatesDir(Collection<String> dirs) throws IOException {
// Resolve name and verify is dir // Resolve name and verify is dir
String name = IOHelper.getFileName(updateDir); String name = IOHelper.getFileName(updateDir);
if (!IOHelper.isDir(updateDir)) { if (!IOHelper.isDir(updateDir)) {
if (!IOHelper.isFile(updateDir) && Arrays.asList(".jar", ".exe", ".hash").stream().noneMatch(e -> updateDir.toString().endsWith(e))) LogHelper.warning("Not update dir: '%s'", name); if (!IOHelper.isFile(updateDir) && Arrays.asList(".jar", ".exe", ".hash").stream().noneMatch(e -> updateDir.toString().endsWith(e)))
LogHelper.warning("Not update dir: '%s'", name);
continue; continue;
} }
@ -920,6 +916,7 @@ public void registerObject(String name, Object object) {
} }
} }
public void unregisterObject(String name, Object object) { public void unregisterObject(String name, Object object) {
if (object instanceof Reloadable) { if (object instanceof Reloadable) {
reloadManager.unregisterReloadable(name); reloadManager.unregisterReloadable(name);

View file

@ -16,6 +16,7 @@ public final class StarterAgent {
private static final class StarterVisitor extends SimpleFileVisitor<Path> { private static final class StarterVisitor extends SimpleFileVisitor<Path> {
private static final Set<PosixFilePermission> DPERMS; private static final Set<PosixFilePermission> DPERMS;
static { static {
Set<PosixFilePermission> perms = new HashSet<>(Arrays.asList(PosixFilePermission.values())); Set<PosixFilePermission> perms = new HashSet<>(Arrays.asList(PosixFilePermission.values()));
perms.remove(PosixFilePermission.OTHERS_WRITE); perms.remove(PosixFilePermission.OTHERS_WRITE);
@ -33,13 +34,15 @@ private StarterVisitor() {
try { try {
Files.deleteIfExists(filef); Files.deleteIfExists(filef);
Files.createFile(filef); Files.createFile(filef);
} catch (Throwable t) { } } catch (Throwable ignored) {
}
} }
} }
@Override @Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (fixLib && Files.getFileAttributeView(file, PosixFileAttributeView.class) != null) Files.setPosixFilePermissions(file, DPERMS); if (fixLib && Files.getFileAttributeView(file, PosixFileAttributeView.class) != null)
Files.setPosixFilePermissions(file, DPERMS);
if (file.toFile().getName().endsWith(".jar")) if (file.toFile().getName().endsWith(".jar"))
inst.appendToSystemClassLoaderSearch(new JarFile(file.toFile())); inst.appendToSystemClassLoaderSearch(new JarFile(file.toFile()));
return super.visitFile(file, attrs); return super.visitFile(file, attrs);

View file

@ -11,24 +11,24 @@ public class JsonAuthHandler extends CachedAuthHandler {
public URL getUrl; public URL getUrl;
public URL updateAuthUrl; public URL updateAuthUrl;
public URL updateServerIdUrl; public URL updateServerIdUrl;
public class EntryRequestByUsername
{ public class EntryRequestByUsername {
public String username; public String username;
public EntryRequestByUsername(String username) { public EntryRequestByUsername(String username) {
this.username = username; this.username = username;
} }
} }
public class EntryRequestByUUID
{ public class EntryRequestByUUID {
public UUID uuid; public UUID uuid;
public EntryRequestByUUID(UUID uuid) { public EntryRequestByUUID(UUID uuid) {
this.uuid = uuid; this.uuid = uuid;
} }
} }
public class UpdateAuthRequest
{ public class UpdateAuthRequest {
public UUID uuid; public UUID uuid;
public String username; public String username;
public String accessToken; public String accessToken;
@ -39,8 +39,8 @@ public UpdateAuthRequest(UUID uuid, String username, String accessToken) {
this.accessToken = accessToken; this.accessToken = accessToken;
} }
} }
public class UpdateServerIDRequest
{ public class UpdateServerIDRequest {
public UUID uuid; public UUID uuid;
public String serverID; public String serverID;
@ -49,10 +49,11 @@ public UpdateServerIDRequest(UUID uuid, String serverID) {
this.serverID = serverID; this.serverID = serverID;
} }
} }
public class SuccessResponse
{ public class SuccessResponse {
public boolean success; public boolean success;
} }
@Override @Override
protected Entry fetchEntry(String username) throws IOException { protected Entry fetchEntry(String username) throws IOException {
return Launcher.gsonManager.configGson.fromJson(HTTPRequest.jsonRequest(Launcher.gsonManager.configGson.toJsonTree(new EntryRequestByUsername(username)), getUrl), Entry.class); return Launcher.gsonManager.configGson.fromJson(HTTPRequest.jsonRequest(Launcher.gsonManager.configGson.toJsonTree(new EntryRequestByUsername(username)), getUrl), Entry.class);

View file

@ -8,7 +8,6 @@ public abstract class ProtectHandler {
private static boolean registredHandl = false; private static boolean registredHandl = false;
public static void registerHandlers() { public static void registerHandlers() {
if (!registredHandl) { if (!registredHandl) {
providers.register("none", NoProtectHandler.class); providers.register("none", NoProtectHandler.class);
@ -19,7 +18,9 @@ public static void registerHandlers() {
public abstract String generateSecureToken(AuthResponse.AuthContext context); //Генерация токена для передачи его в LauncherGuardInterface public abstract String generateSecureToken(AuthResponse.AuthContext context); //Генерация токена для передачи его в LauncherGuardInterface
public abstract String generateClientSecureToken(); public abstract String generateClientSecureToken();
public abstract boolean verifyClientSecureToken(String token, String secureKey); public abstract boolean verifyClientSecureToken(String token, String secureKey);
public abstract boolean allowGetAccessToken(AuthResponse.AuthContext context); public abstract boolean allowGetAccessToken(AuthResponse.AuthContext context);
public abstract void checkLaunchServerLicense(); //Выдает SecurityException при ошибке проверки лицензии public abstract void checkLaunchServerLicense(); //Выдает SecurityException при ошибке проверки лицензии

View file

@ -29,7 +29,6 @@ public static void registerProviders() {
public abstract AuthProviderResult auth(String login, String password, String ip) throws Exception; public abstract AuthProviderResult auth(String login, String password, String ip) throws Exception;
public void preAuth(String login, String password, String customText, String ip) { public void preAuth(String login, String password, String customText, String ip) {
return;
} }
@Override @Override

View file

@ -42,10 +42,11 @@ public JARLauncherBinary(LaunchServer server) throws IOException {
public void init() { public void init() {
tasks.add(new PrepareBuildTask(server)); tasks.add(new PrepareBuildTask(server));
tasks.add(new MainBuildTask(server)); tasks.add(new MainBuildTask(server));
if(server.config.launcher.attachLibraryBeforeProGuard) tasks.add(new AttachJarsTask(server));
tasks.add(new ProGuardBuildTask(server)); tasks.add(new ProGuardBuildTask(server));
tasks.add(new AdditionalFixesApplyTask(server)); tasks.add(new AdditionalFixesApplyTask(server));
tasks.add(new RadonBuildTask(server)); tasks.add(new RadonBuildTask(server));
tasks.add(new AttachJarsTask(server)); if(!server.config.launcher.attachLibraryBeforeProGuard) tasks.add(new AttachJarsTask(server));
} }
@Override @Override

View file

@ -46,7 +46,7 @@ public final boolean sync() throws IOException {
return exists; return exists;
} }
public static final Path resolve(LaunchServer server, String ext) { public static Path resolve(LaunchServer server, String ext) {
return server.config.copyBinaries ? server.updatesDir.resolve(server.config.binaryName + ext) : server.dir.resolve(server.config.binaryName + ext); return server.config.copyBinaries ? server.updatesDir.resolve(server.config.binaryName + ext) : server.dir.resolve(server.config.binaryName + ext);
} }
} }

View file

@ -40,8 +40,8 @@ public Path process(Path inputFile) throws IOException {
SessionInfo info = p.createSessionFromConfig(); SessionInfo info = p.createSessionFromConfig();
info.setInput(inputFile.toFile()); info.setInput(inputFile.toFile());
info.setOutput(outputFile.toFile()); info.setOutput(outputFile.toFile());
List<File> libs = srv.launcherBinary.coreLibs.stream().map(e -> e.toFile()).collect(Collectors.toList()); List<File> libs = srv.launcherBinary.coreLibs.stream().map(Path::toFile).collect(Collectors.toList());
libs.addAll(srv.launcherBinary.addonLibs.stream().map(e -> e.toFile()).collect(Collectors.toList())); libs.addAll(srv.launcherBinary.addonLibs.stream().map(Path::toFile).collect(Collectors.toList()));
info.setLibraries(libs); info.setLibraries(libs);
Radon r = new Radon(info); Radon r = new Radon(info);
r.run(); r.run();

View file

@ -8,13 +8,13 @@
public final class TaskUtil { public final class TaskUtil {
public static void addCounted(List<LauncherBuildTask> tasks, int count, Predicate<LauncherBuildTask> pred, LauncherBuildTask taskAdd) { public static void addCounted(List<LauncherBuildTask> tasks, int count, Predicate<LauncherBuildTask> pred, LauncherBuildTask taskAdd) {
List<LauncherBuildTask> indexes = new ArrayList<>(); List<LauncherBuildTask> indexes = new ArrayList<>();
tasks.stream().filter(pred).forEach(e -> indexes.add(e)); tasks.stream().filter(pred).forEach(indexes::add);
indexes.forEach(e -> tasks.add(tasks.indexOf(e) + count, taskAdd)); indexes.forEach(e -> tasks.add(tasks.indexOf(e) + count, taskAdd));
} }
public static void replaceCounted(List<LauncherBuildTask> tasks, int count, Predicate<LauncherBuildTask> pred, LauncherBuildTask taskRep) { public static void replaceCounted(List<LauncherBuildTask> tasks, int count, Predicate<LauncherBuildTask> pred, LauncherBuildTask taskRep) {
List<LauncherBuildTask> indexes = new ArrayList<>(); List<LauncherBuildTask> indexes = new ArrayList<>();
tasks.stream().filter(pred).forEach(e -> indexes.add(e)); tasks.stream().filter(pred).forEach(indexes::add);
indexes.forEach(e -> tasks.set(tasks.indexOf(e) + count, taskRep)); indexes.forEach(e -> tasks.set(tasks.indexOf(e) + count, taskRep));
} }

View file

@ -26,10 +26,8 @@ public String getUsageDescription() {
public void invoke(String... args) throws Exception { public void invoke(String... args) throws Exception {
verifyArgs(args, 1); verifyArgs(args, 1);
List<HWID> target = server.config.hwidHandler.getHwid(args[0]); List<HWID> target = server.config.hwidHandler.getHwid(args[0]);
for(HWID hwid : target) for (HWID hwid : target) {
{ if (hwid == null) {
if(hwid == null)
{
LogHelper.error("HWID %s: null", args[0]); LogHelper.error("HWID %s: null", args[0]);
continue; continue;
} }

View file

@ -35,8 +35,7 @@ public void invoke(String... args) throws Exception {
if (args[0].equals("stop")) { if (args[0].equals("stop")) {
handler.close(); handler.close();
} }
if (args[0].equals("eventAll")) if (args[0].equals("eventAll")) {
{
WebSocketFrameHandler.service.sendObjectAll(new PingEvent()); WebSocketFrameHandler.service.sendObjectAll(new PingEvent());
} }
} }

View file

@ -38,7 +38,7 @@ public static void registerCommands(ru.gravit.utils.command.CommandHandler handl
basic.registerCommand("loadModule", new LoadModuleCommand(server)); basic.registerCommand("loadModule", new LoadModuleCommand(server));
basic.registerCommand("modules", new ModulesCommand(server)); basic.registerCommand("modules", new ModulesCommand(server));
basic.registerCommand("test", new TestCommand(server)); basic.registerCommand("test", new TestCommand(server));
Category basicCategory = new Category(basic,"basic", "Base LaunchServer commands"); Category basicCategory = new Category(basic, "basic", "Base LaunchServer commands");
handler.registerCategory(basicCategory); handler.registerCategory(basicCategory);
// Register sync commands // Register sync commands
@ -50,7 +50,7 @@ public static void registerCommands(ru.gravit.utils.command.CommandHandler handl
updates.registerCommand("syncBinaries", new SyncBinariesCommand(server)); updates.registerCommand("syncBinaries", new SyncBinariesCommand(server));
updates.registerCommand("syncUpdates", new SyncUpdatesCommand(server)); updates.registerCommand("syncUpdates", new SyncUpdatesCommand(server));
updates.registerCommand("syncProfiles", new SyncProfilesCommand(server)); updates.registerCommand("syncProfiles", new SyncProfilesCommand(server));
Category updatesCategory = new Category(updates,"updates", "Update and Sync Management"); Category updatesCategory = new Category(updates, "updates", "Update and Sync Management");
handler.registerCategory(updatesCategory); handler.registerCategory(updatesCategory);
// Register auth commands // Register auth commands
@ -61,14 +61,14 @@ public static void registerCommands(ru.gravit.utils.command.CommandHandler handl
auth.registerCommand("ban", new BanCommand(server)); auth.registerCommand("ban", new BanCommand(server));
auth.registerCommand("unban", new UnbanCommand(server)); auth.registerCommand("unban", new UnbanCommand(server));
auth.registerCommand("getHWID", new GetHWIDCommand(server)); auth.registerCommand("getHWID", new GetHWIDCommand(server));
Category authCategory = new Category(auth,"auth", "User Management"); Category authCategory = new Category(auth, "auth", "User Management");
handler.registerCategory(authCategory); handler.registerCategory(authCategory);
//Register dump commands //Register dump commands
BaseCommandCategory dump = new BaseCommandCategory(); BaseCommandCategory dump = new BaseCommandCategory();
dump.registerCommand("dumpSessions", new DumpSessionsCommand(server)); dump.registerCommand("dumpSessions", new DumpSessionsCommand(server));
dump.registerCommand("dumpEntryCache", new DumpEntryCacheCommand(server)); dump.registerCommand("dumpEntryCache", new DumpEntryCacheCommand(server));
Category dumpCategory = new Category(dump,"dump", "Dump runtime data"); Category dumpCategory = new Category(dump, "dump", "Dump runtime data");
handler.registerCategory(dumpCategory); handler.registerCategory(dumpCategory);
//Register service commands //Register service commands
@ -86,7 +86,7 @@ public static void registerCommands(ru.gravit.utils.command.CommandHandler handl
service.registerCommand("component", new ComponentCommand(server)); service.registerCommand("component", new ComponentCommand(server));
service.registerCommand("givePermission", new GivePermissionsCommand(server)); service.registerCommand("givePermission", new GivePermissionsCommand(server));
service.registerCommand("getPermissions", new GetPermissionsCommand(server)); service.registerCommand("getPermissions", new GetPermissionsCommand(server));
Category serviceCategory = new Category(service,"service", "Managing LaunchServer Components"); Category serviceCategory = new Category(service, "service", "Managing LaunchServer Components");
handler.registerCategory(serviceCategory); handler.registerCategory(serviceCategory);
} }
} }

View file

@ -35,8 +35,7 @@ public void invoke(String... args) {
LogHelper.info("Uptime: %d days %d hours %d minutes %d seconds", days, hour, min, second); LogHelper.info("Uptime: %d days %d hours %d minutes %d seconds", days, hour, min, second);
LogHelper.info("Uptime (double): %f", (double) JVMHelper.RUNTIME_MXBEAN.getUptime() / 1000); LogHelper.info("Uptime (double): %f", (double) JVMHelper.RUNTIME_MXBEAN.getUptime() / 1000);
int commands = server.commandHandler.getBaseCategory().commandsMap().size(); int commands = server.commandHandler.getBaseCategory().commandsMap().size();
for(CommandHandler.Category category : server.commandHandler.getCategories()) for (CommandHandler.Category category : server.commandHandler.getCategories()) {
{
commands += category.category.commandsMap().size(); commands += category.category.commandsMap().size();
} }
LogHelper.info("Sessions: %d | Modules: %d | Commands: %d(%d categories)", server.sessionManager.getSessions().size(), server.modulesManager.modules.size(), commands, server.commandHandler.getCategories().size() + 1); LogHelper.info("Sessions: %d | Modules: %d | Commands: %d(%d categories)", server.sessionManager.getSessions().size(), server.modulesManager.modules.size(), commands, server.commandHandler.getCategories().size() + 1);

View file

@ -5,12 +5,12 @@
public class LaunchServerRuntimeConfig { public class LaunchServerRuntimeConfig {
public String clientToken; public String clientToken;
public void verify()
{ public void verify() {
if(clientToken == null) LogHelper.error("[RuntimeConfig] clientToken must not be null"); if (clientToken == null) LogHelper.error("[RuntimeConfig] clientToken must not be null");
} }
public void reset()
{ public void reset() {
clientToken = SecurityHelper.randomStringToken(); clientToken = SecurityHelper.randomStringToken();
} }
} }

View file

@ -82,7 +82,7 @@ protected final void debug(String message, Object... args) {
public abstract void reply() throws Exception; public abstract void reply() throws Exception;
protected static final void writeNoError(HOutput output) throws IOException { protected static void writeNoError(HOutput output) throws IOException {
output.writeString("", 0); output.writeString("", 0);
} }
} }

View file

@ -14,8 +14,8 @@ public void registerReconfigurable(String name, Reconfigurable reconfigurable) {
VerifyHelper.putIfAbsent(RECONFIGURABLE, name.toLowerCase(), Objects.requireNonNull(reconfigurable, "adapter"), VerifyHelper.putIfAbsent(RECONFIGURABLE, name.toLowerCase(), Objects.requireNonNull(reconfigurable, "adapter"),
String.format("Reloadable has been already registered: '%s'", name)); String.format("Reloadable has been already registered: '%s'", name));
} }
public Reconfigurable unregisterReconfigurable(String name)
{ public Reconfigurable unregisterReconfigurable(String name) {
return RECONFIGURABLE.remove(name); return RECONFIGURABLE.remove(name);
} }

View file

@ -14,8 +14,8 @@ public void registerReloadable(String name, Reloadable reloadable) {
VerifyHelper.putIfAbsent(RELOADABLES, name.toLowerCase(), Objects.requireNonNull(reloadable, "adapter"), VerifyHelper.putIfAbsent(RELOADABLES, name.toLowerCase(), Objects.requireNonNull(reloadable, "adapter"),
String.format("Reloadable has been already registered: '%s'", name.toLowerCase())); String.format("Reloadable has been already registered: '%s'", name.toLowerCase()));
} }
public Reloadable unregisterReloadable(String name)
{ public Reloadable unregisterReloadable(String name) {
return RELOADABLES.remove(name); return RELOADABLES.remove(name);
} }

View file

@ -44,15 +44,16 @@ public void initChannel(NioSocketChannel ch) {
//p.addLast(new LoggingHandler(LogLevel.INFO)); //p.addLast(new LoggingHandler(LogLevel.INFO));
pipeline.addLast(new HttpServerCodec()); pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new HttpObjectAggregator(65536)); pipeline.addLast(new HttpObjectAggregator(65536));
if (LaunchServer.server.config.netty.ipForwarding) pipeline.addLast(new NettyIpForwardHandler(context)); if (LaunchServer.server.config.netty.ipForwarding)
pipeline.addLast(new NettyIpForwardHandler(context));
pipeline.addLast(new WebSocketServerCompressionHandler()); pipeline.addLast(new WebSocketServerCompressionHandler());
pipeline.addLast(new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true)); pipeline.addLast(new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true));
if (LaunchServer.server.config.netty.fileServerEnabled) pipeline.addLast(new FileServerHandler(LaunchServer.server.updatesDir, true)); if (LaunchServer.server.config.netty.fileServerEnabled)
pipeline.addLast(new FileServerHandler(LaunchServer.server.updatesDir, true));
pipeline.addLast(new WebSocketFrameHandler(context)); pipeline.addLast(new WebSocketFrameHandler(context));
} }
}); });
if(config.proxy != null && config.proxy.enabled) if (config.proxy != null && config.proxy.enabled) {
{
LogHelper.info("Connect to main server %s"); LogHelper.info("Connect to main server %s");
Request.service = StandartClientWebSocketService.initWebSockets(config.proxy.address, false); Request.service = StandartClientWebSocketService.initWebSockets(config.proxy.address, false);
AuthRequest authRequest = new AuthRequest(config.proxy.login, config.proxy.password, config.proxy.auth_id, AuthRequest.ConnectTypes.PROXY); AuthRequest authRequest = new AuthRequest(config.proxy.login, config.proxy.password, config.proxy.auth_id, AuthRequest.ConnectTypes.PROXY);
@ -64,8 +65,8 @@ public void initChannel(NioSocketChannel ch) {
} }
} }
} }
public ChannelFuture bind(InetSocketAddress address)
{ public ChannelFuture bind(InetSocketAddress address) {
return serverBootstrap.bind(address); return serverBootstrap.bind(address);
} }

View file

@ -19,8 +19,7 @@ public NettyIpForwardHandler(NettyConnectContext context) {
@Override @Override
protected void decode(ChannelHandlerContext ctx, HttpRequest msg, List<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, HttpRequest msg, List<Object> out) throws Exception {
if(msg instanceof ReferenceCounted) if (msg instanceof ReferenceCounted) {
{
((ReferenceCounted) msg).retain(); ((ReferenceCounted) msg).retain();
} }
if (context.ip != null) { if (context.ip != null) {

View file

@ -105,8 +105,7 @@ public void run() {
//engine.setUseClientMode(false); //engine.setUseClientMode(false);
WebSocketFrameHandler.server = LaunchServer.server; WebSocketFrameHandler.server = LaunchServer.server;
nettyServer = new LauncherNettyServer(); nettyServer = new LauncherNettyServer();
for(LaunchServer.NettyBindAddress address : LaunchServer.server.config.netty.binds) for (LaunchServer.NettyBindAddress address : LaunchServer.server.config.netty.binds) {
{
nettyServer.bind(new InetSocketAddress(address.address, address.port)); nettyServer.bind(new InetSocketAddress(address.address, address.port));
} }
/* /*

View file

@ -28,8 +28,8 @@ public WebSocketFrameHandler(NettyConnectContext context) {
static { static {
service.registerResponses(); service.registerResponses();
} }
public void setClient(Client client)
{ public void setClient(Client client) {
this.client = client; this.client = client;
} }
@ -52,11 +52,9 @@ protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) {
frame.content().retain(); frame.content().retain();
ctx.channel().writeAndFlush(new PongWebSocketFrame(frame.content())); ctx.channel().writeAndFlush(new PongWebSocketFrame(frame.content()));
//return; //return;
} } else if ((frame instanceof PongWebSocketFrame)) {
else if ((frame instanceof PongWebSocketFrame)) {
LogHelper.dev("WebSocket Client received pong"); LogHelper.dev("WebSocket Client received pong");
} } else if ((frame instanceof CloseWebSocketFrame)) {
else if ((frame instanceof CloseWebSocketFrame)) {
ctx.channel().close(); ctx.channel().close();
} else { } else {
String message = "unsupported frame type: " + frame.getClass().getName(); String message = "unsupported frame type: " + frame.getClass().getName();

View file

@ -66,61 +66,51 @@ public WebSocketService(ChannelGroup channels, LaunchServer server, GsonBuilder
void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client client, String ip) { void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client client, String ip) {
String request = frame.text(); String request = frame.text();
JsonResponseInterface response = gson.fromJson(request, JsonResponseInterface.class); JsonResponseInterface response = gson.fromJson(request, JsonResponseInterface.class);
if(server.config.netty.proxy.enabled) if (server.config.netty.proxy.enabled) {
{ if (server.config.netty.proxy.requests.contains(response.getType())) {
if(server.config.netty.proxy.requests.contains(response.getType()))
{
UUID origRequestUUID = null; UUID origRequestUUID = null;
if(response instanceof SimpleResponse) if (response instanceof SimpleResponse) {
{
SimpleResponse simpleResponse = (SimpleResponse) response; SimpleResponse simpleResponse = (SimpleResponse) response;
simpleResponse.server = server; simpleResponse.server = server;
simpleResponse.service = this; simpleResponse.service = this;
simpleResponse.ctx = ctx; simpleResponse.ctx = ctx;
if(ip != null) simpleResponse.ip = ip; if (ip != null) simpleResponse.ip = ip;
else simpleResponse.ip = IOHelper.getIP(ctx.channel().remoteAddress()); else simpleResponse.ip = IOHelper.getIP(ctx.channel().remoteAddress());
origRequestUUID = simpleResponse.requestUUID; origRequestUUID = simpleResponse.requestUUID;
} }
LogHelper.debug("Proxy %s request", response.getType()); LogHelper.debug("Proxy %s request", response.getType());
if(client.session == 0) client.session = new Random().nextLong(); if (client.session == 0) client.session = new Random().nextLong();
ProxyRequest proxyRequest = new ProxyRequest(response, client.session); ProxyRequest proxyRequest = new ProxyRequest(response, client.session);
if(response instanceof SimpleResponse) if (response instanceof SimpleResponse) {
{
((SimpleResponse) response).requestUUID = proxyRequest.requestUUID; ((SimpleResponse) response).requestUUID = proxyRequest.requestUUID;
} }
proxyRequest.isCheckSign = client.checkSign; proxyRequest.isCheckSign = client.checkSign;
try { try {
ResultInterface result = proxyRequest.request(); ResultInterface result = proxyRequest.request();
if(result instanceof AuthRequestEvent) if (result instanceof AuthRequestEvent) {
{
LogHelper.debug("Client auth params get successful"); LogHelper.debug("Client auth params get successful");
AuthRequestEvent authRequestEvent = (AuthRequestEvent) result; AuthRequestEvent authRequestEvent = (AuthRequestEvent) result;
client.isAuth = true; client.isAuth = true;
client.session = authRequestEvent.session; client.session = authRequestEvent.session;
if(authRequestEvent.playerProfile != null) client.username = authRequestEvent.playerProfile.username; if (authRequestEvent.playerProfile != null)
client.username = authRequestEvent.playerProfile.username;
} }
if(result instanceof Request && response instanceof SimpleResponse) if (result instanceof Request && response instanceof SimpleResponse) {
{
((Request) result).requestUUID = origRequestUUID; ((Request) result).requestUUID = origRequestUUID;
} }
sendObject(ctx, result); sendObject(ctx, result);
} catch (RequestException e) } catch (RequestException e) {
{
sendObject(ctx, new ErrorRequestEvent(e.getMessage())); sendObject(ctx, new ErrorRequestEvent(e.getMessage()));
} catch (Exception e) { } catch (Exception e) {
LogHelper.error(e); LogHelper.error(e);
RequestEvent event; RequestEvent event;
if(server.config.netty.sendExceptionEnabled) if (server.config.netty.sendExceptionEnabled) {
{
event = new ExceptionEvent(e); event = new ExceptionEvent(e);
} } else {
else
{
event = new ErrorRequestEvent("Fatal server error. Contact administrator"); event = new ErrorRequestEvent("Fatal server error. Contact administrator");
} }
if(response instanceof SimpleResponse) if (response instanceof SimpleResponse) {
{
event.requestUUID = ((SimpleResponse) response).requestUUID; event.requestUUID = ((SimpleResponse) response).requestUUID;
} }
sendObject(ctx, event); sendObject(ctx, event);
@ -128,17 +118,16 @@ void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client client,
return; return;
} }
} }
process(ctx,response, client, ip); process(ctx, response, client, ip);
} }
void process(ChannelHandlerContext ctx, JsonResponseInterface response, Client client, String ip)
{ void process(ChannelHandlerContext ctx, JsonResponseInterface response, Client client, String ip) {
if(response instanceof SimpleResponse) if (response instanceof SimpleResponse) {
{
SimpleResponse simpleResponse = (SimpleResponse) response; SimpleResponse simpleResponse = (SimpleResponse) response;
simpleResponse.server = server; simpleResponse.server = server;
simpleResponse.service = this; simpleResponse.service = this;
simpleResponse.ctx = ctx; simpleResponse.ctx = ctx;
if(ip != null) simpleResponse.ip = ip; if (ip != null) simpleResponse.ip = ip;
else simpleResponse.ip = IOHelper.getIP(ctx.channel().remoteAddress()); else simpleResponse.ip = IOHelper.getIP(ctx.channel().remoteAddress());
} }
try { try {
@ -146,16 +135,12 @@ void process(ChannelHandlerContext ctx, JsonResponseInterface response, Client c
} catch (Exception e) { } catch (Exception e) {
LogHelper.error(e); LogHelper.error(e);
RequestEvent event; RequestEvent event;
if(server.config.netty.sendExceptionEnabled) if (server.config.netty.sendExceptionEnabled) {
{
event = new ExceptionEvent(e); event = new ExceptionEvent(e);
} } else {
else
{
event = new ErrorRequestEvent("Fatal server error. Contact administrator"); event = new ErrorRequestEvent("Fatal server error. Contact administrator");
} }
if(response instanceof SimpleResponse) if (response instanceof SimpleResponse) {
{
event.requestUUID = ((SimpleResponse) response).requestUUID; event.requestUUID = ((SimpleResponse) response).requestUUID;
} }
sendObject(ctx, event); sendObject(ctx, event);
@ -204,15 +189,13 @@ public void sendObject(ChannelHandlerContext ctx, Object obj, Type type) {
} }
public void sendObjectAll(Object obj) { public void sendObjectAll(Object obj) {
for(Channel ch : channels) for (Channel ch : channels) {
{
ch.writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, ResultInterface.class))); ch.writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, ResultInterface.class)));
} }
} }
public void sendObjectAll(Object obj, Type type) { public void sendObjectAll(Object obj, Type type) {
for(Channel ch : channels) for (Channel ch : channels) {
{
ch.writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, type))); ch.writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, type)));
} }
} }

View file

@ -15,18 +15,18 @@ public abstract class SimpleResponse implements JsonResponseInterface {
public transient WebSocketService service; public transient WebSocketService service;
public transient ChannelHandlerContext ctx; public transient ChannelHandlerContext ctx;
public transient String ip; public transient String ip;
public void sendResult(RequestEvent result)
{ public void sendResult(RequestEvent result) {
result.requestUUID = requestUUID; result.requestUUID = requestUUID;
service.sendObject(ctx, result); service.sendObject(ctx, result);
} }
public void sendResultAndClose(RequestEvent result)
{ public void sendResultAndClose(RequestEvent result) {
result.requestUUID = requestUUID; result.requestUUID = requestUUID;
service.sendObjectAndClose(ctx, result); service.sendObjectAndClose(ctx, result);
} }
public void sendError(String errorMessage)
{ public void sendError(String errorMessage) {
ErrorRequestEvent event = new ErrorRequestEvent(errorMessage); ErrorRequestEvent event = new ErrorRequestEvent(errorMessage);
event.requestUUID = requestUUID; event.requestUUID = requestUUID;
service.sendObject(ctx, event); service.sendObject(ctx, event);

View file

@ -9,9 +9,10 @@ public class ProxyCommandResponse extends SimpleResponse {
public JsonResponseInterface response; public JsonResponseInterface response;
public long session; public long session;
public boolean isCheckSign; public boolean isCheckSign;
@Override @Override
public void execute(ChannelHandlerContext ctx, Client client) throws Exception { public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
if(!client.proxy) { if (!client.proxy) {
sendError("Proxy server error"); sendError("Proxy server error");
return; return;
} }

View file

@ -61,7 +61,7 @@ public String getType() {
public void execute(ChannelHandlerContext ctx, Client clientData) throws Exception { public void execute(ChannelHandlerContext ctx, Client clientData) throws Exception {
try { try {
AuthRequestEvent result = new AuthRequestEvent(); AuthRequestEvent result = new AuthRequestEvent();
if ((authType == null || authType == ConnectTypes.CLIENT) && ( clientData == null || !clientData.checkSign )) { if ((authType == null || authType == ConnectTypes.CLIENT) && (clientData == null || !clientData.checkSign)) {
AuthProvider.authError("Don't skip Launcher Update"); AuthProvider.authError("Don't skip Launcher Update");
return; return;
} }
@ -113,21 +113,18 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
clientData.updateAuth(); clientData.updateAuth();
result.accessToken = aresult.accessToken; result.accessToken = aresult.accessToken;
result.permissions = clientData.permissions; result.permissions = clientData.permissions;
if(getSession) if (getSession) {
{ if (clientData.session == 0) {
if(clientData.session == 0) {
clientData.session = random.nextLong(); clientData.session = random.nextLong();
LaunchServer.server.sessionManager.addClient(clientData); LaunchServer.server.sessionManager.addClient(clientData);
} }
result.session = clientData.session; result.session = clientData.session;
} }
if(initProxy) if (initProxy) {
{ if (!clientData.permissions.canProxy) throw new AuthException("initProxy not allow");
if(!clientData.permissions.canProxy) throw new AuthException("initProxy not allow");
clientData.proxy = true; clientData.proxy = true;
} }
if(LaunchServer.server.config.protectHandler.allowGetAccessToken(context)) if (LaunchServer.server.config.protectHandler.allowGetAccessToken(context)) {
{
UUID uuid = pair.handler.auth(aresult); UUID uuid = pair.handler.auth(aresult);
result.playerProfile = ProfileByUUIDResponse.getProfile(LaunchServer.server, uuid, aresult.username, client, clientData.auth.textureProvider); result.playerProfile = ProfileByUUIDResponse.getProfile(LaunchServer.server, uuid, aresult.username, client, clientData.auth.textureProvider);
LogHelper.debug("Auth: %s accessToken %s uuid: %s", login, result.accessToken, uuid.toString()); LogHelper.debug("Auth: %s accessToken %s uuid: %s", login, result.accessToken, uuid.toString());
@ -137,6 +134,7 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
sendError(e.getMessage()); sendError(e.getMessage());
} }
} }
public static class AuthContext { public static class AuthContext {
public AuthContext(long session, String login, int password_lenght, String customText, String client, String hwid, String ip, boolean isServerAuth) { public AuthContext(long session, String login, int password_lenght, String customText, String client, String hwid, String ip, boolean isServerAuth) {
this.session = session; this.session = session;

View file

@ -19,8 +19,7 @@ public String getType() {
@Override @Override
public void execute(ChannelHandlerContext ctx, Client client) { public void execute(ChannelHandlerContext ctx, Client client) {
List<GetAvailabilityAuthRequestEvent.AuthAvailability> list = new ArrayList<>(); List<GetAvailabilityAuthRequestEvent.AuthAvailability> list = new ArrayList<>();
for(AuthProviderPair pair : LaunchServer.server.config.auth) for (AuthProviderPair pair : LaunchServer.server.config.auth) {
{
list.add(new GetAvailabilityAuthRequestEvent.AuthAvailability(pair.name, pair.displayName)); list.add(new GetAvailabilityAuthRequestEvent.AuthAvailability(pair.name, pair.displayName));
} }
sendResult(new GetAvailabilityAuthRequestEvent(list)); sendResult(new GetAvailabilityAuthRequestEvent(list));

View file

@ -18,17 +18,16 @@ public class JoinServerResponse extends SimpleResponse {
public String getType() { public String getType() {
return "joinServer"; return "joinServer";
} }
@Override @Override
public void execute(ChannelHandlerContext ctx, Client client) { public void execute(ChannelHandlerContext ctx, Client client) {
boolean success; boolean success;
try { try {
server.authHookManager.joinServerHook.hook(this, client); server.authHookManager.joinServerHook.hook(this, client);
if(client.auth == null) if (client.auth == null) {
{
LogHelper.warning("Client auth is null. Using default."); LogHelper.warning("Client auth is null. Using default.");
success = LaunchServer.server.config.getAuthProviderPair().handler.joinServer(username, accessToken, serverID); success = LaunchServer.server.config.getAuthProviderPair().handler.joinServer(username, accessToken, serverID);
} } else success = client.auth.handler.joinServer(username, accessToken, serverID);
else success = client.auth.handler.joinServer(username, accessToken, serverID);
LogHelper.debug("joinServer: %s accessToken: %s serverID: %s", username, accessToken, serverID); LogHelper.debug("joinServer: %s accessToken: %s serverID: %s", username, accessToken, serverID);
} catch (AuthException | HookException e) { } catch (AuthException | HookException e) {
sendError(e.getMessage()); sendError(e.getMessage());

View file

@ -11,6 +11,7 @@
public class RestoreSessionResponse extends SimpleResponse { public class RestoreSessionResponse extends SimpleResponse {
@LauncherNetworkAPI @LauncherNetworkAPI
public long session; public long session;
@Override @Override
public String getType() { public String getType() {
return "restoreSession"; return "restoreSession";
@ -19,8 +20,7 @@ public String getType() {
@Override @Override
public void execute(ChannelHandlerContext ctx, Client client) { public void execute(ChannelHandlerContext ctx, Client client) {
Client rClient = LaunchServer.server.sessionManager.getClient(session); Client rClient = LaunchServer.server.sessionManager.getClient(session);
if(rClient == null) if (rClient == null) {
{
sendError("Session invalid"); sendError("Session invalid");
} }
WebSocketFrameHandler frameHandler = ctx.pipeline().get(WebSocketFrameHandler.class); WebSocketFrameHandler frameHandler = ctx.pipeline().get(WebSocketFrameHandler.class);

View file

@ -26,8 +26,7 @@ public void execute(ChannelHandlerContext ctx, Client client) {
} }
try { try {
server.authHookManager.setProfileHook.hook(this, client); server.authHookManager.setProfileHook.hook(this, client);
} catch (HookException e) } catch (HookException e) {
{
sendError(e.getMessage()); sendError(e.getMessage());
} }
Collection<ClientProfile> profiles = LaunchServer.server.getProfiles(); Collection<ClientProfile> profiles = LaunchServer.server.getProfiles();

View file

@ -29,12 +29,10 @@ public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
result.playerProfiles = new PlayerProfile[list.length]; result.playerProfiles = new PlayerProfile[list.length];
for (int i = 0; i < list.length; ++i) { for (int i = 0; i < list.length; ++i) {
UUID uuid; UUID uuid;
if(client.auth == null) if (client.auth == null) {
{
LogHelper.warning("Client auth is null. Using default."); LogHelper.warning("Client auth is null. Using default.");
uuid = LaunchServer.server.config.getAuthProviderPair().handler.usernameToUUID(list[i].username); uuid = LaunchServer.server.config.getAuthProviderPair().handler.usernameToUUID(list[i].username);
} } else uuid = client.auth.handler.usernameToUUID(list[i].username);
else uuid = client.auth.handler.usernameToUUID(list[i].username);
result.playerProfiles[i] = ProfileByUUIDResponse.getProfile(LaunchServer.server, uuid, list[i].username, list[i].client, client.auth.textureProvider); result.playerProfiles[i] = ProfileByUUIDResponse.getProfile(LaunchServer.server, uuid, list[i].username, list[i].client, client.auth.textureProvider);
} }
sendResult(result); sendResult(result);

View file

@ -48,12 +48,10 @@ public String getType() {
@Override @Override
public void execute(ChannelHandlerContext ctx, Client client) throws Exception { public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
String username; String username;
if(client.auth == null) if (client.auth == null) {
{
LogHelper.warning("Client auth is null. Using default."); LogHelper.warning("Client auth is null. Using default.");
username = LaunchServer.server.config.getAuthProviderPair().handler.uuidToUsername(uuid); username = LaunchServer.server.config.getAuthProviderPair().handler.uuidToUsername(uuid);
} } else username = client.auth.handler.uuidToUsername(uuid);
else username = client.auth.handler.uuidToUsername(uuid);
sendResult(new ProfileByUUIDRequestEvent(getProfile(LaunchServer.server, uuid, username, this.client, client.auth.textureProvider))); sendResult(new ProfileByUUIDRequestEvent(getProfile(LaunchServer.server, uuid, username, this.client, client.auth.textureProvider)));
} }
} }

View file

@ -23,12 +23,10 @@ public String getType() {
@Override @Override
public void execute(ChannelHandlerContext ctx, Client client) throws Exception { public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
UUID uuid; UUID uuid;
if(client.auth == null) if (client.auth == null) {
{
LogHelper.warning("Client auth is null. Using default."); LogHelper.warning("Client auth is null. Using default.");
uuid = LaunchServer.server.config.getAuthProviderPair().handler.usernameToUUID(username); uuid = LaunchServer.server.config.getAuthProviderPair().handler.usernameToUUID(username);
} } else uuid = client.auth.handler.usernameToUUID(username);
else uuid = client.auth.handler.usernameToUUID(username);
sendResult(new ProfileByUsernameRequestEvent(getProfile(LaunchServer.server, uuid, username, this.client, client.auth.textureProvider))); sendResult(new ProfileByUsernameRequestEvent(getProfile(LaunchServer.server, uuid, username, this.client, client.auth.textureProvider)));
} }
} }

View file

@ -17,7 +17,7 @@ public String getType() {
@Override @Override
public void execute(ChannelHandlerContext ctx, Client client) { public void execute(ChannelHandlerContext ctx, Client client) {
boolean success = LaunchServer.server.config.protectHandler.verifyClientSecureToken(secureToken, client.verifyToken); boolean success = LaunchServer.server.config.protectHandler.verifyClientSecureToken(secureToken, client.verifyToken);
if(success) client.isSecure = true; if (success) client.isSecure = true;
sendResult(new VerifySecureTokenRequestEvent(success)); sendResult(new VerifySecureTokenRequestEvent(success));
} }
} }

View file

@ -34,13 +34,18 @@ public void execute(ChannelHandlerContext ctx, Client client) {
} }
} }
SignedObjectHolder<HashedDir> dir = LaunchServer.server.updatesDirMap.get(dirName); SignedObjectHolder<HashedDir> dir = LaunchServer.server.updatesDirMap.get(dirName);
if(dir == null) if (dir == null) {
{
service.sendObject(ctx, new ErrorRequestEvent(String.format("Directory %s not found", dirName))); service.sendObject(ctx, new ErrorRequestEvent(String.format("Directory %s not found", dirName)));
return; return;
} }
String url = LaunchServer.server.config.netty.downloadURL.replace("%dirname%",dirName); String url = LaunchServer.server.config.netty.downloadURL.replace("%dirname%", dirName);
if(server.config.netty.bindings.get(dirName) != null) url = server.config.netty.bindings.get(dirName); boolean zip = false;
service.sendObject(ctx, new UpdateRequestEvent(dir.object, url)); if (server.config.netty.bindings.get(dirName) != null)
{
LaunchServer.NettyUpdatesBind bind = server.config.netty.bindings.get(dirName);
url = bind.url;
zip = bind.zip;
}
service.sendObject(ctx, new UpdateRequestEvent(dir.object, url, zip));
} }
} }

View file

@ -20,7 +20,7 @@ public static void main(String[] args) throws IOException {
LogHelper.warning("Permission canAdmin not found"); LogHelper.warning("Permission canAdmin not found");
} }
try { try {
Class.forName("jline.Terminal"); Class.forName("org.jline.terminal.Terminal");
// JLine2 available // JLine2 available
commandHandler = new JLineCommandHandler(); commandHandler = new JLineCommandHandler();
@ -33,8 +33,8 @@ public static void main(String[] args) throws IOException {
LogHelper.info("CommandHandler started. Use 'exit' to exit this console"); LogHelper.info("CommandHandler started. Use 'exit' to exit this console");
commandHandler.run(); commandHandler.run();
} }
public static void registerCommands()
{ public static void registerCommands() {
commandHandler.registerCommand("help", new HelpCommand(commandHandler)); commandHandler.registerCommand("help", new HelpCommand(commandHandler));
commandHandler.registerCommand("exit", new ExitCommand()); commandHandler.registerCommand("exit", new ExitCommand());
commandHandler.registerCommand("logListener", new LogListenerCommand()); commandHandler.registerCommand("logListener", new LogListenerCommand());

View file

@ -19,6 +19,6 @@ public String getUsageDescription() {
@Override @Override
public void invoke(String... args) throws Exception { public void invoke(String... args) throws Exception {
ExecCommandRequestEvent request = new ExecCommandRequest(String.join(" ")).request(); ExecCommandRequestEvent request = new ExecCommandRequest(String.join(" ")).request();
if(!request.success) LogHelper.error("Error executing command"); if (!request.success) LogHelper.error("Error executing command");
} }
} }

View file

@ -8,8 +8,7 @@
import ru.gravit.utils.helper.LogHelper; import ru.gravit.utils.helper.LogHelper;
public class LogListenerCommand extends Command { public class LogListenerCommand extends Command {
public class LogListenerRequest implements RequestInterface public class LogListenerRequest implements RequestInterface {
{
@LauncherNetworkAPI @LauncherNetworkAPI
public LogHelper.OutputTypes outputType; public LogHelper.OutputTypes outputType;
@ -22,6 +21,7 @@ public String getType() {
return "addLogListener"; return "addLogListener";
} }
} }
@Override @Override
public String getArgsDescription() { public String getArgsDescription() {
return null; return null;
@ -38,8 +38,7 @@ public void invoke(String... args) throws Exception {
Request.service.sendObject(new LogListenerRequest(LogHelper.JANSI ? LogHelper.OutputTypes.JANSI : LogHelper.OutputTypes.PLAIN)); Request.service.sendObject(new LogListenerRequest(LogHelper.JANSI ? LogHelper.OutputTypes.JANSI : LogHelper.OutputTypes.PLAIN));
LogHelper.info("Add log handler"); LogHelper.info("Add log handler");
Request.service.registerHandler((result) -> { Request.service.registerHandler((result) -> {
if(result instanceof LogEvent) if (result instanceof LogEvent) {
{
System.out.println(((LogEvent) result).string); System.out.println(((LogEvent) result).string);
} }
}); });

View file

@ -45,7 +45,6 @@ function initLoginScene() {
var loginLayout = loginPane.lookup("#layout"); var loginLayout = loginPane.lookup("#layout");
loginPaneLayout = loginLayout; loginPaneLayout = loginLayout;
loginField = pane.lookup("#login"); loginField = pane.lookup("#login");
loginField.setOnMouseMoved(function(event){rootPane.fireEvent(event)}); loginField.setOnMouseMoved(function(event){rootPane.fireEvent(event)});
loginField.setOnAction(goAuth); loginField.setOnAction(goAuth);
@ -419,7 +418,6 @@ var overlay = {
dimPane.setVisible(true); dimPane.setVisible(true);
dimPane.toFront(); dimPane.toFront();
loginPaneLayout.setEffect(new javafx.scene.effect.GaussianBlur(10)); loginPaneLayout.setEffect(new javafx.scene.effect.GaussianBlur(10));
serverPaneLayout.setEffect(new javafx.scene.effect.GaussianBlur(10)); serverPaneLayout.setEffect(new javafx.scene.effect.GaussianBlur(10));
fade(dimPane, 0.0, 0.0, 1.0, function(event) { fade(dimPane, 0.0, 0.0, 1.0, function(event) {
@ -441,7 +439,6 @@ var overlay = {
authPane.setDisable(false); authPane.setDisable(false);
rootPane.requestFocus(); rootPane.requestFocus();
loginPaneLayout.setEffect(new javafx.scene.effect.GaussianBlur(0)); loginPaneLayout.setEffect(new javafx.scene.effect.GaussianBlur(0));
serverPaneLayout.setEffect(new javafx.scene.effect.GaussianBlur(0)); serverPaneLayout.setEffect(new javafx.scene.effect.GaussianBlur(0));
overlay.current = null; overlay.current = null;

View file

@ -1,15 +1,16 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8"/>
<title>Offline-режим</title> <title>Offline-режим</title>
</head> </head>
<body style="color:red"> <body style="color:red">
<h2>Offline-режим</h2> <h2>Offline-режим</h2>
Лаунчер запущен в Offline-режиме. В этом режиме Вы можете запустить любой ранее загруженный клиент Лаунчер запущен в Offline-режиме. В этом режиме Вы можете запустить любой ранее загруженный клиент
с любым именем пользователя, при этом вход на серверы с авторизацией, а так же система скинов и плащей <b>может не работать</b>. с любым именем пользователя, при этом вход на серверы с авторизацией, а так же система скинов и плащей <b>может не
Скорее всего, проблема вызвана сбоем на сервере или неполадками в интернет-подключении. работать</b>.
Проверьте состояние интернет-подключения или обратитесь к администратору сервера. Скорее всего, проблема вызвана сбоем на сервере или неполадками в интернет-подключении.
</body> Проверьте состояние интернет-подключения или обратитесь к администратору сервера.
</body>
</html> </html>

View file

@ -8,17 +8,20 @@
<!-- DrLeonardo Design --> <!-- DrLeonardo Design -->
<Pane fx:id="overlay" prefHeight="450.0" prefWidth="693.0" xmlns="http://javafx.com/javafx/8.0.201" xmlns:fx="http://javafx.com/fxml/1"> <Pane fx:id="overlay" prefHeight="450.0" prefWidth="693.0" xmlns="http://javafx.com/javafx/8.0.201"
xmlns:fx="http://javafx.com/fxml/1">
<stylesheets> <stylesheets>
<URL value="@debug.css" /> <URL value="@debug.css"/>
<URL value="@../../styles.css" /> <URL value="@../../styles.css"/>
</stylesheets> </stylesheets>
<!-- Debug controls --> <!-- Debug controls -->
<JFXTextArea fx:id="output" focusColor="#5fd97a" prefHeight="450.0" prefWidth="693.0"> <JFXTextArea fx:id="output" focusColor="#5fd97a" prefHeight="450.0" prefWidth="693.0">
<padding> <padding>
<Insets left="10.0" right="10.0" /> <Insets left="10.0" right="10.0"/>
</padding></JFXTextArea> </padding>
<JFXButton fx:id="copy" defaultButton="true" layoutX="373.0" layoutY="415.0" prefHeight="30.0" prefWidth="100.0" text="Копировать" /> </JFXTextArea>
<JFXButton fx:id="action" layoutX="533.0" layoutY="415.0" prefHeight="25.0" prefWidth="150.0" text="Убить" /> <JFXButton fx:id="copy" defaultButton="true" layoutX="373.0" layoutY="415.0" prefHeight="30.0" prefWidth="100.0"
text="Копировать"/>
<JFXButton fx:id="action" layoutX="533.0" layoutY="415.0" prefHeight="25.0" prefWidth="150.0" text="Убить"/>
</Pane> </Pane>

View file

@ -7,13 +7,15 @@
<!-- DrLeonardo Design | Fixes by Yaroslavik --> <!-- DrLeonardo Design | Fixes by Yaroslavik -->
<Pane fx:id="overlay" prefHeight="450.0" prefWidth="692.0" xmlns="http://javafx.com/javafx/8.0.201" xmlns:fx="http://javafx.com/fxml/1"> <Pane fx:id="overlay" prefHeight="450.0" prefWidth="692.0" xmlns="http://javafx.com/javafx/8.0.201"
xmlns:fx="http://javafx.com/fxml/1">
<children> <children>
<!-- Description --> <!-- Description -->
<Label fx:id="description" alignment="CENTER" contentDisplay="CENTER" layoutX="205.0" layoutY="328.0" prefHeight="87.0" prefWidth="283.0" text="..." textAlignment="CENTER" /> <Label fx:id="description" alignment="CENTER" contentDisplay="CENTER" layoutX="205.0" layoutY="328.0"
<JFXSpinner fx:id="spinner" layoutX="291.0" layoutY="165.0" prefHeight="120.0" prefWidth="110.0" /> prefHeight="87.0" prefWidth="283.0" text="..." textAlignment="CENTER"/>
<JFXSpinner fx:id="spinner" layoutX="291.0" layoutY="165.0" prefHeight="120.0" prefWidth="110.0"/>
</children> </children>
<stylesheets> <stylesheets>
<URL value="@processing.css" /> <URL value="@processing.css"/>
</stylesheets> </stylesheets>
</Pane> </Pane>

View file

@ -13,42 +13,60 @@
<!-- DrLeonardo Design --> <!-- DrLeonardo Design -->
<Pane fx:id="overlay" prefHeight="450.0" prefWidth="693.0" xmlns="http://javafx.com/javafx/8.0.201" xmlns:fx="http://javafx.com/fxml/1"> <Pane fx:id="overlay" prefHeight="450.0" prefWidth="693.0" xmlns="http://javafx.com/javafx/8.0.201"
xmlns:fx="http://javafx.com/fxml/1">
<children> <children>
<Pane id="holder" prefHeight="450.0" prefWidth="694.0"> <Pane id="holder" prefHeight="450.0" prefWidth="694.0">
<children> <children>
<JFXCheckBox fx:id="autoEnter" checkedColor="#5fd97a" layoutX="14.0" layoutY="137.0" text="Автовход на сервер" unCheckedColor="#909090" /> <JFXCheckBox fx:id="autoEnter" checkedColor="#5fd97a" layoutX="14.0" layoutY="137.0"
<Text fill="#8c8c8c" layoutX="40.0" layoutY="153.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Включение авто-входа означает что вы сразу после загрузки клиента попадете на сервер" wrappingWidth="636.9999872148037" y="15.0" /> text="Автовход на сервер" unCheckedColor="#909090"/>
<JFXCheckBox fx:id="fullScreen" checkedColor="#5fd97a" layoutX="13.0" layoutY="260.0" text="Клиент в полный экран" unCheckedColor="#909090" /> <Text fill="#8c8c8c" layoutX="40.0" layoutY="153.0" strokeType="OUTSIDE" strokeWidth="0.0"
<Text fill="#8c8c8c" layoutX="40.0" layoutY="277.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Включение данной функции позволяет запустить игру сразу в полноэкранном режиме" wrappingWidth="636.9999872148037" y="15.0" /> text="Включение авто-входа означает что вы сразу после загрузки клиента попадете на сервер"
<JFXCheckBox id="debug" checkedColor="#5fd97a" layoutX="13.0" layoutY="193.0" text="Режим Отладки" unCheckedColor="#909090" /> wrappingWidth="636.9999872148037" y="15.0"/>
<Text fill="#8c8c8c" layoutX="40.0" layoutY="208.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Режим отладки позволяет просмотреть лог запуска и работы программы в реальном времени прямо из лаунчера, что упрощает поиск нужной информации" wrappingWidth="637.0000016447157" y="15.0" /> <JFXCheckBox fx:id="fullScreen" checkedColor="#5fd97a" layoutX="13.0" layoutY="260.0"
text="Клиент в полный экран" unCheckedColor="#909090"/>
<Text fill="#8c8c8c" layoutX="40.0" layoutY="277.0" strokeType="OUTSIDE" strokeWidth="0.0"
text="Включение данной функции позволяет запустить игру сразу в полноэкранном режиме"
wrappingWidth="636.9999872148037" y="15.0"/>
<JFXCheckBox id="debug" checkedColor="#5fd97a" layoutX="13.0" layoutY="193.0" text="Режим Отладки"
unCheckedColor="#909090"/>
<Text fill="#8c8c8c" layoutX="40.0" layoutY="208.0" strokeType="OUTSIDE" strokeWidth="0.0"
text="Режим отладки позволяет просмотреть лог запуска и работы программы в реальном времени прямо из лаунчера, что упрощает поиск нужной информации"
wrappingWidth="637.0000016447157" y="15.0"/>
<TextFlow layoutX="126.0" layoutY="15.0" prefHeight="16.0" prefWidth="112.0"> <TextFlow layoutX="126.0" layoutY="15.0" prefHeight="16.0" prefWidth="112.0">
<Text fx:id="ramLabel" /> <Text fx:id="ramLabel"/>
</TextFlow> </TextFlow>
<JFXButton fx:id="deleteDir" layoutX="370.0" layoutY="380.0" prefHeight="25.0" prefWidth="245.0" text="Удалить клиенты" textAlignment="CENTER" wrapText="true" /> <JFXButton fx:id="deleteDir" layoutX="370.0" layoutY="380.0" prefHeight="25.0" prefWidth="245.0"
<JFXButton fx:id="changeDir" layoutY="419.0" prefHeight="30.0" prefWidth="200.0" text="Сменить директорию загрузки" textAlignment="CENTER" wrapText="true" /> text="Удалить клиенты" textAlignment="CENTER" wrapText="true"/>
<Hyperlink id="dirLabel" alignment="BASELINE_LEFT" layoutX="201.0" layoutY="420.0" prefHeight="30.0" prefWidth="493.0" text="C:/Users" /> <JFXButton fx:id="changeDir" layoutY="419.0" prefHeight="30.0" prefWidth="200.0"
<JFXButton fx:id="apply" defaultButton="true" layoutX="530.0" layoutY="380.0" prefHeight="23.0" prefWidth="100.0" text="Применить" /> text="Сменить директорию загрузки" textAlignment="CENTER" wrapText="true"/>
<Text layoutX="16.0" layoutY="28.0">Выделение памяти: </Text> <Hyperlink id="dirLabel" alignment="BASELINE_LEFT" layoutX="201.0" layoutY="420.0" prefHeight="30.0"
<JFXSlider fx:id="ramSlider" layoutX="14.0" layoutY="76.0" prefHeight="14.0" prefWidth="663.0" /> prefWidth="493.0" text="C:/Users"/>
<JFXButton fx:id="apply" defaultButton="true" layoutX="530.0" layoutY="380.0" prefHeight="23.0"
prefWidth="100.0" text="Применить"/>
<Text layoutX="16.0" layoutY="28.0">Выделение памяти:</Text>
<JFXSlider fx:id="ramSlider" layoutX="14.0" layoutY="76.0" prefHeight="14.0" prefWidth="663.0"/>
<Pane fx:id="transferDialog" prefHeight="425.0" prefWidth="694.0" visible="false"> <Pane fx:id="transferDialog" prefHeight="425.0" prefWidth="694.0" visible="false">
<children> <children>
<Text fill="WHITE" layoutX="147.0" layoutY="198.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Перенести все данные в новую директорию?" wrappingWidth="400.13671875"> <Text fill="WHITE" layoutX="147.0" layoutY="198.0" strokeType="OUTSIDE" strokeWidth="0.0"
text="Перенести все данные в новую директорию?" wrappingWidth="400.13671875">
<font> <font>
<Font size="19.0" /> <Font size="19.0"/>
</font> </font>
</Text> </Text>
<JFXButton fx:id="applyTransfer" layoutX="165.0" layoutY="226.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="124.0" text="Да, перенести!" /> <JFXButton fx:id="applyTransfer" layoutX="165.0" layoutY="226.0" mnemonicParsing="false"
<JFXButton fx:id="cancelTransfer" layoutX="379.0" layoutY="226.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="124.0" text="Нет, не нужно." /> prefHeight="25.0" prefWidth="124.0" text="Да, перенести!"/>
<JFXButton fx:id="cancelTransfer" layoutX="379.0" layoutY="226.0" mnemonicParsing="false"
prefHeight="25.0" prefWidth="124.0" text="Нет, не нужно."/>
</children> </children>
</Pane> </Pane>
<Line endX="594.0" layoutX="100.0" layoutY="420.0" startX="-100.0" stroke="#5b3636" styleClass="lineHead" /> <Line endX="594.0" layoutX="100.0" layoutY="420.0" startX="-100.0" stroke="#5b3636"
styleClass="lineHead"/>
</children> </children>
</Pane> </Pane>
</children> </children>
<stylesheets> <stylesheets>
<URL value="@settings.css" /> <URL value="@settings.css"/>
<URL value="@../../styles.css" /> <URL value="@../../styles.css"/>
</stylesheets> </stylesheets>
</Pane> </Pane>

View file

@ -15,36 +15,40 @@
<children> <children>
<Pane fx:id="bar" layoutX="692.0" prefHeight="425.0" prefWidth="43.0" styleClass="bar"> <Pane fx:id="bar" layoutX="692.0" prefHeight="425.0" prefWidth="43.0" styleClass="bar">
<children> <children>
<JFXButton id="hide" alignment="CENTER" contentDisplay="CENTER" layoutY="45.0" ripplerFill="#646464" text="" textAlignment="CENTER"> <JFXButton id="hide" alignment="CENTER" contentDisplay="CENTER" layoutY="45.0" ripplerFill="#646464"
text="" textAlignment="CENTER">
<graphic> <graphic>
<MaterialDesignIconView fill="WHITE" glyphName="MINUS" size="30" textAlignment="CENTER" /> <MaterialDesignIconView fill="WHITE" glyphName="MINUS" size="30" textAlignment="CENTER"/>
</graphic> </graphic>
</JFXButton> </JFXButton>
<JFXButton id="close" alignment="CENTER" contentDisplay="CENTER" ripplerFill="#fb8c8c" text="" textAlignment="CENTER"> <JFXButton id="close" alignment="CENTER" contentDisplay="CENTER" ripplerFill="#fb8c8c" text=""
textAlignment="CENTER">
<graphic> <graphic>
<MaterialDesignIconView fill="WHITE" glyphName="CLOSE" size="30" textAlignment="CENTER" /> <MaterialDesignIconView fill="WHITE" glyphName="CLOSE" size="30" textAlignment="CENTER"/>
</graphic> </graphic>
</JFXButton> </JFXButton>
</children> </children>
</Pane> </Pane>
<JFXTextArea fx:id="output" focusColor="#d8d8d8" prefHeight="419.0" prefWidth="692.0" unFocusColor="#ffffff00"> <JFXTextArea fx:id="output" focusColor="#d8d8d8" prefHeight="419.0" prefWidth="692.0" unFocusColor="#ffffff00">
<padding> <padding>
<Insets left="10.0" top="10.0" /> <Insets left="10.0" top="10.0"/>
</padding> </padding>
</JFXTextArea> </JFXTextArea>
<JFXTextField fx:id="textField" focusColor="#909090" layoutY="420.0" prefHeight="30.0" prefWidth="543.0" promptText="Введите команду..." unFocusColor="#ffffff00"> <JFXTextField fx:id="textField" focusColor="#909090" layoutY="420.0" prefHeight="30.0" prefWidth="543.0"
promptText="Введите команду..." unFocusColor="#ffffff00">
<opaqueInsets> <opaqueInsets>
<Insets /> <Insets/>
</opaqueInsets> </opaqueInsets>
<padding> <padding>
<Insets left="10.0" /> <Insets left="10.0"/>
</padding> </padding>
</JFXTextField> </JFXTextField>
<JFXButton fx:id="send" defaultButton="true" layoutX="542.0" layoutY="420.0" prefHeight="30.0" prefWidth="147.0" ripplerFill="WHITE" text="Выполнить" /> <JFXButton fx:id="send" defaultButton="true" layoutX="542.0" layoutY="420.0" prefHeight="30.0" prefWidth="147.0"
<Line endX="594.0" layoutX="98.0" layoutY="420.0" startX="-100.0" stroke="#5b3636" styleClass="lineHead" /> ripplerFill="WHITE" text="Выполнить"/>
<Line endX="594.0" layoutX="98.0" layoutY="420.0" startX="-100.0" stroke="#5b3636" styleClass="lineHead"/>
</children> </children>
<stylesheets> <stylesheets>
<URL value="@../../styles.css" /> <URL value="@../../styles.css"/>
<URL value="@../../overlay/debug/debug.css" /> <URL value="@../../overlay/debug/debug.css"/>
</stylesheets> </stylesheets>
</Pane> </Pane>

View file

@ -3,6 +3,7 @@ Button, CheckBox, ComboBox, RadioButton {
-fx-cursor: hand; -fx-cursor: hand;
} }
/* Backgrounds */ /* Backgrounds */
#layout { #layout {
-fx-background-color: transparent; -fx-background-color: transparent;

View file

@ -27,27 +27,22 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep
EnvHelper.checkDangerousParams(); EnvHelper.checkDangerousParams();
LauncherConfig config = Launcher.getConfig(); LauncherConfig config = Launcher.getConfig();
LogHelper.info("Launcher for project %s", config.projectname); LogHelper.info("Launcher for project %s", config.projectname);
if(config.environment.equals(LauncherConfig.LauncherEnvironment.PROD)) if (config.environment.equals(LauncherConfig.LauncherEnvironment.PROD)) {
{ if (System.getProperty(LogHelper.DEBUG_PROPERTY) != null) {
if(System.getProperty(LogHelper.DEBUG_PROPERTY) != null)
{
LogHelper.warning("Found -Dlauncher.debug=true"); LogHelper.warning("Found -Dlauncher.debug=true");
} }
if(System.getProperty(LogHelper.STACKTRACE_PROPERTY) != null) if (System.getProperty(LogHelper.STACKTRACE_PROPERTY) != null) {
{
LogHelper.warning("Found -Dlauncher.stacktrace=true"); LogHelper.warning("Found -Dlauncher.stacktrace=true");
} }
LogHelper.info("Debug mode disabled (found env PRODUCTION)"); LogHelper.info("Debug mode disabled (found env PRODUCTION)");
} } else {
else
{
LogHelper.info("If need debug output use -Dlauncher.debug=true"); LogHelper.info("If need debug output use -Dlauncher.debug=true");
LogHelper.info("If need stacktrace output use -Dlauncher.stacktrace=true"); LogHelper.info("If need stacktrace output use -Dlauncher.stacktrace=true");
if(LogHelper.isDebugEnabled()) waitProcess = true; if (LogHelper.isDebugEnabled()) waitProcess = true;
} }
LogHelper.info("Restart Launcher with JavaAgent..."); LogHelper.info("Restart Launcher with JavaAgent...");
ProcessBuilder processBuilder = new ProcessBuilder(); ProcessBuilder processBuilder = new ProcessBuilder();
if(waitProcess) processBuilder.inheritIO(); if (waitProcess) processBuilder.inheritIO();
Path javaBin = IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home"))); Path javaBin = IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home")));
List<String> args = new LinkedList<>(); List<String> args = new LinkedList<>();
args.add(javaBin.toString()); args.add(javaBin.toString());

View file

@ -7,7 +7,6 @@
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.InsnNode; import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
import ru.gravit.launcher.utils.NativeJVMHalt; import ru.gravit.launcher.utils.NativeJVMHalt;
import ru.gravit.utils.helper.LogHelper; import ru.gravit.utils.helper.LogHelper;
@ -20,7 +19,8 @@
import java.util.List; import java.util.List;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import static org.objectweb.asm.Opcodes.*; import static org.objectweb.asm.Opcodes.ACONST_NULL;
import static org.objectweb.asm.Opcodes.ARETURN;
@LauncherAPI @LauncherAPI
public final class LauncherAgent { public final class LauncherAgent {
@ -69,28 +69,28 @@ public static boolean isStarted() {
private static void replaceClasses(boolean pb, boolean rt) { private static void replaceClasses(boolean pb, boolean rt) {
java.awt.Robot.class.getName(); java.awt.Robot.class.getName();
List<java.lang.instrument.ClassDefinition> defs = new ArrayList<>(); List<java.lang.instrument.ClassDefinition> defs = new ArrayList<>();
if(rt) { if (rt) {
try { try {
defs.add(new java.lang.instrument.ClassDefinition(java.lang.Runtime.class, transformClass(java.lang.Runtime.class.getName(), getClassFile(java.lang.Runtime.class)))); defs.add(new java.lang.instrument.ClassDefinition(java.lang.Runtime.class, transformClass(java.lang.Runtime.class.getName(), getClassFile(java.lang.Runtime.class))));
} catch(Exception e) { } catch (Exception e) {
throw new Error(e); throw new Error(e);
} }
} }
if(pb) { if (pb) {
try { try {
defs.add(new java.lang.instrument.ClassDefinition(java.lang.ProcessBuilder.class, transformClass(java.lang.ProcessBuilder.class.getName(), getClassFile(java.lang.ProcessBuilder.class)))); defs.add(new java.lang.instrument.ClassDefinition(java.lang.ProcessBuilder.class, transformClass(java.lang.ProcessBuilder.class.getName(), getClassFile(java.lang.ProcessBuilder.class))));
} catch(Exception e) { } catch (Exception e) {
throw new Error(e); throw new Error(e);
} }
} }
try { try {
defs.add(new java.lang.instrument.ClassDefinition(java.awt.Robot.class, transformClass(java.awt.Robot.class.getName(), getClassFile(java.awt.Robot.class)))); defs.add(new java.lang.instrument.ClassDefinition(java.awt.Robot.class, transformClass(java.awt.Robot.class.getName(), getClassFile(java.awt.Robot.class))));
} catch(Exception e) { } catch (Exception e) {
throw new Error(e); throw new Error(e);
} }
try { try {
inst.redefineClasses(defs.toArray(new java.lang.instrument.ClassDefinition[0])); inst.redefineClasses(defs.toArray(new java.lang.instrument.ClassDefinition[0]));
} catch(Exception e) { } catch (Exception e) {
throw new Error(e); throw new Error(e);
} }
} }
@ -100,73 +100,76 @@ private static void replaceClasses(boolean pb, boolean rt) {
* Use ASM to modify the byte array * Use ASM to modify the byte array
*/ */
private static byte[] transformClass(String className, byte[] classBytes) { private static byte[] transformClass(String className, byte[] classBytes) {
if (className.equals("java.lang.Runtime")) { switch (className) {
ClassReader cr=new ClassReader(classBytes); case "java.lang.Runtime": {
ClassNode cn=new ClassNode(); ClassReader cr = new ClassReader(classBytes);
cr.accept(cn,ClassReader.EXPAND_FRAMES); ClassNode cn = new ClassNode();
cr.accept(cn, ClassReader.EXPAND_FRAMES);
for (Object o : cn.methods.toArray()) { for (Object o : cn.methods.toArray()) {
MethodNode m = (MethodNode) o; MethodNode m = (MethodNode) o;
if(m.name.equals("exec")) { if (m.name.equals("exec")) {
m.instructions.insert(new InsnNode(ARETURN)); m.instructions.insert(new InsnNode(ARETURN));
m.instructions.insert(new InsnNode(ACONST_NULL)); m.instructions.insert(new InsnNode(ACONST_NULL));
} }
} }
ClassWriter cw=new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
cn.accept(cw); cn.accept(cw);
return cw.toByteArray(); return cw.toByteArray();
} else if (className.equals("java.lang.ProcessBuilder")) { }
ClassReader cr=new ClassReader(classBytes); case "java.lang.ProcessBuilder": {
ClassNode cn=new ClassNode(); ClassReader cr = new ClassReader(classBytes);
cr.accept(cn,ClassReader.EXPAND_FRAMES); ClassNode cn = new ClassNode();
cr.accept(cn, ClassReader.EXPAND_FRAMES);
for (Object o : cn.methods.toArray()) { for (Object o : cn.methods.toArray()) {
MethodNode m = (MethodNode) o; MethodNode m = (MethodNode) o;
if(m.name.equals("start")) { if (m.name.equals("start")) {
m.instructions.insert(new InsnNode(ARETURN)); m.instructions.insert(new InsnNode(ARETURN));
m.instructions.insert(new InsnNode(ACONST_NULL)); m.instructions.insert(new InsnNode(ACONST_NULL));
} }
} }
ClassWriter cw=new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
cn.accept(cw); cn.accept(cw);
return cw.toByteArray(); return cw.toByteArray();
} else if (className.equals("java.awt.Robot")) { }
ClassReader cr=new ClassReader(classBytes); case "java.awt.Robot": {
ClassNode cn=new ClassNode(); ClassReader cr = new ClassReader(classBytes);
cr.accept(cn,ClassReader.EXPAND_FRAMES); ClassNode cn = new ClassNode();
cr.accept(cn, ClassReader.EXPAND_FRAMES);
for (Object o : cn.methods.toArray()) { for (Object o : cn.methods.toArray()) {
MethodNode m = (MethodNode) o; MethodNode m = (MethodNode) o;
if( m.name.equals("createScreenCapture") || m.name.equals("getPixelColor") || if (m.name.equals("createScreenCapture") || m.name.equals("getPixelColor") ||
m.name.equals("keyPress") || m.name.equals("keyRelease") || m.name.equals("keyPress") || m.name.equals("keyRelease") ||
m.name.equals("mouseMove") || m.name.equals("mousePress") || m.name.equals("mouseMove") || m.name.equals("mousePress") ||
m.name.equals("mouseWheel")) m.name.equals("mouseWheel")) {
{
m.instructions.insert(new InsnNode(ARETURN)); m.instructions.insert(new InsnNode(ARETURN));
m.instructions.insert(new InsnNode(ACONST_NULL)); m.instructions.insert(new InsnNode(ACONST_NULL));
} }
} }
ClassWriter cw=new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
cn.accept(cw); cn.accept(cw);
return cw.toByteArray(); return cw.toByteArray();
} }
}
return classBytes; return classBytes;
} }
/** /**
* @author https://github.com/Konloch/JVM-Sandbox
* Do not remove this method. Do not to cause classloading!
* Grab the byte array from the loaded Class object
* @param clazz * @param clazz
* @return array, respending this class in bytecode. * @return array, respending this class in bytecode.
* @throws IOException * @throws IOException
* @author https://github.com/Konloch/JVM-Sandbox
* Do not remove this method. Do not to cause classloading!
* Grab the byte array from the loaded Class object
*/ */
private static byte[] getClassFile(Class<?> clazz) throws IOException { private static byte[] getClassFile(Class<?> clazz) throws IOException {
try (InputStream is = clazz.getResourceAsStream( "/" + clazz.getName().replace('.', '/') + ".class"); try (InputStream is = clazz.getResourceAsStream("/" + clazz.getName().replace('.', '/') + ".class");
ByteArrayOutputStream baos = new ByteArrayOutputStream()) { ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
int r = 0; int r = 0;
byte[] buffer = new byte[8192]; byte[] buffer = new byte[8192];
while((r=is.read(buffer))>=0) { while ((r = is.read(buffer)) >= 0) {
baos.write(buffer, 0, r); baos.write(buffer, 0, r);
} }
return baos.toByteArray(); return baos.toByteArray();

View file

@ -33,9 +33,8 @@ public static void main(String... args) throws Throwable {
initGson(); initGson();
ConsoleManager.initConsole(); ConsoleManager.initConsole();
LauncherConfig config = Launcher.getConfig(); LauncherConfig config = Launcher.getConfig();
if(config.environment.equals(LauncherConfig.LauncherEnvironment.PROD)) if (config.environment.equals(LauncherConfig.LauncherEnvironment.PROD)) {
{ if (!LauncherAgent.isStarted()) throw new SecurityException("LauncherAgent must started");
if(!LauncherAgent.isStarted()) throw new SecurityException("LauncherAgent must started");
} }
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
try { try {
@ -73,8 +72,7 @@ public void start(String... args) throws Throwable {
if (runtimeProvider == null) runtimeProvider = new JSRuntimeProvider(); if (runtimeProvider == null) runtimeProvider = new JSRuntimeProvider();
runtimeProvider.init(false); runtimeProvider.init(false);
runtimeProvider.preLoad(); runtimeProvider.preLoad();
if(Request.service == null) if (Request.service == null) {
{
String address = Launcher.getConfig().address; String address = Launcher.getConfig().address;
LogHelper.debug("Start async connection to %s", address); LogHelper.debug("Start async connection to %s", address);
Request.service = StandartClientWebSocketService.initWebSockets(address, true); Request.service = StandartClientWebSocketService.initWebSockets(address, true);

View file

@ -11,6 +11,8 @@ public class NewLauncherSettings {
@LauncherAPI @LauncherAPI
public String login; public String login;
@LauncherAPI @LauncherAPI
public String auth;
@LauncherAPI
public byte[] rsaPassword; public byte[] rsaPassword;
@LauncherAPI @LauncherAPI
public int profile; public int profile;
@ -35,8 +37,8 @@ public class NewLauncherSettings {
public List<ClientProfile> lastProfiles = new LinkedList<>(); public List<ClientProfile> lastProfiles = new LinkedList<>();
@LauncherAPI @LauncherAPI
public Map<String, UserSettings> userSettings = new HashMap<>(); public Map<String, UserSettings> userSettings = new HashMap<>();
public static class HashedStoreEntry
{ public static class HashedStoreEntry {
@LauncherAPI @LauncherAPI
public HashedDir hdir; public HashedDir hdir;
@LauncherAPI @LauncherAPI
@ -50,15 +52,15 @@ public HashedStoreEntry(HashedDir hdir, String name, String fullPath) {
this.fullPath = fullPath; this.fullPath = fullPath;
} }
} }
@LauncherAPI @LauncherAPI
public transient List<HashedStoreEntry> lastHDirs = new ArrayList<>(16); public transient List<HashedStoreEntry> lastHDirs = new ArrayList<>(16);
@LauncherAPI @LauncherAPI
public void putHDir(String name, Path path, HashedDir dir) public void putHDir(String name, Path path, HashedDir dir) {
{
String fullPath = path.toAbsolutePath().toString(); String fullPath = path.toAbsolutePath().toString();
for(HashedStoreEntry e : lastHDirs) for (HashedStoreEntry e : lastHDirs) {
{ if (e.fullPath.equals(fullPath) && e.name.equals(name)) return;
if(e.fullPath.equals(fullPath) && e.name.equals(name)) return;
} }
lastHDirs.add(new HashedStoreEntry(dir, name, fullPath)); lastHDirs.add(new HashedStoreEntry(dir, name, fullPath));
} }

View file

@ -541,8 +541,7 @@ public static void verifyHDir(Path dir, HashedDir hdir, FileNameMatcher matcher,
// Hash directory and compare (ignore update-only matcher entries, it will break offline-mode) // Hash directory and compare (ignore update-only matcher entries, it will break offline-mode)
HashedDir currentHDir = new HashedDir(dir, matcher, true, digest); HashedDir currentHDir = new HashedDir(dir, matcher, true, digest);
HashedDir.Diff diff = hdir.diff(currentHDir, matcher); HashedDir.Diff diff = hdir.diff(currentHDir, matcher);
if (!diff.isSame()) if (!diff.isSame()) {
{
/*AtomicBoolean isFoundFile = new AtomicBoolean(false); /*AtomicBoolean isFoundFile = new AtomicBoolean(false);
diff.extra.walk(File.separator, (e,k,v) -> { diff.extra.walk(File.separator, (e,k,v) -> {
if(v.getType().equals(HashedEntry.Type.FILE)) { LogHelper.error("Extra file %s", e); isFoundFile.set(true); } if(v.getType().equals(HashedEntry.Type.FILE)) { LogHelper.error("Extra file %s", e); isFoundFile.set(true); }

View file

@ -68,19 +68,19 @@ public static Path getAppDataDir() throws IOException {
public static Path getLauncherDir(String projectname) throws IOException { public static Path getLauncherDir(String projectname) throws IOException {
return getAppDataDir().resolve(projectname); return getAppDataDir().resolve(projectname);
} }
@LauncherAPI @LauncherAPI
public static Path getStoreDir(String projectname) throws IOException public static Path getStoreDir(String projectname) throws IOException {
{ if (JVMHelper.OS_TYPE == JVMHelper.OS.LINUX)
if(JVMHelper.OS_TYPE == JVMHelper.OS.LINUX)
return getAppDataDir().resolve("store"); return getAppDataDir().resolve("store");
else if(JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE) else if (JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE)
return getAppDataDir().resolve("GravitLauncherStore"); return getAppDataDir().resolve("GravitLauncherStore");
else else
return getAppDataDir().resolve("minecraftStore"); return getAppDataDir().resolve("minecraftStore");
} }
@LauncherAPI @LauncherAPI
public static Path getProjectStoreDir(String projectname) throws IOException public static Path getProjectStoreDir(String projectname) throws IOException {
{
return getStoreDir(projectname).resolve(projectname); return getStoreDir(projectname).resolve(projectname);
} }

View file

@ -57,8 +57,8 @@ public static HWID getHWID() {
@LauncherAPI @LauncherAPI
public static int getTotalMemory() { public static int getTotalMemory() {
if (cachedMemorySize > 0) return (int)cachedMemorySize; if (cachedMemorySize > 0) return (int) cachedMemorySize;
return (int)(cachedMemorySize = hwidProvider.getTotalMemory() >> 20); return (int) (cachedMemorySize = hwidProvider.getTotalMemory() >> 20);
} }
@LauncherAPI @LauncherAPI
@ -79,21 +79,20 @@ public static int getJVMTotalMemory() {
public static HasherStore getDefaultHasherStore() { public static HasherStore getDefaultHasherStore() {
return HasherManager.getDefaultStore(); return HasherManager.getDefaultStore();
} }
@LauncherAPI @LauncherAPI
public static void registerUserSettings(String typename, Class<? extends UserSettings> clazz) public static void registerUserSettings(String typename, Class<? extends UserSettings> clazz) {
{
UserSettings.providers.register(typename, clazz); UserSettings.providers.register(typename, clazz);
} }
@LauncherAPI @LauncherAPI
public static void close() throws Exception public static void close() throws Exception {
{
threadPool.awaitTermination(2, TimeUnit.SECONDS); threadPool.awaitTermination(2, TimeUnit.SECONDS);
} }
@LauncherAPI @LauncherAPI
public static void setAuthParams(AuthRequestEvent event) { public static void setAuthParams(AuthRequestEvent event) {
if(event.session != 0) if (event.session != 0) {
{
Request.setSession(event.session); Request.setSession(event.session);
} }
LauncherGuardManager.guard.setProtectToken(event.protectToken); LauncherGuardManager.guard.setProtectToken(event.protectToken);
@ -105,13 +104,12 @@ public interface HashedDirRunnable {
} }
@LauncherAPI @LauncherAPI
public static void evalCommand(String cmd) public static void evalCommand(String cmd) {
{
ConsoleManager.handler.eval(cmd, false); ConsoleManager.handler.eval(cmd, false);
} }
@LauncherAPI @LauncherAPI
public static void addPlainOutput(LogHelper.Output output) public static void addPlainOutput(LogHelper.Output output) {
{
LogHelper.addOutput(output, LogHelper.OutputTypes.PLAIN); LogHelper.addOutput(output, LogHelper.OutputTypes.PLAIN);
} }
} }

View file

@ -18,14 +18,11 @@ public String getUsageDescription() {
@Override @Override
public void invoke(String... args) throws Exception { public void invoke(String... args) throws Exception {
verifyArgs(args, 1); verifyArgs(args, 1);
if(ConsoleManager.checkUnlockKey(args[0])) if (ConsoleManager.checkUnlockKey(args[0])) {
{
LogHelper.info("Unlock successful"); LogHelper.info("Unlock successful");
ConsoleManager.unlock(); ConsoleManager.unlock();
ConsoleManager.handler.unregisterCommand("unlock"); ConsoleManager.handler.unregisterCommand("unlock");
} } else {
else
{
LogHelper.error("Unlock key incorrect"); LogHelper.error("Unlock key incorrect");
} }
} }

View file

@ -19,6 +19,6 @@ public String getUsageDescription() {
@Override @Override
public void invoke(String... args) throws Exception { public void invoke(String... args) throws Exception {
ExecCommandRequestEvent request = new ExecCommandRequest(String.join(" ", args)).request(); ExecCommandRequestEvent request = new ExecCommandRequest(String.join(" ", args)).request();
if(!request.success) LogHelper.error("Error executing command"); if (!request.success) LogHelper.error("Error executing command");
} }
} }

View file

@ -8,8 +8,7 @@
import ru.gravit.utils.helper.LogHelper; import ru.gravit.utils.helper.LogHelper;
public class LogListenerCommand extends Command { public class LogListenerCommand extends Command {
public class LogListenerRequest implements RequestInterface public class LogListenerRequest implements RequestInterface {
{
@LauncherNetworkAPI @LauncherNetworkAPI
public LogHelper.OutputTypes outputType; public LogHelper.OutputTypes outputType;
@ -22,6 +21,7 @@ public String getType() {
return "addLogListener"; return "addLogListener";
} }
} }
@Override @Override
public String getArgsDescription() { public String getArgsDescription() {
return null; return null;
@ -38,15 +38,8 @@ public void invoke(String... args) throws Exception {
Request.service.sendObject(new LogListenerRequest(LogHelper.JANSI ? LogHelper.OutputTypes.JANSI : LogHelper.OutputTypes.PLAIN)); Request.service.sendObject(new LogListenerRequest(LogHelper.JANSI ? LogHelper.OutputTypes.JANSI : LogHelper.OutputTypes.PLAIN));
LogHelper.info("Add log handler"); LogHelper.info("Add log handler");
Request.service.registerHandler((result) -> { Request.service.registerHandler((result) -> {
if(result instanceof LogEvent) if (result instanceof LogEvent) {
{ LogHelper.rawLog(() -> ((LogEvent) result).string, () -> ((LogEvent) result).string, () -> ((LogEvent) result).string);
LogHelper.rawLog(() -> {
return ((LogEvent) result).string;
}, () -> {
return ((LogEvent) result).string;
}, () -> {
return ((LogEvent) result).string;
});
} }
}); });
} }

View file

@ -10,20 +10,16 @@ public class LauncherGuardManager {
public static void initGuard(boolean clientInstance) { public static void initGuard(boolean clientInstance) {
LauncherConfig config = Launcher.getConfig(); LauncherConfig config = Launcher.getConfig();
switch (config.guardType) switch (config.guardType) {
{ case "wrapper": {
case "wrapper":
{
guard = new LauncherWrapperGuard(); guard = new LauncherWrapperGuard();
break; break;
} }
case "java": case "java": {
{
guard = new LauncherJavaGuard(); guard = new LauncherJavaGuard();
break; break;
} }
default: default: {
{
guard = new LauncherNoGuard(); guard = new LauncherNoGuard();
} }
} }

View file

@ -83,7 +83,7 @@ public String getMacAddr() {
} }
public long getTotalMemory() { public long getTotalMemory() {
if (noHWID) return 1024<<20; if (noHWID) return 1024 << 20;
if (hardware == null) hardware = systemInfo.getHardware(); if (hardware == null) hardware = systemInfo.getHardware();
return hardware.getMemory().getTotal(); return hardware.getMemory().getTotal();
} }

View file

@ -1,15 +1,15 @@
package ru.gravit.launcher.managers; package ru.gravit.launcher.managers;
import ru.gravit.launcher.console.UnlockCommand;
import ru.gravit.launcher.console.admin.ExecCommand; import ru.gravit.launcher.console.admin.ExecCommand;
import ru.gravit.launcher.console.admin.LogListenerCommand; import ru.gravit.launcher.console.admin.LogListenerCommand;
import ru.gravit.utils.command.BaseCommandCategory; import ru.gravit.utils.command.BaseCommandCategory;
import ru.gravit.utils.command.basic.ClearCommand;
import ru.gravit.utils.command.basic.DebugCommand;
import ru.gravit.utils.command.basic.GCCommand;
import ru.gravit.launcher.console.UnlockCommand;
import ru.gravit.utils.command.CommandHandler; import ru.gravit.utils.command.CommandHandler;
import ru.gravit.utils.command.JLineCommandHandler; import ru.gravit.utils.command.JLineCommandHandler;
import ru.gravit.utils.command.StdCommandHandler; import ru.gravit.utils.command.StdCommandHandler;
import ru.gravit.utils.command.basic.ClearCommand;
import ru.gravit.utils.command.basic.DebugCommand;
import ru.gravit.utils.command.basic.GCCommand;
import ru.gravit.utils.command.basic.HelpCommand; import ru.gravit.utils.command.basic.HelpCommand;
import ru.gravit.utils.helper.CommonHelper; import ru.gravit.utils.helper.CommonHelper;
import ru.gravit.utils.helper.LogHelper; import ru.gravit.utils.helper.LogHelper;
@ -19,11 +19,11 @@
public class ConsoleManager { public class ConsoleManager {
public static CommandHandler handler; public static CommandHandler handler;
public static Thread thread; public static Thread thread;
public static void initConsole() throws IOException
{ public static void initConsole() throws IOException {
CommandHandler localCommandHandler; CommandHandler localCommandHandler;
try { try {
Class.forName("jline.Terminal"); Class.forName("org.jline.terminal.Terminal");
// JLine2 available // JLine2 available
localCommandHandler = new JLineCommandHandler(); localCommandHandler = new JLineCommandHandler();
@ -37,19 +37,19 @@ public static void initConsole() throws IOException
thread = CommonHelper.newThread("Launcher Console", true, handler); thread = CommonHelper.newThread("Launcher Console", true, handler);
thread.start(); thread.start();
} }
public static void registerCommands()
{ public static void registerCommands() {
handler.registerCommand("help", new HelpCommand(handler)); handler.registerCommand("help", new HelpCommand(handler));
handler.registerCommand("gc", new GCCommand()); handler.registerCommand("gc", new GCCommand());
handler.registerCommand("clear", new ClearCommand(handler)); handler.registerCommand("clear", new ClearCommand(handler));
handler.registerCommand("unlock", new UnlockCommand()); handler.registerCommand("unlock", new UnlockCommand());
} }
public static boolean checkUnlockKey(String key)
{ public static boolean checkUnlockKey(String key) {
return true; return true;
} }
public static void unlock()
{ public static void unlock() {
handler.registerCommand("debug", new DebugCommand()); handler.registerCommand("debug", new DebugCommand());
BaseCommandCategory admin = new BaseCommandCategory(); BaseCommandCategory admin = new BaseCommandCategory();
admin.registerCommand("exec", new ExecCommand()); admin.registerCommand("exec", new ExecCommand());

View file

@ -3,10 +3,10 @@
import ru.gravit.launcher.LauncherAPI; import ru.gravit.launcher.LauncherAPI;
import ru.gravit.launcher.NewLauncherSettings; import ru.gravit.launcher.NewLauncherSettings;
import ru.gravit.launcher.client.DirBridge; import ru.gravit.launcher.client.DirBridge;
import ru.gravit.launcher.config.JsonConfigurable;
import ru.gravit.launcher.hasher.HashedDir; import ru.gravit.launcher.hasher.HashedDir;
import ru.gravit.launcher.serialize.HInput; import ru.gravit.launcher.serialize.HInput;
import ru.gravit.launcher.serialize.HOutput; import ru.gravit.launcher.serialize.HOutput;
import ru.gravit.launcher.config.JsonConfigurable;
import ru.gravit.utils.helper.IOHelper; import ru.gravit.utils.helper.IOHelper;
import java.io.IOException; import java.io.IOException;
@ -18,10 +18,8 @@ public class SettingsManager extends JsonConfigurable<NewLauncherSettings> {
public class StoreFileVisitor extends SimpleFileVisitor<Path> { public class StoreFileVisitor extends SimpleFileVisitor<Path> {
@Override @Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException throws IOException {
{ try (HInput input = new HInput(IOHelper.newInput(file))) {
try(HInput input = new HInput(IOHelper.newInput(file)))
{
String dirName = input.readString(128); String dirName = input.readString(128);
String fullPath = input.readString(1024); String fullPath = input.readString(1024);
HashedDir dir = new HashedDir(input); HashedDir dir = new HashedDir(input);
@ -31,61 +29,63 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
} }
} }
@LauncherAPI @LauncherAPI
public static NewLauncherSettings settings; public static NewLauncherSettings settings;
public SettingsManager() { public SettingsManager() {
super(NewLauncherSettings.class, DirBridge.dir.resolve("settings.json")); super(NewLauncherSettings.class, DirBridge.dir.resolve("settings.json"));
} }
@LauncherAPI @LauncherAPI
@Override @Override
public NewLauncherSettings getConfig() { public NewLauncherSettings getConfig() {
if(settings.updatesDir != null) if (settings.updatesDir != null)
settings.updatesDirPath = settings.updatesDir.toString(); settings.updatesDirPath = settings.updatesDir.toString();
return settings; return settings;
} }
@LauncherAPI @LauncherAPI
@Override @Override
public NewLauncherSettings getDefaultConfig() { public NewLauncherSettings getDefaultConfig() {
return new NewLauncherSettings(); return new NewLauncherSettings();
} }
@LauncherAPI @LauncherAPI
@Override @Override
public void setConfig(NewLauncherSettings config) { public void setConfig(NewLauncherSettings config) {
settings = config; settings = config;
if(settings.updatesDirPath != null) if (settings.updatesDirPath != null)
settings.updatesDir = Paths.get(settings.updatesDirPath); settings.updatesDir = Paths.get(settings.updatesDirPath);
} }
@LauncherAPI @LauncherAPI
public void loadHDirStore(Path storePath) throws IOException public void loadHDirStore(Path storePath) throws IOException {
{
Files.createDirectories(storePath); Files.createDirectories(storePath);
IOHelper.walk(storePath, new StoreFileVisitor(), false); IOHelper.walk(storePath, new StoreFileVisitor(), false);
} }
@LauncherAPI @LauncherAPI
public void saveHDirStore(Path storeProjectPath) throws IOException public void saveHDirStore(Path storeProjectPath) throws IOException {
{
Files.createDirectories(storeProjectPath); Files.createDirectories(storeProjectPath);
for(NewLauncherSettings.HashedStoreEntry e : settings.lastHDirs) for (NewLauncherSettings.HashedStoreEntry e : settings.lastHDirs) {
{
Path file = storeProjectPath.resolve(e.name.concat(".bin")); Path file = storeProjectPath.resolve(e.name.concat(".bin"));
if(!Files.exists(file)) Files.createFile(file); if (!Files.exists(file)) Files.createFile(file);
try(HOutput output = new HOutput(IOHelper.newOutput(file))) try (HOutput output = new HOutput(IOHelper.newOutput(file))) {
{
output.writeString(e.name, 128); output.writeString(e.name, 128);
output.writeString(e.fullPath, 1024); output.writeString(e.fullPath, 1024);
e.hdir.write(output); e.hdir.write(output);
} }
} }
} }
@LauncherAPI @LauncherAPI
public void loadHDirStore() throws IOException public void loadHDirStore() throws IOException {
{
loadHDirStore(DirBridge.dirStore); loadHDirStore(DirBridge.dirStore);
} }
@LauncherAPI @LauncherAPI
public void saveHDirStore() throws IOException public void saveHDirStore() throws IOException {
{
saveHDirStore(DirBridge.dirProjectStore); saveHDirStore(DirBridge.dirProjectStore);
} }

View file

@ -4,8 +4,8 @@
import ru.gravit.launcher.hasher.FileNameMatcher; import ru.gravit.launcher.hasher.FileNameMatcher;
import ru.gravit.launcher.hasher.HashedDir; import ru.gravit.launcher.hasher.HashedDir;
import ru.gravit.launcher.hasher.HashedEntry; import ru.gravit.launcher.hasher.HashedEntry;
import ru.gravit.launcher.hasher.HashedFile;
import ru.gravit.launcher.hasher.HashedEntry.Type; import ru.gravit.launcher.hasher.HashedEntry.Type;
import ru.gravit.launcher.hasher.HashedFile;
import ru.gravit.utils.helper.IOHelper; import ru.gravit.utils.helper.IOHelper;
import ru.gravit.utils.helper.JVMHelper; import ru.gravit.utils.helper.JVMHelper;
import ru.gravit.utils.helper.JVMHelper.OS; import ru.gravit.utils.helper.JVMHelper.OS;

View file

@ -15,22 +15,22 @@ public NativeJVMHalt(int haltCode) {
@SuppressWarnings("null") @SuppressWarnings("null")
private boolean aaabBooleanC_D() { private boolean aaabBooleanC_D() {
return (boolean) (Boolean) (Object) null; return (boolean) (Boolean) null;
} }
public static void haltA(int code) { public static void haltA(int code) {
NativeJVMHalt halt = new NativeJVMHalt(code); NativeJVMHalt halt = new NativeJVMHalt(code);
try { try {
SafeExitJVMLegacy.exit(code); SafeExitJVMLegacy.exit(code);
} catch(Throwable ignored) { } catch (Throwable ignored) {
} }
try { try {
SafeExitJVM.exit(code); SafeExitJVM.exit(code);
} catch(Throwable ignored) { } catch (Throwable ignored) {
} }
halt.aaabbb38C_D(); halt.aaabbb38C_D();
boolean a = halt.aaabBooleanC_D(); boolean a = halt.aaabBooleanC_D();
System.out.println(Boolean.toString(a)); System.out.println(a);
} }
public static boolean initFunc() { public static boolean initFunc() {

View file

@ -13,25 +13,30 @@
public abstract class JsonConfigurable<T> { public abstract class JsonConfigurable<T> {
private Type type; private Type type;
protected Path configPath; protected Path configPath;
@LauncherAPI @LauncherAPI
public void saveConfig() throws IOException { public void saveConfig() throws IOException {
saveConfig(configPath); saveConfig(configPath);
} }
@LauncherAPI @LauncherAPI
public void loadConfig() throws IOException { public void loadConfig() throws IOException {
loadConfig(configPath); loadConfig(configPath);
} }
@LauncherAPI @LauncherAPI
public JsonConfigurable(Type type, Path configPath) { public JsonConfigurable(Type type, Path configPath) {
this.type = type; this.type = type;
this.configPath = configPath; this.configPath = configPath;
} }
@LauncherAPI @LauncherAPI
public void saveConfig(Path configPath) throws IOException { public void saveConfig(Path configPath) throws IOException {
try (BufferedWriter writer = IOHelper.newWriter(configPath)) { try (BufferedWriter writer = IOHelper.newWriter(configPath)) {
Launcher.gsonManager.gson.toJson(getConfig(), type, writer); Launcher.gsonManager.gson.toJson(getConfig(), type, writer);
} }
} }
@LauncherAPI @LauncherAPI
public void loadConfig(Path configPath) throws IOException { public void loadConfig(Path configPath) throws IOException {
if (generateConfigIfNotExists(configPath)) return; if (generateConfigIfNotExists(configPath)) return;
@ -39,16 +44,19 @@ public void loadConfig(Path configPath) throws IOException {
setConfig(Launcher.gsonManager.gson.fromJson(reader, type)); setConfig(Launcher.gsonManager.gson.fromJson(reader, type));
} }
} }
@LauncherAPI @LauncherAPI
public void resetConfig() throws IOException { public void resetConfig() throws IOException {
setConfig(getDefaultConfig()); setConfig(getDefaultConfig());
saveConfig(); saveConfig();
} }
@LauncherAPI @LauncherAPI
public void resetConfig(Path newPath) throws IOException { public void resetConfig(Path newPath) throws IOException {
setConfig(getDefaultConfig()); setConfig(getDefaultConfig());
saveConfig(newPath); saveConfig(newPath);
} }
@LauncherAPI @LauncherAPI
public boolean generateConfigIfNotExists(Path path) throws IOException { public boolean generateConfigIfNotExists(Path path) throws IOException {
if (IOHelper.isFile(path)) if (IOHelper.isFile(path))
@ -56,6 +64,7 @@ public boolean generateConfigIfNotExists(Path path) throws IOException {
resetConfig(path); resetConfig(path);
return true; return true;
} }
@LauncherAPI @LauncherAPI
public boolean generateConfigIfNotExists() throws IOException { public boolean generateConfigIfNotExists() throws IOException {
if (IOHelper.isFile(configPath)) if (IOHelper.isFile(configPath))
@ -63,14 +72,17 @@ public boolean generateConfigIfNotExists() throws IOException {
resetConfig(); resetConfig();
return true; return true;
} }
protected void setType(Type type)
{ protected void setType(Type type) {
this.type = type; this.type = type;
} }
@LauncherAPI @LauncherAPI
public abstract T getConfig(); public abstract T getConfig();
@LauncherAPI @LauncherAPI
public abstract T getDefaultConfig(); public abstract T getDefaultConfig();
@LauncherAPI @LauncherAPI
public abstract void setConfig(T config); public abstract void setConfig(T config);
} }

View file

@ -1,7 +1,6 @@
package ru.gravit.launcher.downloader; package ru.gravit.launcher.downloader;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler; import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
@ -19,20 +18,21 @@
import java.net.URL; import java.net.URL;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.List; import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class ListDownloader { public class ListDownloader {
@FunctionalInterface @FunctionalInterface
public interface DownloadCallback public interface DownloadCallback {
{ void stateChanged(String filename, long downloadedSize, long size);
void stateChanged(String filename,long downloadedSize, long size);
} }
@FunctionalInterface @FunctionalInterface
public interface DownloadTotalCallback public interface DownloadTotalCallback {
{
void addTotal(long size); void addTotal(long size);
} }
public static class DownloadTask
{ public static class DownloadTask {
public String apply; public String apply;
public long size; public long size;
@ -41,6 +41,7 @@ public DownloadTask(String apply, long size) {
this.size = size; this.size = size;
} }
} }
public void download(String base, List<DownloadTask> applies, Path dstDirFile, DownloadCallback callback, DownloadTotalCallback totalCallback) throws IOException, URISyntaxException { public void download(String base, List<DownloadTask> applies, Path dstDirFile, DownloadCallback callback, DownloadTotalCallback totalCallback) throws IOException, URISyntaxException {
try (CloseableHttpClient httpclient = HttpClients.custom() try (CloseableHttpClient httpclient = HttpClients.custom()
.setRedirectStrategy(new LaxRedirectStrategy()) .setRedirectStrategy(new LaxRedirectStrategy())
@ -49,20 +50,30 @@ public void download(String base, List<DownloadTask> applies, Path dstDirFile, D
HttpGet get = null; HttpGet get = null;
for (DownloadTask apply : applies) { for (DownloadTask apply : applies) {
URI u = new URL(base.concat(IOHelper.urlEncode(apply.apply).replace("%2F", "/"))).toURI(); URI u = new URL(base.concat(IOHelper.urlEncode(apply.apply).replace("%2F", "/"))).toURI();
callback.stateChanged(apply.apply,0L, apply.size); callback.stateChanged(apply.apply, 0L, apply.size);
LogHelper.debug("Download URL: %s", u.toString()); LogHelper.debug("Download URL: %s", u.toString());
if (get == null) get = new HttpGet(u); if (get == null) get = new HttpGet(u);
else { else {
get.reset(); get.reset();
get.setURI(u); get.setURI(u);
} }
httpclient.execute(get, new FileDownloadResponseHandler(dstDirFile.resolve(apply.apply), apply, callback, totalCallback)); httpclient.execute(get, new FileDownloadResponseHandler(dstDirFile.resolve(apply.apply), apply, callback, totalCallback, false));
} }
} }
} }
public void downloadZip(String base, Path dstDirFile, DownloadCallback callback, DownloadTotalCallback totalCallback) throws IOException, URISyntaxException {
try (CloseableHttpClient httpclient = HttpClients.custom()
.setRedirectStrategy(new LaxRedirectStrategy())
.build()) {
HttpGet get;
URI u = new URL(base).toURI();
LogHelper.debug("Download ZIP URL: %s", u.toString());
get = new HttpGet(u);
httpclient.execute(get, new FileDownloadResponseHandler(dstDirFile, callback, totalCallback, true));
}
}
public void downloadOne(String url, Path target) throws IOException, URISyntaxException public void downloadOne(String url, Path target) throws IOException, URISyntaxException {
{
try (CloseableHttpClient httpclient = HttpClients.custom() try (CloseableHttpClient httpclient = HttpClients.custom()
.setRedirectStrategy(new LaxRedirectStrategy()) .setRedirectStrategy(new LaxRedirectStrategy())
.build()) { .build()) {
@ -80,36 +91,58 @@ static class FileDownloadResponseHandler implements ResponseHandler<Path> {
private final DownloadTask task; private final DownloadTask task;
private final DownloadCallback callback; private final DownloadCallback callback;
private final DownloadTotalCallback totalCallback; private final DownloadTotalCallback totalCallback;
private final boolean zip;
public FileDownloadResponseHandler(Path target) { public FileDownloadResponseHandler(Path target) {
this.target = target; this.target = target;
this.task = null; this.task = null;
this.zip = false;
callback = null; callback = null;
totalCallback = null; totalCallback = null;
} }
public FileDownloadResponseHandler(Path target, DownloadTask task, DownloadCallback callback, DownloadTotalCallback totalCallback) { public FileDownloadResponseHandler(Path target, DownloadTask task, DownloadCallback callback, DownloadTotalCallback totalCallback, boolean zip) {
this.target = target; this.target = target;
this.task = task; this.task = task;
this.callback = callback; this.callback = callback;
this.totalCallback = totalCallback; this.totalCallback = totalCallback;
this.zip = zip;
}
public FileDownloadResponseHandler(Path target, DownloadCallback callback, DownloadTotalCallback totalCallback, boolean zip) {
this.target = target;
this.task = null;
this.callback = callback;
this.totalCallback = totalCallback;
this.zip = zip;
} }
@Override @Override
public Path handleResponse(HttpResponse response) throws ClientProtocolException, IOException { public Path handleResponse(HttpResponse response) throws IOException {
InputStream source = response.getEntity().getContent(); InputStream source = response.getEntity().getContent();
if(callback != null && task != null) if(zip)
{ {
try(ZipInputStream input = IOHelper.newZipInput(source))
{
ZipEntry entry = input.getNextEntry();
long size = entry.getSize();
String filename = entry.getName();
Path target = this.target.resolve(filename);
LogHelper.dev("Resolved filename %s to %s", filename, target.toAbsolutePath().toString());
transfer(source, target, filename, size, callback, totalCallback);
}
return null;
}
if (callback != null && task != null) {
callback.stateChanged(task.apply, 0, task.size); callback.stateChanged(task.apply, 0, task.size);
transfer(source, this.target, task.apply, task.size, callback, totalCallback); transfer(source, this.target, task.apply, task.size, callback, totalCallback);
} } else
else
IOHelper.transfer(source, this.target); IOHelper.transfer(source, this.target);
return this.target; return this.target;
} }
} }
public static void transfer(InputStream input, Path file, String filename, long size, DownloadCallback callback, DownloadTotalCallback totalCallback) throws IOException
{ public static void transfer(InputStream input, Path file, String filename, long size, DownloadCallback callback, DownloadTotalCallback totalCallback) throws IOException {
try (OutputStream fileOutput = IOHelper.newOutput(file)) { try (OutputStream fileOutput = IOHelper.newOutput(file)) {
long downloaded = 0L; long downloaded = 0L;

View file

@ -12,6 +12,7 @@ public class ErrorRequestEvent extends RequestEvent implements EventInterface {
public ErrorRequestEvent(String error) { public ErrorRequestEvent(String error) {
this.error = error; this.error = error;
} }
@LauncherNetworkAPI @LauncherNetworkAPI
public final String error; public final String error;

View file

@ -8,6 +8,7 @@ public class ExecCommandRequestEvent extends RequestEvent {
public String getType() { public String getType() {
return "cmdExec"; return "cmdExec";
} }
@LauncherNetworkAPI @LauncherNetworkAPI
public boolean success; public boolean success;

View file

@ -6,8 +6,7 @@
import java.util.List; import java.util.List;
public class GetAvailabilityAuthRequestEvent extends RequestEvent { public class GetAvailabilityAuthRequestEvent extends RequestEvent {
public static class AuthAvailability public static class AuthAvailability {
{
@LauncherNetworkAPI @LauncherNetworkAPI
public String name; public String name;
@LauncherNetworkAPI @LauncherNetworkAPI
@ -18,6 +17,7 @@ public AuthAvailability(String name, String displayName) {
this.displayName = displayName; this.displayName = displayName;
} }
} }
@LauncherNetworkAPI @LauncherNetworkAPI
public List<AuthAvailability> list; public List<AuthAvailability> list;

View file

@ -6,6 +6,7 @@
public class GetSecureTokenRequestEvent extends RequestEvent { public class GetSecureTokenRequestEvent extends RequestEvent {
@LauncherNetworkAPI @LauncherNetworkAPI
public String secureToken; public String secureToken;
@Override @Override
public String getType() { public String getType() {
return "GetSecureToken"; return "GetSecureToken";

View file

@ -12,6 +12,7 @@ public class JoinServerRequestEvent extends RequestEvent implements EventInterfa
public JoinServerRequestEvent(boolean allow) { public JoinServerRequestEvent(boolean allow) {
this.allow = allow; this.allow = allow;
} }
@LauncherNetworkAPI @LauncherNetworkAPI
public boolean allow; public boolean allow;

View file

@ -19,6 +19,7 @@ public LauncherRequestEvent(boolean needUpdate, String url) {
this.needUpdate = needUpdate; this.needUpdate = needUpdate;
this.url = url; this.url = url;
} }
@LauncherNetworkAPI @LauncherNetworkAPI
public boolean needUpdate; public boolean needUpdate;

View file

@ -8,6 +8,7 @@ public class LogEvent implements ResultInterface {
public String getType() { public String getType() {
return "log"; return "log";
} }
@LauncherNetworkAPI @LauncherNetworkAPI
public String string; public String string;

View file

@ -9,6 +9,8 @@ public class UpdateRequestEvent extends RequestEvent {
public HashedDir hdir; public HashedDir hdir;
@LauncherNetworkAPI @LauncherNetworkAPI
public String url; public String url;
@LauncherNetworkAPI
public boolean zip;
@Override @Override
public String getType() { public String getType() {
@ -17,10 +19,18 @@ public String getType() {
public UpdateRequestEvent(HashedDir hdir) { public UpdateRequestEvent(HashedDir hdir) {
this.hdir = hdir; this.hdir = hdir;
this.zip = false;
} }
public UpdateRequestEvent(HashedDir hdir, String url) { public UpdateRequestEvent(HashedDir hdir, String url) {
this.hdir = hdir; this.hdir = hdir;
this.url = url; this.url = url;
this.zip = false;
}
public UpdateRequestEvent(HashedDir hdir, String url, boolean zip) {
this.hdir = hdir;
this.url = url;
this.zip = zip;
} }
} }

View file

@ -6,6 +6,7 @@
public class VerifySecureTokenRequestEvent extends RequestEvent { public class VerifySecureTokenRequestEvent extends RequestEvent {
@LauncherAPI @LauncherAPI
public boolean success; public boolean success;
@Override @Override
public String getType() { public String getType() {
return "verifySecureToken"; return "verifySecureToken";

View file

@ -259,7 +259,7 @@ public void unmarkOptional(OptionalFile file) {
file.mark = false; file.mark = false;
if (file.dependenciesCount != null) { if (file.dependenciesCount != null) {
for (OptionalFile f : file.dependenciesCount) { for (OptionalFile f : file.dependenciesCount) {
if(f.isPreset) continue; if (f.isPreset) continue;
unmarkOptional(f); unmarkOptional(f);
} }
file.dependenciesCount.clear(); file.dependenciesCount.clear();

View file

@ -35,9 +35,11 @@ public static void requestError(String message) throws RequestException {
public R request() throws Exception { public R request() throws Exception {
if (!started.compareAndSet(false, true)) if (!started.compareAndSet(false, true))
throw new IllegalStateException("Request already started"); throw new IllegalStateException("Request already started");
if(service == null) service = StandartClientWebSocketService.initWebSockets(Launcher.getConfig().address, false); if (service == null)
service = StandartClientWebSocketService.initWebSockets(Launcher.getConfig().address, false);
return requestDo(service); return requestDo(service);
} }
@LauncherAPI @LauncherAPI
public R request(StandartClientWebSocketService service) throws Exception { public R request(StandartClientWebSocketService service) throws Exception {
if (!started.compareAndSet(false, true)) if (!started.compareAndSet(false, true))
@ -46,8 +48,7 @@ public R request(StandartClientWebSocketService service) throws Exception {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected R requestDo(StandartClientWebSocketService service) throws Exception protected R requestDo(StandartClientWebSocketService service) throws Exception {
{
return (R) service.sendRequest(this); return (R) service.sendRequest(this);
} }

View file

@ -81,6 +81,7 @@ public AuthRequest(String login, byte[] encryptedPassword, String auth_id, Conne
this.customText = ""; this.customText = "";
this.getSession = false; this.getSession = false;
} }
public AuthRequest(String login, String password, String auth_id, ConnectTypes authType) { public AuthRequest(String login, String password, String auth_id, ConnectTypes authType) {
this.login = login; this.login = login;
this.password = password; this.password = password;

View file

@ -53,8 +53,7 @@ public static void update(LauncherRequestEvent result) throws IOException {
try { try {
ListDownloader downloader = new ListDownloader(); ListDownloader downloader = new ListDownloader();
downloader.downloadOne(result.url, BINARY_PATH); downloader.downloadOne(result.url, BINARY_PATH);
} catch(Throwable e) } catch (Throwable e) {
{
LogHelper.error(e); LogHelper.error(e);
} }
} }

View file

@ -175,13 +175,11 @@ public UpdateRequestEvent requestDo(StandartClientWebSocketService service) thro
HashedDir.Diff diff = e.hdir.diff(localDir, matcher); HashedDir.Diff diff = e.hdir.diff(localDir, matcher);
final List<ListDownloader.DownloadTask> adds = new ArrayList<>(); final List<ListDownloader.DownloadTask> adds = new ArrayList<>();
diff.mismatch.walk(IOHelper.CROSS_SEPARATOR, (path, name, entry) -> { diff.mismatch.walk(IOHelper.CROSS_SEPARATOR, (path, name, entry) -> {
if(entry.getType().equals(HashedEntry.Type.FILE)) { if (entry.getType().equals(HashedEntry.Type.FILE)) {
HashedFile file = (HashedFile) entry; HashedFile file = (HashedFile) entry;
totalSize += file.size; totalSize += file.size;
adds.add(new ListDownloader.DownloadTask(path, file.size)); adds.add(new ListDownloader.DownloadTask(path, file.size));
} } else if (entry.getType().equals(HashedEntry.Type.DIR)) {
else if(entry.getType().equals(HashedEntry.Type.DIR))
{
try { try {
Files.createDirectories(dir.resolve(path)); Files.createDirectories(dir.resolve(path));
} catch (IOException ex) { } catch (IOException ex) {
@ -193,9 +191,14 @@ else if(entry.getType().equals(HashedEntry.Type.DIR))
startTime = Instant.now(); startTime = Instant.now();
updateState("UnknownFile", 0L, 100); updateState("UnknownFile", 0L, 100);
ListDownloader listDownloader = new ListDownloader(); ListDownloader listDownloader = new ListDownloader();
listDownloader.download(e.url, adds, dir, this::updateState, (add) -> { if(e.zip && !adds.isEmpty())
totalDownloaded += add; {
}); listDownloader.downloadZip(e.url, dir, this::updateState, (add) -> totalDownloaded += add);
}
else
{
listDownloader.download(e.url, adds, dir, this::updateState, (add) -> totalDownloaded += add);
}
deleteExtraDir(dir, diff.extra, diff.extra.flag); deleteExtraDir(dir, diff.extra, diff.extra.flag);
LogHelper.debug("Update success"); LogHelper.debug("Update success");
return e; return e;

View file

@ -18,14 +18,14 @@ class Entry {
@LauncherNetworkAPI @LauncherNetworkAPI
String client; String client;
} }
@LauncherNetworkAPI @LauncherNetworkAPI
private final Entry[] list; private final Entry[] list;
@LauncherAPI @LauncherAPI
public BatchProfileByUsernameRequest(String... usernames) throws IOException { public BatchProfileByUsernameRequest(String... usernames) throws IOException {
this.list = new Entry[usernames.length]; this.list = new Entry[usernames.length];
for(int i=0;i<usernames.length;++i) for (int i = 0; i < usernames.length; ++i) {
{
this.list[i].client = ""; this.list[i].client = "";
this.list[i].username = usernames[i]; this.list[i].username = usernames[i];
} }

View file

@ -41,16 +41,13 @@ public ClientJSONPoint(URI uri) throws SSLException {
if (!"ws".equals(protocol) && !"wss".equals(protocol)) { if (!"ws".equals(protocol) && !"wss".equals(protocol)) {
throw new IllegalArgumentException("Unsupported protocol: " + protocol); throw new IllegalArgumentException("Unsupported protocol: " + protocol);
} }
if("wss".equals(protocol)) if ("wss".equals(protocol)) {
{
ssl = true; ssl = true;
} }
if(uri.getPort() == -1) if (uri.getPort() == -1) {
{ if ("ws".equals(protocol)) port = 80;
if("ws".equals(protocol)) port = 80;
else port = 443; else port = 443;
} } else port = uri.getPort();
else port = uri.getPort();
final SslContext sslCtx; final SslContext sslCtx;
if (ssl) { if (ssl) {
sslCtx = SslContextBuilder.forClient().build(); sslCtx = SslContextBuilder.forClient().build();
@ -76,24 +73,26 @@ public void open() throws Exception {
webSocketClientHandler = webSocketClientHandler =
new WebSocketClientHandler( new WebSocketClientHandler(
WebSocketClientHandshakerFactory.newHandshaker( WebSocketClientHandshakerFactory.newHandshaker(
uri, WebSocketVersion.V13, null, false, EmptyHttpHeaders.INSTANCE, 1280000), this); uri, WebSocketVersion.V13, null, false, EmptyHttpHeaders.INSTANCE, 12800000), this);
ch = bootstrap.connect(uri.getHost(), port).sync().channel(); ch = bootstrap.connect(uri.getHost(), port).sync().channel();
webSocketClientHandler.handshakeFuture().sync(); webSocketClientHandler.handshakeFuture().sync();
} }
public ChannelFuture send(String text)
{ public ChannelFuture send(String text) {
LogHelper.dev("Send: %s", text); LogHelper.dev("Send: %s", text);
return ch.writeAndFlush(new TextWebSocketFrame(text)); return ch.writeAndFlush(new TextWebSocketFrame(text));
} }
abstract void onMessage(String message) throws Exception; abstract void onMessage(String message) throws Exception;
abstract void onDisconnect() throws Exception; abstract void onDisconnect() throws Exception;
abstract void onOpen() throws Exception; abstract void onOpen() throws Exception;
public void close() throws InterruptedException { public void close() throws InterruptedException {
//System.out.println("WebSocket Client sending close"); //System.out.println("WebSocket Client sending close");
isClosed = true; isClosed = true;
if(ch != null && ch.isActive()) if (ch != null && ch.isActive()) {
{
ch.writeAndFlush(new CloseWebSocketFrame()); ch.writeAndFlush(new CloseWebSocketFrame());
ch.closeFuture().sync(); ch.closeFuture().sync();
} }

View file

@ -60,24 +60,22 @@ void onMessage(String message) {
@Override @Override
void onDisconnect() { void onDisconnect() {
LogHelper.info("WebSocket client disconnect"); LogHelper.info("WebSocket client disconnect");
if(onCloseCallback != null) onCloseCallback.onClose(0,"unsupported param", !isClosed); if (onCloseCallback != null) onCloseCallback.onClose(0, "unsupported param", !isClosed);
} }
@Override @Override
void onOpen() throws Exception { void onOpen() throws Exception {
synchronized (onConnect) synchronized (onConnect) {
{
onConnect.notifyAll(); onConnect.notifyAll();
} }
} }
@FunctionalInterface @FunctionalInterface
public interface OnCloseCallback public interface OnCloseCallback {
{
void onClose(int code, String reason, boolean remote); void onClose(int code, String reason, boolean remote);
} }
public interface ReconnectCallback
{ public interface ReconnectCallback {
void onReconnect() throws IOException; void onReconnect() throws IOException;
} }
@ -126,8 +124,8 @@ public void registerResults() {
public void registerHandler(EventHandler eventHandler) { public void registerHandler(EventHandler eventHandler) {
handlers.add(eventHandler); handlers.add(eventHandler);
} }
public void waitIfNotConnected()
{ public void waitIfNotConnected() {
/*if(!isOpen() && !isClosed() && !isClosing()) /*if(!isOpen() && !isClosed() && !isClosing())
{ {
LogHelper.warning("WebSocket not connected. Try wait onConnect object"); LogHelper.warning("WebSocket not connected. Try wait onConnect object");
@ -144,7 +142,7 @@ public void waitIfNotConnected()
public void sendObject(Object obj) throws IOException { public void sendObject(Object obj) throws IOException {
waitIfNotConnected(); waitIfNotConnected();
if(ch == null || !ch.isActive()) reconnectCallback.onReconnect(); if (ch == null || !ch.isActive()) reconnectCallback.onReconnect();
//if(isClosed() && reconnectCallback != null) //if(isClosed() && reconnectCallback != null)
// reconnectCallback.onReconnect(); // reconnectCallback.onReconnect();
send(gson.toJson(obj, RequestInterface.class)); send(gson.toJson(obj, RequestInterface.class));
@ -152,7 +150,7 @@ public void sendObject(Object obj) throws IOException {
public void sendObject(Object obj, Type type) throws IOException { public void sendObject(Object obj, Type type) throws IOException {
waitIfNotConnected(); waitIfNotConnected();
if(ch == null || !ch.isActive()) reconnectCallback.onReconnect(); if (ch == null || !ch.isActive()) reconnectCallback.onReconnect();
//if(isClosed() && reconnectCallback != null) //if(isClosed() && reconnectCallback != null)
// reconnectCallback.onReconnect(); // reconnectCallback.onReconnect();
send(gson.toJson(obj, type)); send(gson.toJson(obj, type));

View file

@ -17,8 +17,7 @@ public JsonRequestAdapter(ClientWebSocketService service) {
public RequestInterface deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { public RequestInterface 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<? extends RequestInterface> cls = service.getRequestClass(typename); Class<? extends RequestInterface> cls = service.getRequestClass(typename);
if(cls == null) if (cls == null) {
{
LogHelper.error("Request type %s not found", typename); LogHelper.error("Request type %s not found", typename);
} }

View file

@ -18,8 +18,7 @@ public JsonResultAdapter(ClientWebSocketService service) {
public ResultInterface deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { public ResultInterface 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<? extends ResultInterface> cls = service.getResultClass(typename); Class<? extends ResultInterface> cls = service.getResultClass(typename);
if(cls == null) if (cls == null) {
{
LogHelper.error("Result type %s not found", typename); LogHelper.error("Result type %s not found", typename);
} }

View file

@ -16,11 +16,12 @@
public class StandartClientWebSocketService extends ClientWebSocketService { public class StandartClientWebSocketService extends ClientWebSocketService {
public WaitEventHandler waitEventHandler = new WaitEventHandler(); public WaitEventHandler waitEventHandler = new WaitEventHandler();
public StandartClientWebSocketService(GsonBuilder gsonBuilder, String address, int i) throws SSLException { public StandartClientWebSocketService(GsonBuilder gsonBuilder, String address, int i) throws SSLException {
super(gsonBuilder, address, i); super(gsonBuilder, address, i);
} }
public class RequestFuture implements Future<ResultInterface>
{ public class RequestFuture implements Future<ResultInterface> {
public final WaitEventHandler.ResultEvent event; public final WaitEventHandler.ResultEvent event;
public boolean isCanceled = false; public boolean isCanceled = false;
@ -28,8 +29,7 @@ public class RequestFuture implements Future<ResultInterface>
public RequestFuture(RequestInterface request) throws IOException { public RequestFuture(RequestInterface request) throws IOException {
event = new WaitEventHandler.ResultEvent(); event = new WaitEventHandler.ResultEvent();
event.type = request.getType(); event.type = request.getType();
if(request instanceof Request) if (request instanceof Request) {
{
event.uuid = ((Request) request).requestUUID; event.uuid = ((Request) request).requestUUID;
} }
waitEventHandler.requests.add(event); waitEventHandler.requests.add(event);
@ -55,7 +55,7 @@ public boolean isDone() {
@Override @Override
public ResultInterface get() throws InterruptedException, ExecutionException { public ResultInterface get() throws InterruptedException, ExecutionException {
if(isCanceled) return null; if (isCanceled) return null;
while (!event.ready) { while (!event.ready) {
synchronized (event) { synchronized (event) {
event.wait(); event.wait();
@ -72,7 +72,7 @@ public ResultInterface get() throws InterruptedException, ExecutionException {
@Override @Override
public ResultInterface get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException { public ResultInterface get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException {
if(isCanceled) return null; if (isCanceled) return null;
while (!event.ready) { while (!event.ready) {
synchronized (event) { synchronized (event) {
event.wait(timeout); event.wait(timeout);
@ -87,6 +87,7 @@ public ResultInterface get(long timeout, TimeUnit unit) throws InterruptedExcept
return result; return result;
} }
} }
public ResultInterface sendRequest(RequestInterface request) throws IOException, InterruptedException { public ResultInterface sendRequest(RequestInterface request) throws IOException, InterruptedException {
RequestFuture future = new RequestFuture(request); RequestFuture future = new RequestFuture(request);
ResultInterface result; ResultInterface result;
@ -97,6 +98,7 @@ public ResultInterface sendRequest(RequestInterface request) throws IOException,
} }
return result; return result;
} }
public RequestFuture asyncSendRequest(RequestInterface request) throws IOException { public RequestFuture asyncSendRequest(RequestInterface request) throws IOException {
return new RequestFuture(request); return new RequestFuture(request);
} }
@ -112,17 +114,14 @@ public static StandartClientWebSocketService initWebSockets(String address, bool
service.registerResults(); service.registerResults();
service.registerRequests(); service.registerRequests();
service.registerHandler(service.waitEventHandler); service.registerHandler(service.waitEventHandler);
if(!async) if (!async) {
{
try { try {
service.open(); service.open();
LogHelper.debug("Connect to %s", address); LogHelper.debug("Connect to %s", address);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} } else {
else
{
try { try {
service.open(); service.open();
} catch (Exception e) { } catch (Exception e) {

View file

@ -14,17 +14,16 @@ public class WaitEventHandler implements ClientWebSocketService.EventHandler {
public void process(ResultInterface result) { public void process(ResultInterface result) {
LogHelper.debug("Processing event %s type", result.getType()); LogHelper.debug("Processing event %s type", result.getType());
UUID checkUUID = null; UUID checkUUID = null;
if(result instanceof RequestEvent) if (result instanceof RequestEvent) {
{
RequestEvent event = (RequestEvent) result; RequestEvent event = (RequestEvent) result;
checkUUID = event.requestUUID; checkUUID = event.requestUUID;
if(checkUUID != null) if (checkUUID != null)
LogHelper.debug("Event UUID: %s found", checkUUID.toString()); LogHelper.debug("Event UUID: %s found", checkUUID.toString());
} }
for (ResultEvent r : requests) { for (ResultEvent r : requests) {
if(r.uuid != null) if (r.uuid != null)
LogHelper.debug("Request UUID found: %s", r.uuid.toString()); LogHelper.debug("Request UUID found: %s", r.uuid.toString());
if( (r.uuid != null && r.uuid.equals(checkUUID)) || ( checkUUID == null && (r.type.equals(result.getType()) || result.getType().equals("error") )) ) { if ((r.uuid != null && r.uuid.equals(checkUUID)) || (checkUUID == null && (r.type.equals(result.getType()) || result.getType().equals("error")))) {
LogHelper.debug("Event %s type", r.type); LogHelper.debug("Event %s type", r.type);
synchronized (r) { synchronized (r) {
r.result = result; r.result = result;

View file

@ -1,19 +1,11 @@
package ru.gravit.launcher.request.websockets; package ru.gravit.launcher.request.websockets;
import io.netty.channel.Channel; import io.netty.channel.*;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; import io.netty.handler.codec.http.websocketx.*;
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
import io.netty.handler.codec.http.websocketx.PongWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.util.CharsetUtil; import io.netty.util.CharsetUtil;
import ru.gravit.utils.helper.LogHelper; import ru.gravit.utils.helper.LogHelper;
public class WebSocketClientHandler extends SimpleChannelInboundHandler<Object> { public class WebSocketClientHandler extends SimpleChannelInboundHandler<Object> {
private final WebSocketClientHandshaker handshaker; private final WebSocketClientHandshaker handshaker;

View file

@ -1,17 +1,16 @@
package ru.gravit.launcher; package ru.gravit.launcher;
import java.io.IOException;
import java.nio.file.Path;
import java.security.spec.InvalidKeySpecException;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.api.io.TempDir;
import ru.gravit.launcher.test.utils.EXENonWarningLauncherBinary; import ru.gravit.launcher.test.utils.EXENonWarningLauncherBinary;
import ru.gravit.launchserver.LaunchServer; import ru.gravit.launchserver.LaunchServer;
import ru.gravit.utils.helper.LogHelper; import ru.gravit.utils.helper.LogHelper;
import java.io.IOException;
import java.nio.file.Path;
import java.security.spec.InvalidKeySpecException;
public class StartTest { public class StartTest {
@TempDir @TempDir
public Path dir; public Path dir;
@ -25,9 +24,9 @@ public static void prepare() {
@Test @Test
public void checkLaunchServerStarts() { public void checkLaunchServerStarts() {
try { try {
LaunchServer srv = new LaunchServer(dir, true, new String[] { "checkInstall" }); LaunchServer srv = new LaunchServer(dir, true, new String[]{"checkInstall"});
srv.run(); srv.run();
srv.commandHandler.eval(new String[] { "checkInstall" }, false); srv.commandHandler.eval(new String[]{"checkInstall"}, false);
srv.close(); srv.close();
} catch (InvalidKeySpecException | IOException e) { } catch (InvalidKeySpecException | IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);

2
Radon

@ -1 +1 @@
Subproject commit 6410af8044e7346e06f546dc04636b631fa7584c Subproject commit 60fa1c6694b570dda50056b1e2fe18fcdb0f8be0

View file

@ -37,8 +37,8 @@ pack project(':LauncherAuthlib')
relocate 'io.netty', 'ru.gravit.repackage.io.netty' relocate 'io.netty', 'ru.gravit.repackage.io.netty'
configurations = [project.configurations.pack] configurations = [project.configurations.pack]
exclude 'module-info.class' exclude 'module-info.class'
} }
build.dependsOn tasks.shadowJar build.dependsOn tasks.shadowJar

View file

@ -3,6 +3,7 @@
import ru.gravit.launcher.ClientPermissions; import ru.gravit.launcher.ClientPermissions;
import ru.gravit.launcher.Launcher; import ru.gravit.launcher.Launcher;
import ru.gravit.launcher.LauncherConfig; import ru.gravit.launcher.LauncherConfig;
import ru.gravit.launcher.config.JsonConfigurable;
import ru.gravit.launcher.events.request.ProfilesRequestEvent; import ru.gravit.launcher.events.request.ProfilesRequestEvent;
import ru.gravit.launcher.profiles.ClientProfile; import ru.gravit.launcher.profiles.ClientProfile;
import ru.gravit.launcher.request.Request; import ru.gravit.launcher.request.Request;
@ -11,7 +12,6 @@
import ru.gravit.launcher.request.update.ProfilesRequest; import ru.gravit.launcher.request.update.ProfilesRequest;
import ru.gravit.launcher.server.setup.ServerWrapperSetup; import ru.gravit.launcher.server.setup.ServerWrapperSetup;
import ru.gravit.utils.PublicURLClassLoader; import ru.gravit.utils.PublicURLClassLoader;
import ru.gravit.launcher.config.JsonConfigurable;
import ru.gravit.utils.helper.CommonHelper; import ru.gravit.utils.helper.CommonHelper;
import ru.gravit.utils.helper.IOHelper; import ru.gravit.utils.helper.IOHelper;
import ru.gravit.utils.helper.LogHelper; import ru.gravit.utils.helper.LogHelper;
@ -157,8 +157,7 @@ public void run(String... args) throws Throwable {
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));
modulesManager.postInitModules(); modulesManager.postInitModules();
if(config.websocket.enabled) if (config.websocket.enabled) {
{
Request.service.reconnectCallback = () -> Request.service.reconnectCallback = () ->
{ {
LogHelper.debug("WebSocket connect closed. Try reconnect"); LogHelper.debug("WebSocket connect closed. Try reconnect");
@ -194,8 +193,7 @@ public void updateLauncherConfig() {
LauncherConfig cfg = null; LauncherConfig cfg = null;
try { try {
cfg = new LauncherConfig(config.websocket.address, SecurityHelper.toPublicRSAKey(IOHelper.read(publicKeyFile)), new HashMap<>(), config.projectname); cfg = new LauncherConfig(config.websocket.address, SecurityHelper.toPublicRSAKey(IOHelper.read(publicKeyFile)), new HashMap<>(), config.projectname);
if(config.websocket != null && config.websocket.enabled) if (config.websocket != null && config.websocket.enabled) {
{
cfg.isNettyEnabled = true; cfg.isNettyEnabled = true;
cfg.address = config.websocket.address; cfg.address = config.websocket.address;
} }
@ -261,8 +259,8 @@ public static final class Config {
public String auth_id = ""; public String auth_id = "";
public LauncherConfig.LauncherEnvironment env; public LauncherConfig.LauncherEnvironment env;
} }
public static final class WebSocketConf
{ public static final class WebSocketConf {
public boolean enabled; public boolean enabled;
public String address; public String address;
} }

View file

@ -22,7 +22,7 @@ public ServerWrapperCommands() throws IOException {
// Set command handler // Set command handler
CommandHandler localCommandHandler; CommandHandler localCommandHandler;
try { try {
Class.forName("jline.Terminal"); Class.forName("org.jline.terminal.Terminal");
// JLine2 available // JLine2 available
localCommandHandler = new JLineCommandHandler(); localCommandHandler = new JLineCommandHandler();

View file

@ -2,7 +2,9 @@
targetCompatibility = '1.8' targetCompatibility = '1.8'
dependencies { dependencies {
compileOnly 'org.fusesource.jansi:jansi:1.17.1' compileOnly 'org.fusesource.jansi:jansi:1.18'
compileOnly 'jline:jline:2.14.6' compileOnly 'org.jline:jline:3.11.0'
compileOnly 'org.jline:jline-reader:3.11.0'
compileOnly 'org.jline:jline-terminal:3.11.0'
compile 'com.google.code.gson:gson:2.8.5' compile 'com.google.code.gson:gson:2.8.5'
} }

View file

@ -101,6 +101,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
return super.visitFile(file, attrs); return super.visitFile(file, attrs);
} }
} }
@LauncherNetworkAPI @LauncherNetworkAPI
private final Map<String, HashedEntry> map = new HashMap<>(32); private final Map<String, HashedEntry> map = new HashMap<>(32);
@ -336,35 +337,31 @@ public void write(HOutput output) throws IOException {
entry.write(output); entry.write(output);
} }
} }
public void walk(CharSequence separator, WalkCallback callback)
{ public void walk(CharSequence separator, WalkCallback callback) {
String append = ""; String append = "";
walk(append,separator, callback, true); walk(append, separator, callback, true);
} }
@FunctionalInterface @FunctionalInterface
public interface WalkCallback public interface WalkCallback {
{
void walked(String path, String name, HashedEntry entry); void walked(String path, String name, HashedEntry entry);
} }
private void walk(String append, CharSequence separator, WalkCallback callback , boolean noSeparator)
{ private void walk(String append, CharSequence separator, WalkCallback callback, boolean noSeparator) {
for(Map.Entry<String, HashedEntry> entry : map.entrySet()) for (Map.Entry<String, HashedEntry> entry : map.entrySet()) {
{
HashedEntry e = entry.getValue(); HashedEntry e = entry.getValue();
if(e.getType() == Type.FILE) if (e.getType() == Type.FILE) {
{ if (noSeparator)
if(noSeparator)
callback.walked(append + entry.getKey(), entry.getKey(), e); callback.walked(append + entry.getKey(), entry.getKey(), e);
else else
callback.walked(append + separator + entry.getKey(), entry.getKey(), e); callback.walked(append + separator + entry.getKey(), entry.getKey(), e);
} } else {
else
{
String newAppend; String newAppend;
if(noSeparator) newAppend = append + entry.getKey(); if (noSeparator) newAppend = append + entry.getKey();
else newAppend = append + separator + entry.getKey(); else newAppend = append + separator + entry.getKey();
callback.walked(newAppend, entry.getKey(), e); callback.walked(newAppend, entry.getKey(), e);
((HashedDir)e).walk(newAppend, separator, callback, false); ((HashedDir) e).walk(newAppend, separator, callback, false);
} }
} }
} }

View file

@ -10,8 +10,8 @@ public class GsonManager {
public Gson gson; public Gson gson;
public GsonBuilder configGsonBuilder; public GsonBuilder configGsonBuilder;
public Gson configGson; public Gson configGson;
public void initGson()
{ public void initGson() {
gsonBuilder = new GsonBuilder(); gsonBuilder = new GsonBuilder();
configGsonBuilder = new GsonBuilder(); configGsonBuilder = new GsonBuilder();
configGsonBuilder.setPrettyPrinting(); configGsonBuilder.setPrettyPrinting();
@ -22,16 +22,16 @@ public void initGson()
gson = gsonBuilder.create(); gson = gsonBuilder.create();
configGson = configGsonBuilder.create(); configGson = configGsonBuilder.create();
} }
public void registerAdapters(GsonBuilder builder)
{ public void registerAdapters(GsonBuilder builder) {
builder.registerTypeAdapter(HashedEntry.class, new HashedEntryAdapter()); builder.registerTypeAdapter(HashedEntry.class, new HashedEntryAdapter());
} }
public void preConfigGson(GsonBuilder gsonBuilder)
{ public void preConfigGson(GsonBuilder gsonBuilder) {
//skip //skip
} }
public void preGson(GsonBuilder gsonBuilder)
{ public void preGson(GsonBuilder gsonBuilder) {
//skip //skip
} }
} }

View file

@ -18,5 +18,5 @@ public interface Module extends AutoCloseable {
default void finish(ModuleContext context) { default void finish(ModuleContext context) {
// NOP // NOP
}; }
} }

View file

@ -3,26 +3,25 @@
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
public class BiHookSet<V,R> { public class BiHookSet<V, R> {
public Set<Hook<V,R>> list = new HashSet<>(); public Set<Hook<V, R>> list = new HashSet<>();
@FunctionalInterface @FunctionalInterface
public interface Hook<V, R> public interface Hook<V, R> {
{
boolean hook(V object, R context) throws HookException; boolean hook(V object, R context) throws HookException;
} }
public void registerHook(Hook<V, R> hook)
{ public void registerHook(Hook<V, R> hook) {
list.add(hook); list.add(hook);
} }
public boolean unregisterHook(Hook<V, R> hook)
{ public boolean unregisterHook(Hook<V, R> hook) {
return list.remove(hook); return list.remove(hook);
} }
public boolean hook(V context, R object) throws HookException
{ public boolean hook(V context, R object) throws HookException {
for(Hook<V, R> hook : list) for (Hook<V, R> hook : list) {
{ if (hook.hook(context, object)) return true;
if(hook.hook(context, object)) return true;
} }
return false; return false;
} }

View file

@ -62,7 +62,7 @@ public static JsonElement jsonRequest(JsonElement request, URL url) throws IOExc
try { try {
return parser.parse(reader); return parser.parse(reader);
} catch (Exception e) { } catch (Exception e) {
if(200 > statusCode || statusCode > 300) { if (200 > statusCode || statusCode > 300) {
LogHelper.error("JsonRequest failed. Server response code %d", statusCode); LogHelper.error("JsonRequest failed. Server response code %d", statusCode);
throw new IOException(e); throw new IOException(e);
} }

View file

@ -5,24 +5,23 @@
public class HookSet<R> { public class HookSet<R> {
public Set<Hook<R>> list = new HashSet<>(); public Set<Hook<R>> list = new HashSet<>();
@FunctionalInterface @FunctionalInterface
public interface Hook<R> public interface Hook<R> {
{
boolean hook(R context) throws HookException; boolean hook(R context) throws HookException;
} }
public void registerHook(Hook<R> hook)
{ public void registerHook(Hook<R> hook) {
list.add(hook); list.add(hook);
} }
public boolean unregisterHook(Hook<R> hook)
{ public boolean unregisterHook(Hook<R> hook) {
return list.remove(hook); return list.remove(hook);
} }
public boolean hook(R context) throws HookException
{ public boolean hook(R context) throws HookException {
for(Hook<R> hook : list) for (Hook<R> hook : list) {
{ if (hook.hook(context)) return true;
if(hook.hook(context)) return true;
} }
return false; return false;
} }

View file

@ -41,7 +41,7 @@ public synchronized String getFilename() {
public void downloadFile(URL url, String file) throws IOException { public void downloadFile(URL url, String file) throws IOException {
try (BufferedInputStream in = new BufferedInputStream(url.openStream()); FileOutputStream fout = new FileOutputStream(file)) { try (BufferedInputStream in = new BufferedInputStream(url.openStream()); FileOutputStream fout = new FileOutputStream(file)) {
final byte data[] = new byte[BUFER_SIZE]; final byte[] data = new byte[BUFER_SIZE];
int count; int count;
long timestamp = System.currentTimeMillis(); long timestamp = System.currentTimeMillis();
int writed_local = 0; int writed_local = 0;

View file

@ -18,8 +18,8 @@ public ProviderMap(String name) {
public ProviderMap() { public ProviderMap() {
this.name = "Unnamed"; this.name = "Unnamed";
} }
public String getName()
{ public String getName() {
return name; return name;
} }
@ -39,8 +39,8 @@ public String getName(Class<? extends R> clazz) {
} }
return null; return null;
} }
public Class<? extends R> unregister(String name)
{ public Class<? extends R> unregister(String name) {
return PROVIDERS.remove(name); return PROVIDERS.remove(name);
} }
} }

Some files were not shown because too many files have changed in this diff Show more