From a3f66779f2fcb04d25cde5b0f25ae51300e77a5b Mon Sep 17 00:00:00 2001 From: Slowly <65243837+noslowdwn@users.noreply.github.com> Date: Thu, 6 Jun 2024 03:35:05 +0200 Subject: [PATCH] Add files via upload --- EnderChestLimiter.iml | 34 +++++ pom.xml | 75 ++++++++++ .../enderchestlimiter/EnderChestLimiter.java | 44 ++++++ .../listeners/ItemLimiter.java | 138 ++++++++++++++++++ .../enderchestlimiter/utils/ColorsParser.java | 38 +++++ src/main/resources/config.yml | 58 ++++++++ src/main/resources/plugin.yml | 15 ++ 7 files changed, 402 insertions(+) create mode 100644 EnderChestLimiter.iml create mode 100644 pom.xml create mode 100644 src/main/java/noslowdwn/enderchestlimiter/EnderChestLimiter.java create mode 100644 src/main/java/noslowdwn/enderchestlimiter/listeners/ItemLimiter.java create mode 100644 src/main/java/noslowdwn/enderchestlimiter/utils/ColorsParser.java create mode 100644 src/main/resources/config.yml create mode 100644 src/main/resources/plugin.yml diff --git a/EnderChestLimiter.iml b/EnderChestLimiter.iml new file mode 100644 index 0000000..161131e --- /dev/null +++ b/EnderChestLimiter.iml @@ -0,0 +1,34 @@ + + + + + + + SPIGOT + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..9bb15c8 --- /dev/null +++ b/pom.xml @@ -0,0 +1,75 @@ + + + 4.0.0 + + noslowdwn + EnderChestLimiter + 1.0 + jar + + EnderChestLimiter + + Limit items for player in his enderchest + + 1.8 + UTF-8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + false + + + + + + + + src/main/resources + true + + + + + + + spigotmc-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + sonatype + https://oss.sonatype.org/content/groups/public/ + + + + + + org.spigotmc + spigot-api + 1.12.2-R0.1-SNAPSHOT + provided + + + diff --git a/src/main/java/noslowdwn/enderchestlimiter/EnderChestLimiter.java b/src/main/java/noslowdwn/enderchestlimiter/EnderChestLimiter.java new file mode 100644 index 0000000..2a26895 --- /dev/null +++ b/src/main/java/noslowdwn/enderchestlimiter/EnderChestLimiter.java @@ -0,0 +1,44 @@ +package noslowdwn.enderchestlimiter; + +import noslowdwn.enderchestlimiter.listeners.ItemLimiter; +import noslowdwn.enderchestlimiter.utils.ColorsParser; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.File; + +public final class EnderChestLimiter extends JavaPlugin { + + public static EnderChestLimiter instance; + + @Override + public void onEnable() { + instance = this; + load(); + this.getCommand("eclimiter").setExecutor((sender, command, label, args) -> { + if (sender instanceof Player && !sender.hasPermission("enderchestlimiter.reload")) + sender.sendMessage(ColorsParser.of(instance.getConfig().getString("messages.no-permission"))); + else { + reloadConfig(); + sender.sendMessage(ColorsParser.of(instance.getConfig().getString("messages.reload-message"))); + } + return true; + }); + this.getServer().getPluginManager().registerEvents(new ItemLimiter(), this); + } + + private void load() { + File file = new File(this.getDataFolder(), "config.yml"); + if (!file.exists()) + this.saveResource("config.yml", false); + + YamlConfiguration config = new YamlConfiguration(); + + try { + config.load(file); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/noslowdwn/enderchestlimiter/listeners/ItemLimiter.java b/src/main/java/noslowdwn/enderchestlimiter/listeners/ItemLimiter.java new file mode 100644 index 0000000..943b8c8 --- /dev/null +++ b/src/main/java/noslowdwn/enderchestlimiter/listeners/ItemLimiter.java @@ -0,0 +1,138 @@ +package noslowdwn.enderchestlimiter.listeners; + +import net.md_5.bungee.api.ChatColor; +import noslowdwn.enderchestlimiter.utils.ColorsParser; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryAction; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static noslowdwn.enderchestlimiter.EnderChestLimiter.instance; +import static org.bukkit.Sound.ENTITY_SHULKER_HURT_CLOSED; + +public class ItemLimiter implements Listener { + + @EventHandler + public void onClick(InventoryClickEvent e) { + if (!(e.getWhoClicked() instanceof Player)) return; + + Inventory clickedInventory = e.getClickedInventory(); + Inventory destInv = e.getView().getTopInventory(); + Player p = (Player) e.getWhoClicked(); + if (p.hasPermission("enderchestlimiter.bypass.all")) return; + + if (clickedInventory == null || destInv.getType() != InventoryType.ENDER_CHEST) return; + + FileConfiguration cfg = instance.getConfig(); + + ItemStack item; + if ((InventoryAction.HOTBAR_SWAP.equals(e.getAction()) + || InventoryAction.HOTBAR_MOVE_AND_READD.equals(e.getAction())) + && e.getHotbarButton() >= 0 && e.getHotbarButton() <= 8) + item = p.getInventory().getItem(e.getHotbarButton()); + else { + if (clickedInventory.getType() == InventoryType.ENDER_CHEST) return; + item = e.getCurrentItem(); + } + + if (item == null) return; + + for (String group : cfg.getConfigurationSection("groups").getKeys(false)) { + if (p.hasPermission("enderchestlimiter.bypass." + group)) return; + + List includedItems = cfg.getStringList("groups." + group + ".included-items"); + for (int i = 0; i < includedItems.size(); i++) + includedItems.set(i, includedItems.get(i).toUpperCase()); + + if (!includedItems.contains(item.getType().toString())) continue; + + int limit = cfg.getInt("groups." + group + ".limit"); + + Map itemCountMap = new HashMap<>(); + + int amount = 0; + for (ItemStack i : destInv.getStorageContents()) { + if (i != null && includedItems.contains(i.getType().name())) { + itemCountMap.put(i.getType(), itemCountMap.getOrDefault(i.getType(), 0) + i.getAmount()); + amount += i.getAmount(); + } + } + + if (amount + item.getAmount() > limit) { + e.setCancelled(true); + p.sendMessage(getDenyMessage(limit, group).replace("%max%", String.valueOf(limit))); + if (cfg.getConfigurationSection("groups." + group).getKeys(false).contains("deny-sound")) + playDenySound(p, cfg.getString("groups." + group + ".deny-sound"), group); + return; + } + } + } + + private String getDenyMessage(int limit, String group) { + String messageKey; + if (limit % 100 >= 11 && limit % 100 <= 19) { + messageKey = "deny-message-3"; + } else { + switch (limit % 10) { + case 1: + messageKey = "deny-message-1"; + break; + case 2: + case 3: + messageKey = "deny-message-2"; + break; + default: + messageKey = "deny-message-3"; + break; + } + } + return ColorsParser.of(instance.getConfig().getString("groups." + group + "." + messageKey)); + } + + private void playDenySound(Player player, String soundConfig, String group) { + if (soundConfig == null || soundConfig.isEmpty()) { + Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "There are not enough arguments to play the sound"); + Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "Path to: groups." + group + ".deny-sound"); + return; + } + + String[] params = soundConfig.split(";", 3); + Sound sound = ENTITY_SHULKER_HURT_CLOSED; + try { + sound = Sound.valueOf(params[0].toUpperCase()); + } catch (IllegalArgumentException exception) { + Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "Sound name given for sound action: " + params[0] + ", is not a valid sound!"); + } + + float volume = 1, pitch = 1; + if (params.length >= 2) { + try { + volume = Float.parseFloat(params[1]); + } catch (NumberFormatException exception) { + Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "Volume given for sound action: " + params[1] + ", is not a valid number!"); + } + } + + if (params.length == 3) { + try { + pitch = Float.parseFloat(params[2]); + } catch (NumberFormatException exception) { + Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "Pitch given for sound action: " + params[2] + ", is not a valid number!"); + } + } + + player.playSound(player.getLocation(), sound, volume, pitch); + } +} \ No newline at end of file diff --git a/src/main/java/noslowdwn/enderchestlimiter/utils/ColorsParser.java b/src/main/java/noslowdwn/enderchestlimiter/utils/ColorsParser.java new file mode 100644 index 0000000..b9da602 --- /dev/null +++ b/src/main/java/noslowdwn/enderchestlimiter/utils/ColorsParser.java @@ -0,0 +1,38 @@ +package noslowdwn.enderchestlimiter.utils; + +import net.md_5.bungee.api.ChatColor; +import org.bukkit.Bukkit; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ColorsParser { + + public static String of(String message) { + if (message == null) { + Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "[EnderChestLimiter] Error message parsing!"); + Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "[EnderChestLimiter] Please check your messages.yml to find error!"); + Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "[EnderChestLimiter] You can also check syntax on https://yamlchecker.com/!"); + Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "[EnderChestLimiter] Or just delete 'messages.yml' and reload plugin!"); + message = "&c[EnderChestLimiter] Error message parsing! Please contact administrator or check console!"; + } + + String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3]; + int subVersion = Integer.parseInt(version.replace("1_", "").replaceAll("_R\\d", "").replace("v", "")); + if (subVersion >= 16) { + Pattern pattern = Pattern.compile("#[a-fA-F0-9]{6}"); + Matcher matcher = pattern.matcher(message); + + while (matcher.find()) { + String color = message.substring(matcher.start(), matcher.end()); + StringBuilder replacement = new StringBuilder("x"); + for (char c : color.substring(1).toCharArray()) + replacement.append('\u00A7').append(c); + message = message.replace(color, replacement.toString()); + matcher = pattern.matcher(message); + } + } + + return ChatColor.translateAlternateColorCodes('&', message); + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..ef5d934 --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,58 @@ +# Команда для перезагрузки: /eclimiter +# Права: +# enderchestlimiter.reload - Разрешает перезагружать плагин +# enderchestlimiter.bypass.all - Даёт обход для любых лимитов +# enderchestlimiter.bypass.<название группы> - Даёт обход лимита выбранной группы +# +# Плейсхолдеры внутри плагина: +# %max% - выводит лимит на предмет +# +# Предметы (Оставьте groups: пустым, чтобы отключить) +groups: + # Название группы (Может быть любым, но оно потребуется для пермишена на байпасс) + shulker_boxes: # enderchestlimiter.bypass.shulker_boxes - чтобы обходить лимит + # Максимально количество предметов из списка которые игрок сможет положить в эндер сундук + limit: 3 + # Сообщение, которое будет отправляться если лимит: 1, 21, 31, 41, 51 итд + deny-message-1: '&cИзвините, но вы не можете положить в ваш эндер сундук больше чем %max% шалкер' + # Сообщение, которое будет отправляться если лимит: 2, 3, 22, 23, 32 итд + deny-message-2: '&cИзвините, но вы не можете положить в ваш эндер сундук больше чем %max% шалкера' + # Сообщение, которое будет отправляться если лимит: 4, 5, 11, 16, 26 итд + deny-message-3: '&cИзвините, но вы не можете положить в ваш эндер сундук больше чем %max% шалкеров' + # Звук, который будет воспроизводиться (Если удалить, то не будет) + # Может быть в формате: + # ITEM_SHIELD_BREAK или ITEM_SHIELD_BREAK;громкость или ITEM_SHIELD_BREAK;громкость;высота + deny-sound: ITEM_SHIELD_BREAK;0.8;1 + # Группированные предметы на которые будет распространяться лимит + included-items: + - BLACK_SHULKER_BOX + - BLUE_SHULKER_BOX + - BROWN_SHULKER_BOX + - CYAN_SHULKER_BOX + - GRAY_SHULKER_BOX + - GREEN_SHULKER_BOX + - LIGHT_BLUE_SHULKER_BOX + - LIGHT_GRAY_SHULKER_BOX + - LIME_SHULKER_BOX + - MAGENTA_SHULKER_BOX + - ORANGE_SHULKER_BOX + - PINK_SHULKER_BOX + - PURPLE_SHULKER_BOX + - RED_SHULKER_BOX + - WHITE_SHULKER_BOX + - YELLOW_SHULKER_BOX + # Пример + tnt: + limit: 64 # 1 стак + deny-message-1: '&cИзвините, но вы не можете положить в ваш эндер сундук больше чем %max% тнт' + deny-message-2: '&cИзвините, но вы не можете положить в ваш эндер сундук больше чем %max% тнт' + deny-message-3: '&cИзвините, но вы не можете положить в ваш эндер сундук больше чем %max% тнт' + included-items: + - TNT + +# Сообщения +messages: + # Сообщение при перезагрузке плагина + reload-message: '&aПлагин EnderChestLimiter успешно перезагружен.' + # Сообщения если не хватает прав на использование команды + no-permission: '&cИзвини, но у тебя не хватает прав на использование данной команды.' \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..448dfe3 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,15 @@ +name: EnderChestLimiter +version: '${project.version}' +main: noslowdwn.enderchestlimiter.EnderChestLimiter +authors: [ noslowdwn ] +description: Limit items for player in his enderchest + +commands: + eclimiter: {} + +permissions: + enderchestlimiter.reload: + description: Allows you to reload plugin's configuration file + enderchestlimiter.bypass.all: + description: Allows you to bypass all limits + default: op \ No newline at end of file