diff --git a/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/v1_7_3/ConfigurationEx.java b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/v1_7_3/ConfigurationEx.java new file mode 100644 index 0000000..6fc8e27 --- /dev/null +++ b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/v1_7_3/ConfigurationEx.java @@ -0,0 +1,89 @@ +package io.github.adrianvic.nemesiseye.impl.v1_7_3; + +import io.github.adrianvic.nemesiseye.Nemesis; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.util.config.Configuration; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; + +public class ConfigurationEx extends Configuration { + private final File configFile; + private final Log logger; + JavaPlugin plugin; + + public ConfigurationEx(String fileName, Log _logger) { + super(new File(Nemesis.getInstance().getDataFolder(), fileName)); + this.plugin = Nemesis.getInstance(); + logger = _logger; + this.configFile = new File(plugin.getDataFolder(), fileName); + } + + @Override + public void load() { + createParentDirectories(); + + if (!configFile.exists()) { + copyDefaultConfig(); + } + + try { + super.load(); + } catch (Exception e) { + logger.severe(String.format("Failed to load config '%s': %s", configFile.getName(), e.getMessage())); + } + } + + private void createParentDirectories() { + try { + Files.createDirectories(configFile.getParentFile().toPath()); + } catch (IOException e) { + logger.severe(String.format("Failed to generate default config directory: %s", e.getMessage())); + } + } + + private void copyDefaultConfig() { + // Load the config from the JAR directly (it is located at the root level) + String resourcePath = "/" + configFile.getName(); // Root path of JAR + + try (InputStream input = plugin.getClass().getResourceAsStream(resourcePath)) { + if (input == null) { + logger.severe(String.format("Default config '%s' wasn't found in the JAR.", configFile.getName())); + return; + } + + Files.copy(input, configFile.toPath()); + if (Files.exists(configFile.toPath())) { + logger.info(String.format("Default config '%s' generated successfully.", configFile.getName())); + } else { + logger.warning("We tried to generate the default config file, but it was not found even after the creation. Maybe your permissions are broken?"); + } + } catch (IOException e) { + logger.severe(String.format("Failed to generate default config '%s': %s", configFile.getName(), e.getMessage())); + } + } + + public void loadConfig() { + try { + this.load(); + logger.info(String.format("Config '%s' loaded successfully.", configFile.getName())); + } catch (Exception e) { + logger.severe(String.format("Failed to load config '%s': %s", configFile.getName(), e.getMessage())); + } + } + + public void saveConfig() { + try { + this.save(); + logger.info(String.format("Config '%s' saved successfully.", configFile.getName())); + } catch (Exception e) { + logger.severe(String.format("Failed to save config '%s': %s", configFile.getName(), e.getMessage())); + } + } + + public File getConfig() { + return configFile; + } +} \ No newline at end of file diff --git a/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/v1_7_3/Log.java b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/v1_7_3/Log.java new file mode 100644 index 0000000..e06b33c --- /dev/null +++ b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/v1_7_3/Log.java @@ -0,0 +1,41 @@ +package io.github.adrianvic.nemesiseye.impl.v1_7_3; + +import static org.bukkit.Bukkit.getServer; + +import io.github.adrianvic.nemesiseye.Nemesis; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.java.JavaPlugin; + +public class Log { + JavaPlugin plugin; + PluginDescriptionFile pdf; + + public Log() { + plugin = Nemesis.getInstance(); + pdf = plugin.getDescription(); + } + + public void info(String message) { + getServer().getLogger().info("[" + pdf.getName() + "] " + message); + } + + public void infoc(String message) { + getServer().getLogger().info("[" + pdf.getName() + "] " + message); + } + + public void warning(String message) { + getServer().getLogger().warning("[" + pdf.getName() + "] " + message); + } + + public void warningc(String message) { + getServer().getLogger().warning("[" + pdf.getName() + "] " + message); + } + + public void severe(String message) { + getServer().getLogger().severe("[" + pdf.getName() + "] " + message); + } + + public void severec(String message) { + getServer().getLogger().severe("[" + pdf.getName() + "] " + message); + } +} \ No newline at end of file diff --git a/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/v1_7_3/b1_7_3.java b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/v1_7_3/b1_7_3.java new file mode 100644 index 0000000..0129a81 --- /dev/null +++ b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/v1_7_3/b1_7_3.java @@ -0,0 +1,152 @@ +package io.github.adrianvic.nemesiseye.impl.v1_7_3; + +import io.github.adrianvic.nemesiseye.Nemesis; +import io.github.adrianvic.nemesiseye.impl.v1_7_3.commands.Eye; +import io.github.adrianvic.nemesiseye.impl.v1_7_3.events.BlockEventListener; +import io.github.adrianvic.nemesiseye.impl.v1_7_3.events.EntityEventListener; +import io.github.adrianvic.nemesiseye.impl.v1_7_3.events.PlayerEventListener; +import io.github.adrianvic.nemesiseye.policy.Policy; +import io.github.adrianvic.nemesiseye.policy.PolicyParsers; +import io.github.adrianvic.nemesiseye.reflection.Glimmer; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.Event; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@SuppressWarnings("unused") +public class b1_7_3 implements Glimmer { + JavaPlugin plugin; + PluginManager pm; + ConfigurationEx config; + + @Override + public File loadConfigFile() { + config = new ConfigurationEx("settings.yml", new Log()); + config.load(); + return config.getConfig(); + } + + @Override + public List loadPoliciesFromFile(File file) { + List rawPolicies = config.getList("Policies"); + + if (rawPolicies == null) { + return new ArrayList<>(); + } + + List> result = new ArrayList<>(rawPolicies.size()); + + for (Object entry : rawPolicies) { + if (entry instanceof Map m) { + result.add(m); + } + } + + List allPolicies = new ArrayList<>(); + for (Map policyMap : result) { + if (policyMap.get("type") != null && policyMap.get("type") instanceof String type) { + allPolicies.add(PolicyParsers.get(type).parse(policyMap)); + } + } + + return allPolicies; + } + + @Override + public void onLoad() { + plugin = Nemesis.getInstance(); + pm = Nemesis.getInstance().getPluginManager(); + pm.registerEvent(Event.Type.ENTITY_DAMAGE, new EntityEventListener(), Event.Priority.Normal, plugin); + pm.registerEvent(Event.Type.BLOCK_BREAK, new BlockEventListener(), Event.Priority.Normal, plugin); + pm.registerEvent(Event.Type.PLAYER_INTERACT, new PlayerEventListener(), Event.Priority.Normal, plugin); + plugin.getCommand("eye").setExecutor(new Eye()); + } + + @Override + public ItemStack getItemInMainHandHumanEntity(HumanEntity entity) { + return entity.getItemInHand(); + } + + @Override + public boolean isAir(ItemStack item) { + return item == null || item.getType() == Material.AIR; + } + + @Override + public boolean isGliding(org.bukkit.entity.Player player) { + return false; + } + + @Override + public void setGliding(org.bukkit.entity.Player player, boolean gliding) { + } + + @Override + public boolean hasPermission(org.bukkit.command.CommandSender sender, String permission) { + if (sender instanceof org.bukkit.entity.Player p) { + return p.isOp(); + } + return true; // Console always has permission + } + + @Override + public boolean isArmorEquipAttempt(org.bukkit.event.Event event) { + return false; + } + + @Override + public ItemStack getEquippedItem(org.bukkit.event.Event event) { + return null; + } + + @Override + public void sendMessage(CommandSender commandSender, String text) { + String[] lines = text.split("\\r?\\n"); + for (String line : lines) { + commandSender.sendMessage(line); + } + } + + @Override + public boolean hasItemMeta(ItemStack item) { + return false; + } + + @Override + public List getWorlds() { + return plugin.getServer().getWorlds(); + } + + @Override + public boolean hasEnchantment(ItemStack item, Map valuesmap) { + return false; + } + + @Override + public boolean hasAnyEnchantment(ItemStack itemStack) { + return false; + } + + @Override + public boolean isArmor(ItemStack item) { + if (item == null || item.getType() == Material.AIR) { + return false; + } + + String name = item.getType().name(); + + return name.endsWith("_HELMET") + || name.endsWith("_CHESTPLATE") + || name.endsWith("_LEGGINGS") + || name.endsWith("_BOOTS"); + } +} diff --git a/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/v1_7_3/commands/Eye.java b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/v1_7_3/commands/Eye.java new file mode 100644 index 0000000..c547c8f --- /dev/null +++ b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/v1_7_3/commands/Eye.java @@ -0,0 +1,19 @@ +package io.github.adrianvic.nemesiseye.impl.v1_7_3.commands; + +import io.github.adrianvic.nemesiseye.commands.EyeCore; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class Eye implements CommandExecutor { + private final EyeCore core; + + public Eye() { + core = new EyeCore(); + } + + @Override + public boolean onCommand(CommandSender commandSender, Command command, String s, String [] strings) { + return core.onCommand(commandSender, command, s, strings); + } +} \ No newline at end of file diff --git a/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/v1_7_3/events/BlockEventListener.java b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/v1_7_3/events/BlockEventListener.java new file mode 100644 index 0000000..b09458f --- /dev/null +++ b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/v1_7_3/events/BlockEventListener.java @@ -0,0 +1,18 @@ +package io.github.adrianvic.nemesiseye.impl.v1_7_3.events; + +import io.github.adrianvic.nemesiseye.Events; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockListener; +import org.bukkit.event.block.BlockPlaceEvent; + +public class BlockEventListener extends BlockListener { + @Override + public void onBlockBreak(BlockBreakEvent event) { + Events.onBlockBreak(event); + } + + @Override + public void onBlockPlace(BlockPlaceEvent event) { + Events.onBlockPlaceEvent(event); + } +} diff --git a/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/v1_7_3/events/EntityEventListener.java b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/v1_7_3/events/EntityEventListener.java new file mode 100644 index 0000000..e342969 --- /dev/null +++ b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/v1_7_3/events/EntityEventListener.java @@ -0,0 +1,13 @@ +package io.github.adrianvic.nemesiseye.impl.v1_7_3.events; + +import io.github.adrianvic.nemesiseye.Events; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityListener; + +public class EntityEventListener extends EntityListener { + @Override + public void onEntityDamage(EntityDamageEvent event) { + if (event instanceof EntityDamageByEntityEvent e) Events.onEntityDamageByEntityEvent(e); + } +} \ No newline at end of file diff --git a/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/v1_7_3/events/PlayerEventListener.java b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/v1_7_3/events/PlayerEventListener.java new file mode 100644 index 0000000..2ec8343 --- /dev/null +++ b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/v1_7_3/events/PlayerEventListener.java @@ -0,0 +1,13 @@ +package io.github.adrianvic.nemesiseye.impl.v1_7_3.events; + +import io.github.adrianvic.nemesiseye.Events; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerListener; + +public class PlayerEventListener extends PlayerListener { + @Override + public void onPlayerInteract(PlayerInteractEvent event) { + Events.onInteractionEvent(event); + } +} + diff --git a/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/v1_21/EventListener.java b/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/v1_21/EventListener.java new file mode 100644 index 0000000..7718061 --- /dev/null +++ b/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/v1_21/EventListener.java @@ -0,0 +1,56 @@ +package io.github.adrianvic.nemesiseye.impl.v1_21; + +import io.github.adrianvic.nemesiseye.Events; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockFormEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntitySpawnEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerMoveEvent; + +public class EventListener implements Listener { + @EventHandler + public void onBlockBreak(BlockBreakEvent event) { + Events.onBlockBreak(event); + } + + @EventHandler + public void onInteractionEvent(PlayerInteractEvent event) { + Events.onInteractionEvent(event); + } + + @EventHandler + public void onEntityDamageByEntityEvent(EntityDamageByEntityEvent event) { + Events.onEntityDamageByEntityEvent(event); + } + + @EventHandler + public void onBlockPlaceEvent(BlockPlaceEvent event) { + Events.onBlockPlaceEvent(event); + } + + @EventHandler + public void onPlayerMoveEvent(PlayerMoveEvent event) { Events.onPlayerMoveEvent(event); } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onInventoryClickEvent(InventoryClickEvent event) { Events.onInventoryClickEvent(event); } + + @EventHandler + public void onCreatureSpawnEvent(CreatureSpawnEvent event) { Events.onCreatureSpawnEvent(event); } + + @EventHandler + public void onEndermanAttackPlayerEvent(com.destroystokyo.paper.event.entity.EndermanAttackPlayerEvent event) { + Events.onEndermanAttackPlayerEvent(event); + } + + @EventHandler + public void onBlockFormEvent(BlockFormEvent event) { + Events.onBlockFormEvent(event); + } +} \ No newline at end of file diff --git a/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/v1_21/commands/Eye.java b/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/v1_21/commands/Eye.java new file mode 100644 index 0000000..30e81f5 --- /dev/null +++ b/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/v1_21/commands/Eye.java @@ -0,0 +1,29 @@ +package io.github.adrianvic.nemesiseye.impl.v1_21.commands; + +import io.github.adrianvic.nemesiseye.commands.EyeCore; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +public class Eye implements CommandExecutor, TabCompleter { + private final EyeCore core; + + public Eye() { + core = new EyeCore(); + } + + @Override + public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String @NotNull [] strings) { + return core.onCommand(commandSender, command, s, strings); + } + + @Override + public @Nullable List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String @NotNull [] strings) { + return core.onTabComplete(commandSender, command, s, strings); + } +} \ No newline at end of file diff --git a/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/v1_21/r1_21.java b/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/v1_21/r1_21.java new file mode 100644 index 0000000..f135aa9 --- /dev/null +++ b/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/v1_21/r1_21.java @@ -0,0 +1,203 @@ +package io.github.adrianvic.nemesiseye.impl.v1_21; + +import io.github.adrianvic.nemesiseye.DataShifter; +import io.github.adrianvic.nemesiseye.Nemesis; +import io.github.adrianvic.nemesiseye.impl.v1_21.commands.Eye; +import io.github.adrianvic.nemesiseye.policy.Policy; +import io.github.adrianvic.nemesiseye.policy.PolicyParsers; +import io.github.adrianvic.nemesiseye.reflection.Glimmer; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.HumanEntity; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.PluginManager; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@SuppressWarnings("unused") +public class r1_21 implements Glimmer { + @Override + public File loadConfigFile() { + File file = new File(Nemesis.getInstance().getDataFolder(), "settings.yml"); + + if (!file.exists()) + Nemesis.getInstance().saveResource("settings.yml", false); + + return file; + } + + @Override + public List loadPoliciesFromFile(File file) { + YamlConfiguration config = new YamlConfiguration(); + config.options().parseComments(true); + + try { + config.load(file); + } catch (Exception e) { + e.printStackTrace(); + } + + List> rawPolicies = config.getMapList("Policies"); + List allPolicies = new ArrayList<>(); + + for (Map policyMap : rawPolicies) { + if (policyMap.get("type") != null && policyMap.get("type") instanceof String type) { + allPolicies.add(PolicyParsers.get(type).parse(policyMap)); + } + } + + return allPolicies; + } + + @Override + public void onLoad() { + PluginManager pm = Nemesis.getInstance().getPluginManager(); + Eye eye = new Eye(); + Nemesis.getInstance().getCommand("eye").setExecutor(eye); + Nemesis.getInstance().getCommand("eye").setTabCompleter(eye); + pm.registerEvents(new EventListener(), Nemesis.getInstance()); + } + + @Override + public ItemStack getItemInMainHandHumanEntity(HumanEntity entity) { + return entity.getInventory().getItemInMainHand(); + } + + @Override + public boolean isAir(ItemStack item) { + return item == null || item.getType().isAir(); + } + + @Override + public boolean isGliding(org.bukkit.entity.Player player) { + return player.isGliding(); + } + + @Override + public void setGliding(org.bukkit.entity.Player player, boolean gliding) { + player.setGliding(gliding); + } + + @Override + public boolean hasPermission(org.bukkit.command.CommandSender sender, String permission) { + return sender.hasPermission(permission); + } + + @Override + public boolean isArmorEquipAttempt(org.bukkit.event.Event event) { + if (!(event instanceof org.bukkit.event.inventory.InventoryClickEvent e)) { + return false; + } + + if (e.getSlotType() == org.bukkit.event.inventory.InventoryType.SlotType.ARMOR) { + return true; + } + + if (e.isShiftClick()) { + return isArmor(e.getCurrentItem()); + } + + if (e.getClick() == org.bukkit.event.inventory.ClickType.NUMBER_KEY + && e.getSlotType() == org.bukkit.event.inventory.InventoryType.SlotType.ARMOR + && e.getWhoClicked() instanceof org.bukkit.entity.Player player) { + return isArmor( + player.getInventory().getItem(e.getHotbarButton()) + ); + } + + return false; + } + + @Override + public ItemStack getEquippedItem(org.bukkit.event.Event event) { + if (event instanceof org.bukkit.event.inventory.InventoryClickEvent e) { + org.bukkit.event.inventory.InventoryType.SlotType slotType = e.getSlotType(); + + if (e.getClick() == org.bukkit.event.inventory.ClickType.NUMBER_KEY // hotbar key swap + && slotType == org.bukkit.event.inventory.InventoryType.SlotType.ARMOR + && e.getWhoClicked() instanceof org.bukkit.entity.Player player) { + return player.getInventory().getItem(e.getHotbarButton()); + } + + if (e.isShiftClick()) { + ItemStack current = e.getCurrentItem(); + if (isArmor(current)) return current; + } + + // regular click + if (slotType == org.bukkit.event.inventory.InventoryType.SlotType.ARMOR) { + ItemStack cursor = e.getCursor(); + if (isArmor(cursor)) return cursor; + } + } + + // Try Paper's PlayerArmorChangeEvent via reflection or just check if class exists + try { + if (event instanceof com.destroystokyo.paper.event.player.PlayerArmorChangeEvent e) { + return e.getNewItem(); + } + } catch (NoClassDefFoundError | Exception ignored) {} + + return null; + } + + @Override + public void sendMessage(CommandSender commandSender, String text) { + commandSender.sendMessage(text); + } + + @Override + public boolean hasItemMeta(ItemStack item) { + return item.getItemMeta() != null; + } + + @Override + public List getWorlds() { + return Bukkit.getWorlds(); + } + + @Override + public boolean hasEnchantment(ItemStack item, Map valuesmap) { + Map enchantments = item.getEnchantments(); + + for (Map.Entry ench : enchantments.entrySet()) { + String enchKey = ench.getKey().getKey().getKey(); + String enchLevel = ench.getValue().toString(); + + for (Map.Entry rule : valuesmap.entrySet()) { + if ( + DataShifter.safeMatches(rule.getKey(), enchKey) && + DataShifter.safeMatches(rule.getValue(), enchLevel) + ) { + return true; + } + } + } + return false; + } + + public boolean hasAnyEnchantment(ItemStack item) { + return !(item.getItemMeta().getEnchants().isEmpty()); + } + + @Override + public boolean isArmor(ItemStack item) { + if (item == null || item.getType().isAir()) { + return false; + } + + String name = item.getType().name(); + + return name.endsWith("_HELMET") + || name.endsWith("_CHESTPLATE") + || name.endsWith("_LEGGINGS") + || name.endsWith("_BOOTS") + || item.getType() == org.bukkit.Material.ELYTRA; + } +}