diff --git a/minestom/build.gradle b/minestom/build.gradle index 45a8e1062..0a6627cbb 100644 --- a/minestom/build.gradle +++ b/minestom/build.gradle @@ -13,7 +13,7 @@ repositories { } dependencies { - var minestom = "ccea53ac44" + var minestom = "net.minestom:minestom-snapshots:2065f63f82" api(project(":common")) { // exclude default config providers as they are inaccessible from the minestom module anyway @@ -22,11 +22,11 @@ dependencies { exclude group: "org.spongepowered", module: "configurate-hocon" exclude group: "me.lucko.configurate", module: "configurate-toml" } - compileOnly "net.minestom:minestom-snapshots:$minestom" + compileOnly minestom // testing testImplementation project(":common") - testImplementation "net.minestom:minestom-snapshots:$minestom" + testImplementation minestom testImplementation "commons-net:commons-net:3.10.0" // fix vulnerability in minestom testImplementation "ch.qos.logback:logback-classic:1.4.14" // logger testImplementation "org.spongepowered:configurate-hocon:3.7.2" // configuration using hocon diff --git a/minestom/src/main/java/me/lucko/luckperms/minestom/LPMinestomPlugin.java b/minestom/src/main/java/me/lucko/luckperms/minestom/LPMinestomPlugin.java index 28a882734..2409a9277 100644 --- a/minestom/src/main/java/me/lucko/luckperms/minestom/LPMinestomPlugin.java +++ b/minestom/src/main/java/me/lucko/luckperms/minestom/LPMinestomPlugin.java @@ -34,9 +34,11 @@ import me.lucko.luckperms.minestom.context.MinestomContextManager; import me.lucko.luckperms.minestom.context.MinestomPlayerCalculator; import me.lucko.luckperms.minestom.dependencies.NoopDependencyManager; +import me.lucko.luckperms.minestom.listeners.MinestomCommandListUpdater; import me.lucko.luckperms.minestom.listeners.MinestomConnectionListener; import me.lucko.luckperms.minestom.messaging.MinestomMessagingFactory; import net.luckperms.api.LuckPerms; +import net.luckperms.api.event.user.UserDataRecalculateEvent; import net.luckperms.api.query.QueryOptions; import net.minestom.server.MinecraftServer; import net.minestom.server.entity.Player; @@ -146,10 +148,15 @@ protected void registerApiOnPlatform(LuckPerms api) { protected void performFinalSetup() { PermissionRegistry permissionRegistry = this.getPermissionRegistry(); this.permissionSuggestions.forEach(permissionRegistry::offer); + + // refresh commands when the user data is recalculated + if (this.commandRegistry != null && this.getConfiguration().get(ConfigKeys.UPDATE_CLIENT_COMMAND_LIST)) { + this.getApiProvider().getEventBus().subscribe(new MinestomCommandListUpdater(this)); + } } @Override - public LuckPermsBootstrap getBootstrap() { + public @NotNull LPMinestomBootstrap getBootstrap() { return this.bootstrap; } diff --git a/minestom/src/main/java/me/lucko/luckperms/minestom/listeners/MinestomCommandListUpdater.java b/minestom/src/main/java/me/lucko/luckperms/minestom/listeners/MinestomCommandListUpdater.java new file mode 100644 index 000000000..a19d08ba0 --- /dev/null +++ b/minestom/src/main/java/me/lucko/luckperms/minestom/listeners/MinestomCommandListUpdater.java @@ -0,0 +1,74 @@ +package me.lucko.luckperms.minestom.listeners; + +import com.github.benmanes.caffeine.cache.LoadingCache; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import me.lucko.luckperms.common.cache.BufferedRequest; +import me.lucko.luckperms.common.event.LuckPermsEventListener; +import me.lucko.luckperms.common.util.CaffeineFactory; +import me.lucko.luckperms.minestom.LPMinestomBootstrap; +import me.lucko.luckperms.minestom.LPMinestomPlugin; +import net.luckperms.api.event.EventBus; +import net.luckperms.api.event.context.ContextUpdateEvent; +import net.luckperms.api.event.user.UserDataRecalculateEvent; +import net.minestom.server.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public final class MinestomCommandListUpdater implements LuckPermsEventListener { + + private final @NotNull LoadingCache sendingBuffers = CaffeineFactory.newBuilder() + .expireAfterAccess(10, TimeUnit.SECONDS) + .build(SendBuffer::new); + + private final @NotNull LPMinestomPlugin plugin; + + public MinestomCommandListUpdater(@NotNull LPMinestomPlugin plugin) { + this.plugin = plugin; + } + + @Override + public void bind(@NotNull EventBus bus) { + bus.subscribe(UserDataRecalculateEvent.class, this::onUserDataRecalculate); + bus.subscribe(ContextUpdateEvent.class, this::onContextUpdate); + } + + private void onUserDataRecalculate(@NotNull UserDataRecalculateEvent event) { + this.requestUpdate(event.getUser().getUniqueId()); + } + + private void onContextUpdate(@NotNull ContextUpdateEvent event) { + event.getSubject(Player.class).map(Player::getUuid).ifPresent(this::requestUpdate); + } + + private void requestUpdate(@NotNull UUID uniqueId) { + if (!this.plugin.getBootstrap().isPlayerOnline(uniqueId)) return; + + SendBuffer sendBuffer = this.sendingBuffers.get(uniqueId); + if (sendBuffer == null) throw new IllegalStateException("send buffer is null"); + sendBuffer.request(); + } + + private void sendUpdate(@NotNull UUID uniqueId) { + LPMinestomBootstrap bootstrap = this.plugin.getBootstrap(); + bootstrap.getScheduler().sync().execute(() -> bootstrap.getPlayer(uniqueId).ifPresent(Player::refreshCommands)); + } + + private final class SendBuffer extends BufferedRequest { + + private final @NotNull UUID uniqueId; + + SendBuffer(@NotNull UUID uniqueId) { + super(500, TimeUnit.MILLISECONDS, MinestomCommandListUpdater.this.plugin.getBootstrap().getScheduler()); + this.uniqueId = uniqueId; + } + + @Override + protected @Nullable Void perform() { + MinestomCommandListUpdater.this.sendUpdate(this.uniqueId); + return null; + } + + } + +}