From 12388226f5a887b747ea1258846f7afca5974aa6 Mon Sep 17 00:00:00 2001
From: Gravit <gravit.min@ya.ru>
Date: Sun, 25 Aug 2019 14:49:44 +0700
Subject: [PATCH] =?UTF-8?q?[FEATURE]=20=D0=9F=D0=B5=D1=80=D0=B5=D0=BD?=
 =?UTF-8?q?=D0=BE=D1=81=20LaunchServerConfig=20=D0=B2=20=D0=BE=D1=82=D0=B4?=
 =?UTF-8?q?=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9=20=D0=BA=D0=BB=D0=B0=D1=81?=
 =?UTF-8?q?=D1=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../pro/gravit/launchserver/LaunchServer.java | 325 +---------------
 .../config/LaunchServerConfig.java            | 353 ++++++++++++++++++
 .../socket/LauncherNettyServer.java           |   3 +-
 .../handlers/NettyServerSocketHandler.java    |   3 +-
 .../response/update/UpdateResponse.java       |   4 +-
 5 files changed, 366 insertions(+), 322 deletions(-)
 create mode 100644 LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java

diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java
index 81247f3b..e3891b96 100644
--- a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java
+++ b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java
@@ -69,6 +69,7 @@
 import pro.gravit.launchserver.components.AuthLimiterComponent;
 import pro.gravit.launchserver.components.Component;
 import pro.gravit.launchserver.components.RegLimiterComponent;
+import pro.gravit.launchserver.config.LaunchServerConfig;
 import pro.gravit.launchserver.config.LaunchServerRuntimeConfig;
 import pro.gravit.launchserver.dao.provider.DaoProvider;
 import pro.gravit.launchserver.manangers.CertificateManager;
@@ -107,9 +108,9 @@ public void reload(ReloadType type) throws Exception {
         }
         LogHelper.info("Reading LaunchServer config file");
         try (BufferedReader reader = IOHelper.newReader(configFile)) {
-            config = Launcher.gsonManager.gson.fromJson(reader, Config.class);
+            config = Launcher.gsonManager.gson.fromJson(reader, LaunchServerConfig.class);
         }
