[FIX][FEATURE] Начальная переработка иницализации лаунчсервера. Фикс инициализации компонентов

This commit is contained in:
Gravit 2019-08-25 13:48:26 +07:00
parent a30c1db986
commit 82e3ae797c
No known key found for this signature in database
GPG key ID: 061981E1E85D3216
4 changed files with 109 additions and 64 deletions

View file

@ -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,35 +282,54 @@ public void init() {
if (protectHandler != null) {
protectHandler.checkLaunchServerLicense();
}
if (components != null) {
LogHelper.debug("PreInit components");
if(components != null)
{
components.forEach((k,v) -> {
LogHelper.subDebug("PreInit component %s", k);
v.preInit(server);
server.registerObject("component.".concat(k), v);
});
LogHelper.debug("PreInit components successful");
}
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() {
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);
}
@ -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);

View file

@ -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;

View file

@ -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 {

View file

@ -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);