From 0516020b1f906f330593585233b329a3adb35929 Mon Sep 17 00:00:00 2001 From: Aya <31237389+tal5@users.noreply.github.com> Date: Wed, 19 Oct 2022 02:31:02 +0300 Subject: [PATCH] Add `PlayerTag.add/remove_tab_completions` mechs (#2390) --- .../denizen/paper/PaperModule.java | 7 +- .../properties/PaperPlayerExtensions.java | 110 +++++++++++++++++ .../properties/PaperPlayerProperties.java | 115 ------------------ .../denizen/objects/PlayerTag.java | 20 +++ 4 files changed, 133 insertions(+), 119 deletions(-) create mode 100644 paper/src/main/java/com/denizenscript/denizen/paper/properties/PaperPlayerExtensions.java delete mode 100644 paper/src/main/java/com/denizenscript/denizen/paper/properties/PaperPlayerProperties.java diff --git a/paper/src/main/java/com/denizenscript/denizen/paper/PaperModule.java b/paper/src/main/java/com/denizenscript/denizen/paper/PaperModule.java index 7c4109bbca..0179957ff5 100644 --- a/paper/src/main/java/com/denizenscript/denizen/paper/PaperModule.java +++ b/paper/src/main/java/com/denizenscript/denizen/paper/PaperModule.java @@ -5,7 +5,6 @@ import com.denizenscript.denizen.nms.NMSVersion; import com.denizenscript.denizen.objects.EntityTag; import com.denizenscript.denizen.objects.ItemTag; -import com.denizenscript.denizen.objects.PlayerTag; import com.denizenscript.denizen.objects.WorldTag; import com.denizenscript.denizen.paper.events.*; import com.denizenscript.denizen.paper.properties.*; @@ -13,9 +12,9 @@ import com.denizenscript.denizen.paper.utilities.PaperAPIToolsImpl; import com.denizenscript.denizen.utilities.FormattedTextHelper; import com.denizenscript.denizen.utilities.PaperAPITools; -import com.denizenscript.denizencore.utilities.debugging.Debug; import com.denizenscript.denizencore.events.ScriptEvent; import com.denizenscript.denizencore.objects.properties.PropertyParser; +import com.denizenscript.denizencore.utilities.debugging.Debug; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.md_5.bungee.api.ChatColor; @@ -72,11 +71,11 @@ public static void init() { PropertyParser.registerProperty(EntityWitherInvulnerable.class, EntityTag.class); PropertyParser.registerProperty(ItemArmorStand.class, ItemTag.class); - // Paper extension properties + // Paper object extensions PropertyParser.registerProperty(PaperEntityProperties.class, EntityTag.class); PropertyParser.registerProperty(PaperItemTagProperties.class, ItemTag.class); PropertyParser.registerProperty(PaperWorldProperties.class, WorldTag.class); - PropertyParser.registerProperty(PaperPlayerProperties.class, PlayerTag.class); + PaperPlayerExtensions.register(); // Paper Tags new PaperTagBase(); diff --git a/paper/src/main/java/com/denizenscript/denizen/paper/properties/PaperPlayerExtensions.java b/paper/src/main/java/com/denizenscript/denizen/paper/properties/PaperPlayerExtensions.java new file mode 100644 index 0000000000..6544a49ee8 --- /dev/null +++ b/paper/src/main/java/com/denizenscript/denizen/paper/properties/PaperPlayerExtensions.java @@ -0,0 +1,110 @@ +package com.denizenscript.denizen.paper.properties; + +import com.denizenscript.denizen.nms.NMSHandler; +import com.denizenscript.denizen.nms.NMSVersion; +import com.denizenscript.denizen.objects.ItemTag; +import com.denizenscript.denizen.objects.PlayerTag; +import com.denizenscript.denizencore.objects.core.ElementTag; +import com.denizenscript.denizencore.objects.core.ListTag; +import org.bukkit.Material; + +public class PaperPlayerExtensions { + + public static void register() { + + // <--[tag] + // @attribute + // @returns ElementTag(Boolean) + // @mechanism PlayerTag.affects_monster_spawning + // @group properties + // @Plugin Paper + // @description + // Returns whether the player affects monster spawning. When false, no monsters will spawn naturally because of this player. + // --> + PlayerTag.registerOnlineOnlyTag(ElementTag.class, "affects_monster_spawning", (attribute, object) -> { + return new ElementTag(object.getPlayerEntity().getAffectsSpawning()); + }); + + // <--[mechanism] + // @object PlayerTag + // @name affects_monster_spawning + // @input ElementTag(Boolean) + // @Plugin Paper + // @description + // Sets whether this player affects monster spawning. When false, no monsters will spawn naturally because of this player. + // @tags + // + // --> + PlayerTag.registerOnlineOnlyMechanism("affects_monster_spawning", ElementTag.class, (object, mechanism, input) -> { + if (mechanism.requireBoolean()) { + object.getPlayerEntity().setAffectsSpawning(input.asBoolean()); + } + }); + + // <--[mechanism] + // @object PlayerTag + // @name firework_boost + // @input ItemTag + // @Plugin Paper + // @description + // Firework boosts the player with the specified firework rocket. + // The player must be gliding. + // --> + PlayerTag.registerOnlineOnlyMechanism("firework_boost", ItemTag.class, (object, mechanism, input) -> { + if (!object.getPlayerEntity().isGliding()) { + mechanism.echoError("Cannot adjust 'firework_boost': player must be gliding."); + return; + } + if (input.getBukkitMaterial() != Material.FIREWORK_ROCKET) { + mechanism.echoError("Invalid input item '" + input + "': must be a firework rocket."); + return; + } + object.getPlayerEntity().boostElytra(input.getItemStack()); + }); + + // <--[mechanism] + // @object PlayerTag + // @name fake_op_level + // @input ElementTag(Number) + // @Plugin Paper + // @description + // Sends a fake operator level to the client, enabling clientside op-required features like the debug gamemode hotkey (F3+F4). + // Input should be a number from 0 to 4, 0 indicating not op and 4 indicating maximum level op. + // The input number value corresponds to "op-permission-level" in the server.properties. See also <@link url https://minecraft.fandom.com/wiki/Permission_level> + // This will be reset when a player rejoins, changes world, has their real op status changed, ... + // --> + PlayerTag.registerOnlineOnlyMechanism("fake_op_level", ElementTag.class, (object, mechanism, input) -> { + if (mechanism.requireInteger()) { + object.getPlayerEntity().sendOpLevel((byte) input.asInt()); + } + }); + + if (NMSHandler.getVersion().isAtLeast(NMSVersion.v1_19)) { + + // <--[mechanism] + // @object PlayerTag + // @name add_tab_completions + // @input ListTag + // @Plugin Paper + // @description + // Adds custom tab completions that will be suggested to the player when typing in chat. + // Tab completions added by this mechanism can be removed using <@link mechanism PlayerTag.remove_tab_completions>. + // --> + PlayerTag.registerOnlineOnlyMechanism("add_tab_completions", ListTag.class, (object, mechanism, input) -> { + object.getPlayerEntity().addAdditionalChatCompletions(input); + }); + + // <--[mechanism] + // @object PlayerTag + // @name remove_tab_completions + // @input ListTag + // @Plugin Paper + // @description + // Removes custom tab completions added by <@link mechanism PlayerTag.add_tab_completions>. + // --> + PlayerTag.registerOnlineOnlyMechanism("remove_tab_completions", ListTag.class, (object, mechanism, input) -> { + object.getPlayerEntity().removeAdditionalChatCompletions(input); + }); + } + } +} diff --git a/paper/src/main/java/com/denizenscript/denizen/paper/properties/PaperPlayerProperties.java b/paper/src/main/java/com/denizenscript/denizen/paper/properties/PaperPlayerProperties.java deleted file mode 100644 index e60eccd8ec..0000000000 --- a/paper/src/main/java/com/denizenscript/denizen/paper/properties/PaperPlayerProperties.java +++ /dev/null @@ -1,115 +0,0 @@ -package com.denizenscript.denizen.paper.properties; - -import com.denizenscript.denizen.objects.ItemTag; -import com.denizenscript.denizen.objects.PlayerTag; -import com.denizenscript.denizencore.objects.Mechanism; -import com.denizenscript.denizencore.objects.ObjectTag; -import com.denizenscript.denizencore.objects.core.ElementTag; -import com.denizenscript.denizencore.objects.properties.Property; -import com.denizenscript.denizencore.objects.properties.PropertyParser; -import org.bukkit.Material; - -public class PaperPlayerProperties implements Property { - public static boolean describes(ObjectTag player) { - return player instanceof PlayerTag - && ((PlayerTag) player).isOnline(); - } - - public static PaperPlayerProperties getFrom(ObjectTag player) { - if (!describes(player)) { - return null; - } - return new PaperPlayerProperties((PlayerTag) player); - } - - public static final String[] handledMechs = new String[] { - "affects_monster_spawning", "firework_boost", "fake_op_level" - }; - - private PaperPlayerProperties(PlayerTag player) { - this.player = player; - } - - PlayerTag player; - - @Override - public String getPropertyString() { - return null; - } - - @Override - public String getPropertyId() { - return "PaperPlayerProperties"; - } - - public static void registerTags() { - - // <--[tag] - // @attribute - // @returns ElementTag(Boolean) - // @mechanism PlayerTag.affects_monster_spawning - // @group properties - // @Plugin Paper - // @description - // Returns whether the player affects monster spawning. When false, no monsters will spawn naturally because of this player. - // --> - PropertyParser.registerTag(PaperPlayerProperties.class, ElementTag.class, "affects_monster_spawning", (attribute, player) -> { - return new ElementTag(player.player.getPlayerEntity().getAffectsSpawning()); - }); - } - - @Override - public void adjust(Mechanism mechanism) { - - // <--[mechanism] - // @object PlayerTag - // @name affects_monster_spawning - // @input ElementTag(Boolean) - // @Plugin Paper - // @description - // Sets whether this player affects monster spawning. When false, no monsters will spawn naturally because of this player. - // @tags - // - // --> - if (mechanism.matches("affects_monster_spawning") && mechanism.requireBoolean()) { - player.getPlayerEntity().setAffectsSpawning(mechanism.getValue().asBoolean()); - } - - // <--[mechanism] - // @object PlayerTag - // @name firework_boost - // @input ItemTag - // @Plugin Paper - // @description - // Firework boosts the player with the specified firework rocket. - // The player must be gliding. - // --> - if (mechanism.matches("firework_boost") && mechanism.requireObject(ItemTag.class)) { - if (!player.getPlayerEntity().isGliding()) { - mechanism.echoError("Player must be gliding to use firework_boost."); - return; - } - ItemTag item = mechanism.valueAsType(ItemTag.class); - if (item.getBukkitMaterial() != Material.FIREWORK_ROCKET) { - mechanism.echoError("Invalid input item: must be a firework rocket."); - return; - } - player.getPlayerEntity().boostElytra(item.getItemStack()); - } - - // <--[mechanism] - // @object PlayerTag - // @name fake_op_level - // @input ElementTag(Number) - // @Plugin Paper - // @description - // Sends a fake operator level to the client, enabling clientside op-required features like the debug gamemode hotkey (F3+F4). - // Input should be a number from 0 to 4, 0 indicating not op and 4 indicating maximum level op. - // The input number value corresponds to "op-permission-level" in the server.properties. See also <@link url https://minecraft.fandom.com/wiki/Permission_level> - // This will be reset when a player rejoins, changes world, has their real op status changed, ... - // --> - if (mechanism.matches("fake_op_level") && mechanism.requireInteger()) { - player.getPlayerEntity().sendOpLevel((byte) mechanism.getValue().asInt()); - } - } -} diff --git a/plugin/src/main/java/com/denizenscript/denizen/objects/PlayerTag.java b/plugin/src/main/java/com/denizenscript/denizen/objects/PlayerTag.java index b45659cedf..66f05d3d75 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/objects/PlayerTag.java +++ b/plugin/src/main/java/com/denizenscript/denizen/objects/PlayerTag.java @@ -2514,6 +2514,26 @@ public static void registerOnlineOnlyTag(Class returnTy }, variants); } + public static void registerOnlineOnlyMechanism(String name, Mechanism.GenericMechRunnerInterface runnable) { + tagProcessor.registerMechanism(name, false, (object, mechanism) -> { + if (!object.isOnline()) { + mechanism.echoError("Player is not online, but mechanism '" + name + "' requires the player be online, for player: " + object.debuggable()); + return; + } + runnable.run(object, mechanism); + }); + } + + public static

void registerOnlineOnlyMechanism(String name, Class

paramType, Mechanism.ObjectInputMechRunnerInterface runnable) { + tagProcessor.registerMechanism(name, false, paramType, (object, mechanism, input) -> { + if (!object.isOnline()) { + mechanism.echoError("Player is not online, but mechanism '" + name + "' requires the player be online, for player: " + object.debuggable()); + return; + } + runnable.run(object, mechanism, input); + }); + } + @Override public ObjectTag getObjectAttribute(Attribute attribute) { return tagProcessor.getObjectAttribute(this, attribute);