mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-12-23 09:01:08 +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 void reload() throws Exception {
|
||||
config.close();
|
||||
public enum ReloadType
|
||||
{
|
||||
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");
|
||||
try (BufferedReader reader = IOHelper.newReader(configFile)) {
|
||||
config = Launcher.gsonManager.gson.fromJson(reader, Config.class);
|
||||
}
|
||||
config.server = this;
|
||||
if(type.equals(ReloadType.NO_AUTH))
|
||||
{
|
||||
config.auth = pairs;
|
||||
}
|
||||
config.verify();
|
||||
config.init();
|
||||
if (config.components != null) {
|
||||
config.init(type);
|
||||
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");
|
||||
config.components.forEach((k, v) -> {
|
||||
LogHelper.subDebug("Init component %s", k);
|
||||
|
@ -124,7 +146,26 @@ public Map<String, Command> getCommands() {
|
|||
SubCommand reload = new SubCommand() {
|
||||
@Override
|
||||
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);
|
||||
|
@ -229,7 +270,7 @@ public void verify() {
|
|||
}
|
||||
}
|
||||
|
||||
public void init() {
|
||||
public void init(ReloadType type) {
|
||||
Launcher.applyLauncherEnv(env);
|
||||
for (AuthProviderPair provider : auth) {
|
||||
provider.init(server);
|
||||
|
@ -241,34 +282,53 @@ public void init() {
|
|||
if (protectHandler != null) {
|
||||
protectHandler.checkLaunchServerLicense();
|
||||
}
|
||||
if (components != null) {
|
||||
LogHelper.debug("PreInit components");
|
||||
components.forEach((k, v) -> {
|
||||
LogHelper.subDebug("PreInit component %s", k);
|
||||
v.preInit(server);
|
||||
if(components != null)
|
||||
{
|
||||
components.forEach((k,v) -> {
|
||||
server.registerObject("component.".concat(k), v);
|
||||
});
|
||||
LogHelper.debug("PreInit components successful");
|
||||
}
|
||||
server.registerObject("permissionsHandler", permissionsHandler);
|
||||
server.registerObject("hwidHandler", hwidHandler);
|
||||
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);
|
||||
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() {
|
||||
public void close(ReloadType type) {
|
||||
try {
|
||||
server.unregisterObject("permissionsHandler", permissionsHandler);
|
||||
server.unregisterObject("hwidHandler", hwidHandler);
|
||||
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.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);
|
||||
|
@ -618,6 +678,14 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException
|
|||
}
|
||||
runtime.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
|
||||
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);
|
||||
GarbageManager.registerNeedGC(sessionManager);
|
||||
|
||||
|
@ -763,7 +831,7 @@ public void buildLauncherBinaries() throws IOException {
|
|||
public void close() {
|
||||
|
||||
// Close handlers & providers
|
||||
config.close();
|
||||
config.close(ReloadType.FULL);
|
||||
modulesManager.close();
|
||||
LogHelper.info("Save LaunchServer runtime config");
|
||||
try (Writer writer = IOHelper.newWriter(runtimeConfigFile)) {
|
||||
|
@ -838,12 +906,12 @@ private void generateConfigIfNotExists(boolean testEnv) throws IOException {
|
|||
newConfig.components = new HashMap<>();
|
||||
AuthLimiterComponent authLimiterComponent = new AuthLimiterComponent();
|
||||
authLimiterComponent.rateLimit = 3;
|
||||
authLimiterComponent.rateLimitMilis = 8000;
|
||||
authLimiterComponent.rateLimitMillis = 8000;
|
||||
authLimiterComponent.message = "Превышен лимит авторизаций";
|
||||
newConfig.components.put("authLimiter", authLimiterComponent);
|
||||
RegLimiterComponent regLimiterComponent = new RegLimiterComponent();
|
||||
regLimiterComponent.rateLimit = 3;
|
||||
regLimiterComponent.rateLimitMilis = 1000 * 60 * 60 * 10; //Блок на 10 часов
|
||||
regLimiterComponent.rateLimitMillis = 1000 * 60 * 60 * 10; //Блок на 10 часов
|
||||
regLimiterComponent.message = "Превышен лимит регистраций";
|
||||
newConfig.components.put("regLimiter", regLimiterComponent);
|
||||
|
||||
|
|
|
@ -1,23 +1,21 @@
|
|||
package pro.gravit.launchserver.components;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import pro.gravit.launcher.NeedGarbageCollection;
|
||||
|
||||
public class AbstractLimiter<T> implements NeedGarbageCollection {
|
||||
public final int maxTrys;
|
||||
public final int banMillis;
|
||||
|
||||
public AbstractLimiter(int maxTrys, int banMillis) {
|
||||
this.maxTrys = maxTrys;
|
||||
this.banMillis = banMillis;
|
||||
}
|
||||
public abstract class AbstractLimiter<T> extends Component implements NeedGarbageCollection {
|
||||
public int rateLimit;
|
||||
public int rateLimitMillis;
|
||||
public List<T> exclude = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void garbageCollection() {
|
||||
long time = System.currentTimeMillis();
|
||||
map.entrySet().removeIf((e) -> e.getValue().time + banMillis < time);
|
||||
map.entrySet().removeIf((e) -> e.getValue().time + rateLimitMillis < time);
|
||||
}
|
||||
|
||||
class LimitEntry
|
||||
|
@ -35,9 +33,10 @@ public LimitEntry() {
|
|||
trys = 0;
|
||||
}
|
||||
}
|
||||
protected Map<T, LimitEntry> map = new HashMap<>();
|
||||
protected transient Map<T, LimitEntry> map = new HashMap<>();
|
||||
public boolean check(T address)
|
||||
{
|
||||
if(exclude.contains(address)) return true;
|
||||
LimitEntry entry = map.get(address);
|
||||
if(entry == null)
|
||||
{
|
||||
|
@ -47,13 +46,13 @@ public boolean check(T address)
|
|||
else
|
||||
{
|
||||
long time = System.currentTimeMillis();
|
||||
if(entry.trys < maxTrys)
|
||||
if(entry.trys < rateLimit)
|
||||
{
|
||||
entry.trys++;
|
||||
entry.time = time;
|
||||
return true;
|
||||
}
|
||||
if(entry.time + banMillis < time)
|
||||
if(entry.time + rateLimitMillis < time)
|
||||
{
|
||||
entry.trys = 1;
|
||||
entry.time = time;
|
||||
|
|
|
@ -9,9 +9,7 @@
|
|||
import pro.gravit.launchserver.socket.response.auth.AuthResponse;
|
||||
import pro.gravit.utils.HookException;
|
||||
|
||||
public class AuthLimiterComponent extends Component implements NeedGarbageCollection, AutoCloseable {
|
||||
|
||||
private transient AbstractLimiter<String> limiter;
|
||||
public class AuthLimiterComponent extends AbstractLimiter<String> implements NeedGarbageCollection, AutoCloseable {
|
||||
private transient LaunchServer srv;
|
||||
@Override
|
||||
public void preInit(LaunchServer launchServer) {
|
||||
|
@ -20,7 +18,6 @@ public void preInit(LaunchServer launchServer) {
|
|||
|
||||
@Override
|
||||
public void init(LaunchServer launchServer) {
|
||||
limiter = new AbstractLimiter<>(rateLimit, rateLimitMilis);
|
||||
launchServer.authHookManager.preHook.registerHook(this::preAuthHook);
|
||||
}
|
||||
|
||||
|
@ -30,22 +27,12 @@ public void postInit(LaunchServer launchServer) {
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int rateLimit;
|
||||
public int rateLimitMilis;
|
||||
public String message;
|
||||
public List<String> excludeIps = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void garbageCollection() {
|
||||
if(limiter != null)
|
||||
limiter.garbageCollection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
|
|
|
@ -8,19 +8,15 @@
|
|||
import pro.gravit.launchserver.manangers.hook.AuthHookManager;
|
||||
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 int rateLimit;
|
||||
public int rateLimitMilis;
|
||||
public String message;
|
||||
|
||||
public List<String> excludeIps = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void preInit(LaunchServer launchServer) {
|
||||
limiter = new AbstractLimiter<>(rateLimit, rateLimitMilis);
|
||||
this.launchServer = launchServer;
|
||||
}
|
||||
|
||||
|
@ -36,17 +32,12 @@ public void postInit(LaunchServer launchServer) {
|
|||
|
||||
public boolean registerHook(AuthHookManager.RegContext context)
|
||||
{
|
||||
if (!limiter.check(context.ip)) {
|
||||
if (!check(context.ip)) {
|
||||
throw new HookException(message);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void garbageCollection() {
|
||||
if(limiter != null)
|
||||
limiter.garbageCollection();
|
||||
}
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
launchServer.authHookManager.registraion.unregisterHook(this::registerHook);
|
||||
|
|
Loading…
Reference in a new issue