mirror of
https://github.com/GravitLauncher/Launcher
synced 2025-01-10 17:49:40 +03:00
Merge branch 'release/5.0.0b7'
This commit is contained in:
commit
cd13b7f5b5
130 changed files with 1355 additions and 1165 deletions
37
.gitlab-ci.yml
Normal file
37
.gitlab-ci.yml
Normal 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/*.jar
|
||||
- ServerWrapper/build/libs/*.jar
|
||||
expire_in: 1 week
|
||||
|
||||
test:
|
||||
stage: test
|
||||
script:
|
||||
- ./gradlew check
|
||||
|
||||
after_script:
|
||||
- echo "End CI"
|
|
@ -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'
|
||||
|
|
|
@ -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 {
|
||||
|
@ -267,14 +264,14 @@ public static class ExeConf {
|
|||
public String txtProductVersion;
|
||||
}
|
||||
|
||||
public class LauncherConf
|
||||
{
|
||||
public class LauncherConf {
|
||||
public String guardType;
|
||||
}
|
||||
|
||||
public class NettyConfig {
|
||||
public boolean fileServerEnabled;
|
||||
public boolean sendExceptionEnabled;
|
||||
public boolean ipForwarding;
|
||||
public String launcherURL;
|
||||
public String downloadURL;
|
||||
public String launcherEXEURL;
|
||||
|
@ -285,13 +282,13 @@ public class NettyConfig {
|
|||
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";
|
||||
|
@ -299,8 +296,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;
|
||||
|
||||
|
@ -480,7 +477,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();
|
||||
|
@ -531,14 +528,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);
|
||||
|
@ -673,10 +667,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");
|
||||
|
@ -761,13 +753,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";
|
||||
}
|
||||
|
@ -868,7 +858,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;
|
||||
}
|
||||
|
||||
|
@ -919,6 +910,7 @@ public void registerObject(String name, Object object) {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterObject(String name, Object object) {
|
||||
if (object instanceof Reloadable) {
|
||||
reloadManager.unregisterReloadable(name);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 при ошибке проверки лицензии
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
|
||||
public class LaunchServerRuntimeConfig {
|
||||
public String clientToken;
|
||||
public void verify()
|
||||
{
|
||||
|
||||
public void verify() {
|
||||
if (clientToken == null) LogHelper.error("[RuntimeConfig] clientToken must not be null");
|
||||
}
|
||||
public void reset()
|
||||
{
|
||||
|
||||
public void reset() {
|
||||
clientToken = SecurityHelper.randomStringToken();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -40,17 +40,20 @@ public LauncherNettyServer() {
|
|||
@Override
|
||||
public void initChannel(NioSocketChannel ch) {
|
||||
ChannelPipeline pipeline = ch.pipeline();
|
||||
NettyConnectContext context = new NettyConnectContext();
|
||||
//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));
|
||||
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));
|
||||
pipeline.addLast(new WebSocketFrameHandler());
|
||||
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);
|
||||
|
@ -62,8 +65,8 @@ public void initChannel(NioSocketChannel ch) {
|
|||
}
|
||||
}
|
||||
}
|
||||
public ChannelFuture bind(InetSocketAddress address)
|
||||
{
|
||||
|
||||
public ChannelFuture bind(InetSocketAddress address) {
|
||||
return serverBootstrap.bind(address);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package ru.gravit.launchserver.websocket;
|
||||
|
||||
public class NettyConnectContext {
|
||||
public String ip = null;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package ru.gravit.launchserver.websocket;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||
import io.netty.handler.codec.http.HttpHeaders;
|
||||
import io.netty.handler.codec.http.HttpRequest;
|
||||
import io.netty.util.ReferenceCounted;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class NettyIpForwardHandler extends MessageToMessageDecoder<HttpRequest> {
|
||||
private NettyConnectContext context;
|
||||
|
||||
public NettyIpForwardHandler(NettyConnectContext context) {
|
||||
super();
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, HttpRequest msg, List<Object> out) throws Exception {
|
||||
if (msg instanceof ReferenceCounted) {
|
||||
((ReferenceCounted) msg).retain();
|
||||
}
|
||||
if (context.ip != null) {
|
||||
out.add(msg);
|
||||
return;
|
||||
}
|
||||
HttpHeaders headers = msg.headers();
|
||||
String realIP = null;
|
||||
if (headers.contains("X-Forwarded-For")) {
|
||||
realIP = headers.get("X-Forwarded-For");
|
||||
}
|
||||
if (headers.contains("X-Real-IP")) {
|
||||
realIP = headers.get("X-Real-IP");
|
||||
}
|
||||
if (realIP != null) {
|
||||
LogHelper.dev("Real IP address %s", realIP);
|
||||
context.ip = realIP;
|
||||
} else LogHelper.error("IpForwarding error. Headers not found");
|
||||
out.add(msg);
|
||||
}
|
||||
}
|
|
@ -100,13 +100,12 @@ public void run() {
|
|||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}*/
|
||||
LogHelper.info("Starting server socket thread");
|
||||
LogHelper.info("Starting netty server socket thread");
|
||||
//SSLEngine engine = sc.createSSLEngine();
|
||||
//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));
|
||||
}
|
||||
/*
|
||||
|
|
|
@ -17,13 +17,19 @@ public class WebSocketFrameHandler extends SimpleChannelInboundHandler<WebSocket
|
|||
public static LaunchServer server;
|
||||
public static GsonBuilder builder = new GsonBuilder();
|
||||
public static WebSocketService service = new WebSocketService(new DefaultChannelGroup(GlobalEventExecutor.INSTANCE), LaunchServer.server, builder);
|
||||
public NettyConnectContext context;
|
||||
|
||||
public WebSocketFrameHandler(NettyConnectContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
private Client client;
|
||||
|
||||
static {
|
||||
service.registerResponses();
|
||||
}
|
||||
public void setClient(Client client)
|
||||
{
|
||||
|
||||
public void setClient(Client client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
|
@ -40,18 +46,15 @@ public void channelActive(ChannelHandlerContext ctx) {
|
|||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) {
|
||||
// ping and pong frames already handled
|
||||
|
||||
if (frame instanceof TextWebSocketFrame) {
|
||||
service.process(ctx, (TextWebSocketFrame) frame, client);
|
||||
service.process(ctx, (TextWebSocketFrame) frame, client, context.ip);
|
||||
} else if ((frame instanceof PingWebSocketFrame)) {
|
||||
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();
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
import ru.gravit.launchserver.websocket.json.update.LauncherResponse;
|
||||
import ru.gravit.launchserver.websocket.json.update.UpdateListResponse;
|
||||
import ru.gravit.launchserver.websocket.json.update.UpdateResponse;
|
||||
import ru.gravit.utils.helper.IOHelper;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
@ -62,94 +63,84 @@ public WebSocketService(ChannelGroup channels, LaunchServer server, GsonBuilder
|
|||
private final GsonBuilder gsonBuiler;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
void process(ChannelHandlerContext ctx, TextWebSocketFrame frame, Client client) {
|
||||
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;
|
||||
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();
|
||||
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);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
process(ctx,response, client);
|
||||
process(ctx, response, client, ip);
|
||||
}
|
||||
void process(ChannelHandlerContext ctx, JsonResponseInterface response, Client client)
|
||||
{
|
||||
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;
|
||||
else simpleResponse.ip = IOHelper.getIP(ctx.channel().remoteAddress());
|
||||
}
|
||||
try {
|
||||
response.execute(ctx, client);
|
||||
} 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);
|
||||
|
@ -198,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)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,18 +14,19 @@ public abstract class SimpleResponse implements JsonResponseInterface {
|
|||
public transient LaunchServer server;
|
||||
public transient WebSocketService service;
|
||||
public transient ChannelHandlerContext ctx;
|
||||
public void sendResult(RequestEvent result)
|
||||
{
|
||||
public transient String ip;
|
||||
|
||||
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);
|
||||
|
|
|
@ -9,6 +9,7 @@ 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) {
|
||||
|
|
|
@ -61,7 +61,6 @@ public String getType() {
|
|||
public void execute(ChannelHandlerContext ctx, Client clientData) throws Exception {
|
||||
try {
|
||||
AuthRequestEvent result = new AuthRequestEvent();
|
||||
String ip = IOHelper.getIP(ctx.channel().remoteAddress());
|
||||
if ((authType == null || authType == ConnectTypes.CLIENT) && (clientData == null || !clientData.checkSign)) {
|
||||
AuthProvider.authError("Don't skip Launcher Update");
|
||||
return;
|
||||
|
@ -114,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 (getSession) {
|
||||
if (clientData.session == 0) {
|
||||
clientData.session = random.nextLong();
|
||||
LaunchServer.server.sessionManager.addClient(clientData);
|
||||
}
|
||||
result.session = clientData.session;
|
||||
}
|
||||
if(initProxy)
|
||||
{
|
||||
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());
|
||||
|
@ -138,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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,8 +34,7 @@ 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;
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
var authPane, dimPane, serverPane, bar, consoleBar, optionsPane, consolePane;
|
||||
var authPane, dimPane, serverPane, bar, consoleBar, optionsPane, consolePane, loginPaneLayout, serverPaneLayout;
|
||||
var loginField, passwordField, savePasswordBox, authOptions;
|
||||
var serverList, serverInfo, serverDescription, serverEntrance, serverLabel, serverStatus;
|
||||
var profilesList = [];
|
||||
var movePoint = null;
|
||||
var pingers = {};
|
||||
var loginData;
|
||||
// Variable which contains all types of auth. Appending data at line 255
|
||||
var authTypes = {};
|
||||
|
||||
function initLauncher() {
|
||||
initLoginScene();
|
||||
|
@ -41,6 +43,9 @@ function initLoginScene() {
|
|||
var pane = loginPane.lookup("#authPane");
|
||||
authPane = pane;
|
||||
|
||||
var loginLayout = loginPane.lookup("#layout");
|
||||
loginPaneLayout = loginLayout;
|
||||
|
||||
loginField = pane.lookup("#login");
|
||||
loginField.setOnMouseMoved(function(event){rootPane.fireEvent(event)});
|
||||
loginField.setOnAction(goAuth);
|
||||
|
@ -59,12 +64,12 @@ function initLoginScene() {
|
|||
savePasswordBox = pane.lookup("#rememberchb");
|
||||
savePasswordBox.setSelected(settings.login === null || settings.rsaPassword !== null);
|
||||
|
||||
authOptions = pane.lookup("#authOptions");
|
||||
|
||||
var link = pane.lookup("#link");
|
||||
link.setText(config.linkText);
|
||||
link.setOnAction(function(event) app.getHostServices().showDocument(config.linkURL.toURI()));
|
||||
|
||||
authOptions = pane.lookup("#authOptions");
|
||||
|
||||
pane.lookup("#goAuth").setOnAction(goAuth);
|
||||
}
|
||||
|
||||
|
@ -91,6 +96,9 @@ function initMenuScene() {
|
|||
var pane = menuPane.lookup("#serverPane");
|
||||
serverPane = pane;
|
||||
|
||||
var menuLayout = menuPane.lookup("#layout");
|
||||
serverPaneLayout = menuLayout;
|
||||
|
||||
pane.lookup("#clientSettings").setOnAction(goOptions);
|
||||
serverList = pane.lookup("#serverlist").getContent();
|
||||
serverInfo = pane.lookup("#serverinfo").getContent();
|
||||
|
@ -187,7 +195,17 @@ function goAuth(event) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Get auth
|
||||
var auth = authOptions.getSelectionModel().getSelectedItem();
|
||||
if (auth === null) {
|
||||
return; // No auth selected
|
||||
}
|
||||
|
||||
var rsaPassword = null;
|
||||
var auth = authOptions.getSelectionModel().getSelectedItem();
|
||||
if (auth === null) {
|
||||
return;
|
||||
}
|
||||
if (!passwordField.isDisable()) {
|
||||
var password = passwordField.getText();
|
||||
if (password !== null && !password.isEmpty()) {
|
||||
|
@ -202,7 +220,7 @@ function goAuth(event) {
|
|||
}
|
||||
|
||||
settings.login = login;
|
||||
doAuth(login, rsaPassword);
|
||||
doAuth(/*auth, */login, rsaPassword, authTypes[auth]);
|
||||
}
|
||||
|
||||
/* ======== Console ======== */
|
||||
|
@ -236,18 +254,25 @@ function verifyLauncher(e) {
|
|||
initOffline();
|
||||
}
|
||||
overlay.swap(0, processing.overlay, function(event) makeAuthAvailabilityRequest(function(result) {
|
||||
//result.list;
|
||||
//result.list[0].name;
|
||||
//result.list[0].displayName;
|
||||
var iter = 0;
|
||||
authTypes = {};
|
||||
result.list.forEach(function(auth_type, i, arr) {
|
||||
|
||||
var serverAuth = new com.jfoenix.controls.JFXComboBox();
|
||||
serverAuth.getStyleClass().add("authOptions");
|
||||
|
||||
(function() {
|
||||
// add display name to items and add name with iter to variable authTypes
|
||||
authOptions.getItems().add(auth_type.displayName);
|
||||
})();
|
||||
authTypes[auth_type.displayName] = auth_type.name;
|
||||
iter++;
|
||||
});
|
||||
authOptions.getSelectionModel().select(0);
|
||||
var sm = authOptions.getSelectionModel().selectedIndexProperty();
|
||||
// add listener to authOptions select
|
||||
sm.addListener(new javafx.beans.value.ChangeListener({
|
||||
changed: function (observableValue, oldSelection, newSelection) {
|
||||
// get auth name from authTypes
|
||||
settings.auth = authTypes[authOptions.getSelectionModel().getSelectedItem()];
|
||||
}
|
||||
}));
|
||||
overlay.swap(0, processing.overlay, function(event) makeProfilesRequest(function(result) {
|
||||
settings.lastProfiles = result.profiles;
|
||||
updateProfilesList(result.profiles);
|
||||
|
@ -262,13 +287,14 @@ function verifyLauncher(e) {
|
|||
}));
|
||||
}
|
||||
|
||||
function doAuth(login, rsaPassword) {
|
||||
function doAuth(login, rsaPassword, auth_type) {
|
||||
processing.resetOverlay();
|
||||
overlay.show(processing.overlay, function (event) {
|
||||
FunctionalBridge.getHWID.join();
|
||||
makeAuthRequest(login, rsaPassword, function (result) {
|
||||
makeAuthRequest(login, rsaPassword, auth_type, function (result) {
|
||||
FunctionalBridge.setAuthParams(result);
|
||||
loginData = { pp: result.playerProfile , accessToken: result.accessToken, permissions: result.permissions};
|
||||
loginData = { pp: result.playerProfile , accessToken: result.accessToken, permissions: result.permissions,
|
||||
auth_type: settings.auth};
|
||||
|
||||
overlay.hide(0, function () {
|
||||
setCurrentScene(menuScene);
|
||||
|
@ -397,7 +423,8 @@ var overlay = {
|
|||
|
||||
dimPane.setVisible(true);
|
||||
dimPane.toFront();
|
||||
|
||||
loginPaneLayout.setEffect(new javafx.scene.effect.GaussianBlur(55));
|
||||
serverPaneLayout.setEffect(new javafx.scene.effect.GaussianBlur(55));
|
||||
fade(dimPane, 0.0, 0.0, 1.0, function(event) {
|
||||
dimPane.requestFocus();
|
||||
dimPane.getChildren().add(newOverlay);
|
||||
|
@ -417,7 +444,8 @@ 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;
|
||||
if (onFinished !== null) {
|
||||
onFinished();
|
||||
|
@ -455,7 +483,7 @@ var serverHolder = {
|
|||
|
||||
set: function(btn){
|
||||
pingServer(btn);
|
||||
serverLabel.setText("СЕРВЕР " + profilesList[btn]);
|
||||
serverLabel.setText(profilesList[btn]);
|
||||
serverDescription.setText(profilesList[btn].info);
|
||||
btn.setSelected(true);
|
||||
btn.setDisable(true);
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
<body style="color:red">
|
||||
<h2>Offline-режим</h2>
|
||||
Лаунчер запущен в Offline-режиме. В этом режиме Вы можете запустить любой ранее загруженный клиент
|
||||
с любым именем пользователя, при этом вход на серверы с авторизацией, а так же система скинов и плащей <b>может не работать</b>.
|
||||
с любым именем пользователя, при этом вход на серверы с авторизацией, а так же система скинов и плащей <b>может не
|
||||
работать</b>.
|
||||
Скорее всего, проблема вызвана сбоем на сервере или неполадками в интернет-подключении.
|
||||
Проверьте состояние интернет-подключения или обратитесь к администратору сервера.
|
||||
</body>
|
||||
|
|
|
@ -10,10 +10,6 @@ #background > #output {
|
|||
-fx-background-radius: 0;
|
||||
-fx-font-family: monospace;
|
||||
-fx-font-size: 8pt;
|
||||
-fx-font-weight: regular;
|
||||
}
|
||||
#background > .textField {
|
||||
-fx-font-weight: regular;
|
||||
}
|
||||
|
||||
#overlay > #output .content,
|
||||
|
|
|
@ -8,17 +8,20 @@
|
|||
|
||||
<!-- DrLeonardo Design -->
|
||||
|
||||
<Pane fx:id="overlay" prefHeight="425.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"/>
|
||||
</stylesheets>
|
||||
|
||||
<!-- Debug controls -->
|
||||
<JFXTextArea fx:id="output" prefHeight="425.0" prefWidth="693.0">
|
||||
<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="390.0" prefHeight="30.0" prefWidth="100.0" text="Копировать" />
|
||||
<JFXButton fx:id="action" layoutX="533.0" layoutY="390.0" prefHeight="25.0" prefWidth="150.0" text="Убить" />
|
||||
</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>
|
||||
|
|
|
@ -7,10 +7,12 @@
|
|||
|
||||
<!-- 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" />
|
||||
<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>
|
||||
|
|
|
@ -124,9 +124,9 @@ function makeSetProfileRequest(profile, callback) {
|
|||
startTask(task);
|
||||
}
|
||||
|
||||
function makeAuthRequest(login, rsaPassword, callback) {
|
||||
function makeAuthRequest(login, rsaPassword, auth_type, callback) {
|
||||
var task = rsaPassword === null ? newTask(offlineAuthRequest(login)) :
|
||||
newRequestTask(new AuthRequest(login, rsaPassword, FunctionalBridge.getHWID()));
|
||||
newRequestTask(new AuthRequest(login, rsaPassword, FunctionalBridge.getHWID(), auth_type));
|
||||
processing.setTaskProperties(task, callback, null, true);
|
||||
task.updateMessage("Авторизация на сервере");
|
||||
startTask(task);
|
||||
|
|
|
@ -13,37 +13,55 @@
|
|||
|
||||
<!-- 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="117.0" text="Автовход на сервер" unCheckedColor="#909090" />
|
||||
<Text fill="#8c8c8c" layoutX="40.0" layoutY="133.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Включение авто-входа означает что вы сразу после загрузки клиента попадете на сервер" wrappingWidth="636.9999872148037" y="15.0" />
|
||||
<JFXCheckBox fx:id="fullScreen" checkedColor="#5fd97a" layoutX="13.0" layoutY="240.0" text="Клиент в полный экран" unCheckedColor="#909090" />
|
||||
<Text fill="#8c8c8c" layoutX="40.0" layoutY="257.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Включение данной функции позволяет запустить игру сразу в полноэкранном режиме" wrappingWidth="636.9999872148037" y="15.0" />
|
||||
<JFXCheckBox id="debug" checkedColor="#5fd97a" layoutX="13.0" layoutY="173.0" text="Режим Отладки" unCheckedColor="#909090" />
|
||||
<Text fill="#8c8c8c" layoutX="40.0" layoutY="188.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"/>
|
||||
</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="Применить" />
|
||||
<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>
|
||||
</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>
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
#overlay {
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-size: cover;
|
||||
-fx-pref-width: 693px;
|
||||
-fx-pref-height: 450px;
|
||||
-fx-background-image: url('../../images/background.jpg');
|
||||
}
|
||||
|
||||
|
@ -23,8 +21,6 @@ #overlay > #description.error {
|
|||
|
||||
.downloadPane {
|
||||
-fx-background-color: rgba(0, 0, 0, 0.3);
|
||||
-fx-pref-width: 693px;
|
||||
-fx-pref-height: 450px;
|
||||
}
|
||||
|
||||
/* Progress bar */
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import com.jfoenix.controls.JFXProgressBar?>
|
||||
<?import com.jfoenix.controls.JFXSpinner?>
|
||||
<?import java.net.URL?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
|
@ -9,19 +8,26 @@
|
|||
|
||||
<!-- DrLeonardo Design -->
|
||||
|
||||
<Pane fx:id="overlay" prefHeight="425.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 prefHeight="425.0" prefWidth="693.0" styleClass="downloadPane">
|
||||
<Pane prefHeight="450.0" prefWidth="693.0" styleClass="downloadPane">
|
||||
<children>
|
||||
<Label fx:id="description" layoutX="17.0" layoutY="320.0" prefHeight="105.0" prefWidth="660.0" text="..." textFill="WHITE" />
|
||||
<Label fx:id="utitle" alignment="TOP_LEFT" layoutX="59.0" layoutY="279.0" prefHeight="18.0" prefWidth="470.0" text="Обновление..." textFill="WHITE">
|
||||
<Label fx:id="utitle" alignment="CENTER" layoutX="100.0" layoutY="125.0" prefHeight="30.0"
|
||||
prefWidth="495.0" text="Загрузка обновления..." textFill="WHITE">
|
||||
<font>
|
||||
<Font name="System Bold" size="13.0" />
|
||||
<Font name="System Bold" size="20.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
<JFXProgressBar fx:id="progress" layoutY="438.0" prefHeight="12.0" prefWidth="693.0" />
|
||||
<JFXSpinner layoutX="14.0" layoutY="271.0" prefHeight="35.0" prefWidth="32.0" />
|
||||
</children></Pane>
|
||||
<JFXSpinner fx:id="progress" layoutX="98.0" layoutY="226.0" prefHeight="100.0" prefWidth="100.0"/>
|
||||
<Label fx:id="description" layoutX="216.0" layoutY="226.0" prefHeight="100.0" prefWidth="380.0"
|
||||
text="..." textFill="WHITE">
|
||||
<font>
|
||||
<Font name="System Bold" size="16.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
</children>
|
||||
</Pane>
|
||||
</children>
|
||||
<stylesheets>
|
||||
<URL value="@update.css"/>
|
||||
|
|
|
@ -15,12 +15,14 @@
|
|||
<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"/>
|
||||
</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"/>
|
||||
</graphic>
|
||||
|
@ -32,7 +34,8 @@
|
|||
<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/>
|
||||
</opaqueInsets>
|
||||
|
@ -40,7 +43,8 @@
|
|||
<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="Выполнить" />
|
||||
<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>
|
||||
|
|
|
@ -14,45 +14,61 @@
|
|||
|
||||
<!-- DrLeonardo Design -->
|
||||
|
||||
<Pane fx:id="layout" prefWidth="740.0" xmlns="http://javafx.com/javafx/8.0.201" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<Pane fx:id="loginPane" prefWidth="740.0" xmlns="http://javafx.com/javafx/8.0.201" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<Pane fx:id="layout" prefWidth="740.0">
|
||||
<children>
|
||||
<Pane fx:id="authPane" layoutX="422.0" prefHeight="411.0" prefWidth="286.0" styleClass="loginPane">
|
||||
<children>
|
||||
<Pane fx:id="logo" layoutX="72.0" layoutY="62.0" prefWidth="124.0" styleClass="logo">
|
||||
</Pane>
|
||||
<JFXTextField id="login" alignment="CENTER" focusColor="#5fd97a" layoutX="34.0" layoutY="196.0" promptText="Логин" unFocusColor="#dadada" />
|
||||
<JFXPasswordField id="password" alignment="CENTER" focusColor="#5fd97a" layoutX="34.0" layoutY="249.0" promptText="Пароль" unFocusColor="#dadada" />
|
||||
<JFXTextField id="login" alignment="CENTER" focusColor="#5fd97a" layoutX="34.0" layoutY="196.0"
|
||||
promptText="Логин" unFocusColor="#dadada"/>
|
||||
<JFXPasswordField id="password" alignment="CENTER" focusColor="#5fd97a" layoutX="34.0"
|
||||
layoutY="249.0" promptText="Пароль" unFocusColor="#dadada"/>
|
||||
<JFXButton id="goAuth" layoutX="34.0" layoutY="370.0" styleClass="auth" text="ВОЙТИ"/>
|
||||
<JFXCheckBox id="rememberchb" fx:id="savePassword" checkedColor="#5fd97a" contentDisplay="CENTER" layoutX="63.0" layoutY="297.0" prefWidth="144.0" text="Сохранить пароль" textFill="#dadada" unCheckedColor="#909090" />
|
||||
<JFXComboBox id="authOptions" fx:id="authOptions" focusColor="#5fd97a" layoutX="34.0" layoutY="341.0" prefHeight="25.0" prefWidth="200.0" promptText="Авторизация 1" unFocusColor="#70666600">
|
||||
<JFXCheckBox id="rememberchb" fx:id="savePassword" checkedColor="#5fd97a"
|
||||
contentDisplay="CENTER" layoutX="63.0" layoutY="297.0" prefWidth="144.0"
|
||||
text="Сохранить пароль" textFill="#dadada" unCheckedColor="#909090"/>
|
||||
<JFXComboBox id="authOptions" fx:id="authOptions" focusColor="#5fd97a" layoutX="34.0"
|
||||
layoutY="341.0" prefHeight="25.0" prefWidth="200.0" promptText="Авторизация 1"
|
||||
unFocusColor="#70666600">
|
||||
<styleClass>
|
||||
<String fx:value="combologin"/>
|
||||
<String fx:value="combologin-popup"/>
|
||||
</styleClass></JFXComboBox>
|
||||
<Hyperlink id="link" fx:id="link" layoutX="94.0" layoutY="422.0" prefHeight="19.0" prefWidth="81.0" textAlignment="CENTER" />
|
||||
</styleClass>
|
||||
</JFXComboBox>
|
||||
<Hyperlink id="link" fx:id="link" layoutX="94.0" layoutY="422.0" prefHeight="19.0"
|
||||
prefWidth="81.0" textAlignment="CENTER"/>
|
||||
</children>
|
||||
</Pane>
|
||||
<JFXMasonryPane fx:id="news" prefHeight="432.0" prefWidth="423.0" styleClass="news"/>
|
||||
<Pane fx:id="bar" layoutX="692.0" prefHeight="425.0" prefWidth="43.0" styleClass="bar">
|
||||
</children>
|
||||
</Pane>
|
||||
<Pane id="mask" opacity="0.0" prefHeight="425.0" prefWidth="694.0" visible="false"/>
|
||||
<Pane fx:id="bar" layoutX="696.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"/>
|
||||
</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"/>
|
||||
</graphic>
|
||||
</JFXButton>
|
||||
<JFXButton id="discord" alignment="CENTER" contentDisplay="CENTER" layoutY="370.0" ripplerFill="#646464" text="" textAlignment="CENTER">
|
||||
<JFXButton id="discord" alignment="CENTER" contentDisplay="CENTER" layoutY="370.0" ripplerFill="#646464"
|
||||
text="" textAlignment="CENTER">
|
||||
<graphic>
|
||||
<MaterialDesignIconView fill="#5fd97a" glyphName="MESSAGE_TEXT" size="20" textAlignment="CENTER" />
|
||||
<MaterialDesignIconView fill="#5fd97a" glyphName="MESSAGE_TEXT" size="20"
|
||||
textAlignment="CENTER"/>
|
||||
</graphic>
|
||||
</JFXButton>
|
||||
</children>
|
||||
</Pane>
|
||||
<Pane id="mask" opacity="0.0" prefHeight="425.0" prefWidth="694.0" visible="false" />
|
||||
</children>
|
||||
<stylesheets>
|
||||
<URL value="@../../styles.css"/>
|
||||
|
|
|
@ -13,91 +13,117 @@
|
|||
|
||||
<!-- DrLeonardo Design -->
|
||||
|
||||
<Pane fx:id="layout" maxHeight="-1.0" maxWidth="-1.0" prefHeight="400.0" prefWidth="600.0" visible="true" xmlns="http://javafx.com/javafx/8.0.201" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<Pane fx:id="serverPaneLayout" maxHeight="-1.0" maxWidth="-1.0" prefWidth="740.0" visible="true"
|
||||
xmlns="http://javafx.com/javafx/8.0.201" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<Pane fx:id="layout" maxHeight="-1.0" maxWidth="-1.0" prefWidth="740.0" visible="true"
|
||||
xmlns="http://javafx.com/javafx/8.0.201" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<Pane id="serverPane" prefHeight="450.0" prefWidth="693.0">
|
||||
<children>
|
||||
<ScrollPane id="serverlist" hbarPolicy="NEVER" layoutX="1.0" prefHeight="450.0" prefWidth="307.0" visible="true">
|
||||
<ScrollPane id="serverlist" hbarPolicy="NEVER" layoutX="1.0" prefHeight="450.0"
|
||||
prefWidth="307.0" visible="true">
|
||||
<content>
|
||||
<FlowPane focusTraversable="false" prefHeight="446.0" prefWidth="306.0" prefWrapLength="0.0" rowValignment="TOP" vgap="10.0" visible="true">
|
||||
<FlowPane focusTraversable="false" prefHeight="446.0" prefWidth="306.0"
|
||||
prefWrapLength="0.0" rowValignment="TOP" vgap="10.0" visible="true">
|
||||
<JFXButton id="servercontainer" ripplerFill="#ffffff80" text="">
|
||||
<FlowPane.margin>
|
||||
<Insets bottom="10.0"/>
|
||||
</FlowPane.margin></JFXButton>
|
||||
</FlowPane.margin>
|
||||
</JFXButton>
|
||||
<padding>
|
||||
<Insets left="10.0" top="10.0"/>
|
||||
</padding>
|
||||
</FlowPane>
|
||||
</content>
|
||||
</ScrollPane>
|
||||
<Pane id="serverentrance" layoutX="306.0" prefHeight="425.0" prefWidth="388.0" styleClass="serverentrance">
|
||||
<Pane id="serverentrance" layoutX="306.0" prefHeight="425.0" prefWidth="388.0"
|
||||
styleClass="serverentrance">
|
||||
<children>
|
||||
<ScrollPane id="serverinfo" hbarPolicy="NEVER" layoutX="4.0" layoutY="53.0" pannable="true" prefHeight="322.0" prefWidth="381.0" visible="true">
|
||||
<ScrollPane id="serverinfo" hbarPolicy="NEVER" layoutX="4.0" layoutY="53.0"
|
||||
pannable="true" prefHeight="322.0" prefWidth="381.0" visible="true">
|
||||
<content>
|
||||
<FlowPane id="" focusTraversable="false" orientation="HORIZONTAL" prefHeight="310.0" prefWidth="369.0" rowValignment="TOP" visible="true">
|
||||
<FlowPane id="" focusTraversable="false" orientation="HORIZONTAL"
|
||||
prefHeight="310.0" prefWidth="369.0" rowValignment="TOP"
|
||||
visible="true">
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="15.0" top="7.0"/>
|
||||
</padding>
|
||||
<children>
|
||||
<Label id="serverDescription" alignment="TOP_LEFT" contentDisplay="LEFT" nodeOrientation="LEFT_TO_RIGHT" prefHeight="274.0" prefWidth="349.0" text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla convallis magna tellus, in bibendum tortor dignissim non. Phasellus vel tincidunt nulla, eu convallis ligula. Suspendisse ut diam vestibulum, tincidunt neque ut, posuere risus. Pellentesque posuere molestie eros, quis laoreet ante ornare quis. Morbi eu tortor fermentum, iaculis risus sit amet, fringilla augue. Aenean nulla purus, rutrum non sapien et, convallis tincidunt purus. Vivamus a eros pulvinar, dignissim leo lacinia, sodales nulla. Aliquam tortor augue, cursus a rutrum viverra, consequat non tellus. Donec porta nisl sed quam dictum commodo. Sed et vulputate dolor. Morbi ultrices justo vitae convallis semper. Donec sodales velit vel velit faucibus, et scelerisque felis finibus. Sed rutrum lacinia mauris, porta cursus mauris tempor eu. Duis turpis nulla, dictum vitae commodo rhoncus, pretium in turpis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos." textAlignment="JUSTIFY" textFill="#141414" wrapText="true" />
|
||||
<Label id="serverDescription" alignment="TOP_LEFT" contentDisplay="LEFT"
|
||||
nodeOrientation="LEFT_TO_RIGHT" prefHeight="274.0"
|
||||
prefWidth="349.0"
|
||||
text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla convallis magna tellus, in bibendum tortor dignissim non. Phasellus vel tincidunt nulla, eu convallis ligula. Suspendisse ut diam vestibulum, tincidunt neque ut, posuere risus. Pellentesque posuere molestie eros, quis laoreet ante ornare quis. Morbi eu tortor fermentum, iaculis risus sit amet, fringilla augue. Aenean nulla purus, rutrum non sapien et, convallis tincidunt purus. Vivamus a eros pulvinar, dignissim leo lacinia, sodales nulla. Aliquam tortor augue, cursus a rutrum viverra, consequat non tellus. Donec porta nisl sed quam dictum commodo. Sed et vulputate dolor. Morbi ultrices justo vitae convallis semper. Donec sodales velit vel velit faucibus, et scelerisque felis finibus. Sed rutrum lacinia mauris, porta cursus mauris tempor eu. Duis turpis nulla, dictum vitae commodo rhoncus, pretium in turpis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos."
|
||||
textAlignment="JUSTIFY" textFill="#141414" wrapText="true"/>
|
||||
</children>
|
||||
</FlowPane>
|
||||
</content>
|
||||
</ScrollPane>
|
||||
<JFXButton id="clientLaunch" layoutX="121.0" layoutY="380.0" prefHeight="51.0" prefWidth="183.0" styleClass="clientLaunch" text="ИГРАТЬ">
|
||||
<JFXButton id="clientLaunch" layoutX="19.0" layoutY="380.0" prefHeight="51.0"
|
||||
prefWidth="285.0" styleClass="clientLaunch" text="ИГРАТЬ">
|
||||
<font>
|
||||
<Font size="22.0"/>
|
||||
</font>
|
||||
</JFXButton>
|
||||
<JFXButton id="clientSettings" alignment="CENTER" centerShape="false" contentDisplay="CENTER" layoutX="305.0" layoutY="380.0" prefHeight="51.0" prefWidth="60.0" ripplerFill="#84da96" styleClass="clientSettings" text="" textAlignment="CENTER">
|
||||
<JFXButton id="clientSettings" alignment="CENTER" centerShape="false"
|
||||
contentDisplay="CENTER" layoutX="305.0" layoutY="380.0" prefHeight="51.0"
|
||||
prefWidth="60.0" ripplerFill="#84da96" styleClass="clientSettings" text=""
|
||||
textAlignment="CENTER">
|
||||
<graphic>
|
||||
<FontAwesomeIconView fill="WHITE" glyphName="SLIDERS" size="30.0"/>
|
||||
</graphic></JFXButton>
|
||||
<Label id="serverStatus" alignment="TOP_RIGHT" contentDisplay="RIGHT" layoutX="252.0" layoutY="12.0" prefHeight="25.0" prefWidth="97.0" text="12/100" textAlignment="RIGHT" textFill="WHITE">
|
||||
</graphic>
|
||||
</JFXButton>
|
||||
<Label id="serverStatus" alignment="TOP_RIGHT" contentDisplay="RIGHT" layoutX="165.0"
|
||||
layoutY="12.0" prefHeight="25.0" prefWidth="97.0" text="12/100"
|
||||
textAlignment="RIGHT" textFill="WHITE">
|
||||
<font>
|
||||
<Font name="System Bold" size="16.0"/>
|
||||
</font>
|
||||
</Label>
|
||||
<Label id="serverLabel" layoutX="4.0" layoutY="11.0" prefHeight="27.0" prefWidth="266.0" text="СЕРВЕР">
|
||||
<Label id="serverLabel" layoutX="20.0" layoutY="11.0" prefHeight="27.0"
|
||||
prefWidth="203.0" text="СЕРВЕР">
|
||||
<font>
|
||||
<Font name="System Bold" size="18.0"/>
|
||||
</font>
|
||||
<padding>
|
||||
<Insets left="14.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<JFXButton id="logout" alignment="CENTER" contentDisplay="CENTER" layoutX="19.0" layoutY="383.0" ripplerFill="#61616100" text="" textAlignment="CENTER">
|
||||
<graphic>
|
||||
<MaterialDesignIconView fill="#323232" glyphName="LOGOUT" size="30" textAlignment="CENTER" />
|
||||
</graphic>
|
||||
</JFXButton>
|
||||
<JFXButton id="logout" alignment="CENTER" contentDisplay="CENTER" layoutX="295.0"
|
||||
layoutY="12.0" prefHeight="25.0" prefWidth="81.0" ripplerFill="#61616100"
|
||||
text="Выйти" textAlignment="CENTER"/>
|
||||
</children>
|
||||
</Pane>
|
||||
</children>
|
||||
</Pane>
|
||||
<Pane fx:id="bar" layoutX="692.0" prefHeight="425.0" prefWidth="43.0" styleClass="bar">
|
||||
</children>
|
||||
</Pane>
|
||||
<Pane fx:id="bar" layoutX="696.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"/>
|
||||
</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"/>
|
||||
</graphic>
|
||||
</JFXButton>
|
||||
<JFXButton id="discord" alignment="CENTER" contentDisplay="CENTER" layoutY="380.0" ripplerFill="#646464" text="" textAlignment="CENTER">
|
||||
<JFXButton id="discord" alignment="CENTER" contentDisplay="CENTER" layoutY="380.0" ripplerFill="#646464"
|
||||
text="" textAlignment="CENTER">
|
||||
<graphic>
|
||||
<MaterialDesignIconView fill="#5fd97a" glyphName="MESSAGE_TEXT" size="20" smooth="false" textAlignment="CENTER" />
|
||||
<MaterialDesignIconView fill="#5fd97a" glyphName="MESSAGE_TEXT" size="20" smooth="false"
|
||||
textAlignment="CENTER"/>
|
||||
</graphic>
|
||||
</JFXButton>
|
||||
<JFXButton id="settings" alignment="CENTER" contentDisplay="CENTER" layoutY="90.0" ripplerFill="#646464" text="" textAlignment="CENTER">
|
||||
<JFXButton id="settings" alignment="CENTER" contentDisplay="CENTER" layoutY="90.0" ripplerFill="#646464"
|
||||
text="" textAlignment="CENTER">
|
||||
<graphic>
|
||||
<MaterialDesignIconView fill="WHITE" glyphName="SETTINGS" size="20" textAlignment="CENTER"/>
|
||||
</graphic>
|
||||
</JFXButton>
|
||||
<JFXButton id="goConsole" alignment="CENTER" contentDisplay="CENTER" layoutY="138.0" ripplerFill="#646464" text="" textAlignment="CENTER">
|
||||
<JFXButton id="goConsole" alignment="CENTER" contentDisplay="CENTER" layoutY="138.0"
|
||||
ripplerFill="#646464" text="" textAlignment="CENTER">
|
||||
<graphic>
|
||||
<MaterialDesignIconView fill="WHITE" glyphName="CONSOLE" size="20" textAlignment="CENTER"/>
|
||||
</graphic>
|
||||
|
|
|
@ -12,14 +12,19 @@
|
|||
|
||||
<!-- DrLeonardo Design -->
|
||||
|
||||
<Pane fx:id="background" prefHeight="450.0" prefWidth="738.0" xmlns="http://javafx.com/javafx/8.0.201" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<Pane fx:id="background" prefHeight="450.0" prefWidth="738.0" xmlns="http://javafx.com/javafx/8.0.201"
|
||||
xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<Pane id="optionsPane" prefHeight="450.0" prefWidth="692.0" styleClass="optionsPane">
|
||||
<children>
|
||||
<JFXToggleButton fx:id="presset" layoutX="30.0" layoutY="10.0" opacity="0.21" styleClass="pressetLight" text="Presset 1" />
|
||||
<JFXToggleButton fx:id="presset" layoutX="287.0" layoutY="10.0" opacity="0.21" styleClass="pressetMedium" text="Presset 2" />
|
||||
<JFXToggleButton fx:id="isPresset" layoutX="528.0" layoutY="10.0" opacity="0.21" prefHeight="58.0" prefWidth="134.0" styleClass="pressetHigh" text="Presset 3" wrapText="true" />
|
||||
<Line endX="595.0" layoutX="100.0" layoutY="80.0" startX="-100.0" stroke="#5b3636" styleClass="lineHead" />
|
||||
<JFXToggleButton fx:id="presset" layoutX="30.0" layoutY="10.0" opacity="0.21" styleClass="pressetLight"
|
||||
text="Presset 1"/>
|
||||
<JFXToggleButton fx:id="presset" layoutX="287.0" layoutY="10.0" opacity="0.21"
|
||||
styleClass="pressetMedium" text="Presset 2"/>
|
||||
<JFXToggleButton fx:id="isPresset" layoutX="528.0" layoutY="10.0" opacity="0.21" prefHeight="58.0"
|
||||
prefWidth="134.0" styleClass="pressetHigh" text="Presset 3" wrapText="true"/>
|
||||
<Line endX="595.0" layoutX="100.0" layoutY="80.0" startX="-100.0" stroke="#5b3636"
|
||||
styleClass="lineHead"/>
|
||||
<ScrollPane id="modlist" layoutY="84.0" prefHeight="364.0" prefWidth="693.0">
|
||||
<content>
|
||||
<VBox prefHeight="360.0" prefWidth="678.0">
|
||||
|
@ -35,17 +40,20 @@
|
|||
</Pane>
|
||||
<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"/>
|
||||
</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"/>
|
||||
</graphic>
|
||||
</JFXButton>
|
||||
<JFXButton id="back" alignment="CENTER" contentDisplay="CENTER" layoutY="405.0" ripplerFill="#646464" text="" textAlignment="CENTER">
|
||||
<JFXButton id="back" alignment="CENTER" contentDisplay="CENTER" layoutY="405.0" ripplerFill="#646464"
|
||||
text="" textAlignment="CENTER">
|
||||
<graphic>
|
||||
<MaterialDesignIconView fill="WHITE" glyphName="CHEVRON_LEFT" size="30" textAlignment="CENTER"/>
|
||||
</graphic>
|
||||
|
|
|
@ -17,9 +17,7 @@ .server-button {
|
|||
}
|
||||
|
||||
.server-button:selected {
|
||||
-fx-border-width: 0 0 0 2;
|
||||
-fx-border-style: none none none solid;
|
||||
-fx-border-color: #323232;
|
||||
-fx-effect: dropshadow(gaussian, rgba(23, 25, 29, 0.3), 15,0,0,3);
|
||||
}
|
||||
|
||||
/** server-button-<your profile name> **/
|
||||
|
|
|
@ -3,6 +3,7 @@ Button, CheckBox, ComboBox, RadioButton {
|
|||
-fx-cursor: hand;
|
||||
}
|
||||
|
||||
|
||||
/* Backgrounds */
|
||||
#layout {
|
||||
-fx-background-color: transparent;
|
||||
|
@ -22,9 +23,6 @@ #background > #settingsTitle {
|
|||
|
||||
#serverLabel{
|
||||
-fx-text-fill: #323232;
|
||||
-fx-padding: 0 0 0 14;
|
||||
-fx-pref-width: 265px;
|
||||
-fx-pref-height: 25px;
|
||||
}
|
||||
|
||||
#serverStatus{
|
||||
|
@ -35,7 +33,7 @@ #serverStatus{
|
|||
|
||||
/* Mask */
|
||||
#mask {
|
||||
-fx-background-color: rgba(0, 0, 0, 0.5);
|
||||
-fx-effect: DropShadow( gaussian , rgba(255,255,255,0.5) , 0,0,0,1 );
|
||||
-fx-pref-width: 692px;
|
||||
-fx-pref-height: 450px;
|
||||
}
|
||||
|
@ -66,7 +64,7 @@ #close {
|
|||
-fx-pref-width: 46px;
|
||||
-fx-pref-height: 45px;
|
||||
}
|
||||
#hide, #back, #goConsole, #settings, #logout, #discord {
|
||||
#hide, #back, #goConsole, #settings, #discord {
|
||||
-fx-background-position: center;
|
||||
-jfx-button-type: FLAT;
|
||||
-fx-background-radius: 0;
|
||||
|
@ -74,6 +72,23 @@ #hide, #back, #goConsole, #settings, #logout, #discord {
|
|||
-fx-pref-height: 45px;
|
||||
}
|
||||
|
||||
#logout{
|
||||
-fx-text-fill:#323232;
|
||||
-fx-font-size:12;
|
||||
-fx-font-weight:normal;
|
||||
-fx-border-color:#CE5757;
|
||||
-fx-border-width:1;
|
||||
-fx-background-color:transparent;
|
||||
-fx-padding:0;
|
||||
}
|
||||
#logout:hover,
|
||||
#logout:focus{
|
||||
-fx-text-fill:#ff6a5e;
|
||||
}
|
||||
#logout:pressed{
|
||||
-fx-border-color:#cb4d43;
|
||||
}
|
||||
|
||||
#send {
|
||||
-fx-background-radius: 0;
|
||||
-fx-text-fill: black;
|
||||
|
|
|
@ -27,20 +27,15 @@ 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;
|
||||
|
|
|
@ -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 {
|
||||
|
@ -100,7 +100,8 @@ 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")) {
|
||||
switch (className) {
|
||||
case "java.lang.Runtime": {
|
||||
ClassReader cr = new ClassReader(classBytes);
|
||||
ClassNode cn = new ClassNode();
|
||||
cr.accept(cn, ClassReader.EXPAND_FRAMES);
|
||||
|
@ -115,7 +116,8 @@ private static byte[] transformClass(String className, byte[] classBytes) {
|
|||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||
cn.accept(cw);
|
||||
return cw.toByteArray();
|
||||
} else if (className.equals("java.lang.ProcessBuilder")) {
|
||||
}
|
||||
case "java.lang.ProcessBuilder": {
|
||||
ClassReader cr = new ClassReader(classBytes);
|
||||
ClassNode cn = new ClassNode();
|
||||
cr.accept(cn, ClassReader.EXPAND_FRAMES);
|
||||
|
@ -130,7 +132,8 @@ private static byte[] transformClass(String className, byte[] classBytes) {
|
|||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||
cn.accept(cw);
|
||||
return cw.toByteArray();
|
||||
} else if (className.equals("java.awt.Robot")) {
|
||||
}
|
||||
case "java.awt.Robot": {
|
||||
ClassReader cr = new ClassReader(classBytes);
|
||||
ClassNode cn = new ClassNode();
|
||||
cr.accept(cn, ClassReader.EXPAND_FRAMES);
|
||||
|
@ -140,8 +143,7 @@ private static byte[] transformClass(String className, byte[] classBytes) {
|
|||
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));
|
||||
}
|
||||
|
@ -150,16 +152,17 @@ private static byte[] transformClass(String className, byte[] classBytes) {
|
|||
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");
|
||||
|
|
|
@ -33,8 +33,7 @@ public static void main(String... args) throws Throwable {
|
|||
initGson();
|
||||
ConsoleManager.initConsole();
|
||||
LauncherConfig config = Launcher.getConfig();
|
||||
if(config.environment.equals(LauncherConfig.LauncherEnvironment.PROD))
|
||||
{
|
||||
if (config.environment.equals(LauncherConfig.LauncherEnvironment.PROD)) {
|
||||
if (!LauncherAgent.isStarted()) throw new SecurityException("LauncherAgent must started");
|
||||
}
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
@ -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);
|
||||
|
|
|
@ -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,14 +52,14 @@ 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)
|
||||
{
|
||||
for (HashedStoreEntry e : lastHDirs) {
|
||||
if (e.fullPath.equals(fullPath) && e.name.equals(name)) return;
|
||||
}
|
||||
lastHDirs.add(new HashedStoreEntry(dir, name, fullPath));
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -68,9 +68,9 @@ 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
|
||||
{
|
||||
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)
|
||||
|
@ -78,9 +78,9 @@ else if(JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE)
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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,12 +29,14 @@ 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() {
|
||||
|
@ -44,11 +44,13 @@ public NewLauncherSettings getConfig() {
|
|||
settings.updatesDirPath = settings.updatesDir.toString();
|
||||
return settings;
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
@Override
|
||||
public NewLauncherSettings getDefaultConfig() {
|
||||
return new NewLauncherSettings();
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
@Override
|
||||
public void setConfig(NewLauncherSettings config) {
|
||||
|
@ -56,36 +58,34 @@ public void setConfig(NewLauncherSettings config) {
|
|||
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)))
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -15,7 +15,7 @@ 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) {
|
||||
|
@ -30,7 +30,7 @@ public static void haltA(int code) {
|
|||
}
|
||||
halt.aaabbb38C_D();
|
||||
boolean a = halt.aaabBooleanC_D();
|
||||
System.out.println(Boolean.toString(a));
|
||||
System.out.println(a);
|
||||
}
|
||||
|
||||
public static boolean initFunc() {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -22,17 +21,16 @@
|
|||
|
||||
public class ListDownloader {
|
||||
@FunctionalInterface
|
||||
public interface DownloadCallback
|
||||
{
|
||||
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 +39,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())
|
||||
|
@ -61,8 +60,7 @@ public void download(String base, List<DownloadTask> applies, Path dstDirFile, D
|
|||
}
|
||||
}
|
||||
|
||||
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()) {
|
||||
|
@ -96,20 +94,18 @@ public FileDownloadResponseHandler(Path target, DownloadTask task, DownloadCallb
|
|||
}
|
||||
|
||||
@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 (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;
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ public class ErrorRequestEvent extends RequestEvent implements EventInterface {
|
|||
public ErrorRequestEvent(String error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
@LauncherNetworkAPI
|
||||
public final String error;
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ public class ExecCommandRequestEvent extends RequestEvent {
|
|||
public String getType() {
|
||||
return "cmdExec";
|
||||
}
|
||||
|
||||
@LauncherNetworkAPI
|
||||
public boolean success;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
public class GetSecureTokenRequestEvent extends RequestEvent {
|
||||
@LauncherNetworkAPI
|
||||
public String secureToken;
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "GetSecureToken";
|
||||
|
|
|
@ -12,6 +12,7 @@ public class JoinServerRequestEvent extends RequestEvent implements EventInterfa
|
|||
public JoinServerRequestEvent(boolean allow) {
|
||||
this.allow = allow;
|
||||
}
|
||||
|
||||
@LauncherNetworkAPI
|
||||
public boolean allow;
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ public LauncherRequestEvent(boolean needUpdate, String url) {
|
|||
this.needUpdate = needUpdate;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
@LauncherNetworkAPI
|
||||
public boolean needUpdate;
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ public class LogEvent implements ResultInterface {
|
|||
public String getType() {
|
||||
return "log";
|
||||
}
|
||||
|
||||
@LauncherNetworkAPI
|
||||
public String string;
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
public class VerifySecureTokenRequestEvent extends RequestEvent {
|
||||
@LauncherAPI
|
||||
public boolean success;
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "verifySecureToken";
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -179,9 +179,7 @@ public UpdateRequestEvent requestDo(StandartClientWebSocketService service) thro
|
|||
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,7 @@ 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;
|
||||
});
|
||||
listDownloader.download(e.url, adds, dir, this::updateState, (add) -> totalDownloaded += add);
|
||||
deleteExtraDir(dir, diff.extra, diff.extra.flag);
|
||||
LogHelper.debug("Update success");
|
||||
return e;
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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 (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();
|
||||
}
|
||||
|
|
|
@ -65,19 +65,17 @@ void onDisconnect() {
|
|||
|
||||
@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");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
|
|
@ -14,8 +14,7 @@ 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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
2
Radon
2
Radon
|
@ -1 +1 @@
|
|||
Subproject commit 6410af8044e7346e06f546dc04636b631fa7584c
|
||||
Subproject commit 60fa1c6694b570dda50056b1e2fe18fcdb0f8be0
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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'
|
||||
}
|
||||
|
|
|
@ -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,30 +337,26 @@ 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);
|
||||
}
|
||||
|
||||
@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 (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();
|
||||
else newAppend = append + separator + entry.getKey();
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,5 +18,5 @@ public interface Module extends AutoCloseable {
|
|||
|
||||
default void finish(ModuleContext context) {
|
||||
// NOP
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,23 +5,22 @@
|
|||
|
||||
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)
|
||||
{
|
||||
|
||||
public boolean hook(V context, R object) throws HookException {
|
||||
for (Hook<V, R> hook : list) {
|
||||
if (hook.hook(context, object)) return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import ru.gravit.utils.helper.IOHelper;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
@ -61,6 +62,10 @@ public static JsonElement jsonRequest(JsonElement request, URL url) throws IOExc
|
|||
try {
|
||||
return parser.parse(reader);
|
||||
} catch (Exception e) {
|
||||
if (200 > statusCode || statusCode > 300) {
|
||||
LogHelper.error("JsonRequest failed. Server response code %d", statusCode);
|
||||
throw new IOException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,23 +5,22 @@
|
|||
|
||||
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)
|
||||
{
|
||||
|
||||
public boolean hook(R context) throws HookException {
|
||||
for (Hook<R> hook : list) {
|
||||
if (hook.hook(context)) return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue