diff --git a/bans-core/src/main/java/space/arim/libertybans/core/selector/SelectorImpl.java b/bans-core/src/main/java/space/arim/libertybans/core/selector/SelectorImpl.java index 2d13cda49..a6f434824 100644 --- a/bans-core/src/main/java/space/arim/libertybans/core/selector/SelectorImpl.java +++ b/bans-core/src/main/java/space/arim/libertybans/core/selector/SelectorImpl.java @@ -112,6 +112,7 @@ public CentralisedFuture executeAndCheckConnection(UUID uuid, String @Override public ReactionStage> getCachedMute(UUID uuid, NetworkAddress address) { Objects.requireNonNull(uuid, "uuid"); + Objects.requireNonNull(address, "address"); return muteCache.get().getCachedMute(uuid, address); } diff --git a/bans-core/src/main/java/space/arim/libertybans/core/selector/cache/AlwaysAvailableMuteCache.java b/bans-core/src/main/java/space/arim/libertybans/core/selector/cache/AlwaysAvailableMuteCache.java index 06c654cce..8c3452c2f 100644 --- a/bans-core/src/main/java/space/arim/libertybans/core/selector/cache/AlwaysAvailableMuteCache.java +++ b/bans-core/src/main/java/space/arim/libertybans/core/selector/cache/AlwaysAvailableMuteCache.java @@ -161,7 +161,29 @@ private CentralisedFuture> cacheRequest(MuteCacheKey ca @Override void clearCachedMuteIf(Predicate removeIfMatches) { - // Do nothing - the mute will automatically expire in due time + ConcurrentHashMap map = cache.map; + + for (Map.Entry mapEntry : map.entrySet()) { + MuteCacheKey key = mapEntry.getKey(); + Entry entry = mapEntry.getValue(); + + // Replace the current value with NULL if it matches the predicate + // However, perform the operation atomically with respect to entry updates + MuteAndMessage currentValue; + while ((currentValue = entry.currentValue) != null && removeIfMatches.test(currentValue.mute())) { + Entry newEntry = new Entry(null, entry.lastUpdated, entry.nextValue); + // Compare-and-swap the old entry with the new one + if (map.replace(key, entry, newEntry)) { + // Success + break; + } + entry = map.get(key); + if (entry == null) { + // Player logged off + break; + } + } + } } @Override @@ -284,6 +306,6 @@ private void stopPurgeTask() { } private record Entry(@Nullable MuteAndMessage currentValue, long lastUpdated, - @Nullable CentralisedFuture nextValue) { - } + @Nullable CentralisedFuture nextValue) { } + } diff --git a/bans-env/spigot/src/main/java/space/arim/libertybans/env/spigot/SpigotUserResolver.java b/bans-env/spigot/src/main/java/space/arim/libertybans/env/spigot/SpigotUserResolver.java index 90952c20a..8b9751555 100644 --- a/bans-env/spigot/src/main/java/space/arim/libertybans/env/spigot/SpigotUserResolver.java +++ b/bans-env/spigot/src/main/java/space/arim/libertybans/env/spigot/SpigotUserResolver.java @@ -24,6 +24,7 @@ import org.bukkit.entity.Player; import space.arim.libertybans.core.env.SimpleEnvUserResolver; import space.arim.libertybans.core.env.UUIDAndAddress; +import space.arim.morepaperlib.MorePaperLib; import space.arim.omnibus.util.concurrent.CentralisedFuture; import space.arim.omnibus.util.concurrent.FactoryOfTheFuture; @@ -36,15 +37,20 @@ public final class SpigotUserResolver extends SimpleEnvUserResolver { private final FactoryOfTheFuture futuresFactory; private final Server server; + private final MorePaperLib morePaperLib; @Inject - public SpigotUserResolver(FactoryOfTheFuture futuresFactory, Server server) { + public SpigotUserResolver(FactoryOfTheFuture futuresFactory, Server server, MorePaperLib morePaperLib) { this.futuresFactory = futuresFactory; this.server = server; + this.morePaperLib = morePaperLib; } @Override protected CentralisedFuture performLookup(Supplier rootImplementation) { + if (morePaperLib.scheduling().isUsingFolia()) { + return futuresFactory.completedFuture(rootImplementation.get()); + } return futuresFactory.supplySync(rootImplementation); } diff --git a/bans-env/sponge/pom.xml b/bans-env/sponge/pom.xml index 62c0f260e..1074a5d1e 100644 --- a/bans-env/sponge/pom.xml +++ b/bans-env/sponge/pom.xml @@ -75,7 +75,7 @@ sponge - https://repo.spongepowered.org/repository/maven-releases/ + https://repo.spongepowered.org/repository/maven-public/ \ No newline at end of file diff --git a/bans-env/sponge/src/main/java/space/arim/libertybans/env/sponge/SpongeLauncher.java b/bans-env/sponge/src/main/java/space/arim/libertybans/env/sponge/SpongeLauncher.java index d61c1e8db..6dedb940a 100644 --- a/bans-env/sponge/src/main/java/space/arim/libertybans/env/sponge/SpongeLauncher.java +++ b/bans-env/sponge/src/main/java/space/arim/libertybans/env/sponge/SpongeLauncher.java @@ -19,6 +19,7 @@ package space.arim.libertybans.env.sponge; +import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spongepowered.api.Game; import org.spongepowered.plugin.PluginContainer; @@ -31,8 +32,10 @@ import space.arim.libertybans.core.CommandsModule; import space.arim.libertybans.core.PillarOneBindModule; import space.arim.libertybans.core.PillarTwoBindModule; +import space.arim.libertybans.env.sponge.listener.RegisterListeners; import space.arim.libertybans.env.sponge.listener.RegisterListenersByMethodScan; import space.arim.libertybans.env.sponge.listener.RegisterListenersStandard; +import space.arim.libertybans.env.sponge.listener.RegisterListenersWithLookup; import space.arim.omnibus.Omnibus; import space.arim.omnibus.OmnibusProvider; @@ -58,12 +61,26 @@ public SpongeLauncher(PluginContainer plugin, Game game, Path folder, Omnibus om @Override public BaseFoundation launch() { - boolean spongeApi9; + Class registerListenersBinding; { int dataVersion = game.platform().minecraftVersion().dataVersion().orElseThrow(); // Sponge servers beyond MC 1.16.5 (data version 2586) use API 9 - spongeApi9 = dataVersion > 2586; - LoggerFactory.getLogger(getClass()).info("Using Sponge API 9+: {}", spongeApi9); + boolean spongeApi9 = dataVersion > 2586; + Logger logger = LoggerFactory.getLogger(getClass()); + logger.info("Using Sponge API 9+: {}", spongeApi9); + + if (!spongeApi9) { + registerListenersBinding = RegisterListenersStandard.class; + } else if (RegisterListenersWithLookup.detectIfUsable()) { + logger.info("Listener registration with lookup API detected and available"); + registerListenersBinding = RegisterListenersWithLookup.class; + } else { + // Fallback to manual method scanning + logger.warn( + "Proper listener registration for Sponge API 9 is not available on your outdated version. " + + "Please update your Sponge implementation so that the latest APIs are usable."); + registerListenersBinding = RegisterListenersByMethodScan.class; + } } return new InjectorBuilder() .bindInstance(PluginContainer.class, plugin) @@ -75,9 +92,9 @@ public BaseFoundation launch() { new PillarOneBindModule(), new PillarTwoBindModule(), new CommandsModule(), - new SpongeBindModule(), - spongeApi9 ? new RegisterListenersByMethodScan.Module() : new RegisterListenersStandard.Module() + new SpongeBindModule() ) + .bindIdentifier(RegisterListeners.class, registerListenersBinding) .specification(SpecificationSupport.JAKARTA) .multiBindings(true) .build() diff --git a/bans-env/sponge/src/main/java/space/arim/libertybans/env/sponge/listener/RegisterListenersByMethodScan.java b/bans-env/sponge/src/main/java/space/arim/libertybans/env/sponge/listener/RegisterListenersByMethodScan.java index 833aa9cdc..855549c01 100644 --- a/bans-env/sponge/src/main/java/space/arim/libertybans/env/sponge/listener/RegisterListenersByMethodScan.java +++ b/bans-env/sponge/src/main/java/space/arim/libertybans/env/sponge/listener/RegisterListenersByMethodScan.java @@ -53,13 +53,6 @@ public RegisterListenersByMethodScan(PluginContainer plugin, Game game) { this.game = game; } - public static class Module { - - public RegisterListeners registerListeners(RegisterListenersByMethodScan registerListeners) { - return registerListeners; - } - } - @Override public void register(PlatformListener listener) { if (registrations.containsKey(listener)) { diff --git a/bans-env/sponge/src/main/java/space/arim/libertybans/env/sponge/listener/RegisterListenersStandard.java b/bans-env/sponge/src/main/java/space/arim/libertybans/env/sponge/listener/RegisterListenersStandard.java index 94ed7cc28..c228d16c2 100644 --- a/bans-env/sponge/src/main/java/space/arim/libertybans/env/sponge/listener/RegisterListenersStandard.java +++ b/bans-env/sponge/src/main/java/space/arim/libertybans/env/sponge/listener/RegisterListenersStandard.java @@ -37,13 +37,6 @@ public RegisterListenersStandard(PluginContainer plugin, Game game) { this.game = game; } - public static final class Module { - - public RegisterListeners registerListeners(RegisterListenersStandard registerListenersStandard) { - return registerListenersStandard; - } - } - @Override public void register(PlatformListener listener) { game.eventManager().registerListeners(plugin, listener); diff --git a/bans-env/sponge/src/main/java/space/arim/libertybans/env/sponge/listener/RegisterListenersWithLookup.java b/bans-env/sponge/src/main/java/space/arim/libertybans/env/sponge/listener/RegisterListenersWithLookup.java new file mode 100644 index 000000000..13c7ead54 --- /dev/null +++ b/bans-env/sponge/src/main/java/space/arim/libertybans/env/sponge/listener/RegisterListenersWithLookup.java @@ -0,0 +1,62 @@ +/* + * LibertyBans + * Copyright © 2023 Anand Beh + * + * LibertyBans is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * LibertyBans is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with LibertyBans. If not, see + * and navigate to version 3 of the GNU Affero General Public License. + */ + +package space.arim.libertybans.env.sponge.listener; + +import jakarta.inject.Inject; +import jakarta.inject.Singleton; +import org.spongepowered.api.Game; +import org.spongepowered.api.event.EventManager; +import org.spongepowered.plugin.PluginContainer; +import space.arim.libertybans.core.env.PlatformListener; + +import java.lang.invoke.MethodHandles; + +@Singleton +public final class RegisterListenersWithLookup implements RegisterListeners { + + private final PluginContainer plugin; + private final Game game; + + @Inject + public RegisterListenersWithLookup(PluginContainer plugin, Game game) { + this.plugin = plugin; + this.game = game; + } + + public static boolean detectIfUsable() { + try { + EventManager.class.getMethod("registerListeners", PluginContainer.class, Object.class, MethodHandles.Lookup.class); + return true; + } catch (NoSuchMethodException ex) { + return false; + } + } + + @Override + public void register(PlatformListener listener) { + game.eventManager().registerListeners(plugin, listener, MethodHandles.lookup()); + } + + @Override + public void unregister(PlatformListener listener) { + game.eventManager().unregisterListeners(listener); + } + +} diff --git a/bans-env/spongeplugin/pom.xml b/bans-env/spongeplugin/pom.xml index 0fa5dd52f..1a7a3a760 100644 --- a/bans-env/spongeplugin/pom.xml +++ b/bans-env/spongeplugin/pom.xml @@ -55,7 +55,7 @@ sponge - https://repo.spongepowered.org/repository/maven-releases/ + https://repo.spongepowered.org/repository/maven-public/ \ No newline at end of file diff --git a/pom.xml b/pom.xml index b4cda68db..9e0b1a734 100644 --- a/pom.xml +++ b/pom.xml @@ -52,7 +52,7 @@ 2.0.0 - 1.1.0-RC1 + 1.1.0-RC2 1.3.0-M2 1.7.30 5.0.1 @@ -64,14 +64,14 @@ 3.18.3 4.7.0 1.3.0 - 0.26.4 + 0.26.5 0.1.3 0.4.3 1.16-R0.4 1.8.8-R0.1-20160221.082514-43 - 9.0.0 + 9.1.0-SNAPSHOT 3.1.0 @@ -156,6 +156,7 @@ space.arim.libertybans:* org.spigotmc:spigot-api + org.spongepowered:spongeapi