diff --git a/.gitignore b/.gitignore index 1e3abdf..026e990 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,4 @@ build/ out/ .idea/ -libs/ -run/ +libs/ \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 488a93d..4aabc3c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -89,25 +89,6 @@ tasks.register("buildAll") { dependsOn(tasks.withType()) } -tasks.register("shadowJar") { - from(sourceSets["main"].output) - mcVersions.forEach { ver -> - from(sourceSets[ver].output) - } - - // This is kinda gross and, essentially, we shouldn't have it here... - duplicatesStrategy = DuplicatesStrategy.EXCLUDE - - archiveClassifier.set("all-implementations") - archiveVersion.set(project.version.toString()) - - manifest { - attributes( - "Implemented-Versions" to mcVersions.joinToString(",") - ) - } -} - /* ----------------------------------------- */ /* JAVA SETTINGS */ /* ----------------------------------------- */ @@ -122,18 +103,4 @@ tasks.withType { tasks.runServer { minecraftVersion("1.21") - downloadPlugins { - modrinth("viaversion", "5.7.0") - modrinth("luckperms", "v5.5.17-bukkit") - } -} - -tasks.register("runServerClean") { - doFirst { - exec { - commandLine("rm", "run/plugins/Eye-of-Nemesis/settings.yml") - } - } - - dependsOn("runServer") } \ No newline at end of file diff --git a/docs/Nodes.md b/docs/Nodes.md deleted file mode 100644 index 57cff1d..0000000 --- a/docs/Nodes.md +++ /dev/null @@ -1,34 +0,0 @@ -# Nodes -Nodes narrow down even further if an action can be done or not. A node needs _properties_ to know what it should check against, for example, a HIT node needs a _list_ of blocks that it will check if the player is holding; while a USE_ENCHANTMENT node needs a mapping of enchantment to level. Some nodes like glyde don't need a value and will ignore if you provide one. -```yaml -nodes: - - [HIT]: - values: - - 'GOLD_SWORD' - - [USE_ENCHANTMENT]: - values: - - "UNBREAKING": "1" - - [GLYDE] -``` - -## Available nodes -### INTERACT -Triggered on `InteractionEvent`, returns true when the provided `list` contains the material used to interact. - -### HIT -Triggered on `EntityDamageByEntityEvent`, returns true when the provided `list` contains the material used to hit. - -### PLACE -Triggered on `BlockPlaceEvent`, returns true when the provided `list` contains the material being placed. - -### BREAK -Triggered on `BlockBreakEvent`, returns true when the provided `list` contains the material used to break. - -### EQUIP -Triggered on `InventoryClickEvent` and `PlayerInteractEvent` (only if item is an armor), returns true when the provided `list` contains the material being equipped. - -### GLYDE -Triggered on `PlayerMoveEvent`, returns true if player is gliding. - -### USE_ENCHANTMENT -Triggered on `BlockBreakEvent` and `onEntityDamageByEntityEvent`, returns true the used item has an enchantment matching the provided mapping of enchantment-level. \ No newline at end of file diff --git a/docs/Policies.md b/docs/Policies.md deleted file mode 100644 index 21d468d..0000000 --- a/docs/Policies.md +++ /dev/null @@ -1,89 +0,0 @@ -# Policies -Policies are a list of nodes with a specific condition to be met, they also determine what effect a node is going to have. Below is an example policy: -```yaml - - name: "Allow example" - type: "location" - effect: ALLOW - weight: 1 - worlds: [world] - locations: - coordinates: - - corner1: { x: 2100, y: 256, z: 1400 } - corner2: { x: 1000, y: -64, z: 2200 } - nodes: - - [INTERACT, BREAK, HIT, PLACE]: - values: - - AIR -``` - -## Properties -### `name` -Name of the policy, must not contain spaces or else commands that require you to type the policy name will not work. - -Example: `name: "disable-axe-damage"` - -### `type` -One of the policy [types](#Types). - -Example: `type: location` - -### `effect` -Can be `deny` to block the action if a node check returns true, `ALLOW` to revert `DENY` effects if the node check is true or `ALLOWONLY` to allow the action **only** if the node check returns true. - -Example: `effect: DENY` - -### `weight` -A policy with greater weight will override a conflicting policy of lower weight. - -Example: `weight: 0` - -### `nodes` -Must contain a list of node mappings to evaluate if the policy applies to a player. - -Example: -```yaml -nodes: - - [HIT]: - values: - - '.*_AXE$' -``` - -### `locations` -Only used for `type: "location"`, is a list of mappings where corner1 and corner2 should map x, y and z to two corners of a rectangular area where the policy will take effect; `worlds` may be defined here. - -Example: - -```yaml -locations: - worlds: [world] - coordinates: - - corner1: { x: 2100, y: 256, z: 1400 } - corner2: { x: 1000, y: -64, z: 2200 } -``` - -### `permissions` -Only used for `type: "permission"`, is a list of permissions. - -Example: - -```yaml -permissions: - - "server.axehit" -``` - -### `names` -Only used for `type: "playerName"`, is a list of player names. - -## Types - -### `global` -Always matches. - -### `location` -Matches if the player location is inside any rectangle defined in the `locations` property. - -### `playerName` -Matches if the player name is in the `names` property. - -### `permission` -Matches if the player has a permission in the `permissions` property. diff --git a/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/BlockEventListener.java b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/BlockEventListener.java index 76fd2d1..bcad2f3 100644 --- a/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/BlockEventListener.java +++ b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/BlockEventListener.java @@ -3,7 +3,6 @@ package io.github.adrianvic.nemesiseye.impl; 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 @@ -11,8 +10,4 @@ public class BlockEventListener extends BlockListener { Events.onBlockBreak(event); } - @Override - public void onBlockPlace(BlockPlaceEvent event) { - Events.onBlockPlaceEvent(event); - } } diff --git a/src/b1_7_3/resources/plugin.yml b/src/b1_7_3/resources/plugin.yml new file mode 100644 index 0000000..bdb6b5a --- /dev/null +++ b/src/b1_7_3/resources/plugin.yml @@ -0,0 +1,17 @@ +name: "Eye-of-Nemesis" +version: ${version} +main: io.github.adrianvic.nemesiseye.Nemesis +author: 'Adrian Victor' +description: "Change what players can do based in custom criteria." +commands: + eye: + description: "Run /eye help to see all available commands." +permissions: + nemesiseye.reload: + default: op + nemesiseye.policy.list.all: + default: op + nemesiseye.policy.list.self: + default: true + nemesiseye.help: + default: true \ No newline at end of file diff --git a/src/b1_7_3/resources/settings.yml b/src/b1_7_3/resources/settings.yml new file mode 100644 index 0000000..09921c7 --- /dev/null +++ b/src/b1_7_3/resources/settings.yml @@ -0,0 +1,9 @@ +Policies: + # NO SPACES + - name: "Block-illegal-items" + type: global # global / location / permission / list of types + allowList: false # Will deny anything that's not allowed by the nodes if set to true + nodes: + - useItem: + value: + - SAND \ No newline at end of file diff --git a/src/b1_7_3/resources/version.properties b/src/b1_7_3/resources/version.properties new file mode 100644 index 0000000..5c6ec00 --- /dev/null +++ b/src/b1_7_3/resources/version.properties @@ -0,0 +1 @@ +impl.version=b1_7_3 \ No newline at end of file diff --git a/src/main/java/io/github/adrianvic/nemesiseye/Config.java b/src/main/java/io/github/adrianvic/nemesiseye/Config.java index 69ec351..52bc4dc 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/Config.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/Config.java @@ -1,28 +1,24 @@ package io.github.adrianvic.nemesiseye; import io.github.adrianvic.nemesiseye.policy.Policy; -import io.github.adrianvic.nemesiseye.policy.PolicyNode; -import io.github.adrianvic.nemesiseye.policy.policies.GlobalPolicy; import io.github.adrianvic.nemesiseye.reflection.Glimmer; import java.io.File; import java.util.ArrayList; -import java.util.Comparator; import java.util.List; public class Config { private static Config instance = new Config(); private final Glimmer glim = Nemesis.getInstance().getGlimmer(); private File file; + private List policies = new ArrayList<>(); private Config() {} public void load() { policies = glim.loadPoliciesFromFile(glim.loadConfigFile()); - policies.sort(Comparator.comparingInt(Policy::weight).reversed()); } - // TODO: Implement config saving // // public void save() { diff --git a/src/main/java/io/github/adrianvic/nemesiseye/DataShifter.java b/src/main/java/io/github/adrianvic/nemesiseye/DataShifter.java index ceb0e36..39331d6 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/DataShifter.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/DataShifter.java @@ -1,5 +1,8 @@ package io.github.adrianvic.nemesiseye; +import io.github.adrianvic.nemesiseye.reflection.Glimmer; +import org.bukkit.Location; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -41,14 +44,38 @@ public class DataShifter { return out; } - public static > T enumOrDefault(Class type, String string, T def) { - try { - return Enum.valueOf(type, string); - } catch (IllegalArgumentException e) { - return def; - } catch (Exception e) { - e.printStackTrace(); - return def; + public static List configLocationParser(Object rawLocations) { + Glimmer glim = Nemesis.getInstance().getGlimmer(); + + if (rawLocations == null) { + return List.of(); } + + // Parsing locations + List groups = rawLocations instanceof List ? (List) rawLocations : List.of(); + + ArrayList boxes = new ArrayList<>(groups.size()); + + // Now iterate over regions + for (Object rObj : groups) { + Map region = (Map) rObj; + Map c1 = (Map) region.get("corner1"); + Map c2 = (Map) region.get("corner2"); + + double x1 = ((Number) c1.get("x")).doubleValue(); + double y1 = ((Number) c1.get("y")).doubleValue(); + double z1 = ((Number) c1.get("z")).doubleValue(); + + double x2 = ((Number) c2.get("x")).doubleValue(); + double y2 = ((Number) c2.get("y")).doubleValue(); + double z2 = ((Number) c2.get("z")).doubleValue(); + + Location loc1 = new Location(glim.getWorlds().getFirst(), x1, y1, z1); + Location loc2 = new Location(glim.getWorlds().getFirst(), x2, y2, z2); + + boxes.add(Glimmer.Box.of(loc1, loc2)); + } + + return boxes; } } diff --git a/src/main/java/io/github/adrianvic/nemesiseye/Events.java b/src/main/java/io/github/adrianvic/nemesiseye/Events.java index 442bbdc..07f0ed2 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/Events.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/Events.java @@ -1,126 +1,25 @@ package io.github.adrianvic.nemesiseye; -import io.github.adrianvic.nemesiseye.policy.Action; -import org.bukkit.Material; import org.bukkit.entity.HumanEntity; import org.bukkit.entity.Player; import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerMoveEvent; -import org.bukkit.inventory.ItemStack; - -import java.util.List; public class Events { - public static void onBlockBreak(BlockBreakEvent event) { - event.setCancelled( - !Validator.can( - event.getPlayer(), - List.of(Action.BREAK, Action.USE_ENCHANTMENT), - event - ) - ); + event.setCancelled(!Validator.canBreak(event.getPlayer())); } public static void onInteractionEvent(PlayerInteractEvent event) { - ItemStack item = event.getItem(); - - if (item == null || item.getType().isAir()) { - return; + if (event.getItem() != null) { + event.setCancelled(!Validator.canInteract(event.getPlayer())); } - - // Right-click armor equipping - if (isArmor(item) - && !Validator.can(event.getPlayer(), Action.EQUIP, event)) { - event.setCancelled(true); - return; - } - - // Normal item interaction - event.setCancelled( - !Validator.can(event.getPlayer(), Action.INTERACT, event) - ); - } - - public static void onBlockPlaceEvent(BlockPlaceEvent event) { - event.setCancelled( - !Validator.can(event.getPlayer(), Action.PLACE, event) - ); } public static void onEntityDamageByEntityEvent(EntityDamageByEntityEvent event) { - if (event.getDamager() instanceof Player player) { - event.setCancelled( - !Validator.can( - player, - List.of(Action.HIT, Action.USE_ENCHANTMENT), - event - ) - ); + if (event.getDamager() instanceof Player) { + event.setCancelled(!Validator.canHit((HumanEntity) event.getDamager())); } } - - public static void onPlayerMoveEvent(PlayerMoveEvent event) { - if (event.getPlayer().isGliding() - && !Validator.can( - event.getPlayer(), - List.of(Action.GLYDE), - event - )) { - event.getPlayer().setGliding(false); - } - } - - public static void onInventoryClickEvent(InventoryClickEvent event) { - if (!isArmorEquipAttempt(event)) { - return; - } - - HumanEntity entity = event.getWhoClicked(); - - if (!Validator.can(entity, Action.EQUIP, event)) { - event.setCancelled(true); - } - } - - private static boolean isArmorEquipAttempt(InventoryClickEvent event) { - if (event.getSlotType() == InventoryType.SlotType.ARMOR) { - return true; - } - - if (event.isShiftClick()) { - return isArmor(event.getCurrentItem()); - } - - if (event.getClick() == ClickType.NUMBER_KEY - && event.getSlotType() == InventoryType.SlotType.ARMOR - && event.getWhoClicked() instanceof Player player) { - return isArmor( - player.getInventory().getItem(event.getHotbarButton()) - ); - } - - return false; - } - - private static boolean isArmor(ItemStack item) { - if (item == null || item.getType().isAir()) { - return false; - } - - Material type = item.getType(); - String name = type.name(); - - return name.endsWith("_HELMET") - || name.endsWith("_CHESTPLATE") - || name.endsWith("_LEGGINGS") - || name.endsWith("_BOOTS") - || type == Material.ELYTRA; - } -} \ No newline at end of file +} diff --git a/src/main/java/io/github/adrianvic/nemesiseye/Nemesis.java b/src/main/java/io/github/adrianvic/nemesiseye/Nemesis.java index 292a35c..d232213 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/Nemesis.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/Nemesis.java @@ -1,10 +1,13 @@ package io.github.adrianvic.nemesiseye; import io.github.adrianvic.nemesiseye.reflection.Glimmer; -import io.github.adrianvic.nemesiseye.reflection.VersionMatcher; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + public final class Nemesis extends JavaPlugin { private Glimmer glim; private static final String VERSION_PROP = "impl.version"; @@ -13,11 +16,44 @@ public final class Nemesis extends JavaPlugin { @Override public void onEnable() { instance = this; - glim = new VersionMatcher().loadGlim(); + glim = loadGlim(); glim.onLoad(); Config.getInstance().load(); } + private String readImplVersion() { + Properties props = new Properties(); + try (InputStream is = getClass().getClassLoader() + .getResourceAsStream("version.properties")) { + if (is == null) { + throw new IllegalStateException("version.properties not found on classpath."); + } + props.load(is); + } catch (IOException e) { + throw new IllegalStateException("Failed to load version.properties", e); + } + String version = props.getProperty(VERSION_PROP); + if (version == null || version.isBlank()) { + throw new IllegalStateException(VERSION_PROP + " property missing in version.properties."); + } + return version.trim(); + } + + private Glimmer loadGlim() { + String implVersion = readImplVersion(); + String className = "io.github.adrianvic.nemesiseye.impl." + implVersion; + + try { + Class clazz = Class.forName(className, true, getClass().getClassLoader()); + if (!Glimmer.class.isAssignableFrom(clazz)) { + throw new IllegalStateException(className + " does not implement Glimmer."); + } + return (Glimmer) clazz.getDeclaredConstructor().newInstance(); + } catch (ReflectiveOperationException e) { + throw new IllegalStateException("Failed to instantiate " + className, e); + } + } + @Override public void onDisable() { } @@ -25,4 +61,4 @@ public final class Nemesis extends JavaPlugin { public static Nemesis getInstance() { return instance; } public Glimmer getGlimmer() { return glim; } public PluginManager getPluginManager() { return this.getServer().getPluginManager(); } -} +} \ No newline at end of file diff --git a/src/main/java/io/github/adrianvic/nemesiseye/Validator.java b/src/main/java/io/github/adrianvic/nemesiseye/Validator.java index 9222de5..ade192d 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/Validator.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/Validator.java @@ -2,53 +2,56 @@ package io.github.adrianvic.nemesiseye; import io.github.adrianvic.nemesiseye.policy.Action; import io.github.adrianvic.nemesiseye.policy.Policy; +import io.github.adrianvic.nemesiseye.policy.PolicyNode; +import io.github.adrianvic.nemesiseye.reflection.Glimmer; import org.bukkit.entity.HumanEntity; -import org.bukkit.event.Event; import java.util.ArrayList; import java.util.List; public class Validator { - public static boolean can(HumanEntity entity, List actions, Event event) { - for (Action action : actions) { - if (!can(entity, action, event)) { - return false; - } - } + private final static Glimmer glim = Nemesis.getInstance().getGlimmer(); + public static boolean canInteract(HumanEntity entity) { + return checkAgainstEntity(entity, Action.INTERACT); + } + public static boolean canBreak(HumanEntity entity) { + return checkAgainstEntity(entity, Action.BREAK); + } + + public static boolean canHit(HumanEntity entity) { + return checkAgainstEntity(entity, Action.HIT); + } + + public static boolean checkAgainstEntity(HumanEntity entity, Action action) { + return checkAgainstNodes(entity, getNodesForPolicies(getPoliciesForEntity(entity)), action); + } + + public static boolean checkAgainstNodes(HumanEntity entity, List nodes, Action action) { + for (PolicyNode n : nodes) { + if (!checkAgainstNode(entity, n, action)) return false; + } return true; } - public static boolean can(HumanEntity entity, Action action, Event event) { - boolean restricted = false; - boolean allowed = false; - - for (Policy policy : getPoliciesForEntity(entity)) { - boolean matches = policy.matches(entity, action, event); - - switch (policy.effect()) { - case ALLOW: - if (matches) return true; - break; - - case DENY: - if (matches) return false; - break; - } - } - - return true; + public static boolean checkAgainstNode(HumanEntity entity, PolicyNode node, Action action) { + return node.getHandler().allows(entity, node, action); } + public static List getNodesForPolicies(List policies) { + List nodes = new ArrayList<>(); + for (Policy p : policies) { + nodes.addAll(p.nodes()); + } + return nodes; + } public static List getPoliciesForEntity(HumanEntity entity) { List ps = Config.getInstance().getPolicies(); List result = new ArrayList<>(); - for (Policy policy : ps) { if (policy.applies(entity)) result.add(policy); } - return result; } } diff --git a/src/main/java/io/github/adrianvic/nemesiseye/commands/EyeCore.java b/src/main/java/io/github/adrianvic/nemesiseye/commands/EyeCore.java index e6583db..31cbd82 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/commands/EyeCore.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/commands/EyeCore.java @@ -29,7 +29,7 @@ public class EyeCore { else if (commandSender.hasPermission(sub.permission())) { return sub.execute(commandSender, Arrays.copyOfRange(strings, 1, strings.length)); } else { - // Nemesis.getInstance().getLogger().info("does not have %s".formatted(sub.permission())); + Nemesis.getInstance().getLogger().info("does not have %s".formatted(sub.permission())); Commands.sendNoPermissionError(commandSender); return true; } diff --git a/src/main/java/io/github/adrianvic/nemesiseye/commands/sub/PolicyInfo.java b/src/main/java/io/github/adrianvic/nemesiseye/commands/sub/PolicyInfo.java index 3092088..ad48e02 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/commands/sub/PolicyInfo.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/commands/sub/PolicyInfo.java @@ -22,7 +22,8 @@ public class PolicyInfo implements Subcommand { Showing info for policy %s%s%s: Type: %s Nodes: %s - """, ChatColor.GREEN, policy.name(), ChatColor.WHITE, policy.getClass().getTypeName(), policy.nodes().size())); + %s + """, ChatColor.GREEN, policy.name(), ChatColor.WHITE, "location", policy.nodes().size(), policy.allowlist() ? "Is allowlist" : "Is blacklist")); } } return true; diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/Action.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/Action.java index b80f6a9..2bcd83e 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/Action.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/policy/Action.java @@ -4,9 +4,6 @@ public enum Action { INTERACT, BREAK, HIT, - // TODO CRAFT, - EQUIP, - PLACE, - USE_ENCHANTMENT, - GLYDE + CRAFT, + EQUIP } diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/Effect.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/Effect.java deleted file mode 100644 index 1f16500..0000000 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/Effect.java +++ /dev/null @@ -1,6 +0,0 @@ -package io.github.adrianvic.nemesiseye.policy; - -public enum Effect { - DENY, - ALLOW, -} diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/NodeHandler.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/NodeHandler.java index 31fa568..6e7edf3 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/NodeHandler.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/policy/NodeHandler.java @@ -1,8 +1,7 @@ package io.github.adrianvic.nemesiseye.policy; import org.bukkit.entity.HumanEntity; -import org.bukkit.event.Event; public interface NodeHandler { - boolean check(HumanEntity entity, PolicyNode node, Action action, Event event); + boolean allows(HumanEntity entity, PolicyNode node, Action action); } \ No newline at end of file diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/NodeHandlers.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/NodeHandlers.java index 465747e..5746e1c 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/NodeHandlers.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/policy/NodeHandlers.java @@ -1,24 +1,22 @@ package io.github.adrianvic.nemesiseye.policy; -import io.github.adrianvic.nemesiseye.policy.handlers.*; +import io.github.adrianvic.nemesiseye.policy.handlers.attackWith; +import io.github.adrianvic.nemesiseye.policy.handlers.useEnchantment; +import io.github.adrianvic.nemesiseye.policy.handlers.useItem; import java.util.HashMap; import java.util.Map; public class NodeHandlers { - private static final Map handlers = new HashMap<>(); + private static final Map handlers = new HashMap<>(); static { - handlers.put(Action.HIT, new useItem()); - handlers.put(Action.PLACE, new bePlaced()); - handlers.put(Action.INTERACT, new useItem()); - handlers.put(Action.USE_ENCHANTMENT, new useEnchantment()); - handlers.put(Action.GLYDE, new glyde()); - handlers.put(Action.EQUIP, new equip()); - handlers.put(Action.BREAK, new useItem()); // TODO: implement place handler + handlers.put("attackWithItemInHand", new attackWith()); + handlers.put("useItem", new useItem()); + handlers.put("useEnchantment", new useEnchantment()); } - public static NodeHandler get(Action type) { + public static NodeHandler get(String type) { return handlers.get(type); } } diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/Policy.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/Policy.java index 5992433..42b3382 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/Policy.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/policy/Policy.java @@ -1,34 +1,13 @@ package io.github.adrianvic.nemesiseye.policy; import org.bukkit.entity.HumanEntity; -import org.bukkit.event.Event; import java.util.List; public interface Policy { String name(); List nodes(); - boolean policyAllowList(); + boolean allowlist(); boolean applies(HumanEntity entity); - Effect effect(); - int weight(); - List worlds(); - default void addNode(PolicyNode node) { - nodes().add(node); - } - - default boolean matches(HumanEntity entity, Action action, Event event) { - if (!worlds().contains(entity.getWorld().getName())) { - return false; - } - - for (PolicyNode node : nodes()) { - if (node.matches(entity, action, event)) { - return true; - } - } - - return false; - } } diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/PolicyNode.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/PolicyNode.java index c87f916..2192821 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/PolicyNode.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/policy/PolicyNode.java @@ -1,72 +1,36 @@ package io.github.adrianvic.nemesiseye.policy; -import io.github.adrianvic.nemesiseye.DataShifter; -import org.bukkit.entity.HumanEntity; -import org.bukkit.event.Event; - import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; -public record PolicyNode(List actions, List values) { - public static List parseNodes(List> raw, Effect effect) { +public record PolicyNode(String type, List values, boolean isWhitelist) { + public static List parseNodes(List> raw, boolean isWhitelist) { List nodes = new ArrayList<>(); - for (Map m : raw) { - for (Map.Entry rawNode : m.entrySet()) { - List nodeActions = new ArrayList<>(); - List nodeValues = new ArrayList<>(); + for (Map m : raw) { + for (Map.Entry entry : m.entrySet()) { + String type = entry.getKey(); + List values = new ArrayList<>(); + Object val = entry.getValue(); - if (rawNode.getKey() instanceof List rawTypes && rawNode.getValue() instanceof Map rawNodeValues) { - for (Object rawType : rawTypes) { - if (rawType instanceof String rts && !rts.isEmpty() && !(rts == null) && DataShifter.enumOrDefault(Action.class, rts, null) != null) { - nodeActions.add(DataShifter.enumOrDefault(Action.class, rts, null)); - } - } - Map semiParsedNodeValue = new HashMap<>(); - for (Map.Entry rawNodeValueEntries : rawNodeValues.entrySet()) { - if (rawNodeValueEntries.getKey() instanceof String stringKey) { - semiParsedNodeValue.put(stringKey, rawNodeValueEntries.getValue()); - } + if (val instanceof Map valMap) { + if (valMap.get("values") instanceof String s) { + values.add(s); + } else if (valMap.get("values") instanceof List l) { + values.addAll(l); + } else if (valMap.get("values") instanceof Map map) { + values.add(map); } - if (semiParsedNodeValue.get("values") instanceof List l) { - for (Object v : l) { - nodeValues.add(v); - } - } - } - - if (!nodeActions.isEmpty() && !nodeValues.isEmpty()) { - PolicyNode newNode = new PolicyNode(nodeActions, nodeValues); - nodes.add(newNode); + nodes.add(new PolicyNode(type, values, isWhitelist)); } } } return nodes; } - public List getHandler() { - List handlers = new ArrayList<>(); - for (Action a : actions) { - handlers.add(NodeHandlers.get(a)); - } - return handlers; - } - - public boolean matches(HumanEntity entity, Action action, Event event) { - if (!actions.contains(action)) { - return false; - } - - NodeHandler handler = NodeHandlers.get(action); - - if (handler == null) { - return false; - } - - boolean result = handler.check(entity, this, action, event); - return result; + public NodeHandler getHandler() { + return NodeHandlers.get(type); } } \ No newline at end of file diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/PolicyParser.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/PolicyParser.java index 8050873..ecddd33 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/PolicyParser.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/policy/PolicyParser.java @@ -1,47 +1,7 @@ package io.github.adrianvic.nemesiseye.policy; -import io.github.adrianvic.nemesiseye.DataShifter; -import io.github.adrianvic.nemesiseye.policy.policies.Core; - -import java.util.ArrayList; -import java.util.List; import java.util.Map; public interface PolicyParser { - default Policy parse(Map raw) { - boolean policyAllowList = Boolean.TRUE.equals(raw.get("policyAllowList")); - boolean nodesAllowList = Boolean.TRUE.equals(raw.get("nodesAllowList")); - Effect effect = DataShifter.enumOrDefault(Effect.class, (String) raw.get("effect"), Effect.DENY); - String name = (String) raw.get("name"); - Integer weightObj = (Integer) raw.get("weight"); - int weight = weightObj != null ? weightObj : 0; - - // Worlds - List worlds = new ArrayList<>(); - if (raw.get("worlds") instanceof List list) { - for (Object object : list) { - if (object instanceof String result) { - worlds.add(result); - } - } - } else { - worlds.add("world"); - } - - // Nodes - Object rawNodes = raw.get("nodes"); - List> nodeList = new ArrayList<>(); - - if (rawNodes instanceof List list) { - for (Object o : list) { - if (o instanceof Map map) - nodeList.add((Map) map); - } - } - - List nodes = PolicyNode.parseNodes(nodeList, effect); - return parse(new Core(name, worlds, nodes, nodesAllowList, policyAllowList, effect, weight), raw); - } - - Policy parse(Core corePolicy, Map raw); + Policy parse(Map raw); } diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/PolicyParsers.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/PolicyParsers.java index 6a7c3b4..9f256af 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/PolicyParsers.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/policy/PolicyParsers.java @@ -2,8 +2,6 @@ package io.github.adrianvic.nemesiseye.policy; import io.github.adrianvic.nemesiseye.policy.parser.GlobalPolicyParser; import io.github.adrianvic.nemesiseye.policy.parser.LocationPolicyParser; -import io.github.adrianvic.nemesiseye.policy.parser.PermissionPolicyParser; -import io.github.adrianvic.nemesiseye.policy.parser.PlayerNamePolicyParser; import java.util.HashMap; import java.util.Map; @@ -14,8 +12,6 @@ public class PolicyParsers { static { handlers.put("location", new LocationPolicyParser()); handlers.put("global", new GlobalPolicyParser()); - handlers.put("playerName", new PlayerNamePolicyParser()); - handlers.put("permission", new PermissionPolicyParser()); } public static PolicyParser get(String type) { diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/handlers/attackWith.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/handlers/attackWith.java new file mode 100644 index 0000000..db54c09 --- /dev/null +++ b/src/main/java/io/github/adrianvic/nemesiseye/policy/handlers/attackWith.java @@ -0,0 +1,25 @@ +package io.github.adrianvic.nemesiseye.policy.handlers; + +import io.github.adrianvic.nemesiseye.DataShifter; +import io.github.adrianvic.nemesiseye.Nemesis; +import io.github.adrianvic.nemesiseye.policy.Action; +import io.github.adrianvic.nemesiseye.policy.NodeHandler; +import io.github.adrianvic.nemesiseye.policy.PolicyNode; +import io.github.adrianvic.nemesiseye.reflection.Glimmer; +import org.bukkit.entity.HumanEntity; + +public class attackWith implements NodeHandler { + + private final static Glimmer glim = Nemesis.getInstance().getGlimmer(); + + @Override + public boolean allows(HumanEntity entity, PolicyNode node, Action action) { + if (action == Action.HIT) { + for (String s : DataShifter.parseValueToStringList(node.values())) { + boolean matches = DataShifter.safeMatches(s, glim.getItemInMainHandHumanEntity(entity).getType().toString()); + if (matches) return node.isWhitelist(); + } + } + return true; + } +} diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/handlers/bePlaced.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/handlers/bePlaced.java deleted file mode 100644 index edf5d7c..0000000 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/handlers/bePlaced.java +++ /dev/null @@ -1,25 +0,0 @@ -package io.github.adrianvic.nemesiseye.policy.handlers; - -import io.github.adrianvic.nemesiseye.DataShifter; -import io.github.adrianvic.nemesiseye.policy.Action; -import io.github.adrianvic.nemesiseye.policy.NodeHandler; -import io.github.adrianvic.nemesiseye.policy.PolicyNode; -import org.bukkit.entity.HumanEntity; -import org.bukkit.event.Event; -import org.bukkit.event.block.BlockPlaceEvent; - -public class bePlaced implements NodeHandler { - @Override - public boolean check(HumanEntity entity, PolicyNode node, Action action, Event event) { - if (event instanceof BlockPlaceEvent bpe) { - String type = bpe.getBlock().getType().toString(); - - for (String s : DataShifter.parseValueToStringList(node.values())) { - if (DataShifter.safeMatches(s, type)) { - return true; - } - } - } - return false; - } -} diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/handlers/equip.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/handlers/equip.java deleted file mode 100644 index 88bb6b6..0000000 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/handlers/equip.java +++ /dev/null @@ -1,84 +0,0 @@ -package io.github.adrianvic.nemesiseye.policy.handlers; - -import com.destroystokyo.paper.event.player.PlayerArmorChangeEvent; -import io.github.adrianvic.nemesiseye.DataShifter; -import io.github.adrianvic.nemesiseye.policy.Action; -import io.github.adrianvic.nemesiseye.policy.NodeHandler; -import io.github.adrianvic.nemesiseye.policy.PolicyNode; -import org.bukkit.entity.HumanEntity; -import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryType; -import org.bukkit.inventory.ItemStack; - -public class equip implements NodeHandler { - - @Override - public boolean check(HumanEntity entity, PolicyNode node, Action action, Event event) { - ItemStack item = null; - - if (event instanceof PlayerArmorChangeEvent e) { - // Right click equip, dispenser equip, etc... - item = e.getNewItem(); - } - - else if (event instanceof InventoryClickEvent e) { - InventoryType.SlotType slotType = e.getSlotType(); - - // Number key swap into armor slot - if (e.getClick() == ClickType.NUMBER_KEY - && slotType == InventoryType.SlotType.ARMOR - && entity instanceof Player player) { - item = player.getInventory().getItem(e.getHotbarButton()); - } - - // Shift click armor from inventory - else if (e.isShiftClick()) { - ItemStack current = e.getCurrentItem(); - - if (isArmor(current)) { - item = current; - } - } - - // Cursor click onto armor slot - else if (slotType == InventoryType.SlotType.ARMOR) { - ItemStack cursor = e.getCursor(); - - if (isArmor(cursor)) { - item = cursor; - } - } - } - - if (!isArmor(item)) { - return false; - } - - String type = item.getType().name(); - - for (String s : DataShifter.parseValueToStringList(node.values())) { - if (DataShifter.safeMatches(s, type)) { - return true; - } - } - - return false; - } - - private 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; - } -} \ No newline at end of file diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/handlers/glyde.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/handlers/glyde.java deleted file mode 100644 index dcce855..0000000 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/handlers/glyde.java +++ /dev/null @@ -1,14 +0,0 @@ -package io.github.adrianvic.nemesiseye.policy.handlers; - -import io.github.adrianvic.nemesiseye.policy.Action; -import io.github.adrianvic.nemesiseye.policy.NodeHandler; -import io.github.adrianvic.nemesiseye.policy.PolicyNode; -import org.bukkit.entity.HumanEntity; -import org.bukkit.event.Event; - -public class glyde implements NodeHandler { - @Override - public boolean check(HumanEntity entity, PolicyNode node, Action action, Event event) { - return true; - } -} diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/handlers/useEnchantment.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/handlers/useEnchantment.java index 5fe3ae0..e34c28f 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/handlers/useEnchantment.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/policy/handlers/useEnchantment.java @@ -7,22 +7,21 @@ import io.github.adrianvic.nemesiseye.policy.NodeHandler; import io.github.adrianvic.nemesiseye.policy.PolicyNode; import io.github.adrianvic.nemesiseye.reflection.Glimmer; import org.bukkit.entity.HumanEntity; -import org.bukkit.event.Event; import org.bukkit.inventory.ItemStack; public class useEnchantment implements NodeHandler { private final Glimmer glim = Nemesis.getInstance().getGlimmer(); @Override - public boolean check(HumanEntity entity, PolicyNode node, Action action, Event event) { + public boolean allows(HumanEntity entity, PolicyNode node, Action action) { ItemStack item = glim.getItemInMainHandHumanEntity(entity); - if (!glim.hasItemMeta(item)) return false; - if (!glim.hasAnyEnchantment(item)) return false; + if (!glim.hasItemMeta(item)) return true; + if (!glim.hasAnyEnchantment(item)) return true; boolean matches = glim.hasEnchantment(item, DataShifter.parseValueToStringMap(node.values())); - return matches; + return matches ? node.isWhitelist() : !node.isWhitelist(); } } diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/handlers/useItem.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/handlers/useItem.java index 6009407..a28a700 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/handlers/useItem.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/policy/handlers/useItem.java @@ -7,22 +7,19 @@ import io.github.adrianvic.nemesiseye.policy.NodeHandler; import io.github.adrianvic.nemesiseye.policy.PolicyNode; import io.github.adrianvic.nemesiseye.reflection.Glimmer; import org.bukkit.entity.HumanEntity; -import org.bukkit.event.Event; public class useItem implements NodeHandler { private final Glimmer glim = Nemesis.getInstance().getGlimmer(); @Override - public boolean check(HumanEntity entity, PolicyNode node, Action action, Event event) { + public boolean allows(HumanEntity entity, PolicyNode node, Action action) { String type = glim.getItemInMainHandHumanEntity(entity).getType().toString(); for (String s : DataShifter.parseValueToStringList(node.values())) { - if (DataShifter.safeMatches(s, type)) { - return true; - } + boolean matches = DataShifter.safeMatches(s, type); + if (matches) return node.isWhitelist(); } - - return false; + return !node.isWhitelist(); } } diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/parser/GlobalPolicyParser.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/parser/GlobalPolicyParser.java index 8b993a6..8716f02 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/parser/GlobalPolicyParser.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/policy/parser/GlobalPolicyParser.java @@ -1,15 +1,32 @@ package io.github.adrianvic.nemesiseye.policy.parser; import io.github.adrianvic.nemesiseye.policy.Policy; +import io.github.adrianvic.nemesiseye.policy.PolicyNode; import io.github.adrianvic.nemesiseye.policy.PolicyParser; -import io.github.adrianvic.nemesiseye.policy.policies.Core; import io.github.adrianvic.nemesiseye.policy.policies.GlobalPolicy; +import java.util.ArrayList; +import java.util.List; import java.util.Map; public class GlobalPolicyParser implements PolicyParser { @Override - public Policy parse(Core corePolicy, Map raw) { - return new GlobalPolicy(corePolicy.name(), corePolicy.worlds(), corePolicy.nodes(), corePolicy.policyAllowList(), corePolicy.effect(), corePolicy.weight()); + public Policy parse(Map raw) { + boolean allowlist = (boolean) raw.get("allowList"); + String name = (String) raw.get("name"); + + // Nodes + Object rawNodes = raw.get("nodes"); + List> nodeList = new ArrayList<>(); + if (rawNodes instanceof List list) { + for (Object o : list) { + if (o instanceof Map map) + nodeList.add((Map) map); + } + } + + List nodes = PolicyNode.parseNodes(nodeList, allowlist); + + return new GlobalPolicy(name, nodes, allowlist); } } diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/parser/LocationPolicyParser.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/parser/LocationPolicyParser.java index 7a11077..cacf4e9 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/parser/LocationPolicyParser.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/policy/parser/LocationPolicyParser.java @@ -1,11 +1,10 @@ package io.github.adrianvic.nemesiseye.policy.parser; +import io.github.adrianvic.nemesiseye.DataShifter; import io.github.adrianvic.nemesiseye.Nemesis; import io.github.adrianvic.nemesiseye.policy.*; -import io.github.adrianvic.nemesiseye.policy.policies.Core; import io.github.adrianvic.nemesiseye.policy.policies.LocationPolicy; import io.github.adrianvic.nemesiseye.reflection.Glimmer; -import org.bukkit.Location; import java.util.ArrayList; import java.util.List; @@ -14,49 +13,24 @@ import java.util.Map; public class LocationPolicyParser implements PolicyParser { private Glimmer glim = Nemesis.getInstance().getGlimmer(); - public Policy parse(Core corePolicy, Map raw) { - Object rawLocations = raw.get("locations"); - Object rawCoordinates = null; - List worlds = new ArrayList<>(); - if (rawLocations instanceof Map rawLocationMap) { - rawCoordinates = rawLocationMap.get("coordinates"); + public Policy parse(Map raw) { + String name = (String) raw.get("name"); + boolean allowlist = Boolean.TRUE.equals(raw.get("allowList")); - if (rawLocationMap.get("worlds") instanceof List rawWorldsList) { - for (Object worldObject : rawWorldsList) { - if (worldObject instanceof String worldString) { - worlds.add(worldString); - } + // Nodes + Object rawNodes = raw.get("nodes"); + List> nodeList = new ArrayList<>(); + if (rawNodes instanceof List list) { + for (Object o : list) { + if (o instanceof Map map) + nodeList.add((Map) map); } - } else { - worlds.add("world"); } - } - List locations = new ArrayList<>(); + List nodes = PolicyNode.parseNodes(nodeList, allowlist); - // Parsing locations - List groups = rawCoordinates instanceof List ? (List) rawCoordinates : List.of(); + List locations = DataShifter.configLocationParser(raw.get("locations")); - // Now iterate over regions - for (Object rObj : groups) { - Map region = (Map) rObj; - Map c1 = (Map) region.get("corner1"); - Map c2 = (Map) region.get("corner2"); - - double x1 = ((Number) c1.get("x")).doubleValue(); - double y1 = ((Number) c1.get("y")).doubleValue(); - double z1 = ((Number) c1.get("z")).doubleValue(); - - double x2 = ((Number) c2.get("x")).doubleValue(); - double y2 = ((Number) c2.get("y")).doubleValue(); - double z2 = ((Number) c2.get("z")).doubleValue(); - - Location loc1 = new Location(glim.getWorlds().getFirst(), x1, y1, z1); - Location loc2 = new Location(glim.getWorlds().getFirst(), x2, y2, z2); - - locations.add(Glimmer.Box.of(loc1, loc2)); - } - - return new LocationPolicy(corePolicy.name(), corePolicy.worlds(), locations, corePolicy.nodes(), corePolicy.nodeAllowlist(), corePolicy.policyAllowList(), corePolicy.effect(), corePolicy.weight()); + return new LocationPolicy(name, locations, nodes, allowlist); } } diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/parser/PermissionPolicyParser.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/parser/PermissionPolicyParser.java deleted file mode 100644 index 491e5f7..0000000 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/parser/PermissionPolicyParser.java +++ /dev/null @@ -1,28 +0,0 @@ -package io.github.adrianvic.nemesiseye.policy.parser; - -import io.github.adrianvic.nemesiseye.policy.Policy; -import io.github.adrianvic.nemesiseye.policy.PolicyParser; -import io.github.adrianvic.nemesiseye.policy.policies.Core; -import io.github.adrianvic.nemesiseye.policy.policies.PermissionPolicy; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -public class PermissionPolicyParser implements PolicyParser { - @Override - public Policy parse(Core corePolicy, Map raw) { - Object rawPerms = raw.get("permissions"); - List permissions = new ArrayList<>(); - - if (rawPerms instanceof List list) { - for (Object o : list) { - if (o instanceof String s) { - permissions.add(s); - } - } - } - - return new PermissionPolicy(corePolicy.name(), corePolicy.worlds(), permissions, corePolicy.nodes(), corePolicy.policyAllowList(), corePolicy.effect(), corePolicy.weight()); - } -} diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/parser/PlayerNamePolicyParser.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/parser/PlayerNamePolicyParser.java deleted file mode 100644 index ae9f244..0000000 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/parser/PlayerNamePolicyParser.java +++ /dev/null @@ -1,28 +0,0 @@ -package io.github.adrianvic.nemesiseye.policy.parser; - -import io.github.adrianvic.nemesiseye.policy.Policy; -import io.github.adrianvic.nemesiseye.policy.PolicyParser; -import io.github.adrianvic.nemesiseye.policy.policies.Core; -import io.github.adrianvic.nemesiseye.policy.policies.PlayerNamePolicy; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -public class PlayerNamePolicyParser implements PolicyParser { - @Override - public Policy parse(Core corePolicy, Map raw) { - Object rawNames = raw.get("names"); - List names = new ArrayList<>(); - - if (rawNames instanceof List list) { - for (Object o : list) { - if (o instanceof String s) { - names.add(s); - } - } - } - - return new PlayerNamePolicy(corePolicy.name(), corePolicy.worlds(), names, corePolicy.nodes(), corePolicy.effect(), corePolicy.policyAllowList(), corePolicy.weight()); - } -} diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/policies/Core.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/policies/Core.java deleted file mode 100644 index 8476fda..0000000 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/policies/Core.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.github.adrianvic.nemesiseye.policy.policies; - -import io.github.adrianvic.nemesiseye.policy.Effect; -import io.github.adrianvic.nemesiseye.policy.Policy; -import io.github.adrianvic.nemesiseye.policy.PolicyNode; -import org.bukkit.entity.HumanEntity; - -import java.util.List; - -public record Core(String name, List worlds, List nodes, boolean nodeAllowlist, boolean policyAllowList, Effect effect, int weight) implements Policy { - @Override - public boolean applies(HumanEntity entity) { - return false; - } -} \ No newline at end of file diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/policies/GlobalPolicy.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/policies/GlobalPolicy.java index 7080ea8..c9797a0 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/policies/GlobalPolicy.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/policy/policies/GlobalPolicy.java @@ -1,13 +1,12 @@ package io.github.adrianvic.nemesiseye.policy.policies; -import io.github.adrianvic.nemesiseye.policy.Effect; import io.github.adrianvic.nemesiseye.policy.Policy; import io.github.adrianvic.nemesiseye.policy.PolicyNode; import org.bukkit.entity.HumanEntity; import java.util.List; -public record GlobalPolicy(String name, List worlds, List nodes, boolean policyAllowList, Effect effect, int weight) implements Policy { +public record GlobalPolicy(String name, List nodes, boolean allowlist) implements Policy { public boolean applies(HumanEntity entity) { return true; } diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/policies/LocationPolicy.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/policies/LocationPolicy.java index 5765535..8e63cf6 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/policies/LocationPolicy.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/policy/policies/LocationPolicy.java @@ -1,6 +1,5 @@ package io.github.adrianvic.nemesiseye.policy.policies; -import io.github.adrianvic.nemesiseye.policy.Effect; import io.github.adrianvic.nemesiseye.policy.Policy; import io.github.adrianvic.nemesiseye.policy.PolicyNode; import io.github.adrianvic.nemesiseye.reflection.Glimmer; @@ -8,14 +7,12 @@ import org.bukkit.entity.HumanEntity; import java.util.List; -public record LocationPolicy(String name, List worlds, List locations, List nodes, boolean nodeAllowlist, boolean policyAllowList, Effect effect, int weight) implements Policy { +public record LocationPolicy(String name, List locations, List nodes, boolean allowlist) implements Policy { @Override public boolean applies(HumanEntity entity) { for (Glimmer.Box box : locations) { - if (box.contains(entity.getLocation().toVector(), entity.getWorld())) { - return !policyAllowList; - } + if (box.contains(entity.getLocation().toVector())) return true; } - return policyAllowList; + return false; } } \ No newline at end of file diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/policies/PermissionPolicy.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/policies/PermissionPolicy.java index 1c952ac..b1c63dc 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/policies/PermissionPolicy.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/policy/policies/PermissionPolicy.java @@ -1,22 +1,8 @@ package io.github.adrianvic.nemesiseye.policy.policies; -import io.github.adrianvic.nemesiseye.policy.Effect; -import io.github.adrianvic.nemesiseye.policy.Policy; import io.github.adrianvic.nemesiseye.policy.PolicyNode; -import org.bukkit.entity.HumanEntity; +import org.bukkit.permissions.Permission; -import java.util.List; +import java.util.ArrayList; -public record PermissionPolicy(String name, List worlds, List permissions, List nodes, boolean policyAllowList, Effect effect, int weight) implements Policy { - - @Override - public boolean applies(HumanEntity entity) { - for (String perm : permissions) { - if (entity.hasPermission(perm)) { - return true; - } - } - - return false; - } -} +public record PermissionPolicy(String name, ArrayList permissions, PolicyNode nodes, boolean allowlist) {} diff --git a/src/main/java/io/github/adrianvic/nemesiseye/policy/policies/PlayerNamePolicy.java b/src/main/java/io/github/adrianvic/nemesiseye/policy/policies/PlayerNamePolicy.java index 8eeae4b..2a1a821 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/policies/PlayerNamePolicy.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/policy/policies/PlayerNamePolicy.java @@ -1,20 +1,7 @@ package io.github.adrianvic.nemesiseye.policy.policies; -import io.github.adrianvic.nemesiseye.policy.Effect; -import io.github.adrianvic.nemesiseye.policy.Policy; import io.github.adrianvic.nemesiseye.policy.PolicyNode; -import org.bukkit.entity.HumanEntity; -import java.util.List; +import java.util.ArrayList; -public record PlayerNamePolicy(String name, List worlds, List playerName, List nodes, Effect effect, boolean policyAllowList, int weight) implements Policy { - - @Override - public boolean applies(HumanEntity entity) { - if (playerName.contains(entity.getName())) { - return !policyAllowList(); - } else { - return policyAllowList(); - } - } -} \ No newline at end of file +public record PlayerNamePolicy(String name, ArrayList playerName, PolicyNode nodes, boolean allowlist) {} \ No newline at end of file diff --git a/src/main/java/io/github/adrianvic/nemesiseye/reflection/Glimmer.java b/src/main/java/io/github/adrianvic/nemesiseye/reflection/Glimmer.java index dec3092..ec5aa5d 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/reflection/Glimmer.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/reflection/Glimmer.java @@ -11,7 +11,6 @@ import org.bukkit.util.Vector; import java.io.File; import java.util.List; import java.util.Map; -import java.util.Objects; public interface Glimmer { void onLoad(); @@ -33,16 +32,14 @@ public interface Glimmer { class Box { public final double x1, y1, z1, x2, y2, z2; - public final String world; - public Box(String world, double x1, double y1, double z1, double x2, double y2, double z2) { + public Box(double x1, double y1, double z1, double x2, double y2, double z2) { this.x1 = Math.min(x1, x2); this.y1 = Math.min(y1, y2); this.z1 = Math.min(z1, z2); this.x2 = Math.max(x1, x2); this.y2 = Math.max(y1, y2); this.z2 = Math.max(z1, z2); - this.world = world; } public boolean contains(double x, double y, double z) { @@ -50,22 +47,13 @@ public interface Glimmer { && y >= y1 && y <= y2 && z >= z1 && z <= z2; } - public boolean contains(Vector v) { return v.getX() >= x1 && v.getX() <= x2 && v.getY() >= y1 && v.getY() <= y2 && v.getZ() >= z1 && v.getZ() <= z2; } - public boolean contains(Vector v, String w) { - return (Objects.equals(w, world)) && contains(v); - } - - public boolean contains(Vector v, World w) { - return contains(v, w.getName()); - } - - public static Box of(Location loc1, Location loc2) { return new Box(loc1.getWorld().getName(), loc1.getX(), loc1.getY(), loc1.getZ(), loc2.getX(), loc2.getY(), loc2.getZ()); } + public static Box of(Location loc1, Location loc2) { return new Box(loc1.getX(), loc1.getY(), loc1.getZ(), loc2.getX(), loc2.getY(), loc2.getZ()); } } } diff --git a/src/main/java/io/github/adrianvic/nemesiseye/reflection/VersionMatcher.java b/src/main/java/io/github/adrianvic/nemesiseye/reflection/VersionMatcher.java deleted file mode 100644 index 7852cd5..0000000 --- a/src/main/java/io/github/adrianvic/nemesiseye/reflection/VersionMatcher.java +++ /dev/null @@ -1,158 +0,0 @@ -package io.github.adrianvic.nemesiseye.reflection; - -import io.github.adrianvic.nemesiseye.DataShifter; -import org.bukkit.Bukkit; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class VersionMatcher { - - public VersionMatcher() {} - - private record Entry(String pattern, String classSuffix) {} - - public String getVersion(String type, String serverVersion) { - if (type == null || serverVersion == null) { - return ""; - } - - Map> map = populateMap(); - List entries = map.get(type.toLowerCase()); - if (entries == null || entries.isEmpty()) { - return ""; - } - - for (Entry e : entries) { - if (DataShifter.safeMatches(e.pattern, serverVersion)) { - return e.pattern + "|" + e.classSuffix; - } - } - - List sorted = new ArrayList<>(entries); - Collections.sort(sorted, (a, b) -> compareVersions(a.pattern, b.pattern)); - - Entry oldest = sorted.get(0); - Entry newest = sorted.get(sorted.size() - 1); - - int cmpOldest = compareVersions(serverVersion, oldest.pattern); - int cmpNewest = compareVersions(serverVersion, newest.pattern); - - if (cmpOldest < 0) { - return oldest.pattern + "|" + oldest.classSuffix; - } else if (cmpNewest > 0) { - return newest.pattern + "|" + newest.classSuffix; - } - - // should not happen because we already tried all patterns - return newest.pattern + "|" + newest.classSuffix; - } - - private Map> populateMap() { - Map> map = new HashMap<>(); - - // RELEASE patterns, newest first (order does not matter for matching) - map.put("release", List.of( - new Entry("^1\\.21\\..*$", "r1_21") - )); - - // BETA patterns - map.put("beta", List.of( - new Entry("^1\\.7\\.3$", "b1_7_3") - )); - - return map; - } - - private int compareVersions(String v1, String v2) { - String clean1 = v1.replaceAll("[^0-9.]", ""); - String clean2 = v2.replaceAll("[^0-9.]", ""); - - String[] a1 = clean1.split("\\."); - String[] a2 = clean2.split("\\."); - - int len = Math.max(a1.length, a2.length); - for (int i = 0; i < len; i++) { - int n1 = i < a1.length ? parseInt(a1[i]) : 0; - int n2 = i < a2.length ? parseInt(a2[i]) : 0; - if (n1 != n2) { - return n1 - n2; - } - } - return 0; - } - - private int parseInt(String s) { - try { - return Integer.parseInt(s); - } catch (NumberFormatException e) { - return 0; - } - } - - public Glimmer loadGlim() { - String rawVersion; - try { - rawVersion = Bukkit.getMinecraftVersion(); // returns something like "1.21.10" - } catch (NoSuchMethodError e) { - return betaLoadGlim(); - } - - String matchInfo = getVersion("release", rawVersion); - if (matchInfo.isEmpty()) { - // TODO: Should change to something more robust, it's not beta since we have Bukkit.getMinecraftVersion() - return betaLoadGlim(); - } - - // split the returned string: "pattern|classSuffix" - String[] partsInfo = matchInfo.split("\\|"); - String classSuffix = partsInfo[1]; // e.g. "r1_21" - - String[] versionParts = rawVersion.split("\\."); - int major = parseInt(versionParts[0]); - int minor = parseInt(versionParts[1]); - int patch = versionParts.length > 2 ? parseInt(versionParts[2]) : 0; - - while (true) { - String className = "io.github.adrianvic.nemesiseye.impl." + classSuffix; - Glimmer glimmer = tryInstantiate(className); - if (glimmer != null) return glimmer; - - if (patch > 0) { - patch--; - continue; - } - if (minor > 0) { - minor--; - patch = 20; - continue; - } - className = "io.github.adrianvic.nemesiseye.impl.r" + major + "_" + minor; - glimmer = tryInstantiate(className); - if (glimmer != null) return glimmer; - - throw new IllegalStateException( - "No suitable implementation found for version " + rawVersion); - } - } - - private Glimmer betaLoadGlim() { - // Bukkit.getVersion() // returns something like "1.1.10 (MC: 1.7.3)" WEIRD - return tryInstantiate("io.github.adrianvic.nemesiseye.impl.b1_7_3"); // only supported beta version for now - } - - private Glimmer tryInstantiate(String className) { - try { - Class clazz = Class.forName(className, true, getClass().getClassLoader()); - if (!Glimmer.class.isAssignableFrom(clazz)) { - return null; - } - return (Glimmer) clazz.getDeclaredConstructor().newInstance(); - } catch (ReflectiveOperationException ignored) { - return null; - } - } -} \ No newline at end of file diff --git a/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/EventListener.java b/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/EventListener.java index f7bf288..d1afe2d 100644 --- a/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/EventListener.java +++ b/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/EventListener.java @@ -2,14 +2,10 @@ package io.github.adrianvic.nemesiseye.impl; 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.BlockPlaceEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerMoveEvent; public class EventListener implements Listener { @EventHandler @@ -26,15 +22,4 @@ public class EventListener implements Listener { 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);} -} \ No newline at end of file +} diff --git a/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/r1_21.java b/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/r1_21.java index b929d0b..3cdd6fd 100644 --- a/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/r1_21.java +++ b/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/r1_21.java @@ -1,6 +1,5 @@ package io.github.adrianvic.nemesiseye.impl; -import io.github.adrianvic.nemesiseye.DataShifter; import io.github.adrianvic.nemesiseye.Nemesis; import io.github.adrianvic.nemesiseye.impl.commands.Eye; import io.github.adrianvic.nemesiseye.policy.Policy; @@ -84,17 +83,10 @@ public class r1_21 implements Glimmer { @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) - ) { + Map enchantmentList = item.getEnchantments(); + for (Map.Entry enchantmentEntry : enchantmentList.entrySet()) { + for (Map.Entry valueEntry : valuesmap.entrySet()) { + if (enchantmentEntry.getKey().getKey().getKey().equals(valueEntry.getKey()) && enchantmentEntry.getValue().toString().equals(valueEntry.getValue())) { return true; } } diff --git a/src/main/resources/plugin.yml b/src/r1_21/resources/plugin.yml similarity index 96% rename from src/main/resources/plugin.yml rename to src/r1_21/resources/plugin.yml index e9273aa..07679ff 100644 --- a/src/main/resources/plugin.yml +++ b/src/r1_21/resources/plugin.yml @@ -1,7 +1,7 @@ name: "Eye-of-Nemesis" version: ${version} main: io.github.adrianvic.nemesiseye.Nemesis -api-version: '1.13' +api-version: '1.21' author: 'Adrian Victor' website: "https://github.io/adrianvic/NemesisEye" description: "Change what players can do based in custom criteria." diff --git a/src/main/resources/settings.yml b/src/r1_21/resources/settings.yml similarity index 59% rename from src/main/resources/settings.yml rename to src/r1_21/resources/settings.yml index a94dd2f..0336fb6 100644 --- a/src/main/resources/settings.yml +++ b/src/r1_21/resources/settings.yml @@ -1,65 +1,13 @@ -# __ _______ __ ___________________ _______ -# / / \ _ \ \ \ \_ _____/\_____ \ \ \ -# / / / /_\ \ \ \ | __)_ / | \ / | \ -# \ \ \ \_/ \ / / | \/ | \/ | \ -# \_\ \_____ / /_/ /_______ /\_______ /\____|__ / -# \/ \/ \/ \/ -# EYE OF NEMESIS - Example config file. -# Documentation in our wiki: https://github.com/adrianvic/NemesisEye - Policies: - - name: "Bedrock-allow-admins" - type: "permission" - worlds: [world] - effect: ALLOW - weight: 3 - permissions: - - "server.usebedrock" - nodes: - - [BREAK, PLACE, HIT, INTERACT]: - values: - - BEDROCK - - - name: "Bedrock-deny" - type: "global" - worlds: [world] - effect: DENY - weight: 2 - nodes: - - [BREAK, PLACE, HIT, INTERACT]: - values: - - BEDROCK - - - name: "Block-non-beta-items" # No spaces here or else commands which need the name as argument will not work - type: "location" # global | location | permission | playerName - effect: DENY # DENY | ALLOW (overrides deny) | ALLOWONLY (allow only if met) - worlds: [world] - weight: 0 # Greater weight overrides lower - policyAllowList: false # Inverts the policy validation logic, for example a location policy will affect all players NOT inside it's location - locations: - worlds: [world] - coordinates: - - corner1: { x: 2100, y: 256, z: 1400 } - corner2: { x: 1000, y: -64, z: 2200 } - nodes: - - [INTERACT, BREAK, HIT, PLACE]: - values: - - '.*' - - [USE_ENCHANTMENT]: - values: - - ".*": ".*" - - - name: "Allow-beta-items" + # NO SPACES + - name: "Beta-1.7.3-items-only" type: "location" - effect: ALLOW - weight: 1 - worlds: [world] + allowList: true # Will deny anything that's not allowed by the nodes if set to true locations: - coordinates: - - corner1: { x: 2100, y: 256, z: 1400 } - corner2: { x: 1000, y: -64, z: 2200 } + - corner1: { x: 2100, y: 256, z: 1400 } + corner2: { x: 1000, y: -64, z: 2200 } nodes: - - [INTERACT, BREAK, HIT, PLACE]: + - useItem: values: - AIR - STONE @@ -77,7 +25,7 @@ Policies: - COBWEB - PISTON - STICKY_PISTON - - GRASS_BLOCK + - GRASS - DISPENSER - NOTE_BLOCK - SANDSTONE @@ -89,7 +37,7 @@ Policies: - POPPY - DANDELION - "^(RED|BROWN)_MUSHROOM$" - - "^(OAK|COBBLESTONE|SMOOTH_STONE)_SLAB$" + - "^(OAK|COBBLESTONE)_SLAB$" - BRICK_BLOCK - TNT - BOOKSHELF @@ -158,7 +106,7 @@ Policies: - FISHING_ROD - CLOCK - GLOWSTONE_DUST - - INK_SAC + - INK_SACw - BONE_MEAL - SUGAR - COOKIE @@ -168,4 +116,6 @@ Policies: - MUSIC_DISK_CAT - MUSIC_DISK_13 - DIRT - - BREAD \ No newline at end of file + - BREAD + - useEnchantment: + "flying bananas": "0" \ No newline at end of file diff --git a/src/r1_21/resources/version.properties b/src/r1_21/resources/version.properties new file mode 100644 index 0000000..89241bf --- /dev/null +++ b/src/r1_21/resources/version.properties @@ -0,0 +1 @@ +impl.version=r1_21 \ No newline at end of file