diff --git a/src/main/java/fr/xephi/authme/api/v3/AuthMeApi.java b/src/main/java/fr/xephi/authme/api/v3/AuthMeApi.java index fd487d66..27743d5d 100644 --- a/src/main/java/fr/xephi/authme/api/v3/AuthMeApi.java +++ b/src/main/java/fr/xephi/authme/api/v3/AuthMeApi.java @@ -15,6 +15,8 @@ import fr.xephi.authme.util.PlayerUtils; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; import javax.inject.Inject; import java.time.Instant; @@ -24,6 +26,8 @@ import java.util.List; import java.util.Locale; import java.util.Optional; +import static fr.xephi.authme.listener.PlayerListener.PENDING_INVENTORIES; + /** * The current API of AuthMe. * @@ -32,6 +36,7 @@ import java.util.Optional; * AuthMeApi authmeApi = AuthMeApi.getInstance(); * */ +@SuppressWarnings("unused") public class AuthMeApi { private static AuthMeApi singleton; @@ -256,6 +261,18 @@ public class AuthMeApi { return dataSource.saveAuth(auth); } + /** + * Open an inventory for the given player at any time. + * + * @param player The player to open the inventory for + * @param inventory The inventory to open + * @return The inventory view + */ + public InventoryView openInventory(Player player, Inventory inventory) { + PENDING_INVENTORIES.add(inventory); + return player.openInventory(inventory); + } + /** * Force a player to login, i.e. the player is logged in without needing his password. * diff --git a/src/main/java/fr/xephi/authme/listener/PlayerListener.java b/src/main/java/fr/xephi/authme/listener/PlayerListener.java index e435b9c2..973b8e6c 100644 --- a/src/main/java/fr/xephi/authme/listener/PlayerListener.java +++ b/src/main/java/fr/xephi/authme/listener/PlayerListener.java @@ -50,9 +50,12 @@ import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.event.player.PlayerShearEntityEvent; +import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryView; import javax.inject.Inject; +import java.util.ArrayList; +import java.util.List; import java.util.Locale; import java.util.Set; @@ -93,6 +96,7 @@ public class PlayerListener implements Listener { @Inject private QuickCommandsProtectionManager quickCommandsProtectionManager; + public static List PENDING_INVENTORIES = new ArrayList<>(); // Lowest priority to apply fast protection checks @EventHandler(priority = EventPriority.LOWEST) @@ -489,6 +493,17 @@ public class PlayerListener implements Listener { } } + private boolean isInventoryOpenedByApi(Inventory inventory) { + if (inventory == null) { + return false; + } + if (PENDING_INVENTORIES.contains(inventory)) { + PENDING_INVENTORIES.remove(inventory); + return true; + } else { + return false; + } + } @SuppressWarnings("all") private boolean isInventoryWhitelisted(InventoryView inventory) { if (inventory == null) { @@ -515,7 +530,8 @@ public class PlayerListener implements Listener { public void onPlayerInventoryOpen(InventoryOpenEvent event) { final HumanEntity player = event.getPlayer(); if (listenerService.shouldCancelEvent(player) - && !isInventoryWhitelisted(event.getView())) { + && !isInventoryWhitelisted(event.getView()) + && !isInventoryOpenedByApi(event.getInventory())) { event.setCancelled(true); /* diff --git a/src/main/java/fr/xephi/authme/service/BukkitService.java b/src/main/java/fr/xephi/authme/service/BukkitService.java index 45008a38..d78ea92e 100644 --- a/src/main/java/fr/xephi/authme/service/BukkitService.java +++ b/src/main/java/fr/xephi/authme/service/BukkitService.java @@ -380,7 +380,11 @@ public class BukkitService implements SettingsDependent { * @param bytes the message */ public void sendVelocityMessage(Player player, byte[] bytes) { - player.sendPluginMessage(authMe, "authmevelocity:main", bytes); + if (player != null) { + player.sendPluginMessage(authMe, "authmevelocity:main", bytes); + } else { + Bukkit.getServer().sendPluginMessage(authMe, "authmevelocity:main", bytes); + } } diff --git a/src/main/java/fr/xephi/authme/util/message/MiniMessageUtils.java b/src/main/java/fr/xephi/authme/util/message/MiniMessageUtils.java index 5d7e6216..2fe72811 100644 --- a/src/main/java/fr/xephi/authme/util/message/MiniMessageUtils.java +++ b/src/main/java/fr/xephi/authme/util/message/MiniMessageUtils.java @@ -1,5 +1,6 @@ package fr.xephi.authme.util.message; +import fr.xephi.authme.util.Utils; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer; @@ -8,6 +9,15 @@ import net.md_5.bungee.api.chat.BaseComponent; public class MiniMessageUtils { private static final MiniMessage miniMessage = MiniMessage.miniMessage(); + private static final BungeeComponentSerializer bungeeSerializer; + + static { + if (Utils.MAJOR_VERSION >= 16) { + bungeeSerializer = BungeeComponentSerializer.get(); + } else { + bungeeSerializer = BungeeComponentSerializer.legacy(); + } + } /** * Parse a MiniMessage string into a legacy string. @@ -28,7 +38,7 @@ public class MiniMessageUtils { */ public static BaseComponent[] parseMiniMessageToBaseComponent(String message) { Component component = miniMessage.deserialize(message); - return BungeeComponentSerializer.legacy().serialize(component); + return bungeeSerializer.serialize(component); } private MiniMessageUtils() {