mirror of
https://github.com/GravitLauncher/Launcher
synced 2025-01-10 17:49:40 +03:00
[FIX][FEATURE] Начальная переработка иницализации лаунчсервера. Фикс инициализации компонентов
This commit is contained in:
parent
a30c1db986
commit
82e3ae797c
4 changed files with 109 additions and 64 deletions
|
@ -91,16 +91,38 @@
|
||||||
|
|
||||||
public final class LaunchServer implements Runnable, AutoCloseable, Reconfigurable {
|
public final class LaunchServer implements Runnable, AutoCloseable, Reconfigurable {
|
||||||
|
|
||||||
public void reload() throws Exception {
|
public enum ReloadType
|
||||||
config.close();
|
{
|
||||||
|
NO_AUTH,
|
||||||
|
NO_COMPONENTS,
|
||||||
|
FULL
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reload(ReloadType type) throws Exception {
|
||||||
|
config.close(type);
|
||||||
|
AuthProviderPair[] pairs = null;
|
||||||
|
if(type.equals(ReloadType.NO_AUTH))
|
||||||
|
{
|
||||||
|
pairs = config.auth;
|
||||||
|
}
|
||||||
LogHelper.info("Reading LaunchServer config file");
|
LogHelper.info("Reading LaunchServer config file");
|
||||||
try (BufferedReader reader = IOHelper.newReader(configFile)) {
|
try (BufferedReader reader = IOHelper.newReader(configFile)) {
|
||||||
config = Launcher.gsonManager.gson.fromJson(reader, Config.class);
|
config = Launcher.gsonManager.gson.fromJson(reader, Config.class);
|
||||||
}
|
}
|
||||||
config.server = this;
|
config.server = this;
|
||||||
|
if(type.equals(ReloadType.NO_AUTH))
|
||||||
|
{
|
||||||
|
config.auth = pairs;
|
||||||
|
}
|
||||||
config.verify();
|
config.verify();
|
||||||
config.init();
|
config.init(type);
|
||||||
if (config.components != null) {
|
if (type.equals(ReloadType.FULL) && config.components != null) {
|
||||||
|
LogHelper.debug("PreInit components");
|
||||||
|
config.components.forEach((k, v) -> {
|
||||||
|
LogHelper.subDebug("PreInit component %s", k);
|
||||||
|
v.preInit(this);
|
||||||
|
});
|
||||||
|
LogHelper.debug("PreInit components successful");
|
||||||
LogHelper.debug("Init components");
|
LogHelper.debug("Init components");
|
||||||
config.components.forEach((k, v) -> {
|
config.components.forEach((k, v) -> {
|
||||||
LogHelper.subDebug("Init component %s", k);
|
LogHelper.subDebug("Init component %s", k);
|
||||||
|
@ -124,7 +146,26 @@ public Map<String, Command> getCommands() {
|
||||||
SubCommand reload = new SubCommand() {
|
SubCommand reload = new SubCommand() {
|
||||||
@Override
|
@Override
|
||||||
public void invoke(String... args) throws Exception {
|
public void invoke(String... args) throws Exception {
|
||||||
reload();
|
if(args.length == 0)
|
||||||
|
{
|
||||||
|
reload(ReloadType.FULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (args[0])
|
||||||
|
{
|
||||||
|
case "full":
|
||||||
|
reload(ReloadType.FULL);
|
||||||
|
break;
|
||||||
|
case "no_auth":
|
||||||
|
reload(ReloadType.NO_AUTH);
|
||||||
|
break;
|
||||||
|
case "no_components":
|
||||||
|
reload(ReloadType.NO_COMPONENTS);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
reload(ReloadType.FULL);;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
commands.put("reload", reload);
|
commands.put("reload", reload);
|
||||||
|
@ -229,7 +270,7 @@ public void verify() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init() {
|
public void init(ReloadType type) {
|
||||||
Launcher.applyLauncherEnv(env);
|
Launcher.applyLauncherEnv(env);
|
||||||
for (AuthProviderPair provider : auth) {
|
for (AuthProviderPair provider : auth) {
|
||||||
provider.init(server);
|
provider.init(server);
|
||||||
|
@ -241,34 +282,53 @@ public void init() {
|
||||||
if (protectHandler != null) {
|
if (protectHandler != null) {
|
||||||
protectHandler.checkLaunchServerLicense();
|
protectHandler.checkLaunchServerLicense();
|
||||||
}
|
}
|
||||||
if (components != null) {
|
if(components != null)
|
||||||
LogHelper.debug("PreInit components");
|
{
|
||||||
components.forEach((k, v) -> {
|
components.forEach((k,v) -> {
|
||||||
LogHelper.subDebug("PreInit component %s", k);
|
server.registerObject("component.".concat(k), v);
|
||||||
v.preInit(server);
|
|
||||||
});
|
});
|
||||||
LogHelper.debug("PreInit components successful");
|
|
||||||
}
|
}
|
||||||
server.registerObject("permissionsHandler", permissionsHandler);
|
server.registerObject("permissionsHandler", permissionsHandler);
|
||||||
server.registerObject("hwidHandler", hwidHandler);
|
server.registerObject("hwidHandler", hwidHandler);
|
||||||
for (int i = 0; i < auth.length; ++i) {
|
if(!type.equals(ReloadType.NO_AUTH))
|
||||||
AuthProviderPair pair = auth[i];
|
{
|
||||||
server.registerObject("auth.".concat(pair.name).concat(".provider"), pair.provider);
|
for (int i = 0; i < auth.length; ++i) {
|
||||||
server.registerObject("auth.".concat(pair.name).concat(".handler"), pair.handler);
|
AuthProviderPair pair = auth[i];
|
||||||
server.registerObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider);
|
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);
|
Arrays.stream(mirrors).forEach(server.mirrorManager::addMirror);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close(ReloadType type) {
|
||||||
try {
|
try {
|
||||||
server.unregisterObject("permissionsHandler", permissionsHandler);
|
server.unregisterObject("permissionsHandler", permissionsHandler);
|
||||||
server.unregisterObject("hwidHandler", hwidHandler);
|
server.unregisterObject("hwidHandler", hwidHandler);
|
||||||
for (AuthProviderPair pair : auth) {
|
if(!type.equals(ReloadType.NO_AUTH))
|
||||||
server.unregisterObject("auth.".concat(pair.name).concat(".provider"), pair.provider);
|
{
|
||||||
server.unregisterObject("auth.".concat(pair.name).concat(".handler"), pair.handler);
|
for (AuthProviderPair pair : auth) {
|
||||||
server.unregisterObject("auth.".concat(pair.name).concat(".texture"), pair.textureProvider);
|
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) {
|
} catch (Exception e) {
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
|
@ -618,6 +678,14 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException
|
||||||
}
|
}
|
||||||
runtime.verify();
|
runtime.verify();
|
||||||
config.verify();
|
config.verify();
|
||||||
|
if (config.components != null) {
|
||||||
|
LogHelper.debug("PreInit components");
|
||||||
|
config.components.forEach((k, v) -> {
|
||||||
|
LogHelper.subDebug("PreInit component %s", k);
|
||||||
|
v.preInit(this);
|
||||||
|
});
|
||||||
|
LogHelper.debug("PreInit components successful");
|
||||||
|
}
|
||||||
|
|
||||||
// build hooks, anti-brutforce and other
|
// build hooks, anti-brutforce and other
|
||||||
buildHookManager = new BuildHookManager();
|
buildHookManager = new BuildHookManager();
|
||||||
|
@ -665,7 +733,7 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
config.init();
|
config.init(ReloadType.FULL);
|
||||||
registerObject("launchServer", this);
|
registerObject("launchServer", this);
|
||||||
GarbageManager.registerNeedGC(sessionManager);
|
GarbageManager.registerNeedGC(sessionManager);
|
||||||
|
|
||||||
|
@ -763,7 +831,7 @@ public void buildLauncherBinaries() throws IOException {
|
||||||
public void close() {
|
public void close() {
|
||||||
|
|
||||||
// Close handlers & providers
|
// Close handlers & providers
|
||||||
config.close();
|
config.close(ReloadType.FULL);
|
||||||
modulesManager.close();
|
modulesManager.close();
|
||||||
LogHelper.info("Save LaunchServer runtime config");
|
LogHelper.info("Save LaunchServer runtime config");
|
||||||
try (Writer writer = IOHelper.newWriter(runtimeConfigFile)) {
|
try (Writer writer = IOHelper.newWriter(runtimeConfigFile)) {
|
||||||
|
@ -838,12 +906,12 @@ private void generateConfigIfNotExists(boolean testEnv) throws IOException {
|
||||||
newConfig.components = new HashMap<>();
|
newConfig.components = new HashMap<>();
|
||||||
AuthLimiterComponent authLimiterComponent = new AuthLimiterComponent();
|
AuthLimiterComponent authLimiterComponent = new AuthLimiterComponent();
|
||||||
authLimiterComponent.rateLimit = 3;
|
authLimiterComponent.rateLimit = 3;
|
||||||
authLimiterComponent.rateLimitMilis = 8000;
|
authLimiterComponent.rateLimitMillis = 8000;
|
||||||
authLimiterComponent.message = "Превышен лимит авторизаций";
|
authLimiterComponent.message = "Превышен лимит авторизаций";
|
||||||
newConfig.components.put("authLimiter", authLimiterComponent);
|
newConfig.components.put("authLimiter", authLimiterComponent);
|
||||||
RegLimiterComponent regLimiterComponent = new RegLimiterComponent();
|
RegLimiterComponent regLimiterComponent = new RegLimiterComponent();
|
||||||
regLimiterComponent.rateLimit = 3;
|
regLimiterComponent.rateLimit = 3;
|
||||||
regLimiterComponent.rateLimitMilis = 1000 * 60 * 60 * 10; //Блок на 10 часов
|
regLimiterComponent.rateLimitMillis = 1000 * 60 * 60 * 10; //Блок на 10 часов
|
||||||
regLimiterComponent.message = "Превышен лимит регистраций";
|
regLimiterComponent.message = "Превышен лимит регистраций";
|
||||||
newConfig.components.put("regLimiter", regLimiterComponent);
|
newConfig.components.put("regLimiter", regLimiterComponent);
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,21 @@
|
||||||
package pro.gravit.launchserver.components;
|
package pro.gravit.launchserver.components;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import pro.gravit.launcher.NeedGarbageCollection;
|
import pro.gravit.launcher.NeedGarbageCollection;
|
||||||
|
|
||||||
public class AbstractLimiter<T> implements NeedGarbageCollection {
|
public abstract class AbstractLimiter<T> extends Component implements NeedGarbageCollection {
|
||||||
public final int maxTrys;
|
public int rateLimit;
|
||||||
public final int banMillis;
|
public int rateLimitMillis;
|
||||||
|
public List<T> exclude = new ArrayList<>();
|
||||||
public AbstractLimiter(int maxTrys, int banMillis) {
|
|
||||||
this.maxTrys = maxTrys;
|
|
||||||
this.banMillis = banMillis;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void garbageCollection() {
|
public void garbageCollection() {
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
map.entrySet().removeIf((e) -> e.getValue().time + banMillis < time);
|
map.entrySet().removeIf((e) -> e.getValue().time + rateLimitMillis < time);
|
||||||
}
|
}
|
||||||
|
|
||||||
class LimitEntry
|
class LimitEntry
|
||||||
|
@ -35,9 +33,10 @@ public LimitEntry() {
|
||||||
trys = 0;
|
trys = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected Map<T, LimitEntry> map = new HashMap<>();
|
protected transient Map<T, LimitEntry> map = new HashMap<>();
|
||||||
public boolean check(T address)
|
public boolean check(T address)
|
||||||
{
|
{
|
||||||
|
if(exclude.contains(address)) return true;
|
||||||
LimitEntry entry = map.get(address);
|
LimitEntry entry = map.get(address);
|
||||||
if(entry == null)
|
if(entry == null)
|
||||||
{
|
{
|
||||||
|
@ -47,13 +46,13 @@ public boolean check(T address)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
if(entry.trys < maxTrys)
|
if(entry.trys < rateLimit)
|
||||||
{
|
{
|
||||||
entry.trys++;
|
entry.trys++;
|
||||||
entry.time = time;
|
entry.time = time;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if(entry.time + banMillis < time)
|
if(entry.time + rateLimitMillis < time)
|
||||||
{
|
{
|
||||||
entry.trys = 1;
|
entry.trys = 1;
|
||||||
entry.time = time;
|
entry.time = time;
|
||||||
|
|
|
@ -9,9 +9,7 @@
|
||||||
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
||||||
import pro.gravit.utils.HookException;
|
import pro.gravit.utils.HookException;
|
||||||
|
|
||||||
public class AuthLimiterComponent extends Component implements NeedGarbageCollection, AutoCloseable {
|
public class AuthLimiterComponent extends AbstractLimiter<String> implements NeedGarbageCollection, AutoCloseable {
|
||||||
|
|
||||||
private transient AbstractLimiter<String> limiter;
|
|
||||||
private transient LaunchServer srv;
|
private transient LaunchServer srv;
|
||||||
@Override
|
@Override
|
||||||
public void preInit(LaunchServer launchServer) {
|
public void preInit(LaunchServer launchServer) {
|
||||||
|
@ -20,7 +18,6 @@ public void preInit(LaunchServer launchServer) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(LaunchServer launchServer) {
|
public void init(LaunchServer launchServer) {
|
||||||
limiter = new AbstractLimiter<>(rateLimit, rateLimitMilis);
|
|
||||||
launchServer.authHookManager.preHook.registerHook(this::preAuthHook);
|
launchServer.authHookManager.preHook.registerHook(this::preAuthHook);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,22 +27,12 @@ public void postInit(LaunchServer launchServer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean preAuthHook(AuthResponse.AuthContext context, Client client) {
|
public boolean preAuthHook(AuthResponse.AuthContext context, Client client) {
|
||||||
if (!excludeIps.contains(context.ip) && !limiter.check(context.ip)) {
|
if (!check(context.ip)) {
|
||||||
throw new HookException(message);
|
throw new HookException(message);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int rateLimit;
|
|
||||||
public int rateLimitMilis;
|
|
||||||
public String message;
|
public String message;
|
||||||
public List<String> excludeIps = new ArrayList<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void garbageCollection() {
|
|
||||||
if(limiter != null)
|
|
||||||
limiter.garbageCollection();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws Exception {
|
public void close() throws Exception {
|
||||||
|
|
|
@ -8,19 +8,15 @@
|
||||||
import pro.gravit.launchserver.manangers.hook.AuthHookManager;
|
import pro.gravit.launchserver.manangers.hook.AuthHookManager;
|
||||||
import pro.gravit.utils.HookException;
|
import pro.gravit.utils.HookException;
|
||||||
|
|
||||||
public class RegLimiterComponent extends Component implements NeedGarbageCollection, AutoCloseable {
|
public class RegLimiterComponent extends AbstractLimiter<String> implements NeedGarbageCollection, AutoCloseable {
|
||||||
|
|
||||||
private transient AbstractLimiter<String> limiter;
|
|
||||||
public transient LaunchServer launchServer;
|
public transient LaunchServer launchServer;
|
||||||
public int rateLimit;
|
|
||||||
public int rateLimitMilis;
|
|
||||||
public String message;
|
public String message;
|
||||||
|
|
||||||
public List<String> excludeIps = new ArrayList<>();
|
public List<String> excludeIps = new ArrayList<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void preInit(LaunchServer launchServer) {
|
public void preInit(LaunchServer launchServer) {
|
||||||
limiter = new AbstractLimiter<>(rateLimit, rateLimitMilis);
|
|
||||||
this.launchServer = launchServer;
|
this.launchServer = launchServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,17 +32,12 @@ public void postInit(LaunchServer launchServer) {
|
||||||
|
|
||||||
public boolean registerHook(AuthHookManager.RegContext context)
|
public boolean registerHook(AuthHookManager.RegContext context)
|
||||||
{
|
{
|
||||||
if (!limiter.check(context.ip)) {
|
if (!check(context.ip)) {
|
||||||
throw new HookException(message);
|
throw new HookException(message);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void garbageCollection() {
|
|
||||||
if(limiter != null)
|
|
||||||
limiter.garbageCollection();
|
|
||||||
}
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws Exception {
|
public void close() throws Exception {
|
||||||
launchServer.authHookManager.registraion.unregisterHook(this::registerHook);
|
launchServer.authHookManager.registraion.unregisterHook(this::registerHook);
|
||||||
|
|
Loading…
Reference in a new issue