-        config.server = this;
+        config.setLaunchServer(this);
         if(type.equals(ReloadType.NO_AUTH))
         {
             config.auth = pairs;
@@ -172,258 +173,6 @@ public void invoke(String... args) throws Exception {
         return commands;
     }
 
-    public static final class Config {
-    	private transient LaunchServer server = null;
-
-        public String projectName;
-
-        public String[] mirrors;
-
-        public String binaryName;
-
-        public boolean copyBinaries = true;
-
-        public LauncherConfig.LauncherEnvironment env;
-
-        // Handlers & Providers
-
-        public AuthProviderPair[] auth;
-
-        public DaoProvider dao;
-
-        private transient AuthProviderPair authDefault;
-
-        public AuthProviderPair getAuthProviderPair(String name) {
-            for (AuthProviderPair pair : auth) {
-                if (pair.name.equals(name)) return pair;
-            }
-            return null;
-        }
-
-        public ProtectHandler protectHandler;
-
-        public PermissionsHandler permissionsHandler;
-
-        public AuthProviderPair getAuthProviderPair() {
-            if (authDefault != null) return authDefault;
-            for (AuthProviderPair pair : auth) {
-                if (pair.isDefault) {
-                    authDefault = pair;
-                    return pair;
-                }
-            }
-            return null;
-        }
-
-        public HWIDHandler hwidHandler;
-
-        public Map<String, Component> components;
-
-        public ExeConf launch4j;
-        public NettyConfig netty;
-        public GuardLicenseConf guardLicense;
-
-        public String whitelistRejectString;
-        public LauncherConf launcher;
-        public CertificateConf certificate;
-
-        public String startScript;
-
-        public void setProjectName(String projectName) {
-            this.projectName = projectName;
-        }
-
-        public void setBinaryName(String binaryName) {
-            this.binaryName = binaryName;
-        }
-
-        public void setEnv(LauncherConfig.LauncherEnvironment env) {
-            this.env = env;
-        }
-
-
-        public void verify() {
-            if (auth == null || auth[0] == null) {
-                throw new NullPointerException("AuthHandler must not be null");
-            }
-            boolean isOneDefault = false;
-            for (AuthProviderPair pair : auth) {
-                if (pair.isDefault) {
-                    isOneDefault = true;
-                    break;
-                }
-            }
-            if (protectHandler == null) {
-                throw new NullPointerException("ProtectHandler must not be null");
-            }
-            if (!isOneDefault) {
-                throw new IllegalStateException("No auth pairs declared by default.");
-            }
-            if (permissionsHandler == null) {
-                throw new NullPointerException("PermissionsHandler must not be null");
-            }
-            if (env == null) {
-                throw new NullPointerException("Env must not be null");
-            }
-            if (netty == null) {
-                throw new NullPointerException("Netty must not be null");
-            }
-        }
-
-        public void init(ReloadType type) {
-            Launcher.applyLauncherEnv(env);
-            for (AuthProviderPair provider : auth) {
-                provider.init(server);
-            }
-            permissionsHandler.init(server);
-            hwidHandler.init();
-            if(dao != null)
-                dao.init(server);
-            if (protectHandler != null) {
-                protectHandler.checkLaunchServerLicense();
-            }
-            if(components != null)
-            {
-                components.forEach((k,v) -> {
-                    server.registerObject("component.".concat(k), v);
-                });
-            }
-            server.registerObject("permissionsHandler", permissionsHandler);
-            server.registerObject("hwidHandler", hwidHandler);
-            if(!type.equals(ReloadType.NO_AUTH))
-            {
-                for (int i = 0; i < auth.length; ++i) {
-                    AuthProviderPair pair = auth[i];
-                    server.registerObject("auth.".concat(pair.name).concat(".provider"), pair.provider);
-                    server.registerObject("auth.".concat(pair.name).concat(".handler"), pair.handler);
-                    server.registerObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider);
-                }
-            }
-
-
-            Arrays.stream(mirrors).forEach(server.mirrorManager::addMirror);
-        }
-
-        public void close(ReloadType type) {
-            try {
-                server.unregisterObject("permissionsHandler", permissionsHandler);
-                server.unregisterObject("hwidHandler", hwidHandler);
-                if(!type.equals(ReloadType.NO_AUTH))
-                {
-                    for (AuthProviderPair pair : auth) {
-                        server.unregisterObject("auth.".concat(pair.name).concat(".provider"), pair.provider);
-                        server.unregisterObject("auth.".concat(pair.name).concat(".handler"), pair.handler);
-                        server.unregisterObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider);
-                    }
-                }
-                if(type.equals(ReloadType.FULL))
-                {
-                    components.forEach((k, component) -> {
-                        server.unregisterObject("component.".concat(k), component);
-                        if(component instanceof AutoCloseable)
-                        {
-                            try {
-                                ((AutoCloseable) component).close();
-                            } catch (Exception e) {
-                                LogHelper.error(e);
-                            }
-                        }
-                    });
-                }
-            } catch (Exception e) {
-                LogHelper.error(e);
-            }
-            try {
-                for (AuthProviderPair p : auth) p.close();
-            } catch (IOException e) {
-                LogHelper.error(e);
-            }
-            try {
-                hwidHandler.close();
-            } catch (Exception e) {
-                LogHelper.error(e);
-            }
-            try {
-                permissionsHandler.close();
-            } catch (Exception e) {
-                LogHelper.error(e);
-            }
-        }
-    }
-
-    public static class ExeConf {
-        public boolean enabled;
-        public String alternative;
-        public boolean setMaxVersion;
-        public String maxVersion;
-        public String productName;
-        public String productVer;
-        public String fileDesc;
-        public String fileVer;
-        public String internalName;
-        public String copyright;
-        public String trademarks;
-
-        public String txtFileVersion;
-        public String txtProductVersion;
-    }
-
-    public static class CertificateConf
-    {
-        public boolean enabled;
-    }
-
-    public static class NettyUpdatesBind {
-        public String url;
-        public boolean zip;
-    }
-
-    public class LauncherConf {
-        public String guardType;
-        public boolean attachLibraryBeforeProGuard;
-        public boolean compress;
-        public boolean warningMissArchJava;
-        public boolean enabledProGuard;
-        public boolean stripLineNumbers;
-        public boolean deleteTempFiles;
-        public boolean proguardGenMappings;
-    }
-
-    public class NettyConfig {
-        public boolean fileServerEnabled;
-        public boolean sendExceptionEnabled;
-        public boolean ipForwarding;
-        public String launcherURL;
-        public String downloadURL;
-        public String launcherEXEURL;
-        public String address;
-        public Map<String, NettyUpdatesBind> bindings = new HashMap<>();
-        public NettyPerformanceConfig performance;
-        public NettyBindAddress[] binds;
-        public LogLevel logLevel = LogLevel.DEBUG;
-    }
-
-    public class NettyPerformanceConfig {
-        public boolean usingEpoll;
-        public int bossThread;
-        public int workerThread;
-    }
-
-    public class NettyBindAddress {
-        public String address;
-        public int port;
-
-        public NettyBindAddress(String address, int port) {
-            this.address = address;
-            this.port = port;
-        }
-    }
-
-    public class GuardLicenseConf {
-        public String name;
-        public String key;
-        public String encryptKey;
-    }
 
     private final class ProfilesFileVisitor extends SimpleFileVisitor<Path> {
         private final Collection<ClientProfile> result;
@@ -511,7 +260,7 @@ public static void main(String... args) throws Throwable {
     public final Path profilesDir;
     // Server config
 
-    public Config config;
+    public LaunchServerConfig config;
     public LaunchServerRuntimeConfig runtime;
 
 
@@ -663,9 +412,9 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException
         generateConfigIfNotExists(testEnv);
         LogHelper.info("Reading LaunchServer config file");
         try (BufferedReader reader = IOHelper.newReader(configFile)) {
-            config = Launcher.gsonManager.gson.fromJson(reader, Config.class);
+            config = Launcher.gsonManager.gson.fromJson(reader, LaunchServerConfig.class);
         }
-        config.server = this;
+        config.setLaunchServer(this);
         if (!Files.exists(runtimeConfigFile)) {
             LogHelper.info("Reset LaunchServer runtime config file");
             runtime = new LaunchServerRuntimeConfig();
@@ -852,68 +601,9 @@ private void generateConfigIfNotExists(boolean testEnv) throws IOException {
 
         // Create new config
         LogHelper.info("Creating LaunchServer config");
-        Config newConfig = new Config();
-        newConfig.mirrors = new String[]{"https://mirror.gravit.pro/"};
-        newConfig.launch4j = new ExeConf();
-        newConfig.launch4j.enabled = true;
-        newConfig.launch4j.copyright = "© GravitLauncher Team";
-        newConfig.launch4j.alternative = "no";
-        newConfig.launch4j.fileDesc = "GravitLauncher ".concat(Version.getVersion().getVersionString());
-        newConfig.launch4j.fileVer = Version.getVersion().getVersionString().concat(".").concat(String.valueOf(Version.getVersion().patch));
-        newConfig.launch4j.internalName = "Launcher";
-        newConfig.launch4j.trademarks = "This product is licensed under GPLv3";
-        newConfig.launch4j.txtFileVersion = "%s, build %d";
-        newConfig.launch4j.txtProductVersion = "%s, build %d";
-        newConfig.launch4j.productName = "GravitLauncher";
-        newConfig.launch4j.productVer = newConfig.launch4j.fileVer;
-        newConfig.launch4j.maxVersion = "1.8.999";
-        newConfig.env = LauncherConfig.LauncherEnvironment.STD;
-        newConfig.startScript = JVMHelper.OS_TYPE.equals(JVMHelper.OS.MUSTDIE) ? "." + File.separator + "start.bat" : "." + File.separator + "start.sh";
-        newConfig.hwidHandler = new AcceptHWIDHandler();
-        newConfig.auth = new AuthProviderPair[]{new AuthProviderPair(new RejectAuthProvider("Настройте authProvider"),
-                new MemoryAuthHandler(),
-                new RequestTextureProvider("http://example.com/skins/%username%.png", "http://example.com/cloaks/%username%.png")
-                , "std")};
-        newConfig.auth[0].displayName = "Default";
-        newConfig.protectHandler = new StdProtectHandler();
-        if (testEnv) newConfig.permissionsHandler = new DefaultPermissionsHandler();
-        else newConfig.permissionsHandler = new JsonFilePermissionsHandler();
-        newConfig.binaryName = "Launcher";
-        newConfig.whitelistRejectString = "Вас нет в белом списке";
 
-        newConfig.netty = new NettyConfig();
-        newConfig.netty.fileServerEnabled = true;
-        newConfig.netty.binds = new NettyBindAddress[]{new NettyBindAddress("0.0.0.0", 9274)};
-        newConfig.netty.performance = new NettyPerformanceConfig();
-        newConfig.netty.performance.usingEpoll = Epoll.isAvailable();
-        newConfig.netty.performance.bossThread = 2;
-        newConfig.netty.performance.workerThread = 8;
-
-        newConfig.launcher = new LauncherConf();
-        newConfig.launcher.guardType = "no";
-        newConfig.launcher.compress = true;
-        newConfig.launcher.warningMissArchJava = true;
-        newConfig.launcher.attachLibraryBeforeProGuard = false;
-        newConfig.launcher.deleteTempFiles = true;
-        newConfig.launcher.enabledProGuard = true;
-        newConfig.launcher.stripLineNumbers = true;
-        newConfig.launcher.proguardGenMappings = true;
-
-        newConfig.certificate = new CertificateConf();
-        newConfig.certificate.enabled = false;
-
-        newConfig.components = new HashMap<>();
-        AuthLimiterComponent authLimiterComponent = new AuthLimiterComponent();
-        authLimiterComponent.rateLimit = 3;
-        authLimiterComponent.rateLimitMillis = 8000;
-        authLimiterComponent.message = "Превышен лимит авторизаций";
-        newConfig.components.put("authLimiter", authLimiterComponent);
-        RegLimiterComponent regLimiterComponent = new RegLimiterComponent();
-        regLimiterComponent.rateLimit = 3;
-        regLimiterComponent.rateLimitMillis = 1000 * 60 * 60 * 10; //Блок на 10 часов
-        regLimiterComponent.message = "Превышен лимит регистраций";
-        newConfig.components.put("regLimiter", regLimiterComponent);
 
+        LaunchServerConfig newConfig = LaunchServerConfig.getDefault();
         // Set server address
         String address;
         if (testEnv) {
@@ -938,7 +628,6 @@ private void generateConfigIfNotExists(boolean testEnv) throws IOException {
         newConfig.netty.downloadURL = "http://" + address + ":9274/%dirname%/";
         newConfig.netty.launcherURL = "http://" + address + ":9274/Launcher.jar";
         newConfig.netty.launcherEXEURL = "http://" + address + ":9274/Launcher.exe";
-        newConfig.netty.sendExceptionEnabled = true;
 
         // Write LaunchServer config
         LogHelper.info("Writing LaunchServer config file");
diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java b/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java
new file mode 100644
index 00000000..94c58c7d
--- /dev/null
+++ b/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java
@@ -0,0 +1,353 @@
+package pro.gravit.launchserver.config;
+
+import io.netty.channel.epoll.Epoll;
+import io.netty.handler.logging.LogLevel;
+import pro.gravit.launcher.Launcher;
+import pro.gravit.launcher.LauncherConfig;
+import pro.gravit.launchserver.LaunchServer;
+import pro.gravit.launchserver.auth.AuthProviderPair;
+import pro.gravit.launchserver.auth.handler.MemoryAuthHandler;
+import pro.gravit.launchserver.auth.hwid.AcceptHWIDHandler;
+import pro.gravit.launchserver.auth.hwid.HWIDHandler;
+import pro.gravit.launchserver.auth.permissions.DefaultPermissionsHandler;
+import pro.gravit.launchserver.auth.permissions.JsonFilePermissionsHandler;
+import pro.gravit.launchserver.auth.permissions.PermissionsHandler;
+import pro.gravit.launchserver.auth.protect.ProtectHandler;
+import pro.gravit.launchserver.auth.protect.StdProtectHandler;
+import pro.gravit.launchserver.auth.provider.RejectAuthProvider;
+import pro.gravit.launchserver.auth.texture.RequestTextureProvider;
+import pro.gravit.launchserver.components.AuthLimiterComponent;
+import pro.gravit.launchserver.components.Component;
+import pro.gravit.launchserver.components.RegLimiterComponent;
+import pro.gravit.launchserver.dao.provider.DaoProvider;
+import pro.gravit.utils.Version;
+import pro.gravit.utils.helper.JVMHelper;
+import pro.gravit.utils.helper.LogHelper;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+public final class LaunchServerConfig {
+    private transient LaunchServer server = null;
+
+    public LaunchServerConfig setLaunchServer(LaunchServer server) {
+        this.server = server;
+        return this;
+    }
+
+    public String projectName;
+
+    public String[] mirrors;
+
+    public String binaryName;
+
+    public boolean copyBinaries = true;
+
+    public LauncherConfig.LauncherEnvironment env;
+
+    // Handlers & Providers
+
+    public AuthProviderPair[] auth;
+
+    public DaoProvider dao;
+
+    private transient AuthProviderPair authDefault;
+
+    public AuthProviderPair getAuthProviderPair(String name) {
+        for (AuthProviderPair pair : auth) {
+            if (pair.name.equals(name)) return pair;
+        }
+        return null;
+    }
+
+    public ProtectHandler protectHandler;
+
+    public PermissionsHandler permissionsHandler;
+
+    public AuthProviderPair getAuthProviderPair() {
+        if (authDefault != null) return authDefault;
+        for (AuthProviderPair pair : auth) {
+            if (pair.isDefault) {
+                authDefault = pair;
+                return pair;
+            }
+        }
+        return null;
+    }
+
+    public HWIDHandler hwidHandler;
+
+    public Map<String, Component> components;
+
+    public ExeConf launch4j;
+    public NettyConfig netty;
+    public GuardLicenseConf guardLicense;
+
+    public String whitelistRejectString;
+    public LauncherConf launcher;
+    public CertificateConf certificate;
+
+    public String startScript;
+
+    public void setProjectName(String projectName) {
+        this.projectName = projectName;
+    }
+
+    public void setBinaryName(String binaryName) {
+        this.binaryName = binaryName;
+    }
+
+    public void setEnv(LauncherConfig.LauncherEnvironment env) {
+        this.env = env;
+    }
+
+
+    public void verify() {
+        if (auth == null || auth[0] == null) {
+            throw new NullPointerException("AuthHandler must not be null");
+        }
+        boolean isOneDefault = false;
+        for (AuthProviderPair pair : auth) {
+            if (pair.isDefault) {
+                isOneDefault = true;
+                break;
+            }
+        }
+        if (protectHandler == null) {
+            throw new NullPointerException("ProtectHandler must not be null");
+        }
+        if (!isOneDefault) {
+            throw new IllegalStateException("No auth pairs declared by default.");
+        }
+        if (permissionsHandler == null) {
+            throw new NullPointerException("PermissionsHandler must not be null");
+        }
+        if (env == null) {
+            throw new NullPointerException("Env must not be null");
+        }
+        if (netty == null) {
+            throw new NullPointerException("Netty must not be null");
+        }
+    }
+
+    public void init(LaunchServer.ReloadType type) {
+        Launcher.applyLauncherEnv(env);
+        for (AuthProviderPair provider : auth) {
+            provider.init(server);
+        }
+        permissionsHandler.init(server);
+        hwidHandler.init();
+        if(dao != null)
+            dao.init(server);
+        if (protectHandler != null) {
+            protectHandler.checkLaunchServerLicense();
+        }
+        if(components != null)
+        {
+            components.forEach((k,v) -> {
+                server.registerObject("component.".concat(k), v);
+            });
+        }
+        server.registerObject("permissionsHandler", permissionsHandler);
+        server.registerObject("hwidHandler", hwidHandler);
+        if(!type.equals(LaunchServer.ReloadType.NO_AUTH))
+        {
+            for (int i = 0; i < auth.length; ++i) {
+                AuthProviderPair pair = auth[i];
+                server.registerObject("auth.".concat(pair.name).concat(".provider"), pair.provider);
+                server.registerObject("auth.".concat(pair.name).concat(".handler"), pair.handler);
+                server.registerObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider);
+            }
+        }
+
+
+        Arrays.stream(mirrors).forEach(server.mirrorManager::addMirror);
+    }
+
+    public void close(LaunchServer.ReloadType type) {
+        try {
+            server.unregisterObject("permissionsHandler", permissionsHandler);
+            server.unregisterObject("hwidHandler", hwidHandler);
+            if(!type.equals(LaunchServer.ReloadType.NO_AUTH))
+            {
+                for (AuthProviderPair pair : auth) {
+                    server.unregisterObject("auth.".concat(pair.name).concat(".provider"), pair.provider);
+                    server.unregisterObject("auth.".concat(pair.name).concat(".handler"), pair.handler);
+                    server.unregisterObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider);
+                }
+            }
+            if(type.equals(LaunchServer.ReloadType.FULL))
+            {
+                components.forEach((k, component) -> {
+                    server.unregisterObject("component.".concat(k), component);
+                    if(component instanceof AutoCloseable)
+                    {
+                        try {
+                            ((AutoCloseable) component).close();
+                        } catch (Exception e) {
+                            LogHelper.error(e);
+                        }
+                    }
+                });
+            }
+        } catch (Exception e) {
+            LogHelper.error(e);
+        }
+        try {
+            for (AuthProviderPair p : auth) p.close();
+        } catch (IOException e) {
+            LogHelper.error(e);
+        }
+        try {
+            hwidHandler.close();
+        } catch (Exception e) {
+            LogHelper.error(e);
+        }
+        try {
+            permissionsHandler.close();
+        } catch (Exception e) {
+            LogHelper.error(e);
+        }
+    }
+
+    public static class ExeConf {
+        public boolean enabled;
+        public String alternative;
+        public boolean setMaxVersion;
+        public String maxVersion;
+        public String productName;
+        public String productVer;
+        public String fileDesc;
+        public String fileVer;
+        public String internalName;
+        public String copyright;
+        public String trademarks;
+
+        public String txtFileVersion;
+        public String txtProductVersion;
+    }
+
+    public static class CertificateConf
+    {
+        public boolean enabled;
+    }
+
+    public static class NettyUpdatesBind {
+        public String url;
+        public boolean zip;
+    }
+    public static class LauncherConf {
+        public String guardType;
+        public boolean attachLibraryBeforeProGuard;
+        public boolean compress;
+        public boolean warningMissArchJava;
+        public boolean enabledProGuard;
+        public boolean stripLineNumbers;
+        public boolean deleteTempFiles;
+        public boolean proguardGenMappings;
+    }
+
+    public static class NettyConfig {
+        public boolean fileServerEnabled;
+        public boolean sendExceptionEnabled;
+        public boolean ipForwarding;
+        public String launcherURL;
+        public String downloadURL;
+        public String launcherEXEURL;
+        public String address;
+        public Map<String, LaunchServerConfig.NettyUpdatesBind> bindings = new HashMap<>();
+        public NettyPerformanceConfig performance;
+        public NettyBindAddress[] binds;
+        public LogLevel logLevel = LogLevel.DEBUG;
+    }
+
+    public static class NettyPerformanceConfig {
+        public boolean usingEpoll;
+        public int bossThread;
+        public int workerThread;
+    }
+
+    public static class NettyBindAddress {
+        public String address;
+        public int port;
+
+        public NettyBindAddress(String address, int port) {
+            this.address = address;
+            this.port = port;
+        }
+    }
+
+    public static class GuardLicenseConf {
+        public String name;
+        public String key;
+        public String encryptKey;
+    }
+    public static LaunchServerConfig getDefault()
+    {
+        LaunchServerConfig newConfig = new LaunchServerConfig();
+        newConfig.mirrors = new String[]{"https://mirror.gravit.pro/"};
+        newConfig.launch4j = new LaunchServerConfig.ExeConf();
+        newConfig.launch4j.enabled = true;
+        newConfig.launch4j.copyright = "© GravitLauncher Team";
+        newConfig.launch4j.alternative = "no";
+        newConfig.launch4j.fileDesc = "GravitLauncher ".concat(Version.getVersion().getVersionString());
+        newConfig.launch4j.fileVer = Version.getVersion().getVersionString().concat(".").concat(String.valueOf(Version.getVersion().patch));
+        newConfig.launch4j.internalName = "Launcher";
+        newConfig.launch4j.trademarks = "This product is licensed under GPLv3";
+        newConfig.launch4j.txtFileVersion = "%s, build %d";
+        newConfig.launch4j.txtProductVersion = "%s, build %d";
+        newConfig.launch4j.productName = "GravitLauncher";
+        newConfig.launch4j.productVer = newConfig.launch4j.fileVer;
+        newConfig.launch4j.maxVersion = "1.8.999";
+        newConfig.env = LauncherConfig.LauncherEnvironment.STD;
+        newConfig.startScript = JVMHelper.OS_TYPE.equals(JVMHelper.OS.MUSTDIE) ? "." + File.separator + "start.bat" : "." + File.separator + "start.sh";
+        newConfig.hwidHandler = new AcceptHWIDHandler();
+        newConfig.auth = new AuthProviderPair[]{new AuthProviderPair(new RejectAuthProvider("Настройте authProvider"),
+                new MemoryAuthHandler(),
+                new RequestTextureProvider("http://example.com/skins/%username%.png", "http://example.com/cloaks/%username%.png")
+                , "std")};
+        newConfig.auth[0].displayName = "Default";
+        newConfig.protectHandler = new StdProtectHandler();
+        newConfig.permissionsHandler = new JsonFilePermissionsHandler();
+        newConfig.binaryName = "Launcher";
+        newConfig.whitelistRejectString = "Вас нет в белом списке";
+
+        newConfig.netty = new NettyConfig();
+        newConfig.netty.fileServerEnabled = true;
+        newConfig.netty.binds = new NettyBindAddress[]{new NettyBindAddress("0.0.0.0", 9274)};
+        newConfig.netty.performance = new NettyPerformanceConfig();
+        newConfig.netty.performance.usingEpoll = Epoll.isAvailable();
+        newConfig.netty.performance.bossThread = 2;
+        newConfig.netty.performance.workerThread = 8;
+
+        newConfig.launcher = new LauncherConf();
+        newConfig.launcher.guardType = "no";
+        newConfig.launcher.compress = true;
+        newConfig.launcher.warningMissArchJava = true;
+        newConfig.launcher.attachLibraryBeforeProGuard = false;
+        newConfig.launcher.deleteTempFiles = true;
+        newConfig.launcher.enabledProGuard = true;
+        newConfig.launcher.stripLineNumbers = true;
+        newConfig.launcher.proguardGenMappings = true;
+
+        newConfig.certificate = new LaunchServerConfig.CertificateConf();
+        newConfig.certificate.enabled = false;
+
+        newConfig.components = new HashMap<>();
+        AuthLimiterComponent authLimiterComponent = new AuthLimiterComponent();
+        authLimiterComponent.rateLimit = 3;
+        authLimiterComponent.rateLimitMillis = 8000;
+        authLimiterComponent.message = "Превышен лимит авторизаций";
+        newConfig.components.put("authLimiter", authLimiterComponent);
+        RegLimiterComponent regLimiterComponent = new RegLimiterComponent();
+        regLimiterComponent.rateLimit = 3;
+        regLimiterComponent.rateLimitMillis = 1000 * 60 * 60 * 10; //Блок на 10 часов
+        regLimiterComponent.message = "Превышен лимит регистраций";
+        newConfig.components.put("regLimiter", regLimiterComponent);
+        newConfig.netty.sendExceptionEnabled = true;
+        return newConfig;
+    }
+}
diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/LauncherNettyServer.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/LauncherNettyServer.java
index 63a1e79e..b1ab80b7 100644
--- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/LauncherNettyServer.java
+++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/LauncherNettyServer.java
@@ -17,6 +17,7 @@
 import io.netty.handler.logging.LoggingHandler;
 import io.netty.util.concurrent.GlobalEventExecutor;
 import pro.gravit.launchserver.LaunchServer;
+import pro.gravit.launchserver.config.LaunchServerConfig;
 import pro.gravit.launchserver.socket.handlers.NettyIpForwardHandler;
 import pro.gravit.launchserver.socket.handlers.WebSocketFrameHandler;
 import pro.gravit.launchserver.socket.handlers.fileserver.FileServerHandler;
@@ -32,7 +33,7 @@ public class LauncherNettyServer implements AutoCloseable {
     private static final String WEBSOCKET_PATH = "/api";
 
     public LauncherNettyServer(LaunchServer server) {
-        LaunchServer.NettyConfig config = server.config.netty;
+        LaunchServerConfig.NettyConfig config = server.config.netty;
         NettyObjectFactory.setUsingEpoll(config.performance.usingEpoll);
         if(config.performance.usingEpoll)
         {
diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/NettyServerSocketHandler.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/NettyServerSocketHandler.java
index 86652ae7..f041aa39 100644
--- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/NettyServerSocketHandler.java
+++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/handlers/NettyServerSocketHandler.java
@@ -20,6 +20,7 @@
 import pro.gravit.launcher.ssl.LauncherKeyStore;
 import pro.gravit.launcher.ssl.LauncherTrustManager;
 import pro.gravit.launchserver.LaunchServer;
+import pro.gravit.launchserver.config.LaunchServerConfig;
 import pro.gravit.launchserver.socket.LauncherNettyServer;
 import pro.gravit.utils.helper.LogHelper;
 
@@ -90,7 +91,7 @@ public void run() {
         //SSLEngine engine = sc.createSSLEngine();
         //engine.setUseClientMode(false);
         nettyServer = new LauncherNettyServer(server);
-        for (LaunchServer.NettyBindAddress address : server.config.netty.binds) {
+        for (LaunchServerConfig.NettyBindAddress address : server.config.netty.binds) {
             nettyServer.bind(new InetSocketAddress(address.address, address.port));
         }
         /*
diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/update/UpdateResponse.java b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/update/UpdateResponse.java
index 967b6f85..bb3156d8 100644
--- a/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/update/UpdateResponse.java
+++ b/LaunchServer/src/main/java/pro/gravit/launchserver/socket/response/update/UpdateResponse.java
@@ -5,7 +5,7 @@
 import pro.gravit.launcher.events.request.UpdateRequestEvent;
 import pro.gravit.launcher.hasher.HashedDir;
 import pro.gravit.launcher.profiles.ClientProfile;
-import pro.gravit.launchserver.LaunchServer;
+import pro.gravit.launchserver.config.LaunchServerConfig;
 import pro.gravit.launchserver.socket.Client;
 import pro.gravit.launchserver.socket.response.SimpleResponse;
 import pro.gravit.utils.helper.IOHelper;
@@ -41,7 +41,7 @@ public void execute(ChannelHandlerContext ctx, Client client) {
         String url = server.config.netty.downloadURL.replace("%dirname%", IOHelper.urlEncode(dirName));
         boolean zip = false;
         if (server.config.netty.bindings.get(dirName) != null) {
-            LaunchServer.NettyUpdatesBind bind = server.config.netty.bindings.get(dirName);
+            LaunchServerConfig.NettyUpdatesBind bind = server.config.netty.bindings.get(dirName);
             url = bind.url;
             zip = bind.zip;
         }