From b130e1b75a9d9d9ea3c93499e049bde10ae35a75 Mon Sep 17 00:00:00 2001 From: MrJeremyFisher <63616270+MrJeremyFisher@users.noreply.github.com> Date: Fri, 22 Dec 2023 23:39:55 -0500 Subject: [PATCH 1/4] Add map copy protection --- .../hacks/basic/MapCopyProtection.java | 126 ++++++++++++++++++ paper/src/main/resources/config.yml | 2 + paper/src/main/resources/plugin.yml | 14 +- 3 files changed, 137 insertions(+), 5 deletions(-) create mode 100644 paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/MapCopyProtection.java diff --git a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/MapCopyProtection.java b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/MapCopyProtection.java new file mode 100644 index 00000000..80683b25 --- /dev/null +++ b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/MapCopyProtection.java @@ -0,0 +1,126 @@ +package com.programmerdan.minecraft.simpleadminhacks.hacks.basic; + +import com.programmerdan.minecraft.simpleadminhacks.SimpleAdminHacks; +import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHack; +import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHackConfig; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.TextColor; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftInventoryCrafting; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.CartographyInventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataType; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +public class MapCopyProtection extends BasicHack implements CommandExecutor { + final NamespacedKey copyKey = new NamespacedKey(plugin, "copy-protected"); + + public MapCopyProtection(SimpleAdminHacks plugin, BasicHackConfig config) { + super(plugin, config); + } + + @Override + public void onEnable() { + super.onEnable(); + plugin().registerCommand("copyprotect", this); + } + + @Override + public void onDisable() { + super.onDisable(); + } + + @EventHandler + public void onMapCopyCartography(InventoryClickEvent event) { + if (!(event.getInventory() instanceof CartographyInventory) || event.getSlotType() != InventoryType.SlotType.RESULT) + return; + + ItemStack item = event.getInventory().getItem(1); // paper, glass pane, blank map slot + + if (item == null) return; + + if (item.getType() == Material.GLASS_PANE || item.getType() == Material.PAPER) return; // Allow locking and scaling of copy protected maps + + handleCopyProtection(event); + } + + @EventHandler + public void onMapCopyCrafting(InventoryClickEvent event) { + if (!(event.getInventory() instanceof CraftInventoryCrafting) || event.getSlotType() != InventoryType.SlotType.RESULT) + return; + + handleCopyProtection(event); + } + + private void handleCopyProtection(InventoryClickEvent event) { + ItemStack item = event.getCurrentItem(); + + if (item == null || item.getType() == Material.AIR) return; + + if (isCopy(item)) { + event.setCancelled(true); + event.getWhoClicked().sendMessage( + Component.text() + .color(TextColor.color(0xFF5555)) + .content("You can not copy copy protected maps") + ); + } + } + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + Player player = Bukkit.getPlayer(sender.getName()); + + if (player == null) return false; + + ItemStack item = player.getInventory().getItemInMainHand(); + + if (item.getType() != Material.FILLED_MAP) { + sender.sendMessage( + Component.text() + .color(TextColor.color(0xFF5555)) + .content("Only filled maps can be copy protected") + ); + return true; // Command failed, but was syntactically correct, so no need to tell the player how to use it + } + + if (isCopy(item)) { + sender.sendMessage( + Component.text() + .color(TextColor.color(0xFF5555)) + .content("You can not copy protect copy protected maps") + ); + return true; // Command failed, but was syntactically correct, so no need to tell the player how to use it + } + + ItemMeta itemMeta = item.getItemMeta(); + + itemMeta.getPersistentDataContainer().set(copyKey, PersistentDataType.INTEGER, 1); + + itemMeta.lore(new ArrayList<>(List.of(Component.text(String.format("Copy protected by %s", sender.getName()))))); + + player.getInventory().getItemInMainHand().setItemMeta(itemMeta); + + return true; + } + + private boolean isCopy(ItemStack item) { + if (item.getItemMeta().getPersistentDataContainer().has(copyKey, PersistentDataType.INTEGER)) { + int val = item.getItemMeta().getPersistentDataContainer().get(copyKey, PersistentDataType.INTEGER); + return val == 1; + } else return false; + } +} diff --git a/paper/src/main/resources/config.yml b/paper/src/main/resources/config.yml index 55a65dec..9ea08e87 100644 --- a/paper/src/main/resources/config.yml +++ b/paper/src/main/resources/config.yml @@ -136,6 +136,8 @@ hacks: disableGapples: true ItemMetaConverterHack: enabled: true + MapCopyProtection: + enabled: true OldEnchanting: enabled: true # Hides what enchantment will be granted within the Enchanting Table diff --git a/paper/src/main/resources/plugin.yml b/paper/src/main/resources/plugin.yml index 9ff97acc..3089d892 100644 --- a/paper/src/main/resources/plugin.yml +++ b/paper/src/main/resources/plugin.yml @@ -1,10 +1,10 @@ name: ${name} main: com.programmerdan.minecraft.simpleadminhacks.SimpleAdminHacks author: ProgrammerDan -authors: [ProgrammerDan, Maxopoly] +authors: [ ProgrammerDan, Maxopoly ] version: ${version} -depend: [CivModCore] -softdepend: [CombatTagPlus, NameLayer, Citadel, ProtocolLib, BanStick, ExilePearl] +depend: [ CivModCore ] +softdepend: [ CombatTagPlus, NameLayer, Citadel, ProtocolLib, BanStick, ExilePearl ] api-version: 1.18 commands: hacks: @@ -25,7 +25,11 @@ commands: permission: simpleadmin.invmod chunklimits: description: Display block chunk limit in chat - usage: / + usage: / + copyprotect: + description: Protect a map from copying. + usage: / + permission: simpleadmin.copyright serialize: description: Print to console the object held as serialized yaml usage: / @@ -88,7 +92,7 @@ commands: description: Allows debugging of an event and its handlers usage: / full.path.to.event permission: simpleadmin.eventdebug - stats: {} # Defined in (basic) PlayerStats + stats: { } # Defined in (basic) PlayerStats permissions: simpleadmin.*: description: Gives access to all SimpleAdminHacks commands From 7a989b9b68f3d10422a003636c79518ca473203a Mon Sep 17 00:00:00 2001 From: Jeremy Favro <63616270+MrJeremyFisher@users.noreply.github.com> Date: Sat, 23 Dec 2023 00:26:48 -0500 Subject: [PATCH 2/4] Fix autoformat and rename permission --- paper/src/main/resources/plugin.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/paper/src/main/resources/plugin.yml b/paper/src/main/resources/plugin.yml index 3089d892..5198b32e 100644 --- a/paper/src/main/resources/plugin.yml +++ b/paper/src/main/resources/plugin.yml @@ -1,10 +1,10 @@ name: ${name} main: com.programmerdan.minecraft.simpleadminhacks.SimpleAdminHacks author: ProgrammerDan -authors: [ ProgrammerDan, Maxopoly ] +authors: [ProgrammerDan, Maxopoly] version: ${version} -depend: [ CivModCore ] -softdepend: [ CombatTagPlus, NameLayer, Citadel, ProtocolLib, BanStick, ExilePearl ] +depend: [CivModCore] +softdepend: [CombatTagPlus, NameLayer, Citadel, ProtocolLib, BanStick, ExilePearl] api-version: 1.18 commands: hacks: @@ -29,7 +29,7 @@ commands: copyprotect: description: Protect a map from copying. usage: / - permission: simpleadmin.copyright + permission: simpleadmin.copyprotect serialize: description: Print to console the object held as serialized yaml usage: / @@ -92,7 +92,7 @@ commands: description: Allows debugging of an event and its handlers usage: / full.path.to.event permission: simpleadmin.eventdebug - stats: { } # Defined in (basic) PlayerStats + stats: {} # Defined in (basic) PlayerStats permissions: simpleadmin.*: description: Gives access to all SimpleAdminHacks commands From ca9e6b9b593885acefc0ac78480737cdbdfe1f30 Mon Sep 17 00:00:00 2001 From: MrJeremyFisher <63616270+MrJeremyFisher@users.noreply.github.com> Date: Thu, 28 Dec 2023 12:45:23 -0500 Subject: [PATCH 3/4] Review --- .../hacks/basic/MapCopyProtection.java | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/MapCopyProtection.java b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/MapCopyProtection.java index 80683b25..54f0fc3e 100644 --- a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/MapCopyProtection.java +++ b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/MapCopyProtection.java @@ -4,7 +4,7 @@ import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHack; import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHackConfig; import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.NamespacedKey; @@ -22,7 +22,6 @@ import org.bukkit.persistence.PersistentDataType; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; import java.util.List; public class MapCopyProtection extends BasicHack implements CommandExecutor { @@ -74,14 +73,23 @@ private void handleCopyProtection(InventoryClickEvent event) { event.setCancelled(true); event.getWhoClicked().sendMessage( Component.text() - .color(TextColor.color(0xFF5555)) - .content("You can not copy copy protected maps") + .color(NamedTextColor.RED) + .content("You can not clone copy protected maps") ); } } @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage( + Component.text() + .color(NamedTextColor.RED) + .content("This command can only be run by players") + ); + return true; + } + Player player = Bukkit.getPlayer(sender.getName()); if (player == null) return false; @@ -91,7 +99,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command if (item.getType() != Material.FILLED_MAP) { sender.sendMessage( Component.text() - .color(TextColor.color(0xFF5555)) + .color(NamedTextColor.RED) .content("Only filled maps can be copy protected") ); return true; // Command failed, but was syntactically correct, so no need to tell the player how to use it @@ -100,7 +108,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command if (isCopy(item)) { sender.sendMessage( Component.text() - .color(TextColor.color(0xFF5555)) + .color(NamedTextColor.RED) .content("You can not copy protect copy protected maps") ); return true; // Command failed, but was syntactically correct, so no need to tell the player how to use it @@ -110,7 +118,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command itemMeta.getPersistentDataContainer().set(copyKey, PersistentDataType.INTEGER, 1); - itemMeta.lore(new ArrayList<>(List.of(Component.text(String.format("Copy protected by %s", sender.getName()))))); + itemMeta.lore(List.of(Component.text(String.format("Copy protected by %s", sender.getName())))); player.getInventory().getItemInMainHand().setItemMeta(itemMeta); @@ -118,9 +126,6 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command } private boolean isCopy(ItemStack item) { - if (item.getItemMeta().getPersistentDataContainer().has(copyKey, PersistentDataType.INTEGER)) { - int val = item.getItemMeta().getPersistentDataContainer().get(copyKey, PersistentDataType.INTEGER); - return val == 1; - } else return false; + return item.getItemMeta().getPersistentDataContainer().has(copyKey, PersistentDataType.INTEGER); } } From cfb7f1565ad989f363c50aed52bbf1e0de82dcf9 Mon Sep 17 00:00:00 2001 From: MrJeremyFisher <63616270+MrJeremyFisher@users.noreply.github.com> Date: Thu, 28 Dec 2023 12:45:23 -0500 Subject: [PATCH 4/4] Review --- .../hacks/basic/MapCopyProtection.java | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/MapCopyProtection.java b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/MapCopyProtection.java index 80683b25..8210115d 100644 --- a/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/MapCopyProtection.java +++ b/paper/src/main/java/com/programmerdan/minecraft/simpleadminhacks/hacks/basic/MapCopyProtection.java @@ -4,8 +4,7 @@ import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHack; import com.programmerdan.minecraft.simpleadminhacks.framework.BasicHackConfig; import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.TextColor; -import org.bukkit.Bukkit; +import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.command.Command; @@ -22,7 +21,6 @@ import org.bukkit.persistence.PersistentDataType; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; import java.util.List; public class MapCopyProtection extends BasicHack implements CommandExecutor { @@ -74,24 +72,29 @@ private void handleCopyProtection(InventoryClickEvent event) { event.setCancelled(true); event.getWhoClicked().sendMessage( Component.text() - .color(TextColor.color(0xFF5555)) - .content("You can not copy copy protected maps") + .color(NamedTextColor.RED) + .content("You can not clone copy protected maps") ); } } @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - Player player = Bukkit.getPlayer(sender.getName()); - - if (player == null) return false; + if (!(sender instanceof Player player)) { + sender.sendMessage( + Component.text() + .color(NamedTextColor.RED) + .content("This command can only be run by players") + ); + return true; + } ItemStack item = player.getInventory().getItemInMainHand(); if (item.getType() != Material.FILLED_MAP) { sender.sendMessage( Component.text() - .color(TextColor.color(0xFF5555)) + .color(NamedTextColor.RED) .content("Only filled maps can be copy protected") ); return true; // Command failed, but was syntactically correct, so no need to tell the player how to use it @@ -100,7 +103,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command if (isCopy(item)) { sender.sendMessage( Component.text() - .color(TextColor.color(0xFF5555)) + .color(NamedTextColor.RED) .content("You can not copy protect copy protected maps") ); return true; // Command failed, but was syntactically correct, so no need to tell the player how to use it @@ -110,7 +113,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command itemMeta.getPersistentDataContainer().set(copyKey, PersistentDataType.INTEGER, 1); - itemMeta.lore(new ArrayList<>(List.of(Component.text(String.format("Copy protected by %s", sender.getName()))))); + itemMeta.lore(List.of(Component.text(String.format("Copy protected by %s", sender.getName())))); player.getInventory().getItemInMainHand().setItemMeta(itemMeta); @@ -118,9 +121,6 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command } private boolean isCopy(ItemStack item) { - if (item.getItemMeta().getPersistentDataContainer().has(copyKey, PersistentDataType.INTEGER)) { - int val = item.getItemMeta().getPersistentDataContainer().get(copyKey, PersistentDataType.INTEGER); - return val == 1; - } else return false; + return item.getItemMeta().getPersistentDataContainer().has(copyKey, PersistentDataType.INTEGER); } }