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(':LauncherAPI')
bundle project(':Radon')
bundle 'mysql:mysql-connector-java:8.0.13'
bundle 'jline:jline:2.14.6'
bundle 'net.sf.proguard:proguard-base:6.0.3'
bundle 'org.fusesource.jansi:jansi:1.17.1'
bundle 'mysql:mysql-connector-java:8.0.16'
bundle 'org.jline:jline:3.11.0'
bundle 'org.jline:jline-reader:3.11.0'
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-codec:commons-codec:1.11'
bundle 'org.javassist:javassist:3.24.1-GA'
bundle 'commons-codec:commons-codec:1.12'
bundle 'org.javassist:javassist:3.25.0-GA'
bundle 'io.netty:netty-all:4.1.36.Final'
bundle 'org.slf4j:slf4j-simple:1.7.25'

View file

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

View file

@ -16,6 +16,7 @@ public final class StarterAgent {
private static final class StarterVisitor extends SimpleFileVisitor<Path> {
private static final Set<PosixFilePermission> DPERMS;
static {
Set<PosixFilePermission> perms = new HashSet<>(Arrays.asList(PosixFilePermission.values()));
perms.remove(PosixFilePermission.OTHERS_WRITE);
@ -33,13 +34,15 @@ private StarterVisitor() {
try {
Files.deleteIfExists(filef);
Files.createFile(filef);
} catch (Throwable t) { }
} catch (Throwable ignored) {
}
}
}
@Override
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"))
inst.appendToSystemClassLoaderSearch(new JarFile(file.toFile()));
return super.visitFile(file, attrs);

View file

@ -11,24 +11,24 @@ public class JsonAuthHandler extends CachedAuthHandler {
public URL getUrl;
public URL updateAuthUrl;
public URL updateServerIdUrl;
public class EntryRequestByUsername
{
public class EntryRequestByUsername {
public String username;
public EntryRequestByUsername(String username) {
this.username = username;
}
}
public class EntryRequestByUUID
{
public class EntryRequestByUUID {
public UUID uuid;
public EntryRequestByUUID(UUID uuid) {
this.uuid = uuid;
}
}
public class UpdateAuthRequest
{
public class UpdateAuthRequest {
public UUID uuid;
public String username;
public String accessToken;
@ -39,8 +39,8 @@ public UpdateAuthRequest(UUID uuid, String username, String accessToken) {
this.accessToken = accessToken;
}
}
public class UpdateServerIDRequest
{
public class UpdateServerIDRequest {
public UUID uuid;
public String serverID;
@ -49,10 +49,11 @@ public UpdateServerIDRequest(UUID uuid, String serverID) {
this.serverID = serverID;
}
}
public class SuccessResponse
{
public class SuccessResponse {
public boolean success;
}
@Override
protected Entry fetchEntry(String username) throws IOException {
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;
public static void registerHandlers() {
if (!registredHandl) {
providers.register("none", NoProtectHandler.class);
@ -19,7 +18,9 @@ public static void registerHandlers() {
public abstract String generateSecureToken(AuthResponse.AuthContext context); //Генерация токена для передачи его в LauncherGuardInterface
public abstract String generateClientSecureToken();
public abstract boolean verifyClientSecureToken(String token, String secureKey);
public abstract boolean allowGetAccessToken(AuthResponse.AuthContext context);
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 void preAuth(String login, String password, String customText, String ip) {
return;
}
@Override

View file

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

View file

@ -46,7 +46,7 @@ public final boolean sync() throws IOException {
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);
}
}

View file

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

View file

@ -8,13 +8,13 @@
public final class TaskUtil {
public static void addCounted(List<LauncherBuildTask> tasks, int count, Predicate<LauncherBuildTask> pred, LauncherBuildTask taskAdd) {
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));
}
public static void replaceCounted(List<LauncherBuildTask> tasks, int count, Predicate<LauncherBuildTask> pred, LauncherBuildTask taskRep) {
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));
}

View file

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

View file

@ -35,8 +35,7 @@ public void invoke(String... args) throws Exception {
if (args[0].equals("stop")) {
handler.close();
}
if (args[0].equals("eventAll"))
{
if (args[0].equals("eventAll")) {
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("modules", new ModulesCommand(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);
// 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("syncUpdates", new SyncUpdatesCommand(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);
// 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("unban", new UnbanCommand(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);
//Register dump commands
BaseCommandCategory dump = new BaseCommandCategory();
dump.registerCommand("dumpSessions", new DumpSessionsCommand(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);
//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("givePermission", new GivePermissionsCommand(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);
}
}

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 (double): %f", (double) JVMHelper.RUNTIME_MXBEAN.getUptime() / 1000);
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();
}
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 String clientToken;
public void verify()
{
if(clientToken == null) LogHelper.error("[RuntimeConfig] clientToken must not be null");
public void verify() {
if (clientToken == null) LogHelper.error("[RuntimeConfig] clientToken must not be null");
}
public void reset()
{
public void reset() {
clientToken = SecurityHelper.randomStringToken();
}
}

View file

@ -82,7 +82,7 @@ protected final void debug(String message, Object... args) {
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);
}
}

View file

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

View file

@ -44,15 +44,16 @@ public void initChannel(NioSocketChannel ch) {
//p.addLast(new LoggingHandler(LogLevel.INFO));
pipeline.addLast(new HttpServerCodec());
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 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));
}
});
if(config.proxy != null && config.proxy.enabled)
{
if (config.proxy != null && config.proxy.enabled) {
LogHelper.info("Connect to main server %s");
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);
@ -64,8 +65,8 @@ public void initChannel(NioSocketChannel ch) {
}
}
}
public ChannelFuture bind(InetSocketAddress address)
{
public ChannelFuture bind(InetSocketAddress address) {
return serverBootstrap.bind(address);
}

View file

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

View file

@ -105,8 +105,7 @@ public void run() {
//engine.setUseClientMode(false);
WebSocketFrameHandler.server = LaunchServer.server;
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));
}
/*

View file

@ -28,8 +28,8 @@ public WebSocketFrameHandler(NettyConnectContext context) {
static {
service.registerResponses();
}
public void setClient(Client client)
{
public void setClient(Client client) {
this.client = client;
}
@ -52,11 +52,9 @@ protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) {
frame.content().retain();
ctx.channel().writeAndFlush(new PongWebSocketFrame(frame.content()));
//return;
}
else if ((frame instanceof PongWebSocketFrame)) {
} else if ((frame instanceof PongWebSocketFrame)) {
LogHelper.dev("WebSocket Client received pong");
}
else if ((frame instanceof CloseWebSocketFrame)) {
} else if ((frame instanceof CloseWebSocketFrame)) {
ctx.channel().close();
} else {
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) {
String request = frame.text();
JsonResponseInterface response = gson.fromJson(request, JsonResponseInterface.class);
if(server.config.netty.proxy.enabled)
{
if(server.config.netty.proxy.requests.contains(response.getType()))
{
if (server.config.netty.proxy.enabled) {
if (server.config.netty.proxy.requests.contains(response.getType())) {
UUID origRequestUUID = null;
if(response instanceof SimpleResponse)
{
if (response instanceof SimpleResponse) {
SimpleResponse simpleResponse = (SimpleResponse) response;
simpleResponse.server = server;
simpleResponse.service = this;
simpleResponse.ctx = ctx;
if(ip != null) simpleResponse.ip = ip;
if (ip != null) simpleResponse.ip = ip;
else simpleResponse.ip = IOHelper.getIP(ctx.channel().remoteAddress());
origRequestUUID = simpleResponse.requestUUID;
}
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);
if(response instanceof SimpleResponse)
{
if (response instanceof SimpleResponse) {
((SimpleResponse) response).requestUUID = proxyRequest.requestUUID;
}
proxyRequest.isCheckSign = client.checkSign;
try {
ResultInterface result = proxyRequest.request();
if(result instanceof AuthRequestEvent)
{
if (result instanceof AuthRequestEvent) {
LogHelper.debug("Client auth params get successful");
AuthRequestEvent authRequestEvent = (AuthRequestEvent) result;
client.isAuth = true;
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;
}
sendObject(ctx, result);
} catch (RequestException e)
{
} catch (RequestException e) {
sendObject(ctx, new ErrorRequestEvent(e.getMessage()));
} catch (Exception e) {
LogHelper.error(e);
RequestEvent event;
if(server.config.netty.sendExceptionEnabled)
{
if (server.config.netty.sendExceptionEnabled) {
event = new ExceptionEvent(e);
}
else
{
} else {
event = new ErrorRequestEvent("Fatal server error. Contact administrator");
}
if(response instanceof SimpleResponse)
{
if (response instanceof SimpleResponse) {
event.requestUUID = ((SimpleResponse) response).requestUUID;
}
sendObject(ctx, event);
@ -128,17 +118,16 @@ void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client client,
return;
}
}
process(ctx,response, client, ip);
process(ctx, response, client, ip);
}
void process(ChannelHandlerContext ctx, JsonResponseInterface response, Client client, String ip)
{
if(response instanceof SimpleResponse)
{
void process(ChannelHandlerContext ctx, JsonResponseInterface response, Client client, String ip) {
if (response instanceof SimpleResponse) {
SimpleResponse simpleResponse = (SimpleResponse) response;
simpleResponse.server = server;
simpleResponse.service = this;
simpleResponse.ctx = ctx;
if(ip != null) simpleResponse.ip = ip;
if (ip != null) simpleResponse.ip = ip;
else simpleResponse.ip = IOHelper.getIP(ctx.channel().remoteAddress());
}
try {
@ -146,16 +135,12 @@ void process(ChannelHandlerContext ctx, JsonResponseInterface response, Client c
} catch (Exception e) {
LogHelper.error(e);
RequestEvent event;
if(server.config.netty.sendExceptionEnabled)
{
if (server.config.netty.sendExceptionEnabled) {
event = new ExceptionEvent(e);
}
else
{
} else {
event = new ErrorRequestEvent("Fatal server error. Contact administrator");
}
if(response instanceof SimpleResponse)
{
if (response instanceof SimpleResponse) {
event.requestUUID = ((SimpleResponse) response).requestUUID;
}
sendObject(ctx, event);
@ -204,15 +189,13 @@ public void sendObject(ChannelHandlerContext ctx, Object obj, Type type) {
}
public void sendObjectAll(Object obj) {
for(Channel ch : channels)
{
for (Channel ch : channels) {
ch.writeAndFlush(new TextWebSocketFrame(gson.toJson(obj, ResultInterface.class)));
}
}
public void sendObjectAll(Object obj, Type type) {
for(Channel ch : channels)
{
for (Channel ch : channels) {
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 ChannelHandlerContext ctx;
public transient String ip;
public void sendResult(RequestEvent result)
{
public void sendResult(RequestEvent result) {
result.requestUUID = requestUUID;
service.sendObject(ctx, result);
}
public void sendResultAndClose(RequestEvent result)
{
public void sendResultAndClose(RequestEvent result) {
result.requestUUID = requestUUID;
service.sendObjectAndClose(ctx, result);
}
public void sendError(String errorMessage)
{
public void sendError(String errorMessage) {
ErrorRequestEvent event = new ErrorRequestEvent(errorMessage);
event.requestUUID = requestUUID;
service.sendObject(ctx, event);

View file

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

View file

@ -61,7 +61,7 @@ public String getType() {
public void execute(ChannelHandlerContext ctx, Client clientData) throws Exception {
try {
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");
return;
}
@ -113,21 +113,18 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
clientData.updateAuth();
result.accessToken = aresult.accessToken;
result.permissions = clientData.permissions;
if(getSession)
{
if(clientData.session == 0) {
if (getSession) {
if (clientData.session == 0) {
clientData.session = random.nextLong();
LaunchServer.server.sessionManager.addClient(clientData);
}
result.session = clientData.session;
}
if(initProxy)
{
if(!clientData.permissions.canProxy) throw new AuthException("initProxy not allow");
if (initProxy) {
if (!clientData.permissions.canProxy) throw new AuthException("initProxy not allow");
clientData.proxy = true;
}
if(LaunchServer.server.config.protectHandler.allowGetAccessToken(context))
{
if (LaunchServer.server.config.protectHandler.allowGetAccessToken(context)) {
UUID uuid = pair.handler.auth(aresult);
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());
@ -137,6 +134,7 @@ public void execute(ChannelHandlerContext ctx, Client clientData) throws Excepti
sendError(e.getMessage());
}
}
public static class AuthContext {
public AuthContext(long session, String login, int password_lenght, String customText, String client, String hwid, String ip, boolean isServerAuth) {
this.session = session;

View file

@ -19,8 +19,7 @@ public String getType() {
@Override
public void execute(ChannelHandlerContext ctx, Client client) {
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));
}
sendResult(new GetAvailabilityAuthRequestEvent(list));

View file

@ -18,17 +18,16 @@ public class JoinServerResponse extends SimpleResponse {
public String getType() {
return "joinServer";
}
@Override
public void execute(ChannelHandlerContext ctx, Client client) {
boolean success;
try {
server.authHookManager.joinServerHook.hook(this, client);
if(client.auth == null)
{
if (client.auth == null) {
LogHelper.warning("Client auth is null. Using default.");
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);
} catch (AuthException | HookException e) {
sendError(e.getMessage());

View file

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

View file

@ -26,8 +26,7 @@ public void execute(ChannelHandlerContext ctx, Client client) {
}
try {
server.authHookManager.setProfileHook.hook(this, client);
} catch (HookException e)
{
} catch (HookException e) {
sendError(e.getMessage());
}
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];
for (int i = 0; i < list.length; ++i) {
UUID uuid;
if(client.auth == null)
{
if (client.auth == null) {
LogHelper.warning("Client auth is null. Using default.");
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);
}
sendResult(result);

View file

@ -48,12 +48,10 @@ public String getType() {
@Override
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
String username;
if(client.auth == null)
{
if (client.auth == null) {
LogHelper.warning("Client auth is null. Using default.");
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)));
}
}

View file

@ -23,12 +23,10 @@ public String getType() {
@Override
public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
UUID uuid;
if(client.auth == null)
{
if (client.auth == null) {
LogHelper.warning("Client auth is null. Using default.");
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)));
}
}

View file

@ -17,7 +17,7 @@ public String getType() {
@Override
public void execute(ChannelHandlerContext ctx, Client client) {
boolean success = LaunchServer.server.config.protectHandler.verifyClientSecureToken(secureToken, client.verifyToken);
if(success) client.isSecure = true;
if (success) client.isSecure = true;
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);
if(dir == null)
{
if (dir == null) {
service.sendObject(ctx, new ErrorRequestEvent(String.format("Directory %s not found", dirName)));
return;
}
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);
service.sendObject(ctx, new UpdateRequestEvent(dir.object, url));
String url = LaunchServer.server.config.netty.downloadURL.replace("%dirname%", dirName);
boolean zip = false;
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");
}
try {
Class.forName("jline.Terminal");
Class.forName("org.jline.terminal.Terminal");
// JLine2 available
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");
commandHandler.run();
}
public static void registerCommands()
{
public static void registerCommands() {
commandHandler.registerCommand("help", new HelpCommand(commandHandler));
commandHandler.registerCommand("exit", new ExitCommand());
commandHandler.registerCommand("logListener", new LogListenerCommand());

View file

@ -19,6 +19,6 @@ public String getUsageDescription() {
@Override
public void invoke(String... args) throws Exception {
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;
public class LogListenerCommand extends Command {
public class LogListenerRequest implements RequestInterface
{
public class LogListenerRequest implements RequestInterface {
@LauncherNetworkAPI
public LogHelper.OutputTypes outputType;
@ -22,6 +21,7 @@ public String getType() {
return "addLogListener";
}
}
@Override
public String getArgsDescription() {
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));
LogHelper.info("Add log handler");
Request.service.registerHandler((result) -> {
if(result instanceof LogEvent)
{
if (result instanceof LogEvent) {
System.out.println(((LogEvent) result).string);
}
});

View file

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

View file

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

View file

@ -8,17 +8,20 @@
<!-- 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>
<URL value="@debug.css" />
<URL value="@../../styles.css" />
<URL value="@debug.css"/>
<URL value="@../../styles.css"/>
</stylesheets>
<!-- Debug controls -->
<JFXTextArea fx:id="output" focusColor="#5fd97a" prefHeight="450.0" prefWidth="693.0">
<padding>
<Insets left="10.0" right="10.0" />
</padding></JFXTextArea>
<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="Убить" />
<Insets left="10.0" right="10.0"/>
</padding>
</JFXTextArea>
<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>

View file

@ -7,13 +7,15 @@
<!-- 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>
<!-- Description -->
<Label fx:id="description" alignment="CENTER" contentDisplay="CENTER" layoutX="205.0" layoutY="328.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" />
<Label fx:id="description" alignment="CENTER" contentDisplay="CENTER" layoutX="205.0" layoutY="328.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>
<stylesheets>
<URL value="@processing.css" />
<URL value="@processing.css"/>
</stylesheets>
</Pane>

View file

@ -13,42 +13,60 @@
<!-- 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>
<Pane id="holder" prefHeight="450.0" prefWidth="694.0">
<children>
<JFXCheckBox fx:id="autoEnter" checkedColor="#5fd97a" layoutX="14.0" layoutY="137.0" text="Автовход на сервер" unCheckedColor="#909090" />
<Text fill="#8c8c8c" layoutX="40.0" layoutY="153.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Включение авто-входа означает что вы сразу после загрузки клиента попадете на сервер" wrappingWidth="636.9999872148037" 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" />
<JFXCheckBox fx:id="autoEnter" checkedColor="#5fd97a" layoutX="14.0" layoutY="137.0"
text="Автовход на сервер" unCheckedColor="#909090"/>
<Text fill="#8c8c8c" layoutX="40.0" layoutY="153.0" strokeType="OUTSIDE" strokeWidth="0.0"
text="Включение авто-входа означает что вы сразу после загрузки клиента попадете на сервер"
wrappingWidth="636.9999872148037" 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">
<Text fx:id="ramLabel" />
<Text fx:id="ramLabel"/>
</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="changeDir" layoutY="419.0" prefHeight="30.0" prefWidth="200.0" 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="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" />
<JFXButton fx:id="deleteDir" layoutX="370.0" layoutY="380.0" prefHeight="25.0" prefWidth="245.0"
text="Удалить клиенты" textAlignment="CENTER" wrapText="true"/>
<JFXButton fx:id="changeDir" layoutY="419.0" prefHeight="30.0" prefWidth="200.0"
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="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">
<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 size="19.0" />
<Font size="19.0"/>
</font>
</Text>
<JFXButton fx:id="applyTransfer" layoutX="165.0" layoutY="226.0" mnemonicParsing="false" 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="Нет, не нужно." />
<JFXButton fx:id="applyTransfer" layoutX="165.0" layoutY="226.0" mnemonicParsing="false"
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>
</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>
</Pane>
</children>
<stylesheets>
<URL value="@settings.css" />
<URL value="@../../styles.css" />
<URL value="@settings.css"/>
<URL value="@../../styles.css"/>
</stylesheets>
</Pane>

View file

@ -15,36 +15,40 @@
<children>
<Pane fx:id="bar" layoutX="692.0" prefHeight="425.0" prefWidth="43.0" styleClass="bar">
<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>
<MaterialDesignIconView fill="WHITE" glyphName="MINUS" size="30" textAlignment="CENTER" />
<MaterialDesignIconView fill="WHITE" glyphName="MINUS" size="30" textAlignment="CENTER"/>
</graphic>
</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>
<MaterialDesignIconView fill="WHITE" glyphName="CLOSE" size="30" textAlignment="CENTER" />
<MaterialDesignIconView fill="WHITE" glyphName="CLOSE" size="30" textAlignment="CENTER"/>
</graphic>
</JFXButton>
</children>
</Pane>
<JFXTextArea fx:id="output" focusColor="#d8d8d8" prefHeight="419.0" prefWidth="692.0" unFocusColor="#ffffff00">
<padding>
<Insets left="10.0" top="10.0" />
<Insets left="10.0" top="10.0"/>
</padding>
</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>
<Insets />
<Insets/>
</opaqueInsets>
<padding>
<Insets left="10.0" />
<Insets left="10.0"/>
</padding>
</JFXTextField>
<JFXButton fx:id="send" defaultButton="true" layoutX="542.0" layoutY="420.0" prefHeight="30.0" prefWidth="147.0" ripplerFill="WHITE" text="Выполнить" />
<Line endX="594.0" layoutX="98.0" layoutY="420.0" startX="-100.0" stroke="#5b3636" styleClass="lineHead" />
<JFXButton fx:id="send" defaultButton="true" layoutX="542.0" layoutY="420.0" prefHeight="30.0" prefWidth="147.0"
ripplerFill="WHITE" text="Выполнить"/>
<Line endX="594.0" layoutX="98.0" layoutY="420.0" startX="-100.0" stroke="#5b3636" styleClass="lineHead"/>
</children>
<stylesheets>
<URL value="@../../styles.css" />
<URL value="@../../overlay/debug/debug.css" />
<URL value="@../../styles.css"/>
<URL value="@../../overlay/debug/debug.css"/>
</stylesheets>
</Pane>

View file

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

View file

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

View file

@ -7,7 +7,6 @@
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.MethodNode;
import ru.gravit.launcher.utils.NativeJVMHalt;
import ru.gravit.utils.helper.LogHelper;
@ -20,7 +19,8 @@
import java.util.List;
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
public final class LauncherAgent {
@ -69,28 +69,28 @@ public static boolean isStarted() {
private static void replaceClasses(boolean pb, boolean rt) {
java.awt.Robot.class.getName();
List<java.lang.instrument.ClassDefinition> defs = new ArrayList<>();
if(rt) {
if (rt) {
try {
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);
}
}
if(pb) {
if (pb) {
try {
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);
}
}
try {
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);
}
try {
inst.redefineClasses(defs.toArray(new java.lang.instrument.ClassDefinition[0]));
} catch(Exception e) {
} catch (Exception e) {
throw new Error(e);
}
}
@ -100,73 +100,76 @@ private static void replaceClasses(boolean pb, boolean rt) {
* Use ASM to modify the byte array
*/
private static byte[] transformClass(String className, byte[] classBytes) {
if (className.equals("java.lang.Runtime")) {
ClassReader cr=new ClassReader(classBytes);
ClassNode cn=new ClassNode();
cr.accept(cn,ClassReader.EXPAND_FRAMES);
switch (className) {
case "java.lang.Runtime": {
ClassReader cr = new ClassReader(classBytes);
ClassNode cn = new ClassNode();
cr.accept(cn, ClassReader.EXPAND_FRAMES);
for (Object o : cn.methods.toArray()) {
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(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);
return cw.toByteArray();
} else if (className.equals("java.lang.ProcessBuilder")) {
ClassReader cr=new ClassReader(classBytes);
ClassNode cn=new ClassNode();
cr.accept(cn,ClassReader.EXPAND_FRAMES);
}
case "java.lang.ProcessBuilder": {
ClassReader cr = new ClassReader(classBytes);
ClassNode cn = new ClassNode();
cr.accept(cn, ClassReader.EXPAND_FRAMES);
for (Object o : cn.methods.toArray()) {
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(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);
return cw.toByteArray();
} else if (className.equals("java.awt.Robot")) {
ClassReader cr=new ClassReader(classBytes);
ClassNode cn=new ClassNode();
cr.accept(cn,ClassReader.EXPAND_FRAMES);
}
case "java.awt.Robot": {
ClassReader cr = new ClassReader(classBytes);
ClassNode cn = new ClassNode();
cr.accept(cn, ClassReader.EXPAND_FRAMES);
for (Object o : cn.methods.toArray()) {
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("mouseMove") || m.name.equals("mousePress") ||
m.name.equals("mouseWheel"))
{
m.name.equals("mouseWheel")) {
m.instructions.insert(new InsnNode(ARETURN));
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);
return cw.toByteArray();
}
}
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
* @return array, respending this class in bytecode.
* @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 {
try (InputStream is = clazz.getResourceAsStream( "/" + clazz.getName().replace('.', '/') + ".class");
try (InputStream is = clazz.getResourceAsStream("/" + clazz.getName().replace('.', '/') + ".class");
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
int r = 0;
byte[] buffer = new byte[8192];
while((r=is.read(buffer))>=0) {
while ((r = is.read(buffer)) >= 0) {
baos.write(buffer, 0, r);
}
return baos.toByteArray();

View file

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

View file

@ -11,6 +11,8 @@ public class NewLauncherSettings {
@LauncherAPI
public String login;
@LauncherAPI
public String auth;
@LauncherAPI
public byte[] rsaPassword;
@LauncherAPI
public int profile;
@ -35,8 +37,8 @@ public class NewLauncherSettings {
public List<ClientProfile> lastProfiles = new LinkedList<>();
@LauncherAPI
public Map<String, UserSettings> userSettings = new HashMap<>();
public static class HashedStoreEntry
{
public static class HashedStoreEntry {
@LauncherAPI
public HashedDir hdir;
@LauncherAPI
@ -50,15 +52,15 @@ public HashedStoreEntry(HashedDir hdir, String name, String fullPath) {
this.fullPath = fullPath;
}
}
@LauncherAPI
public transient List<HashedStoreEntry> lastHDirs = new ArrayList<>(16);
@LauncherAPI
public void putHDir(String name, Path path, HashedDir dir)
{
public void putHDir(String name, Path path, HashedDir dir) {
String fullPath = path.toAbsolutePath().toString();
for(HashedStoreEntry e : lastHDirs)
{
if(e.fullPath.equals(fullPath) && e.name.equals(name)) return;
for (HashedStoreEntry e : lastHDirs) {
if (e.fullPath.equals(fullPath) && e.name.equals(name)) return;
}
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)
HashedDir currentHDir = new HashedDir(dir, matcher, true, digest);
HashedDir.Diff diff = hdir.diff(currentHDir, matcher);
if (!diff.isSame())
{
if (!diff.isSame()) {
/*AtomicBoolean isFoundFile = new AtomicBoolean(false);
diff.extra.walk(File.separator, (e,k,v) -> {
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 {
return getAppDataDir().resolve(projectname);
}
@LauncherAPI
public static Path getStoreDir(String projectname) throws IOException
{
if(JVMHelper.OS_TYPE == JVMHelper.OS.LINUX)
public static Path getStoreDir(String projectname) throws IOException {
if (JVMHelper.OS_TYPE == JVMHelper.OS.LINUX)
return getAppDataDir().resolve("store");
else if(JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE)
else if (JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE)
return getAppDataDir().resolve("GravitLauncherStore");
else
return getAppDataDir().resolve("minecraftStore");
}
@LauncherAPI
public static Path getProjectStoreDir(String projectname) throws IOException
{
public static Path getProjectStoreDir(String projectname) throws IOException {
return getStoreDir(projectname).resolve(projectname);
}

View file

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

View file

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

View file

@ -19,6 +19,6 @@ public String getUsageDescription() {
@Override
public void invoke(String... args) throws Exception {
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;
public class LogListenerCommand extends Command {
public class LogListenerRequest implements RequestInterface
{
public class LogListenerRequest implements RequestInterface {
@LauncherNetworkAPI
public LogHelper.OutputTypes outputType;
@ -22,6 +21,7 @@ public String getType() {
return "addLogListener";
}
}
@Override
public String getArgsDescription() {
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));
LogHelper.info("Add log handler");
Request.service.registerHandler((result) -> {
if(result instanceof LogEvent)
{
LogHelper.rawLog(() -> {
return ((LogEvent) result).string;
}, () -> {
return ((LogEvent) result).string;
}, () -> {
return ((LogEvent) result).string;
});
if (result instanceof LogEvent) {
LogHelper.rawLog(() -> ((LogEvent) result).string, () -> ((LogEvent) result).string, () -> ((LogEvent) result).string);
}
});
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,7 +1,6 @@
package ru.gravit.launcher.downloader;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
@ -19,20 +18,21 @@
import java.net.URL;
import java.nio.file.Path;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class ListDownloader {
@FunctionalInterface
public interface DownloadCallback
{
void stateChanged(String filename,long downloadedSize, long size);
public interface DownloadCallback {
void stateChanged(String filename, long downloadedSize, long size);
}
@FunctionalInterface
public interface DownloadTotalCallback
{
public interface DownloadTotalCallback {
void addTotal(long size);
}
public static class DownloadTask
{
public static class DownloadTask {
public String apply;
public long size;
@ -41,6 +41,7 @@ public DownloadTask(String apply, long size) {
this.size = size;
}
}
public void download(String base, List<DownloadTask> applies, Path dstDirFile, DownloadCallback callback, DownloadTotalCallback totalCallback) throws IOException, URISyntaxException {
try (CloseableHttpClient httpclient = HttpClients.custom()
.setRedirectStrategy(new LaxRedirectStrategy())
@ -49,20 +50,30 @@ public void download(String base, List<DownloadTask> applies, Path dstDirFile, D
HttpGet get = null;
for (DownloadTask apply : applies) {
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());
if (get == null) get = new HttpGet(u);
else {
get.reset();
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()
.setRedirectStrategy(new LaxRedirectStrategy())
.build()) {
@ -80,36 +91,58 @@ static class FileDownloadResponseHandler implements ResponseHandler<Path> {
private final DownloadTask task;
private final DownloadCallback callback;
private final DownloadTotalCallback totalCallback;
private final boolean zip;
public FileDownloadResponseHandler(Path target) {
this.target = target;
this.task = null;
this.zip = false;
callback = 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.task = task;
this.callback = callback;
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
public Path handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
public Path handleResponse(HttpResponse response) throws IOException {
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);
transfer(source, this.target, task.apply, task.size, callback, totalCallback);
}
else
} else
IOHelper.transfer(source, 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)) {
long downloaded = 0L;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -9,6 +9,8 @@ public class UpdateRequestEvent extends RequestEvent {
public HashedDir hdir;
@LauncherNetworkAPI
public String url;
@LauncherNetworkAPI
public boolean zip;
@Override
public String getType() {
@ -17,10 +19,18 @@ public String getType() {
public UpdateRequestEvent(HashedDir hdir) {
this.hdir = hdir;
this.zip = false;
}
public UpdateRequestEvent(HashedDir hdir, String url) {
this.hdir = hdir;
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 {
@LauncherAPI
public boolean success;
@Override
public String getType() {
return "verifySecureToken";

View file

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

View file

@ -35,9 +35,11 @@ public static void requestError(String message) throws RequestException {
public R request() throws Exception {
if (!started.compareAndSet(false, true))
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);
}
@LauncherAPI
public R request(StandartClientWebSocketService service) throws Exception {
if (!started.compareAndSet(false, true))
@ -46,8 +48,7 @@ public R request(StandartClientWebSocketService service) throws Exception {
}
@SuppressWarnings("unchecked")
protected R requestDo(StandartClientWebSocketService service) throws Exception
{
protected R requestDo(StandartClientWebSocketService service) throws Exception {
return (R) service.sendRequest(this);
}

View file

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

View file

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

View file

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

View file

@ -18,14 +18,14 @@ class Entry {
@LauncherNetworkAPI
String client;
}
@LauncherNetworkAPI
private final Entry[] list;
@LauncherAPI
public BatchProfileByUsernameRequest(String... usernames) throws IOException {
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].username = usernames[i];
}

View file

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

View file

@ -60,24 +60,22 @@ void onMessage(String message) {
@Override
void onDisconnect() {
LogHelper.info("WebSocket client disconnect");
if(onCloseCallback != null) onCloseCallback.onClose(0,"unsupported param", !isClosed);
if (onCloseCallback != null) onCloseCallback.onClose(0, "unsupported param", !isClosed);
}
@Override
void onOpen() throws Exception {
synchronized (onConnect)
{
synchronized (onConnect) {
onConnect.notifyAll();
}
}
@FunctionalInterface
public interface OnCloseCallback
{
public interface OnCloseCallback {
void onClose(int code, String reason, boolean remote);
}
public interface ReconnectCallback
{
public interface ReconnectCallback {
void onReconnect() throws IOException;
}
@ -126,8 +124,8 @@ public void registerResults() {
public void registerHandler(EventHandler eventHandler) {
handlers.add(eventHandler);
}
public void waitIfNotConnected()
{
public void waitIfNotConnected() {
/*if(!isOpen() && !isClosed() && !isClosing())
{
LogHelper.warning("WebSocket not connected. Try wait onConnect object");
@ -144,7 +142,7 @@ public void waitIfNotConnected()
public void sendObject(Object obj) throws IOException {
waitIfNotConnected();
if(ch == null || !ch.isActive()) reconnectCallback.onReconnect();
if (ch == null || !ch.isActive()) reconnectCallback.onReconnect();
//if(isClosed() && reconnectCallback != null)
// reconnectCallback.onReconnect();
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 {
waitIfNotConnected();
if(ch == null || !ch.isActive()) reconnectCallback.onReconnect();
if (ch == null || !ch.isActive()) reconnectCallback.onReconnect();
//if(isClosed() && reconnectCallback != null)
// reconnectCallback.onReconnect();
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 {
String typename = json.getAsJsonObject().getAsJsonPrimitive(PROP_NAME).getAsString();
Class<? extends RequestInterface> cls = service.getRequestClass(typename);
if(cls == null)
{
if (cls == null) {
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 {
String typename = json.getAsJsonObject().getAsJsonPrimitive(PROP_NAME).getAsString();
Class<? extends ResultInterface> cls = service.getResultClass(typename);
if(cls == null)
{
if (cls == null) {
LogHelper.error("Result type %s not found", typename);
}

View file

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

View file

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

View file

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

View file

@ -1,17 +1,16 @@
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.Test;
import org.junit.jupiter.api.io.TempDir;
import ru.gravit.launcher.test.utils.EXENonWarningLauncherBinary;
import ru.gravit.launchserver.LaunchServer;
import ru.gravit.utils.helper.LogHelper;
import java.io.IOException;
import java.nio.file.Path;
import java.security.spec.InvalidKeySpecException;
public class StartTest {
@TempDir
public Path dir;
@ -25,9 +24,9 @@ public static void prepare() {
@Test
public void checkLaunchServerStarts() {
try {
LaunchServer srv = new LaunchServer(dir, true, new String[] { "checkInstall" });
LaunchServer srv = new LaunchServer(dir, true, new String[]{"checkInstall"});
srv.run();
srv.commandHandler.eval(new String[] { "checkInstall" }, false);
srv.commandHandler.eval(new String[]{"checkInstall"}, false);
srv.close();
} catch (InvalidKeySpecException | IOException 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'
configurations = [project.configurations.pack]
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.Launcher;
import ru.gravit.launcher.LauncherConfig;
import ru.gravit.launcher.config.JsonConfigurable;
import ru.gravit.launcher.events.request.ProfilesRequestEvent;
import ru.gravit.launcher.profiles.ClientProfile;
import ru.gravit.launcher.request.Request;
@ -11,7 +12,6 @@
import ru.gravit.launcher.request.update.ProfilesRequest;
import ru.gravit.launcher.server.setup.ServerWrapperSetup;
import ru.gravit.utils.PublicURLClassLoader;
import ru.gravit.launcher.config.JsonConfigurable;
import ru.gravit.utils.helper.CommonHelper;
import ru.gravit.utils.helper.IOHelper;
import ru.gravit.utils.helper.LogHelper;
@ -157,8 +157,7 @@ public void run(String... args) throws Throwable {
else mainClass = Class.forName(classname);
MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class));
modulesManager.postInitModules();
if(config.websocket.enabled)
{
if (config.websocket.enabled) {
Request.service.reconnectCallback = () ->
{
LogHelper.debug("WebSocket connect closed. Try reconnect");
@ -194,8 +193,7 @@ public void updateLauncherConfig() {
LauncherConfig cfg = null;
try {
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.address = config.websocket.address;
}
@ -261,8 +259,8 @@ public static final class Config {
public String auth_id = "";
public LauncherConfig.LauncherEnvironment env;
}
public static final class WebSocketConf
{
public static final class WebSocketConf {
public boolean enabled;
public String address;
}

View file

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

View file

@ -2,7 +2,9 @@
targetCompatibility = '1.8'
dependencies {
compileOnly 'org.fusesource.jansi:jansi:1.17.1'
compileOnly 'jline:jline:2.14.6'
compileOnly 'org.fusesource.jansi:jansi:1.18'
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'
}

View file

@ -101,6 +101,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
return super.visitFile(file, attrs);
}
}
@LauncherNetworkAPI
private final Map<String, HashedEntry> map = new HashMap<>(32);
@ -336,35 +337,31 @@ public void write(HOutput output) throws IOException {
entry.write(output);
}
}
public void walk(CharSequence separator, WalkCallback callback)
{
public void walk(CharSequence separator, WalkCallback callback) {
String append = "";
walk(append,separator, callback, true);
walk(append, separator, callback, true);
}
@FunctionalInterface
public interface WalkCallback
{
public interface WalkCallback {
void walked(String path, String name, HashedEntry entry);
}
private void walk(String append, CharSequence separator, WalkCallback callback , boolean noSeparator)
{
for(Map.Entry<String, HashedEntry> entry : map.entrySet())
{
private void walk(String append, CharSequence separator, WalkCallback callback, boolean noSeparator) {
for (Map.Entry<String, HashedEntry> entry : map.entrySet()) {
HashedEntry e = entry.getValue();
if(e.getType() == Type.FILE)
{
if(noSeparator)
if (e.getType() == Type.FILE) {
if (noSeparator)
callback.walked(append + entry.getKey(), entry.getKey(), e);
else
callback.walked(append + separator + entry.getKey(), entry.getKey(), e);
}
else
{
} else {
String newAppend;
if(noSeparator) newAppend = append + entry.getKey();
if (noSeparator) newAppend = append + entry.getKey();
else newAppend = append + separator + entry.getKey();
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 GsonBuilder configGsonBuilder;
public Gson configGson;
public void initGson()
{
public void initGson() {
gsonBuilder = new GsonBuilder();
configGsonBuilder = new GsonBuilder();
configGsonBuilder.setPrettyPrinting();
@ -22,16 +22,16 @@ public void initGson()
gson = gsonBuilder.create();
configGson = configGsonBuilder.create();
}
public void registerAdapters(GsonBuilder builder)
{
public void registerAdapters(GsonBuilder builder) {
builder.registerTypeAdapter(HashedEntry.class, new HashedEntryAdapter());
}
public void preConfigGson(GsonBuilder gsonBuilder)
{
public void preConfigGson(GsonBuilder gsonBuilder) {
//skip
}
public void preGson(GsonBuilder gsonBuilder)
{
public void preGson(GsonBuilder gsonBuilder) {
//skip
}
}

View file

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

View file

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

View file

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

View file

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

View file

@ -41,7 +41,7 @@ public synchronized String getFilename() {
public void downloadFile(URL url, String file) throws IOException {
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;
long timestamp = System.currentTimeMillis();
int writed_local = 0;

View file

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

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