diff --git a/LaunchServer/src/test/java/pro/gravit/launchserver/ConfigurationTest.java b/LaunchServer/src/test/java/pro/gravit/launchserver/ConfigurationTest.java index a594adef..61badc26 100644 --- a/LaunchServer/src/test/java/pro/gravit/launchserver/ConfigurationTest.java +++ b/LaunchServer/src/test/java/pro/gravit/launchserver/ConfigurationTest.java @@ -64,7 +64,7 @@ public static void prepare() throws Throwable { launchServer = builder.build(); } @Test - public static void reloadTest() throws Exception { + public void reloadTest() throws Exception { AuthProvider provider = new AuthProvider() { @Override public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws Exception { diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/modules/LauncherModule.java b/LauncherAPI/src/main/java/pro/gravit/launcher/modules/LauncherModule.java index ed2eccd2..85a465e4 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/modules/LauncherModule.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/modules/LauncherModule.java @@ -1,14 +1,24 @@ package pro.gravit.launcher.modules; import pro.gravit.launcher.LauncherTrustManager; +import pro.gravit.utils.Version; -import java.util.HashMap; +import java.util.ArrayList; +import java.util.List; import java.util.Map; public abstract class LauncherModule { protected final LauncherModuleInfo moduleInfo; - @SuppressWarnings("rawtypes") - private final Map, EventHandler> eventMap = new HashMap<>(); + private final static class EventEntity { + final Class clazz; + final EventHandler handler; + + private EventEntity(EventHandler handler, Class clazz) { + this.clazz = clazz; + this.handler = handler; + } + } + private final List> eventList = new ArrayList<>(4); protected LauncherModulesManager modulesManager; protected ModulesConfigManager modulesConfigManager; protected InitStatus initStatus = InitStatus.CREATED; @@ -23,7 +33,7 @@ protected LauncherModule(LauncherModuleInfo info) { moduleInfo = info; } - public LauncherModuleInfo getModuleInfo() { + public final LauncherModuleInfo getModuleInfo() { return moduleInfo; } @@ -60,6 +70,27 @@ public final LauncherTrustManager.CheckClassResult getCheckResult() { return new LauncherTrustManager.CheckClassResult(this.checkResult); } + protected final LauncherModule requireModule(String name, Version minVersion) { + if(context == null) throw new IllegalStateException("requireModule must be used in init() phase"); + LauncherModule module = context.getModulesManager().getModule(name); + requireModule(module, minVersion, name); + return module; + } + + protected final T requireModule(Class clazz, Version minVersion) { + if(context == null) throw new IllegalStateException("requireModule must be used in init() phase"); + T module = context.getModulesManager().getModule(clazz); + requireModule(module, minVersion, clazz.getName()); + return module; + } + + private void requireModule(LauncherModule module, Version minVersion, String requiredModuleName) { + if(module == null) + throw new RuntimeException(String.format("Module %s required %s v%s or higher", moduleInfo.name, requiredModuleName, minVersion.getVersionString())); + else if(module.moduleInfo.version.isLowerThan(minVersion)) + throw new RuntimeException(String.format("Module %s required %s v%s or higher (current version %s)", moduleInfo.name, requiredModuleName, minVersion.getVersionString(), module.moduleInfo.version.getVersionString())); + } + /** * The internal method used by the ModuleManager * DO NOT TOUCH @@ -86,7 +117,7 @@ public void preInitAction() { //NOP } - public LauncherModule preInit() { + public final LauncherModule preInit() { if (!initStatus.equals(InitStatus.PRE_INIT_WAIT)) throw new IllegalStateException("PreInit not allowed in current state"); initStatus = InitStatus.PRE_INIT; @@ -121,7 +152,8 @@ public LauncherModule preInit() { * @return true if adding a handler was successful */ protected boolean registerEvent(EventHandler handle, Class tClass) { - eventMap.put(tClass, handle); + EventEntity eventEntity = new EventEntity(handle, tClass); + eventList.add(eventEntity); return true; } @@ -134,10 +166,11 @@ protected boolean registerEvent(EventHandler handle, Class< @SuppressWarnings("unchecked") public final void callEvent(T event) { Class tClass = event.getClass(); - for (@SuppressWarnings("rawtypes") Map.Entry, EventHandler> e : eventMap.entrySet()) { + for (EventEntity entity : eventList) { - if (e.getKey().isAssignableFrom(tClass)) { - e.getValue().event(event); + if (entity.clazz.isAssignableFrom(tClass)) { + //noinspection RedundantCast + ((EventEntity)entity).handler.event(event); if (event.isCancel()) return; } } diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/modules/LauncherModulesManager.java b/LauncherAPI/src/main/java/pro/gravit/launcher/modules/LauncherModulesManager.java index d7fdb7bf..0ac63a2c 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/modules/LauncherModulesManager.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/modules/LauncherModulesManager.java @@ -37,6 +37,8 @@ default boolean containsModule(Class cla T findModule(Class clazz, Predicate versionPredicate); + LauncherModule findModule(String name, Predicate versionPredicate); + /** * Invoke event processing for all modules. * Event processing is carried out in the order of the modules in the list (sorted by priority) diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/modules/impl/SimpleModuleManager.java b/LauncherAPI/src/main/java/pro/gravit/launcher/modules/impl/SimpleModuleManager.java index f612bc21..529d73d5 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/modules/impl/SimpleModuleManager.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/modules/impl/SimpleModuleManager.java @@ -266,6 +266,16 @@ public T findModule(Class clazz, Predica return null; } + @Override + public LauncherModule findModule(String name, Predicate versionPredicate) { + for (LauncherModule module : modules) { + LauncherModuleInfo info = module.getModuleInfo(); + if (!versionPredicate.test(info.version)) continue; + if (name.equals(info.name)) return module; + } + return null; + } + @Override public void invokeEvent(T event) { for (LauncherModule module : modules) { diff --git a/LauncherAPI/src/test/java/pro/gravit/launcher/impl/Depend2Module.java b/LauncherAPI/src/test/java/pro/gravit/launcher/impl/Depend2Module.java index d19246ea..feaeef63 100644 --- a/LauncherAPI/src/test/java/pro/gravit/launcher/impl/Depend2Module.java +++ b/LauncherAPI/src/test/java/pro/gravit/launcher/impl/Depend2Module.java @@ -1,8 +1,10 @@ package pro.gravit.launcher.impl; +import org.junit.jupiter.api.Assertions; import pro.gravit.launcher.modules.LauncherInitContext; import pro.gravit.launcher.modules.LauncherModule; import pro.gravit.launcher.modules.LauncherModuleInfo; +import pro.gravit.utils.Version; public class Depend2Module extends LauncherModule { public Depend2Module() { @@ -17,5 +19,18 @@ public void preInitAction() { @Override public void init(LauncherInitContext initContext) { + requireModule("depend1", new Version(1,0,0)); + try { + requireModule("dependNotFound", new Version(1,0,0)); + Assertions.fail("dependNotFound"); + } catch (RuntimeException ignored) { + + } + try { + requireModule("depend1", new Version(10,0,0)); + Assertions.fail("depend1 high version"); + } catch (RuntimeException ignored) { + + } } } diff --git a/LauncherCore/src/main/java/pro/gravit/utils/Version.java b/LauncherCore/src/main/java/pro/gravit/utils/Version.java index 0a8e2e27..08100278 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/Version.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/Version.java @@ -2,7 +2,7 @@ import java.util.*; -public final class Version { +public final class Version implements Comparable { public static final int MAJOR = 5; public static final int MINOR = 2; @@ -24,6 +24,18 @@ public Version(int major, int minor, int patch) { release = Type.UNKNOWN; } + public static Version of(int major, int minor, int patch) { + return new Version(major, minor, patch); + } + + public static Version of(int major, int minor, int patch, int build) { + return new Version(major, minor, patch, build); + } + + public static Version of(int major, int minor, int patch, int build, Type release) { + return new Version(major, minor, patch, build, release); + } + public Version(int major, int minor, int patch, int build) { this.major = major; @@ -81,6 +93,22 @@ public String toString() { return String.format("%d.%d.%d-%d %s", major, minor, patch, build, getReleaseStatus()); } + @Override + public int compareTo(Version version) { + if(version.major != major) return Integer.compare(major, version.major); + if(version.minor != minor) return Integer.compare(minor, version.minor); + if(version.patch != patch) return Integer.compare(patch, version.patch); + return 0; + } + + public boolean isUpperThan(Version version) { + return this.compareTo(version) > 0; + } + + public boolean isLowerThan(Version version) { + return this.compareTo(version) < 0; + } + public enum Type { LTS, diff --git a/LauncherCore/src/test/java/pro/gravit/launcher/VersionCompareTest.java b/LauncherCore/src/test/java/pro/gravit/launcher/VersionCompareTest.java new file mode 100644 index 00000000..7b592544 --- /dev/null +++ b/LauncherCore/src/test/java/pro/gravit/launcher/VersionCompareTest.java @@ -0,0 +1,16 @@ +package pro.gravit.launcher; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import pro.gravit.utils.Version; + + +public class VersionCompareTest { + @Test + public void compareTest() { + Assertions.assertTrue(new Version(1,0,0).compareTo(new Version(1,1,0)) < 0); + Assertions.assertTrue(new Version(1,1,0).compareTo(new Version(1,0,0)) > 0); + Assertions.assertTrue(new Version(1,0,0).isLowerThan(new Version(1,1,0))); + Assertions.assertTrue(new Version(1,0,1).isUpperThan(new Version(1,0,0))); + } +}