From d63c61ace80dbe8abaac4565059bf8cfbcf85bee Mon Sep 17 00:00:00 2001 From: joserobjr Date: Tue, 18 Aug 2020 23:43:28 -0300 Subject: [PATCH] Implements the /getid command --- pom.xml | 6 +- .../plugins/example/CloneCommand.java | 32 -------- .../plugins/example/CloneListener.java | 45 ----------- .../plugins/example/CloneMePlugin.java | 52 ------------- .../plugins/getid/GetIdCommand.java | 70 +++++++++++++++++ .../plugins/getid/GetIdPlugin.java | 11 +++ src/main/resources/plugin.yml | 76 +++---------------- 7 files changed, 96 insertions(+), 196 deletions(-) delete mode 100644 src/main/java/org/powernukkit/plugins/example/CloneCommand.java delete mode 100644 src/main/java/org/powernukkit/plugins/example/CloneListener.java delete mode 100644 src/main/java/org/powernukkit/plugins/example/CloneMePlugin.java create mode 100644 src/main/java/org/powernukkit/plugins/getid/GetIdCommand.java create mode 100644 src/main/java/org/powernukkit/plugins/getid/GetIdPlugin.java diff --git a/pom.xml b/pom.xml index 5cdf765..67c8106 100644 --- a/pom.xml +++ b/pom.xml @@ -2,10 +2,10 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - ExamplePlugin - example-plugin + GetIdPlugin + getid-plugin org.powernukkit.plugins - 0.1.0-SNAPSHOT + 1.0.0 jar diff --git a/src/main/java/org/powernukkit/plugins/example/CloneCommand.java b/src/main/java/org/powernukkit/plugins/example/CloneCommand.java deleted file mode 100644 index 1272601..0000000 --- a/src/main/java/org/powernukkit/plugins/example/CloneCommand.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.powernukkit.plugins.example; - -import cn.nukkit.Player; -import cn.nukkit.command.Command; -import cn.nukkit.command.CommandExecutor; -import cn.nukkit.command.CommandSender; -import cn.nukkit.entity.EntityHuman; -import cn.nukkit.nbt.tag.CompoundTag; -import cn.nukkit.utils.TextFormat; - -public class CloneCommand implements CommandExecutor { - @Override - public boolean onCommand(CommandSender commandSender, Command command, String s, String[] strings) { - if (!(commandSender instanceof Player)) { - commandSender.sendMessage(TextFormat.DARK_RED+""+TextFormat.BOLD + "Error!"+TextFormat.RESET+TextFormat.RED+" Only players can execute this command!"); - return false; - } - Player player = (Player) commandSender; - player.saveNBT(); - EntityHuman human = new EntityHuman(player.getChunk(), new CompoundTag() - .put("Pos", player.namedTag.get("Pos").copy()) - .put("Rotation", player.namedTag.get("Rotation").copy()) - .put("Motion", player.namedTag.get("Motion").copy()) - .put("Skin", player.namedTag.get("Skin").copy()) - .putBoolean("IsCloned", true) - ); - human.setSkin(player.getSkin()); - human.spawnToAll(); - player.sendMessage(TextFormat.DARK_GREEN+""+TextFormat.BOLD+"Success!"+TextFormat.RESET+TextFormat.GREEN+" You have been cloned!"); - return true; - } -} diff --git a/src/main/java/org/powernukkit/plugins/example/CloneListener.java b/src/main/java/org/powernukkit/plugins/example/CloneListener.java deleted file mode 100644 index 00a897d..0000000 --- a/src/main/java/org/powernukkit/plugins/example/CloneListener.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.powernukkit.plugins.example; - -import cn.nukkit.Player; -import cn.nukkit.block.BlockID; -import cn.nukkit.entity.Entity; -import cn.nukkit.entity.EntityHuman; -import cn.nukkit.event.EventHandler; -import cn.nukkit.event.Listener; -import cn.nukkit.event.entity.EntityDamageByEntityEvent; -import cn.nukkit.item.Item; -import cn.nukkit.utils.TextFormat; - -public class CloneListener implements Listener { - @EventHandler - public void onCloneDamage(EntityDamageByEntityEvent event) { - Entity entity = event.getEntity(); - - // Affect only the clones - if (!(entity instanceof EntityHuman) - || !entity.namedTag.getBoolean("IsCloned")) { - return; - } - - // Makes the clones invulnerable to non-player damage - if (!(event.getDamager() instanceof Player)) { - event.setCancelled(); - return; - } - - // If the clone is hit by a player, despawn it - Player player = (Player) event.getDamager(); - player.sendMessage(TextFormat.GOLD+""+TextFormat.BOLD+"WOW!"+TextFormat.RESET+TextFormat.YELLOW+" You found a clone!"); - entity.close(); - - // And give the player a present - Item flowerItem = Item.getBlock(BlockID.RED_FLOWER); - flowerItem.setCustomName(TextFormat.RESET+""+TextFormat.RED+"Congratulations!"); - flowerItem.setLore(TextFormat.RESET+""+TextFormat.LIGHT_PURPLE+"This is a present for your finding!"); - - // The will guarantee that the player receive the present by dropping it on the floor if the inventory is full - for (Item drop: player.getInventory().addItem(flowerItem)) { - player.getLevel().dropItem(player, drop); - } - } -} diff --git a/src/main/java/org/powernukkit/plugins/example/CloneMePlugin.java b/src/main/java/org/powernukkit/plugins/example/CloneMePlugin.java deleted file mode 100644 index 8a47df3..0000000 --- a/src/main/java/org/powernukkit/plugins/example/CloneMePlugin.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.powernukkit.plugins.example; - -import cn.nukkit.command.Command; -import cn.nukkit.command.CommandSender; -import cn.nukkit.command.PluginCommand; -import cn.nukkit.plugin.PluginBase; - -public class CloneMePlugin extends PluginBase { - @Override - public void onEnable() { - getLogger().info("Hello world! :D"); - if (System.getProperty("os.name").startsWith("Windows")) { - getLogger().warning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); - getLogger().warning("!!! ATTENTION WINDOWS USER !!!"); - getLogger().warning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); - getLogger().warning("To connect to the server in localhost you must allow the game to access localhost:"); - getLogger().warning("1. Open PowerShell as admin"); - getLogger().warning("2. Run this command: CheckNetIsolation LoopbackExempt -a -n=\"Microsoft.MinecraftUWP_8wekyb3d8bbwe\""); - getLogger().warning("3. Restart your computer (if needed, try to restart your game first)"); - getLogger().warning("This issue occurs due to loopback restrictions on Windows 10 UWP apps"); - } - - getLogger().info("TIP: Make sure your break points are set to pause ONLY THE THREAD and NOT ALL THREADS!"); - getLogger().info("https://imgur.com/ygwen76"); - getLogger().info("If you do this, you won't get disconnected when you hit a break point"); - - getLogger().info("TIP: If you are using IntelliJ, use Ctrl+F9 (Build Project) to apply non-structural java changes without restart"); - - // TODO: Make it easier - // This make the command be executed in a separated class, you need to choose if you want - // it being executed there or in the onCommand bellow, you can't use both - // Simple commands are fine in onCommand but complex command might be more organized - // in their own classes. Also make sure you register this command in plugin.yml - ((PluginCommand) getCommand("cloneme")).setExecutor(new CloneCommand()); - - // You must register your listeners to capture events - // You can make this class implement the Listener itself and invoke registerEvents(this, this) - // But again, if the listener gets too complicated it might be better to group them in different classes - getServer().getPluginManager().registerEvents(new CloneListener(), this); - } - - @Override - public void onDisable() { - getLogger().info("Goodbye world :("); - } - - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - // You can also override this command instead of setting an executor in onEnable if you prefer - return false; - } -} diff --git a/src/main/java/org/powernukkit/plugins/getid/GetIdCommand.java b/src/main/java/org/powernukkit/plugins/getid/GetIdCommand.java new file mode 100644 index 0000000..dea8003 --- /dev/null +++ b/src/main/java/org/powernukkit/plugins/getid/GetIdCommand.java @@ -0,0 +1,70 @@ +package org.powernukkit.plugins.getid; + +import cn.nukkit.block.BlockID; +import cn.nukkit.command.Command; +import cn.nukkit.command.CommandExecutor; +import cn.nukkit.command.CommandSender; +import cn.nukkit.command.PluginCommand; +import cn.nukkit.command.data.CommandParameter; +import cn.nukkit.item.ItemID; +import cn.nukkit.lang.TranslationContainer; + +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.OptionalInt; +import java.util.stream.Stream; + +public class GetIdCommand implements CommandExecutor { + GetIdCommand(PluginCommand command) { + command.setExecutor(this); + command.getCommandParameters().clear(); + command.getCommandParameters().put("default", new CommandParameter[] { + new CommandParameter("blockOrItemName", false, + Stream.of(BlockID.class, ItemID.class) + .map(Class::getDeclaredFields) + .flatMap(Arrays::stream) + .filter(f-> f.getModifiers() == (Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL)) + .map(f-> f.getName().toLowerCase()) + .toArray(String[]::new) + ) + }); + } + + @Override + public boolean onCommand(CommandSender commandSender, Command command, String label, String[] args) { + if (args.length < 1 || args[0].trim().isEmpty()) { + commandSender.sendMessage(new TranslationContainer("commands.generic.usage", command.getUsage())); + } + String name = args[0].trim(); + OptionalInt id = findId(ItemID.class, name); + if (!id.isPresent()) { + id = findId(BlockID.class, name); + if (id.isPresent()) { + int blockId = id.getAsInt(); + if (blockId > 255) { + id = OptionalInt.of(255 - blockId); + } + } + } + + if (!id.isPresent()) { + commandSender.sendMessage(name+" was not found"); + } else { + commandSender.sendMessage(name + " = " + id.getAsInt()); + } + return true; + } + + private OptionalInt findId(Class c, String name) { + return Arrays.stream(c.getDeclaredFields()) + .filter(f -> f.getModifiers() == (Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL)) + .filter(f -> f.getName().equalsIgnoreCase(name)) + .mapToInt(f -> { + try { + return f.getInt(null); + } catch (IllegalAccessException e) { + throw new InternalError(e); + } + }).findFirst(); + } +} diff --git a/src/main/java/org/powernukkit/plugins/getid/GetIdPlugin.java b/src/main/java/org/powernukkit/plugins/getid/GetIdPlugin.java new file mode 100644 index 0000000..769b706 --- /dev/null +++ b/src/main/java/org/powernukkit/plugins/getid/GetIdPlugin.java @@ -0,0 +1,11 @@ +package org.powernukkit.plugins.getid; + +import cn.nukkit.command.PluginCommand; +import cn.nukkit.plugin.PluginBase; + +public class GetIdPlugin extends PluginBase { + @Override + public void onEnable() { + new GetIdCommand(((PluginCommand) getCommand("getid"))); + } +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 25b9989..3f055fe 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,78 +1,26 @@ -# Required -# The final name of your plugin, other plugins may use this name to declare dependency on your plugin -name: CloneMe +name: GetId -# Required -# The name of your class file that overrides PluginBase -main: org.powernukkit.plugins.example.CloneMePlugin +main: org.powernukkit.plugins.getid.GetIdPlugin -# Required -# The version of your plugin, it's recommended to follow the https://semver.org/ standard version: "1.0.0" -# Required -# The minimum Cloudburst Nukkit API version, it's not the PowerNukkit version! -# Setting an outdated version usually don't cause issues so it's not a thing to worry too much -api: ["1.0.0"] +api: ["1.0.11"] -# Optional -# At which time your plugin will load. -# Valid options are: POSTWORLD, STARTUP -# Default value is POSTWORLD -load: POSTWORLD +author: joserobjr -# Optional -# Your name or your organization name or how people identify you -author: Nukkit Project +description: Simple plugin that shows the ID of a block using the /getid command -# Optional -# Explain in few words what this plugin does -description: Example plugin showing the API +website: https://github.com/PowerNukkit/getid-plugin -# Optional -# A link where the admins can find more info about your plugin -website: https://github.com/Nukkit/ExamplePlugin - -# Optional -# Every sub-item must be a block, the key is the command name, you can create as many commands as you want -# Make sure to keep the exact same alignment, it is important commands: - # The key is how the command will be used, like /cloneme . Avoid uppercase, the client game don't like it so much and may crash. - cloneme: - # Optional - # This information will be displayed in /help - description: Example command + getid: + description: Shows the ID of an item or block by it's name - # Optional - # This information will be displayed in /help and when your command executor returns false - usage: "/example" + usage: "/getid light_block" - # Optional - # The permission required to use your command. It's a good practice to always define one even if the command can be used by everybody - # More information below - permission: cloneme.cmd.use + permission: getid.cmd.use -# Optional -# Although you don't need to register your permissions here for them to work, it's good to allow the server owners to see all them quicker -# This section also allows to customize their behavior and provide more information about them -# You can also create group of permission -# Also, every sub-item must be a block just like the commands block above permissions: - # The key must be the same value you use to define the permission - # It's a good practice to prefix it with your plugin name and create segmentation and then group them to make the permission management easier - cloneme.cmd.use: - # Optional - # This can be used by permission management plugins to show details about the permission key - description: "Allows the user to run the example command" - - # Optional - # If a player don't have an allow-deny definition for this key, this default value will be used - # Valid options: - # - true: the permission is granted by default to everybody - # - false: the permission is revoked by default to everybody, including admins and OP - # - op: the permission is revoked by default to everybody, but is granted to OP players - # - notop: the permission is granted by default to everybody, but is revoked to OP players - # Default value is false + getid.cmd.use: + description: "Allows the user to run the getid command" default: true - -# TODO Add all possible configuration here