From f352610157fc433b35b572a942f3d9e54bcfecc4 Mon Sep 17 00:00:00 2001 From: JRoy <10731363+JRoy@users.noreply.github.com> Date: Sat, 2 Aug 2025 22:09:02 -0700 Subject: [PATCH 1/5] Migrate PlayerLoginEvent to modern events --- .../essentials/EssentialsPlayerListener.java | 92 ++++++++++++++----- 1 file changed, 69 insertions(+), 23 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java index 8b6b2d51f16..ddda930ee37 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java @@ -14,6 +14,8 @@ import com.earth2me.essentials.utils.MaterialUtil; import com.earth2me.essentials.utils.VersionUtil; import io.papermc.lib.PaperLib; +import io.papermc.paper.ban.BanListType; +import io.papermc.paper.event.player.PlayerServerFullCheckEvent; import net.ess3.api.IEssentials; import net.ess3.api.events.AfkStatusChangeEvent; import net.ess3.provider.CommandSendListenerProvider; @@ -45,6 +47,7 @@ import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; import org.bukkit.event.player.PlayerBucketEmptyEvent; import org.bukkit.event.player.PlayerChangedWorldEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent; @@ -53,7 +56,6 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerLoginEvent; -import org.bukkit.event.player.PlayerLoginEvent.Result; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerRespawnEvent; @@ -158,6 +160,12 @@ public void registerEvents() { } else if (isCommandSendEvent()) { ess.getServer().getPluginManager().registerEvents(new BukkitCommandSendListenerProvider(new CommandSendFilter()), ess); } + + if (VersionUtil.isPaper() && VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_21_8_R01)) { + ess.getServer().getPluginManager().registerEvents(new LoginListener1_21(), ess); + } else { + ess.getServer().getPluginManager().registerEvents(new LoginListenerPre1_21(), ess); + } } @EventHandler(priority = EventPriority.NORMAL) @@ -540,38 +548,76 @@ private void updateCompass(final User user) { user.getBase().setCompassTarget(loc); } - @EventHandler(priority = EventPriority.LOW) - public void onPlayerLoginBanned(final PlayerLoginEvent event) { - if (event.getResult() == Result.KICK_BANNED) { - BanEntry banEntry = ess.getServer().getBanList(BanList.Type.NAME).getBanEntry(event.getPlayer().getName()); - if (banEntry != null) { - final Date banExpiry = banEntry.getExpiration(); - if (banExpiry != null) { - final String expiry = DateUtil.formatDateDiff(banExpiry.getTime()); - event.setKickMessage(AdventureUtil.miniToLegacy(tlLiteral("tempbanJoin", expiry, banEntry.getReason()))); + private final class LoginListenerPre1_21 implements Listener { + @EventHandler(priority = EventPriority.LOW) + public void onPlayerLoginBanned(final PlayerLoginEvent event) { + if (event.getResult() == PlayerLoginEvent.Result.KICK_BANNED) { + BanEntry banEntry = ess.getServer().getBanList(BanList.Type.NAME).getBanEntry(event.getPlayer().getName()); + if (banEntry != null) { + final Date banExpiry = banEntry.getExpiration(); + if (banExpiry != null) { + final String expiry = DateUtil.formatDateDiff(banExpiry.getTime()); + event.setKickMessage(AdventureUtil.miniToLegacy(tlLiteral("tempbanJoin", expiry, banEntry.getReason()))); + } else { + event.setKickMessage(AdventureUtil.miniToLegacy(tlLiteral("banJoin", banEntry.getReason()))); + } } else { - event.setKickMessage(AdventureUtil.miniToLegacy(tlLiteral("banJoin", banEntry.getReason()))); + banEntry = ess.getServer().getBanList(BanList.Type.IP).getBanEntry(event.getAddress().getHostAddress()); + if (banEntry != null) { + event.setKickMessage(AdventureUtil.miniToLegacy(tlLiteral("banIpJoin", banEntry.getReason()))); + } } - } else { - banEntry = ess.getServer().getBanList(BanList.Type.IP).getBanEntry(event.getAddress().getHostAddress()); - if (banEntry != null) { - event.setKickMessage(AdventureUtil.miniToLegacy(tlLiteral("banIpJoin", banEntry.getReason()))); + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void onPlayerLogin(final PlayerLoginEvent event) { + if (event.getResult() == PlayerLoginEvent.Result.KICK_FULL) { + final User kfuser = ess.getUser(event.getPlayer()); + kfuser.update(event.getPlayer()); + if (kfuser.isAuthorized("essentials.joinfullserver")) { + event.allow(); + return; + } + if (ess.getSettings().isCustomServerFullMessage()) { + event.disallow(PlayerLoginEvent.Result.KICK_FULL, tlLiteral("serverFull")); } } } } - @EventHandler(priority = EventPriority.HIGH) - public void onPlayerLogin(final PlayerLoginEvent event) { - if (event.getResult() == Result.KICK_FULL) { - final User kfuser = ess.getUser(event.getPlayer()); - kfuser.update(event.getPlayer()); - if (kfuser.isAuthorized("essentials.joinfullserver")) { - event.allow(); + private final class LoginListener1_21 implements Listener { + @EventHandler(priority = EventPriority.HIGH) + public void onPlayerListFull(final PlayerServerFullCheckEvent event) { + final User user = ess.getUser(event.getPlayerProfile().getId()); + if (user.isAuthorized("essentials.joinfullserver")) { + event.allow(true); return; } + if (ess.getSettings().isCustomServerFullMessage()) { - event.disallow(Result.KICK_FULL, tlLiteral("serverFull")); + event.deny(user.tlComponent("serverFull")); + } + } + + @EventHandler(priority = EventPriority.LOW) + public void onPlayerKickBanned(final AsyncPlayerPreLoginEvent event) { + if (event.getLoginResult() == AsyncPlayerPreLoginEvent.Result.KICK_BANNED) { + BanEntry banEntry = ess.getServer().getBanList(BanListType.PROFILE).getBanEntry(event.getPlayerProfile()); + if (banEntry != null) { + final Date banExpiry = banEntry.getExpiration(); + if (banExpiry != null) { + final String expiry = DateUtil.formatDateDiff(banExpiry.getTime()); + event.setKickMessage(AdventureUtil.miniToLegacy(tlLiteral("tempbanJoin", expiry, banEntry.getReason()))); + } else { + event.setKickMessage(AdventureUtil.miniToLegacy(tlLiteral("banJoin", banEntry.getReason()))); + } + } else { + banEntry = ess.getServer().getBanList(BanListType.IP).getBanEntry(event.getAddress()); + if (banEntry != null) { + event.setKickMessage(AdventureUtil.miniToLegacy(tlLiteral("banIpJoin", banEntry.getReason()))); + } + } } } } From 609e07bcf660034a6ba2f140f41f095cb1036f6a Mon Sep 17 00:00:00 2001 From: JRoy <10731363+JRoy@users.noreply.github.com> Date: Sun, 3 Aug 2025 21:04:23 -0700 Subject: [PATCH 2/5] move to config api --- .../essentials/EssentialsPlayerListener.java | 361 ++--- .../essentials/userstorage/IUserMap.java | 7 + .../essentials/userstorage/ModernUserMap.java | 15 + .../com/earth2me/essentials/FakeAccessor.java | 13 - .../com/earth2me/essentials/FakeServer.java | 1269 ----------------- 5 files changed, 220 insertions(+), 1445 deletions(-) delete mode 100644 providers/1_12Provider/src/main/java/com/earth2me/essentials/FakeAccessor.java delete mode 100644 providers/1_12Provider/src/main/java/com/earth2me/essentials/FakeServer.java diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java index ddda930ee37..b820e0bf101 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java @@ -1,5 +1,6 @@ package com.earth2me.essentials; +import com.destroystokyo.paper.profile.ProfileProperty; import com.earth2me.essentials.commands.Commandfireball; import com.earth2me.essentials.craftbukkit.Inventories; import com.earth2me.essentials.textreader.IText; @@ -15,6 +16,7 @@ import com.earth2me.essentials.utils.VersionUtil; import io.papermc.lib.PaperLib; import io.papermc.paper.ban.BanListType; +import io.papermc.paper.event.connection.configuration.AsyncPlayerConnectionConfigureEvent; import io.papermc.paper.event.player.PlayerServerFullCheckEvent; import net.ess3.api.IEssentials; import net.ess3.api.events.AfkStatusChangeEvent; @@ -79,13 +81,14 @@ import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; import java.util.function.Predicate; import java.util.logging.Level; import java.util.regex.Pattern; import static com.earth2me.essentials.I18n.tlLiteral; -public class EssentialsPlayerListener implements Listener, FakeAccessor { +public class EssentialsPlayerListener implements Listener { private final transient IEssentials ess; private final ConcurrentHashMap pendingMotdTasks = new ConcurrentHashMap<>(); @@ -163,8 +166,10 @@ public void registerEvents() { if (VersionUtil.isPaper() && VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_21_8_R01)) { ess.getServer().getPluginManager().registerEvents(new LoginListener1_21(), ess); + ess.getServer().getPluginManager().registerEvents(new JoinListener1_21(), ess); } else { ess.getServer().getPluginManager().registerEvents(new LoginListenerPre1_21(), ess); + ess.getServer().getPluginManager().registerEvents(new JoinListenerPre1_21(), ess); } } @@ -332,8 +337,55 @@ public void onPlayerQuit(final PlayerQuitEvent event) { user.dispose(); } - @EventHandler(priority = EventPriority.HIGHEST) - public void onPlayerJoin(final PlayerJoinEvent event) { + @SuppressWarnings("UnstableApiUsage") + private final class JoinListener1_21 implements Listener { + @EventHandler + public void onPlayerConfigure(final AsyncPlayerConnectionConfigureEvent event) { + ess.getBackup().onPlayerJoin(); + final User dUser = ess.getUser(event.getConnection().getProfile().getId()); + + dUser.startTransaction(); + if (dUser.isNPC()) { + dUser.setNPC(false); + } + + final long currentTime = System.currentTimeMillis(); + dUser.checkMuteTimeout(currentTime); + dUser.updateActivity(false, AfkStatusChangeEvent.Cause.JOIN); + dUser.stopTransaction(); + + System.out.println("EssentialsPlayerListener.onPlayerConfigure: " + event.getConnection().getProfile().getName() + " has joined the server."); + for (final ProfileProperty property : event.getConnection().getProfile().getProperties()) { + System.out.println(property.getName() + " " + property.getValue()); + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onPlayerJoin(final PlayerJoinEvent event) { + if (!ess.getUsers().isCached(event.getPlayer().getUniqueId())) { + legacyJoinFlow(event); + return; + } + + final User user = ess.getUser(event.getPlayer()); + user.update(event.getPlayer()); + final long currentTime = System.currentTimeMillis(); + joinFlow(user, currentTime, event.getJoinMessage(), event::setJoinMessage); + } + } + + private final class JoinListenerPre1_21 implements Listener { + @EventHandler(priority = EventPriority.HIGHEST) + public void onPlayerJoin(final PlayerJoinEvent event) { + legacyJoinFlow(event); + } + } + + private boolean hideJoinQuitMessages() { + return ess.getSettings().hasJoinQuitMessagePlayerCount() && ess.getServer().getOnlinePlayers().size() > ess.getSettings().getJoinQuitMessagePlayerCount(); + } + + private void legacyJoinFlow(final PlayerJoinEvent event) { final String joinMessage = event.getJoinMessage(); ess.runTaskAsynchronously(() -> delayedJoin(event.getPlayer(), joinMessage)); @@ -342,193 +394,181 @@ public void onPlayerJoin(final PlayerJoinEvent event) { } } - private boolean hideJoinQuitMessages() { - return ess.getSettings().hasJoinQuitMessagePlayerCount() && ess.getServer().getOnlinePlayers().size() > ess.getSettings().getJoinQuitMessagePlayerCount(); - } + private void joinFlow(final User user, final long currentTime, final String message, final Consumer joinMessageConsumer) { + user.startTransaction(); - public void delayedJoin(final Player player, final String message) { - if (!player.isOnline()) { - return; + final String lastAccountName = user.getLastAccountName(); // For comparison + user.setLastAccountName(user.getBase().getName()); + user.setLastLogin(currentTime); + user.setDisplayNick(); + updateCompass(user); + user.setLeavingHidden(false); + + // Check for new username. If they don't want the message, let's just say it's false. + final boolean newUsername = ess.getSettings().isCustomNewUsernameMessage() && lastAccountName != null && !lastAccountName.equals(user.getBase().getName()); + + if (!ess.getVanishedPlayersNew().isEmpty() && !user.isAuthorized("essentials.vanish.see")) { + for (final String p : ess.getVanishedPlayersNew()) { + final Player toVanish = ess.getServer().getPlayerExact(p); + if (toVanish != null && toVanish.isOnline()) { + user.getBase().hidePlayer(toVanish); + if (ess.getSettings().isDebug()) { + ess.getLogger().info("Hiding vanished player: " + p); + } + } + } } - ess.getBackup().onPlayerJoin(); - final User dUser = ess.getUser(player); - dUser.update(player); + if (user.isAuthorized("essentials.sleepingignored")) { + user.getBase().setSleepingIgnored(true); + } - dUser.startTransaction(); - if (dUser.isNPC()) { - dUser.setNPC(false); + final String effectiveMessage; + if (ess.getSettings().allowSilentJoinQuit() && (user.isAuthorized("essentials.silentjoin") || user.isAuthorized("essentials.silentjoin.vanish"))) { + if (user.isAuthorized("essentials.silentjoin.vanish")) { + user.setVanished(true); + } + effectiveMessage = null; + } else if (message == null || hideJoinQuitMessages()) { + effectiveMessage = null; + } else if (ess.getSettings().isCustomJoinMessage()) { + final String msg = (newUsername ? ess.getSettings().getCustomNewUsernameMessage() : ess.getSettings().getCustomJoinMessage()) + .replace("{PLAYER}", user.getDisplayName()).replace("{USERNAME}", user.getName()) + .replace("{UNIQUE}", NumberFormat.getInstance().format(ess.getUsers().getUserCount())) + .replace("{ONLINE}", NumberFormat.getInstance().format(ess.getOnlinePlayers().size())) + .replace("{UPTIME}", DateUtil.formatDateDiff(ManagementFactory.getRuntimeMXBean().getStartTime())) + .replace("{PREFIX}", FormatUtil.replaceFormat(ess.getPermissionsHandler().getPrefix(user.getBase()))) + .replace("{SUFFIX}", FormatUtil.replaceFormat(ess.getPermissionsHandler().getSuffix(user.getBase()))) + .replace("{OLDUSERNAME}", lastAccountName == null ? "" : lastAccountName); + effectiveMessage = msg.isEmpty() ? null : msg; + } else if (ess.getSettings().allowSilentJoinQuit()) { + effectiveMessage = message; + } else { + effectiveMessage = message; } - final long currentTime = System.currentTimeMillis(); - dUser.checkMuteTimeout(currentTime); - dUser.updateActivity(false, AfkStatusChangeEvent.Cause.JOIN); - dUser.stopTransaction(); + joinMessageConsumer.accept(effectiveMessage); - class DelayJoinTask implements Runnable { - @Override - public void run() { - final User user = ess.getUser(player); + ess.runTaskAsynchronously(() -> ess.getServer().getPluginManager().callEvent(new AsyncUserDataLoadEvent(user, effectiveMessage))); - if (!user.getBase().isOnline()) { - return; - } + if (ess.getSettings().getMotdDelay() >= 0) { + final int motdDelay = ess.getSettings().getMotdDelay() / 50; + final Runnable motdTask = () -> motdFlow(user); + if (motdDelay > 0) { + pendingMotdTasks.put(user.getUUID(), ess.scheduleSyncDelayedTask(motdTask, motdDelay)); + } else { + motdTask.run(); + } + } - user.startTransaction(); - - final String lastAccountName = user.getLastAccountName(); // For comparison - user.setLastAccountName(user.getBase().getName()); - user.setLastLogin(currentTime); - user.setDisplayNick(); - updateCompass(user); - user.setLeavingHidden(false); - - // Check for new username. If they don't want the message, let's just say it's false. - final boolean newUsername = ess.getSettings().isCustomNewUsernameMessage() && lastAccountName != null && !lastAccountName.equals(user.getBase().getName()); - - if (!ess.getVanishedPlayersNew().isEmpty() && !user.isAuthorized("essentials.vanish.see")) { - for (final String p : ess.getVanishedPlayersNew()) { - final Player toVanish = ess.getServer().getPlayerExact(p); - if (toVanish != null && toVanish.isOnline()) { - user.getBase().hidePlayer(toVanish); - if (ess.getSettings().isDebug()) { - ess.getLogger().info("Hiding vanished player: " + p); - } - } - } + if (!ess.getSettings().isCommandDisabled("mail") && user.isAuthorized("essentials.mail")) { + if (user.getUnreadMailAmount() == 0) { + if (ess.getSettings().isNotifyNoNewMail()) { + user.sendTl("noNewMail"); // Only notify if they want us to. } + } else { + user.notifyOfMail(); + } + } - if (user.isAuthorized("essentials.sleepingignored")) { - user.getBase().setSleepingIgnored(true); + if (user.isAuthorized("essentials.updatecheck")) { + ess.runTaskAsynchronously(() -> { + for (final Component component : ess.getUpdateChecker().getVersionMessages(false, false, user.getSource())) { + user.sendComponent(component); } + }); + } - final String effectiveMessage; - if (ess.getSettings().allowSilentJoinQuit() && (user.isAuthorized("essentials.silentjoin") || user.isAuthorized("essentials.silentjoin.vanish"))) { - if (user.isAuthorized("essentials.silentjoin.vanish")) { - user.setVanished(true); - } - effectiveMessage = null; - } else if (message == null || hideJoinQuitMessages()) { - effectiveMessage = null; - } else if (ess.getSettings().isCustomJoinMessage()) { - final String msg = (newUsername ? ess.getSettings().getCustomNewUsernameMessage() : ess.getSettings().getCustomJoinMessage()) - .replace("{PLAYER}", player.getDisplayName()).replace("{USERNAME}", player.getName()) - .replace("{UNIQUE}", NumberFormat.getInstance().format(ess.getUsers().getUserCount())) - .replace("{ONLINE}", NumberFormat.getInstance().format(ess.getOnlinePlayers().size())) - .replace("{UPTIME}", DateUtil.formatDateDiff(ManagementFactory.getRuntimeMXBean().getStartTime())) - .replace("{PREFIX}", FormatUtil.replaceFormat(ess.getPermissionsHandler().getPrefix(player))) - .replace("{SUFFIX}", FormatUtil.replaceFormat(ess.getPermissionsHandler().getSuffix(player))) - .replace("{OLDUSERNAME}", lastAccountName == null ? "" : lastAccountName); - if (!msg.isEmpty()) { - ess.getServer().broadcastMessage(msg); - } - effectiveMessage = msg.isEmpty() ? null : msg; - } else if (ess.getSettings().allowSilentJoinQuit()) { - ess.getServer().broadcastMessage(message); - effectiveMessage = message; - } else { - effectiveMessage = message; + if (user.isAuthorized("essentials.fly.safelogin")) { + user.getBase().setFallDistance(0); + if (LocationUtil.shouldFly(ess, user.getLocation())) { + user.getBase().setAllowFlight(true); + user.getBase().setFlying(true); + if (ess.getSettings().isSendFlyEnableOnJoin()) { + user.sendTl("flyMode", CommonPlaceholders.enableDisable(user.getSource(), true), user.getDisplayName()); } + } + } - ess.runTaskAsynchronously(() -> ess.getServer().getPluginManager().callEvent(new AsyncUserDataLoadEvent(user, effectiveMessage))); + if (!user.isAuthorized("essentials.speed")) { + user.getBase().setFlySpeed(0.1f); + user.getBase().setWalkSpeed(0.2f); + } - if (ess.getSettings().getMotdDelay() >= 0) { - final int motdDelay = ess.getSettings().getMotdDelay() / 50; - final DelayMotdTask motdTask = new DelayMotdTask(user); - if (motdDelay > 0) { - pendingMotdTasks.put(user.getUUID(), ess.scheduleSyncDelayedTask(motdTask, motdDelay)); - } else { - motdTask.run(); - } - } + if (user.isSocialSpyEnabled() && !user.isAuthorized("essentials.socialspy")) { + user.setSocialSpyEnabled(false); + ess.getLogger().log(Level.INFO, "Set socialspy to false for {0} because they had it enabled without permission.", user.getName()); + } - if (!ess.getSettings().isCommandDisabled("mail") && user.isAuthorized("essentials.mail")) { - if (user.getUnreadMailAmount() == 0) { - if (ess.getSettings().isNotifyNoNewMail()) { - user.sendTl("noNewMail"); // Only notify if they want us to. - } - } else { - user.notifyOfMail(); - } - } + if (user.isGodModeEnabled() && !user.isAuthorized("essentials.god")) { + user.setGodModeEnabled(false); + ess.getLogger().log(Level.INFO, "Set god mode to false for {0} because they had it enabled without permission.", user.getName()); + } - if (user.isAuthorized("essentials.updatecheck")) { - ess.runTaskAsynchronously(() -> { - for (final Component component : ess.getUpdateChecker().getVersionMessages(false, false, user.getSource())) { - user.sendComponent(component); - } - }); - } + user.setConfirmingClearCommand(null); + user.getConfirmingPayments().clear(); - if (user.isAuthorized("essentials.fly.safelogin")) { - user.getBase().setFallDistance(0); - if (LocationUtil.shouldFly(ess, user.getLocation())) { - user.getBase().setAllowFlight(true); - user.getBase().setFlying(true); - if (ess.getSettings().isSendFlyEnableOnJoin()) { - user.sendTl("flyMode", CommonPlaceholders.enableDisable(user.getSource(), true), user.getDisplayName()); - } - } - } + user.stopTransaction(); + } - if (!user.isAuthorized("essentials.speed")) { - user.getBase().setFlySpeed(0.1f); - user.getBase().setWalkSpeed(0.2f); - } + private void motdFlow(final User user) { + pendingMotdTasks.remove(user.getUUID()); - if (user.isSocialSpyEnabled() && !user.isAuthorized("essentials.socialspy")) { - user.setSocialSpyEnabled(false); - ess.getLogger().log(Level.INFO, "Set socialspy to false for {0} because they had it enabled without permission.", user.getName()); - } + IText tempInput = null; - if (user.isGodModeEnabled() && !user.isAuthorized("essentials.god")) { - user.setGodModeEnabled(false); - ess.getLogger().log(Level.INFO, "Set god mode to false for {0} because they had it enabled without permission.", user.getName()); + if (!ess.getSettings().isCommandDisabled("motd")) { + try { + tempInput = new TextInput(user.getSource(), "motd", true, ess); + } catch (final IOException ex) { + if (ess.getSettings().isDebug()) { + ess.getLogger().log(Level.WARNING, ex.getMessage(), ex); + } else { + ess.getLogger().log(Level.WARNING, ex.getMessage()); } + } + } - user.setConfirmingClearCommand(null); - user.getConfirmingPayments().clear(); + final IText input = tempInput; - user.stopTransaction(); - } + if (input != null && !input.getLines().isEmpty() && user.isAuthorized("essentials.motd")) { + final IText output = new KeywordReplacer(input, user.getSource(), ess); + final TextPager pager = new TextPager(output, true); + pager.showPage("1", null, "motd", user.getSource()); + } + } - class DelayMotdTask implements Runnable { - private final User user; + private void delayedJoin(final Player player, final String message) { + if (!player.isOnline()) { + return; + } - DelayMotdTask(final User user) { - this.user = user; - } + ess.getBackup().onPlayerJoin(); + final User dUser = ess.getUser(player); + dUser.update(player); - @Override - public void run() { - pendingMotdTasks.remove(user.getUUID()); - - IText tempInput = null; - - if (!ess.getSettings().isCommandDisabled("motd")) { - try { - tempInput = new TextInput(user.getSource(), "motd", true, ess); - } catch (final IOException ex) { - if (ess.getSettings().isDebug()) { - ess.getLogger().log(Level.WARNING, ex.getMessage(), ex); - } else { - ess.getLogger().log(Level.WARNING, ex.getMessage()); - } - } - } + dUser.startTransaction(); + if (dUser.isNPC()) { + dUser.setNPC(false); + } - final IText input = tempInput; + final long currentTime = System.currentTimeMillis(); + dUser.checkMuteTimeout(currentTime); + dUser.updateActivity(false, AfkStatusChangeEvent.Cause.JOIN); + dUser.stopTransaction(); - if (input != null && !input.getLines().isEmpty() && user.isAuthorized("essentials.motd")) { - final IText output = new KeywordReplacer(input, user.getSource(), ess); - final TextPager pager = new TextPager(output, true); - pager.showPage("1", null, "motd", user.getSource()); - } - } + ess.scheduleSyncDelayedTask(() -> { + final User user = ess.getUser(player); + + if (!user.getBase().isOnline()) { + return; } - } - ess.scheduleSyncDelayedTask(new DelayJoinTask()); + joinFlow(user, currentTime, message, msg -> { + if (msg != null && !msg.isEmpty()) { + ess.getServer().broadcastMessage(msg); + } + }); + }); } // Makes the compass item ingame always point to the first essentials home. #EasterEgg @@ -1149,9 +1189,4 @@ private boolean isEssentialsCommand(final String label) { && (ess.getSettings().isCommandOverridden(label) || (ess.getAlternativeCommandsHandler().getAlternative(label) == null)); } } - - @Override - public void getUser(Player player) { - ess.getUser(player); - } } diff --git a/Essentials/src/main/java/com/earth2me/essentials/userstorage/IUserMap.java b/Essentials/src/main/java/com/earth2me/essentials/userstorage/IUserMap.java index 6bb13d55474..dec9319012f 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/userstorage/IUserMap.java +++ b/Essentials/src/main/java/com/earth2me/essentials/userstorage/IUserMap.java @@ -20,6 +20,13 @@ public interface IUserMap { */ long getCachedCount(); + /** + * Checks if a user is cached. + * @param uuid the UUID of the user to check. + * @return true if the user is cached, false otherwise. + */ + boolean isCached(final UUID uuid); + /** * Gets the amount of users stored by Essentials. * @return the amount of users stored by Essentials. diff --git a/Essentials/src/main/java/com/earth2me/essentials/userstorage/ModernUserMap.java b/Essentials/src/main/java/com/earth2me/essentials/userstorage/ModernUserMap.java index 6c9351c0d06..ade6981c37a 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/userstorage/ModernUserMap.java +++ b/Essentials/src/main/java/com/earth2me/essentials/userstorage/ModernUserMap.java @@ -62,6 +62,21 @@ public long getCachedCount() { return userCache.size(); } + @Override + public boolean isCached(final UUID uuid) { + if (uuid == null) { + return false; + } + try { + return userCache.getIfPresent(uuid) != null; + } catch (Exception e) { + if (ess.getSettings().isDebug()) { + ess.getLogger().log(Level.WARNING, "Exception while checking if user is cached for " + uuid, e); + } + return false; + } + } + @Override public int getUserCount() { return uuidCache.getCacheSize(); diff --git a/providers/1_12Provider/src/main/java/com/earth2me/essentials/FakeAccessor.java b/providers/1_12Provider/src/main/java/com/earth2me/essentials/FakeAccessor.java deleted file mode 100644 index 5de96c3ac02..00000000000 --- a/providers/1_12Provider/src/main/java/com/earth2me/essentials/FakeAccessor.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.earth2me.essentials; - -import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerJoinEvent; - -/** - * Utility method to bridge certain features between our test suite and the base module. - */ -public interface FakeAccessor { - void onPlayerJoin(PlayerJoinEvent event); - - void getUser(Player player); -} diff --git a/providers/1_12Provider/src/main/java/com/earth2me/essentials/FakeServer.java b/providers/1_12Provider/src/main/java/com/earth2me/essentials/FakeServer.java deleted file mode 100644 index 8651f519a8d..00000000000 --- a/providers/1_12Provider/src/main/java/com/earth2me/essentials/FakeServer.java +++ /dev/null @@ -1,1269 +0,0 @@ -package com.earth2me.essentials; - -import org.bukkit.Achievement; -import org.bukkit.BanList; -import org.bukkit.Bukkit; -import org.bukkit.GameMode; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.Server; -import org.bukkit.Statistic; -import org.bukkit.UnsafeValues; -import org.bukkit.Warning.WarningState; -import org.bukkit.World; -import org.bukkit.World.Environment; -import org.bukkit.WorldCreator; -import org.bukkit.advancement.Advancement; -import org.bukkit.boss.BarColor; -import org.bukkit.boss.BarFlag; -import org.bukkit.boss.BarStyle; -import org.bukkit.boss.BossBar; -import org.bukkit.command.CommandSender; -import org.bukkit.command.ConsoleCommandSender; -import org.bukkit.command.PluginCommand; -import org.bukkit.conversations.Conversation; -import org.bukkit.conversations.ConversationAbandonedEvent; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.inventory.InventoryType; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.generator.ChunkGenerator; -import org.bukkit.help.HelpMap; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.ItemFactory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.Merchant; -import org.bukkit.inventory.Recipe; -import org.bukkit.map.MapView; -import org.bukkit.permissions.Permissible; -import org.bukkit.permissions.Permission; -import org.bukkit.permissions.PermissionAttachment; -import org.bukkit.permissions.PermissionAttachmentInfo; -import org.bukkit.plugin.EventExecutor; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.PluginLoader; -import org.bukkit.plugin.PluginManager; -import org.bukkit.plugin.RegisteredListener; -import org.bukkit.plugin.RegisteredServiceProvider; -import org.bukkit.plugin.ServicePriority; -import org.bukkit.plugin.ServicesManager; -import org.bukkit.plugin.UnknownDependencyException; -import org.bukkit.plugin.messaging.Messenger; -import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.scheduler.BukkitScheduler; -import org.bukkit.scheduler.BukkitTask; -import org.bukkit.scheduler.BukkitWorker; -import org.bukkit.scoreboard.ScoreboardManager; -import org.bukkit.util.CachedServerIcon; - -import java.awt.image.BufferedImage; -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Callable; -import java.util.concurrent.Future; -import java.util.logging.Logger; - -@SuppressWarnings({"NullableProblems"}) -public final class FakeServer implements Server { - private final List worlds = new ArrayList<>(); - private final PluginManager pluginManager = new FakePluginManager(); - private final List players = new ArrayList<>(); - - private FakeServer() { - createWorld("testWorld", Environment.NORMAL); - } - - public static FakeServer getServer() { - if (Bukkit.getServer() == null) { - Bukkit.setServer(new FakeServer()); - } - return (FakeServer) Bukkit.getServer(); - } - - @Override - public String getName() { - return "Essentials Fake Server"; - } - - @Override - public String getVersion() { - return "1.0"; - } - - @Override - public Collection getOnlinePlayers() { - return players; - } - - @Override - public int getMaxPlayers() { - return 100; - } - - @Override - public int getPort() { - return 25565; - } - - @Override - public String getIp() { - return "127.0.0.1"; - } - - @Override - public String getServerName() { - return getName(); - } - - @Override - public String getServerId() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int broadcastMessage(final String string) { - int i = 0; - for (final Player player : players) { - player.sendMessage(string); - i++; - } - return i; - } - - @Override - public String getUpdateFolder() { - return "update"; - } - - @Override - public File getUpdateFolderFile() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean isHardcore() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Player getPlayer(final String string) { - for (final Player player : players) { - if (player.getName().equalsIgnoreCase(string)) { - return player; - } - } - return null; - } - - @Override - public List matchPlayer(final String string) { - final List matches = new ArrayList<>(); - for (final Player player : players) { - if (player.getName().substring(0, Math.min(player.getName().length(), string.length())).equalsIgnoreCase(string)) { - matches.add(player); - } - } - return matches; - } - - @Override - public PluginManager getPluginManager() { - return pluginManager; - } - - @Override - public BukkitScheduler getScheduler() { - return new BukkitScheduler() { - @Override - public int scheduleSyncDelayedTask(final Plugin plugin, final Runnable r, final long l) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int scheduleSyncDelayedTask(final Plugin plugin, final BukkitRunnable bukkitRunnable, final long l) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int scheduleSyncDelayedTask(final Plugin plugin, final Runnable r) { - return -1; - } - - @Override - public int scheduleSyncDelayedTask(final Plugin plugin, final BukkitRunnable bukkitRunnable) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int scheduleSyncRepeatingTask(final Plugin plugin, final Runnable r, final long l, final long l1) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int scheduleSyncRepeatingTask(final Plugin plugin, final BukkitRunnable bukkitRunnable, final long l, final long l1) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int scheduleAsyncRepeatingTask(final Plugin plugin, final Runnable r, final long l, final long l1) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Future callSyncMethod(final Plugin plugin, final Callable clbl) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void cancelTask(final int i) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void cancelTasks(final Plugin plugin) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void cancelAllTasks() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean isCurrentlyRunning(final int i) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean isQueued(final int i) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public List getActiveWorkers() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public List getPendingTasks() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public BukkitTask runTask(final Plugin plugin, final Runnable r) throws IllegalArgumentException { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public BukkitTask runTask(final Plugin plugin, final BukkitRunnable bukkitRunnable) throws IllegalArgumentException { - return null; - } - - @Override - public BukkitTask runTaskAsynchronously(final Plugin plugin, final Runnable r) throws IllegalArgumentException { - r.run(); - return null; - } - - @Override - public BukkitTask runTaskAsynchronously(final Plugin plugin, final BukkitRunnable bukkitRunnable) throws IllegalArgumentException { - return null; - } - - @Override - public BukkitTask runTaskLater(final Plugin plugin, final Runnable r, final long l) throws IllegalArgumentException { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public BukkitTask runTaskLater(final Plugin plugin, final BukkitRunnable bukkitRunnable, final long l) throws IllegalArgumentException { - return null; - } - - @Override - public BukkitTask runTaskLaterAsynchronously(final Plugin plugin, final Runnable r, final long l) throws IllegalArgumentException { - r.run(); - return null; - } - - @Override - public BukkitTask runTaskLaterAsynchronously(final Plugin plugin, final BukkitRunnable bukkitRunnable, final long l) throws IllegalArgumentException { - return null; - } - - @Override - public BukkitTask runTaskTimer(final Plugin plugin, final Runnable r, final long l, final long l1) throws IllegalArgumentException { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public BukkitTask runTaskTimer(final Plugin plugin, final BukkitRunnable bukkitRunnable, final long l, final long l1) throws IllegalArgumentException { - return null; - } - - @Override - public BukkitTask runTaskTimerAsynchronously(final Plugin plugin, final Runnable r, final long l, final long l1) throws IllegalArgumentException { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public BukkitTask runTaskTimerAsynchronously(final Plugin plugin, final BukkitRunnable bukkitRunnable, final long l, final long l1) throws IllegalArgumentException { - return null; - } - - @Override - public int scheduleAsyncDelayedTask(final Plugin plugin, final Runnable r, final long l) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int scheduleAsyncDelayedTask(final Plugin plugin, final Runnable r) { - throw new UnsupportedOperationException("Not supported yet."); - } - }; - } - - @Override - public ServicesManager getServicesManager() { - return new ServicesManager() { - @Override - public void register(Class service, T provider, Plugin plugin, ServicePriority priority) { - - } - - @Override - public void unregisterAll(Plugin plugin) { - - } - - @Override - public void unregister(Class service, Object provider) { - - } - - @Override - public void unregister(Object provider) { - - } - - @Override - public T load(Class service) { - return null; - } - - @Override - public RegisteredServiceProvider getRegistration(Class service) { - return null; - } - - @Override - public List> getRegistrations(Plugin plugin) { - return null; - } - - @Override - public Collection> getRegistrations(Class service) { - return null; - } - - @Override - public Collection> getKnownServices() { - return null; - } - - @Override - public boolean isProvidedFor(Class service) { - return false; - } - }; - } - - @Override - public List getWorlds() { - return worlds; - } - - public World createWorld(final String string, final Environment e) { - final World w = new FakeWorld(string, e); - worlds.add(w); - return w; - } - - @Override - public World getWorld(final String string) { - for (final World world : worlds) { - if (world.getName().equalsIgnoreCase(string)) { - return world; - } - } - return null; - } - - @Override - public World getWorld(final UUID uuid) { - for (final World world : worlds) { - if (world.getUID().equals(uuid)) { - return world; - } - } - return null; - } - - @Override - public MapView getMap(short id) { - return null; - } - - @Override - public void reload() { - } - - @Override - public Logger getLogger() { - return Logger.getLogger("Minecraft"); - } - - @Override - public PluginCommand getPluginCommand(final String string) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void savePlayers() { - } - - @Override - public boolean dispatchCommand(final CommandSender cs, final String string) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean addRecipe(final Recipe recipe) { - throw new UnsupportedOperationException("Not supported yet."); - } - - void addPlayer(final Player base1) { - players.add(base1); - pluginManager.callEvent(new PlayerJoinEvent(base1, null)); - } - - OfflinePlayerStub createPlayer(final String name) { - final OfflinePlayerStub player = new OfflinePlayerStub(name, this); - player.setLocation(new Location(worlds.get(0), 0, 0, 0, 0, 0)); - return player; - } - - @Override - public World createWorld(final WorldCreator creator) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean unloadWorld(final String string, final boolean bln) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean unloadWorld(final World world, final boolean bln) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Map getCommandAliases() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int getSpawnRadius() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void setSpawnRadius(final int i) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean getOnlineMode() { - throw new UnsupportedOperationException("Not supported yet."); - } - - public MapView getMap(final int id) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int getViewDistance() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean getAllowNether() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean hasWhitelist() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public MapView createMap(final World world) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean getAllowFlight() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void setWhitelist(final boolean bln) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Set getWhitelistedPlayers() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void reloadWhitelist() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Player getPlayerExact(final String string) { - for (final Player player : players) { - if (player.getName().equals(string)) { - return player; - } - } - return null; - } - - @Override - public void shutdown() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int broadcast(final String string, final String string1) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public org.bukkit.OfflinePlayer getOfflinePlayer(final String string) { - return createOPlayer(string); - } - - private org.bukkit.OfflinePlayer createOPlayer(final String string) { - return new org.bukkit.OfflinePlayer() { - @Override - public boolean isOnline() { - return false; - } - - @Override - public String getName() { - return string; - } - - @Override - public boolean isBanned() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean isWhitelisted() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void setWhitelisted(final boolean bln) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Player getPlayer() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean isOp() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Map serialize() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public long getFirstPlayed() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void setOp(final boolean bln) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public long getLastPlayed() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean hasPlayedBefore() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Location getBedSpawnLocation() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public UUID getUniqueId() { - switch (string) { - case "testPlayer1": - return UUID.fromString("3c9ebe1a-9098-43fd-bc0c-a369b76817ba"); - case "testPlayer2": - return UUID.fromString("2c9ebe1a-9098-43fd-bc0c-a369b76817ba"); - case "npc1": - return UUID.fromString("f4a37409-5c40-3b2c-9cd6-57d3c5abdc76"); - } - throw new UnsupportedOperationException("Not supported yet."); - } - }; - } - - @Override - public Set getIPBans() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void banIP(final String string) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void unbanIP(final String string) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Set getBannedPlayers() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public GameMode getDefaultGameMode() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void setDefaultGameMode(final GameMode gamemode) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public ConsoleCommandSender getConsoleSender() { - return new ConsoleCommandSender() { - @Override - public void sendMessage(final String message) { - System.out.println("Console message: " + message); - } - - @Override - public void sendMessage(final String[] messages) { - for (final String message : messages) { - System.out.println("Console message: " + message); - } - } - - public void sendMessage(final UUID uuid, final String message) { - sendMessage(message); - } - - public void sendMessage(final UUID uuid, final String[] messages) { - sendMessage(messages); - } - - @Override - public Server getServer() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public String getName() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean isPermissionSet(final String name) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean isPermissionSet(final Permission perm) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean hasPermission(final String name) { - return true; - } - - @Override - public boolean hasPermission(final Permission perm) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public PermissionAttachment addAttachment(final Plugin plugin, final String name, final boolean value) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public PermissionAttachment addAttachment(final Plugin plugin) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public PermissionAttachment addAttachment(final Plugin plugin, final String name, final boolean value, final int ticks) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public PermissionAttachment addAttachment(final Plugin plugin, final int ticks) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void removeAttachment(final PermissionAttachment attachment) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void recalculatePermissions() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Set getEffectivePermissions() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean isOp() { - return true; - } - - @Override - public boolean isConversing() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void acceptConversationInput(final String input) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void setOp(final boolean value) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean beginConversation(final Conversation conversation) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void abandonConversation(final Conversation conversation) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void abandonConversation(final Conversation conversation, final ConversationAbandonedEvent details) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void sendRawMessage(final String message) { - throw new UnsupportedOperationException("Not supported yet."); - } - }; - } - - @Override - public Set getOperators() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public String getBukkitVersion() { - return "Essentials Fake-Server"; - } - - @Override - public File getWorldContainer() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public OfflinePlayerStub[] getOfflinePlayers() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean getAllowEnd() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Messenger getMessenger() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void sendPluginMessage(final Plugin plugin, final String string, final byte[] bytes) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Set getListeningPluginChannels() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int getTicksPerAnimalSpawns() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int getTicksPerMonsterSpawns() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public List getRecipesFor(final ItemStack is) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Iterator recipeIterator() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void clearRecipes() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void resetRecipes() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public HelpMap getHelpMap() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Inventory createInventory(final InventoryHolder ih, final InventoryType it) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Inventory createInventory(final InventoryHolder ih, final int i) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Inventory createInventory(final InventoryHolder ih, final int i, final String string) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Merchant createMerchant(final String s) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public String getWorldType() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean getGenerateStructures() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public long getConnectionThrottle() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int getMonsterSpawnLimit() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int getAnimalSpawnLimit() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int getWaterAnimalSpawnLimit() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean isPrimaryThread() { - return true; // Can be set to true or false, just needs to return for AFK status test to pass. - } - - @Override - public String getMotd() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public WarningState getWarningState() { - return WarningState.DEFAULT; - } - - @Override - public int getAmbientSpawnLimit() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public String getShutdownMessage() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public ItemFactory getItemFactory() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public ScoreboardManager getScoreboardManager() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public CachedServerIcon getServerIcon() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public CachedServerIcon loadServerIcon(final File file) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public CachedServerIcon loadServerIcon(final BufferedImage bufferedImage) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public int getIdleTimeout() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void setIdleTimeout(final int i) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public ChunkGenerator.ChunkData createChunkData(final World world) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public BossBar createBossBar(final String s, final BarColor barColor, final BarStyle barStyle, final BarFlag... barFlags) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - @SuppressWarnings("deprecation") - public UnsafeValues getUnsafe() { - return new UnsafeValues() { - public int getDataVersion() { - // 1.21.5 - return 4325; - } - - @Override - public Material getMaterialFromInternalName(String s) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public List tabCompleteInternalMaterialName(String s, List list) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public ItemStack modifyItemStack(ItemStack itemStack, String s) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Statistic getStatisticFromInternalName(String s) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Achievement getAchievementFromInternalName(String s) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public List tabCompleteInternalStatisticOrAchievementName(String s, List list) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Advancement loadAdvancement(NamespacedKey namespacedKey, String s) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean removeAdvancement(NamespacedKey namespacedKey) { - throw new UnsupportedOperationException("Not supported yet."); - } - }; - } - - @Override - public BanList getBanList(final BanList.Type arg0) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Player getPlayer(final UUID arg0) { - for (final Player player : players) { - if (player.getUniqueId().equals(arg0)) { - return player; - } - } - return null; - } - - @Override - public org.bukkit.OfflinePlayer getOfflinePlayer(final UUID arg0) { - if (arg0.toString().equalsIgnoreCase("3c9ebe1a-9098-43fd-bc0c-a369b76817ba")) { - return createOPlayer("testPlayer1"); - } - if (arg0.toString().equalsIgnoreCase("f4a37409-5c40-3b2c-9cd6-57d3c5abdc76")) { - return createOPlayer("npc1"); - } - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Inventory createInventory(final InventoryHolder arg0, final InventoryType arg1, final String arg2) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void reloadData() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Entity getEntity(final UUID uuid) { - return getPlayer(uuid); - } - - @Override - public Advancement getAdvancement(final NamespacedKey key) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Iterator advancementIterator() { - throw new UnsupportedOperationException("Not supported yet."); - } - - static class FakePluginManager implements PluginManager { - final ArrayList listeners = new ArrayList<>(); - - @Override - public void registerInterface(final Class loader) throws IllegalArgumentException { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Plugin getPlugin(final String name) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Plugin[] getPlugins() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean isPluginEnabled(final String name) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean isPluginEnabled(final Plugin plugin) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Plugin loadPlugin(final File file) throws UnknownDependencyException { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Plugin[] loadPlugins(final File directory) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void disablePlugins() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void clearPlugins() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void callEvent(final Event event) throws IllegalStateException { - Logger.getLogger("Minecraft").info("Called event " + event.getEventName()); - if (event instanceof PlayerJoinEvent) { - for (final RegisteredListener listener : listeners) { - if (listener.getListener() instanceof FakeAccessor) { - final PlayerJoinEvent jEvent = (PlayerJoinEvent) event; - final FakeAccessor epl = (FakeAccessor) listener.getListener(); - epl.onPlayerJoin(jEvent); - Logger.getLogger("Essentials").info("Sending join event to Essentials"); - epl.getUser(jEvent.getPlayer()); - } - } - } - } - - @Override - public void registerEvents(final Listener listener, final Plugin plugin) { - listeners.add(new RegisteredListener(listener, null, null, plugin, false)); - } - - @Override - public void registerEvent(final Class event, final Listener listener, final EventPriority priority, final EventExecutor executor, final Plugin plugin) { - listeners.add(new RegisteredListener(listener, executor, priority, plugin, false)); - } - - @Override - public void registerEvent(final Class event, final Listener listener, final EventPriority priority, final EventExecutor executor, final Plugin plugin, final boolean ignoreCancelled) { - listeners.add(new RegisteredListener(listener, executor, priority, plugin, false)); - } - - @Override - public void enablePlugin(final Plugin plugin) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void disablePlugin(final Plugin plugin) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Permission getPermission(final String name) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void addPermission(final Permission perm) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void removePermission(final Permission perm) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void removePermission(final String name) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Set getDefaultPermissions(final boolean op) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void recalculatePermissionDefaults(final Permission perm) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void subscribeToPermission(final String permission, final Permissible permissible) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void unsubscribeFromPermission(final String permission, final Permissible permissible) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Set getPermissionSubscriptions(final String permission) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void subscribeToDefaultPerms(final boolean op, final Permissible permissible) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void unsubscribeFromDefaultPerms(final boolean op, final Permissible permissible) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Set getDefaultPermSubscriptions(final boolean op) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public Set getPermissions() { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public boolean useTimings() { - throw new UnsupportedOperationException("Not supported yet."); - } - } -} From 70692c6dd04a3290fac419ccb3239a4b9be8d17a Mon Sep 17 00:00:00 2001 From: JRoy <10731363+JRoy@users.noreply.github.com> Date: Sun, 3 Aug 2025 21:30:40 -0700 Subject: [PATCH 3/5] properly smuggle components to paper --- .../essentials/EssentialsPlayerListener.java | 9 ++------ providers/PaperProvider/build.gradle | 3 +-- .../essentialsx/PaperAdventureSmuggler.java | 23 +++++++++++++++++++ 3 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 providers/PaperProvider/src/main/java/net/essentialsx/PaperAdventureSmuggler.java diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java index b820e0bf101..dfca0f37cac 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java @@ -1,6 +1,5 @@ package com.earth2me.essentials; -import com.destroystokyo.paper.profile.ProfileProperty; import com.earth2me.essentials.commands.Commandfireball; import com.earth2me.essentials.craftbukkit.Inventories; import com.earth2me.essentials.textreader.IText; @@ -27,6 +26,7 @@ import net.ess3.provider.TickCountProvider; import net.ess3.provider.providers.BukkitCommandSendListenerProvider; import net.ess3.provider.providers.PaperCommandSendListenerProvider; +import net.essentialsx.PaperAdventureSmuggler; import net.essentialsx.api.v2.events.AsyncUserDataLoadEvent; import net.kyori.adventure.text.Component; import org.bukkit.BanEntry; @@ -353,11 +353,6 @@ public void onPlayerConfigure(final AsyncPlayerConnectionConfigureEvent event) { dUser.checkMuteTimeout(currentTime); dUser.updateActivity(false, AfkStatusChangeEvent.Cause.JOIN); dUser.stopTransaction(); - - System.out.println("EssentialsPlayerListener.onPlayerConfigure: " + event.getConnection().getProfile().getName() + " has joined the server."); - for (final ProfileProperty property : event.getConnection().getProfile().getProperties()) { - System.out.println(property.getName() + " " + property.getValue()); - } } @EventHandler(priority = EventPriority.HIGHEST) @@ -636,7 +631,7 @@ public void onPlayerListFull(final PlayerServerFullCheckEvent event) { } if (ess.getSettings().isCustomServerFullMessage()) { - event.deny(user.tlComponent("serverFull")); + PaperAdventureSmuggler.smugglePlayerServerFullCheckEvent(event, AdventureUtil.miniToLegacy(tlLiteral("serverFull"))); } } diff --git a/providers/PaperProvider/build.gradle b/providers/PaperProvider/build.gradle index 8a764dff0b2..e91e54ca47e 100644 --- a/providers/PaperProvider/build.gradle +++ b/providers/PaperProvider/build.gradle @@ -11,8 +11,7 @@ dependencies { implementation(project(':providers:BaseProviders')) { exclude(module: 'spigot-api') } - compileOnly 'io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT' - compileOnly 'io.papermc.paper:paper-mojangapi:1.20.4-R0.1-SNAPSHOT' + compileOnly 'io.papermc.paper:paper-api:1.21.8-R0.1-SNAPSHOT' } essentials { diff --git a/providers/PaperProvider/src/main/java/net/essentialsx/PaperAdventureSmuggler.java b/providers/PaperProvider/src/main/java/net/essentialsx/PaperAdventureSmuggler.java new file mode 100644 index 00000000000..f81fc77f4bd --- /dev/null +++ b/providers/PaperProvider/src/main/java/net/essentialsx/PaperAdventureSmuggler.java @@ -0,0 +1,23 @@ +package net.essentialsx; + +import io.papermc.paper.event.player.PlayerServerFullCheckEvent; +import net.ess3.provider.AbstractChatEvent; +import net.kyori.adventure.text.flattener.ComponentFlattener; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; + +public final class PaperAdventureSmuggler { + private static final LegacyComponentSerializer LEGACY_COMPONENT_SERIALIZER = LegacyComponentSerializer.builder() + .flattener(ComponentFlattener.basic()) + .extractUrls(AbstractChatEvent.URL_PATTERN) + .hexColors() + .useUnusualXRepeatedCharacterHexFormat() + .hexColors() + .build(); + + private PaperAdventureSmuggler() { + } + + public static void smugglePlayerServerFullCheckEvent(final PlayerServerFullCheckEvent event, final String legacyMessage) { + event.deny(LEGACY_COMPONENT_SERIALIZER.deserialize(legacyMessage)); + } +} From ac702ada284cf9d2bc9c48883b6355259f5a3aed Mon Sep 17 00:00:00 2001 From: JRoy <10731363+JRoy@users.noreply.github.com> Date: Sun, 3 Aug 2025 21:40:33 -0700 Subject: [PATCH 4/5] preload locale bundle during configuration --- .../com/earth2me/essentials/EssentialsPlayerListener.java | 5 +++++ Essentials/src/main/java/com/earth2me/essentials/User.java | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java index dfca0f37cac..40a91496174 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java @@ -1,5 +1,6 @@ package com.earth2me.essentials; +import com.destroystokyo.paper.ClientOption; import com.earth2me.essentials.commands.Commandfireball; import com.earth2me.essentials.craftbukkit.Inventories; import com.earth2me.essentials.textreader.IText; @@ -353,6 +354,10 @@ public void onPlayerConfigure(final AsyncPlayerConnectionConfigureEvent event) { dUser.checkMuteTimeout(currentTime); dUser.updateActivity(false, AfkStatusChangeEvent.Cause.JOIN); dUser.stopTransaction(); + + // Set the locale for player to preload the language bundle. + final String locale = event.getConnection().getClientOption(ClientOption.LOCALE); + dUser.getPlayerLocale(locale); } @EventHandler(priority = EventPriority.HIGHEST) diff --git a/Essentials/src/main/java/com/earth2me/essentials/User.java b/Essentials/src/main/java/com/earth2me/essentials/User.java index d529a96d101..04a2f212971 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/User.java +++ b/Essentials/src/main/java/com/earth2me/essentials/User.java @@ -1083,7 +1083,10 @@ public void sendTl(String tlKey, Object... args) { public String playerTl(String tlKey, Object... args) { if (ess.getSettings().isPerPlayerLocale()) { final PlayerLocaleProvider provider = ess.provider(PlayerLocaleProvider.class); - return tlLocale(getPlayerLocale(provider.getLocale(base)), tlKey, args); + final Locale locale = base != null ? getPlayerLocale(provider.getLocale(base)) : playerLocale; + if (locale != null) { + return tlLocale(locale, tlKey, args); + } } return tlLiteral(tlKey, args); } From ff8aa8d96231a39ecf530edbb4df05f360f288ab Mon Sep 17 00:00:00 2001 From: JRoy <10731363+JRoy@users.noreply.github.com> Date: Sun, 3 Aug 2025 22:24:08 -0700 Subject: [PATCH 5/5] port whitelist upstream changes correctly --- .../essentials/EssentialsPlayerListener.java | 19 ++++++++----------- .../essentials/perm/IPermissionsHandler.java | 3 +++ .../essentials/perm/PermissionsHandler.java | 6 ++++++ .../perm/impl/LuckPermsHandler.java | 14 +++++++++++++- .../perm/impl/SuperpermsHandler.java | 6 ++++++ 5 files changed, 36 insertions(+), 12 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java index 00c5dc2344b..34f779e771b 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java @@ -658,17 +658,14 @@ public void onPlayerKickBanned(final AsyncPlayerPreLoginEvent event) { event.setKickMessage(AdventureUtil.miniToLegacy(tlLiteral("banIpJoin", banEntry.getReason()))); } } - } - } - if (event.getResult() == Result.KICK_WHITELIST) { - final User kfuser = ess.getUser(event.getPlayer()); - kfuser.update(event.getPlayer()); - if (kfuser.isAuthorized("essentials.whitelist.bypass")) { - event.allow(); - return; - } - if (ess.getSettings().isCustomWhitelistMessage()) { - event.disallow(Result.KICK_WHITELIST, tlLiteral("whitelistKick")); + } else if (event.getLoginResult() == AsyncPlayerPreLoginEvent.Result.KICK_WHITELIST) { + if (ess.getPermissionsHandler().isOfflinePermissionSet(event.getUniqueId(), "essentials.whitelist.bypass")) { + event.allow(); + return; + } + if (ess.getSettings().isCustomWhitelistMessage()) { + event.setKickMessage(AdventureUtil.miniToLegacy(tlLiteral("whitelistKick"))); + } } } } diff --git a/Essentials/src/main/java/com/earth2me/essentials/perm/IPermissionsHandler.java b/Essentials/src/main/java/com/earth2me/essentials/perm/IPermissionsHandler.java index 9897b41ece0..76d47a2e160 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/perm/IPermissionsHandler.java +++ b/Essentials/src/main/java/com/earth2me/essentials/perm/IPermissionsHandler.java @@ -7,6 +7,7 @@ import org.bukkit.entity.Player; import java.util.List; +import java.util.UUID; import java.util.function.Function; import java.util.function.Supplier; @@ -30,6 +31,8 @@ public interface IPermissionsHandler { // Does not check for * permissions boolean isPermissionSet(Player base, String node); + boolean isOfflinePermissionSet(UUID uuid, String node); + TriState isPermissionSetExact(Player base, String node); String getPrefix(Player base); diff --git a/Essentials/src/main/java/com/earth2me/essentials/perm/PermissionsHandler.java b/Essentials/src/main/java/com/earth2me/essentials/perm/PermissionsHandler.java index 0b61c6baea0..974e761f5a7 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/perm/PermissionsHandler.java +++ b/Essentials/src/main/java/com/earth2me/essentials/perm/PermissionsHandler.java @@ -18,6 +18,7 @@ import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.UUID; import java.util.function.Function; import java.util.function.Supplier; import java.util.logging.Level; @@ -106,6 +107,11 @@ public boolean isPermissionSet(final Player base, final String node) { return handler.isPermissionSet(base, node); } + @Override + public boolean isOfflinePermissionSet(UUID uuid, String node) { + return handler.isOfflinePermissionSet(uuid, node); + } + @Override public TriState isPermissionSetExact(Player base, String node) { return handler.isPermissionSetExact(base, node); diff --git a/Essentials/src/main/java/com/earth2me/essentials/perm/impl/LuckPermsHandler.java b/Essentials/src/main/java/com/earth2me/essentials/perm/impl/LuckPermsHandler.java index b8d92879980..83336cc53c6 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/perm/impl/LuckPermsHandler.java +++ b/Essentials/src/main/java/com/earth2me/essentials/perm/impl/LuckPermsHandler.java @@ -2,18 +2,19 @@ import com.earth2me.essentials.Essentials; import com.earth2me.essentials.User; - import net.luckperms.api.LuckPerms; import net.luckperms.api.context.ContextCalculator; import net.luckperms.api.context.ContextConsumer; import net.luckperms.api.context.ContextSet; import net.luckperms.api.context.ImmutableContextSet; +import net.luckperms.api.query.QueryOptions; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.plugin.RegisteredServiceProvider; import java.util.HashSet; import java.util.Set; +import java.util.UUID; import java.util.function.Function; import java.util.function.Supplier; @@ -39,6 +40,17 @@ public void unregisterContexts() { } } + @Override + public boolean isOfflinePermissionSet(UUID uuid, String node) { + final net.luckperms.api.model.user.User user = this.luckPerms.getUserManager().loadUser(uuid).join(); + if (user == null) { + return false; + } + + final QueryOptions options = luckPerms.getContextManager().getStaticQueryOptions(); + return user.getCachedData().getPermissionData(options).checkPermission(node).asBoolean(); + } + @Override public boolean tryProvider(Essentials ess) { final RegisteredServiceProvider provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class); diff --git a/Essentials/src/main/java/com/earth2me/essentials/perm/impl/SuperpermsHandler.java b/Essentials/src/main/java/com/earth2me/essentials/perm/impl/SuperpermsHandler.java index 3cc267c09e1..5683315f142 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/perm/impl/SuperpermsHandler.java +++ b/Essentials/src/main/java/com/earth2me/essentials/perm/impl/SuperpermsHandler.java @@ -13,6 +13,7 @@ import java.util.Arrays; import java.util.List; +import java.util.UUID; import java.util.function.Function; import java.util.function.Supplier; @@ -121,6 +122,11 @@ public boolean isPermissionSet(final Player base, final String node) { return base.isPermissionSet(node); } + @Override + public boolean isOfflinePermissionSet(UUID uuid, String node) { + return false; + } + @Override public TriState isPermissionSetExact(Player base, String node) { for (final PermissionAttachmentInfo perm : base.getEffectivePermissions()) {