Refactor codebase to use LivingEntity, add SPAWN action and handler, add DataShifter.parseValueToStringList overload that iterates over a list of strings.

This commit is contained in:
天クマ 2026-05-20 15:38:45 -03:00
commit af6ac27960
21 changed files with 123 additions and 61 deletions

View file

@ -7,13 +7,22 @@ import java.util.Map;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class DataShifter { public class DataShifter {
public static boolean safeMatches(String expression, String against) { public static boolean safeMatches(String expression, String against) {
String cleanPattern = expression.trim(); String cleanPattern = expression.trim();
Pattern pattern = Pattern.compile(cleanPattern, Pattern.CASE_INSENSITIVE); Pattern pattern = Pattern.compile(cleanPattern, Pattern.CASE_INSENSITIVE);
return pattern.matcher(against).matches(); return pattern.matcher(against).matches();
} }
public static boolean safeMatches(List<String> expressions, String against) {
for (String s : expressions) {
if (DataShifter.safeMatches(s, against)) {
return true;
}
}
return false;
}
public static List<String> parseValueToStringList(List<Object> values) { public static List<String> parseValueToStringList(List<Object> values) {
List<String> result = new ArrayList<>(); List<String> result = new ArrayList<>();
for (Object o : values) { for (Object o : values) {

View file

@ -6,6 +6,7 @@ import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
@ -89,6 +90,10 @@ public class Events {
} }
} }
public static void onCreatureSpawnEvent(CreatureSpawnEvent event) {
event.setCancelled(!Validator.can(event.getEntity(), Action.SPAWN, event));
}
private static boolean isArmorEquipAttempt(InventoryClickEvent event) { private static boolean isArmorEquipAttempt(InventoryClickEvent event) {
if (event.getSlotType() == InventoryType.SlotType.ARMOR) { if (event.getSlotType() == InventoryType.SlotType.ARMOR) {
return true; return true;

View file

@ -3,6 +3,7 @@ package io.github.adrianvic.nemesiseye;
import io.github.adrianvic.nemesiseye.policy.Action; import io.github.adrianvic.nemesiseye.policy.Action;
import io.github.adrianvic.nemesiseye.policy.Policy; import io.github.adrianvic.nemesiseye.policy.Policy;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import java.util.ArrayList; import java.util.ArrayList;
@ -19,7 +20,7 @@ public class Validator {
return true; return true;
} }
public static boolean can(HumanEntity entity, Action action, Event event) { public static boolean can(LivingEntity entity, Action action, Event event) {
boolean restricted = false; boolean restricted = false;
boolean allowed = false; boolean allowed = false;
@ -41,7 +42,7 @@ public class Validator {
} }
public static List<Policy> getPoliciesForEntity(HumanEntity entity) { public static List<Policy> getPoliciesForEntity(LivingEntity entity) {
List<Policy> ps = Config.getInstance().getPolicies(); List<Policy> ps = Config.getInstance().getPolicies();
List<Policy> result = new ArrayList<>(); List<Policy> result = new ArrayList<>();

View file

@ -8,5 +8,6 @@ public enum Action {
EQUIP, EQUIP,
PLACE, PLACE,
USE_ENCHANTMENT, USE_ENCHANTMENT,
GLYDE GLYDE,
SPAWN
} }

View file

@ -1,8 +1,9 @@
package io.github.adrianvic.nemesiseye.policy; package io.github.adrianvic.nemesiseye.policy;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.Event; import org.bukkit.event.Event;
public interface NodeHandler { public interface NodeHandler {
boolean check(HumanEntity entity, PolicyNode node, Action action, Event event); boolean check(LivingEntity entity, PolicyNode node, Action action, Event event);
} }

View file

@ -9,13 +9,14 @@ public class NodeHandlers {
private static final Map<Action, NodeHandler> handlers = new HashMap<>(); private static final Map<Action, NodeHandler> handlers = new HashMap<>();
static { static {
handlers.put(Action.HIT, new useItem()); handlers.put(Action.HIT, new UseItem());
handlers.put(Action.PLACE, new bePlaced()); handlers.put(Action.PLACE, new BePlaced());
handlers.put(Action.INTERACT, new useItem()); handlers.put(Action.INTERACT, new UseItem());
handlers.put(Action.USE_ENCHANTMENT, new useEnchantment()); handlers.put(Action.USE_ENCHANTMENT, new UseEnchantment());
handlers.put(Action.GLYDE, new glyde()); handlers.put(Action.GLYDE, new Glyde());
handlers.put(Action.EQUIP, new equip()); handlers.put(Action.EQUIP, new Equip());
handlers.put(Action.BREAK, new useItem()); // TODO: implement place handler handlers.put(Action.SPAWN, new Spawn());
handlers.put(Action.BREAK, new UseItem()); // TODO: implement place handler
} }
public static NodeHandler get(Action type) { public static NodeHandler get(Action type) {

View file

@ -1,6 +1,7 @@
package io.github.adrianvic.nemesiseye.policy; package io.github.adrianvic.nemesiseye.policy;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import java.util.List; import java.util.List;
@ -9,7 +10,7 @@ public interface Policy {
String name(); String name();
List<PolicyNode> nodes(); List<PolicyNode> nodes();
boolean policyAllowList(); boolean policyAllowList();
boolean applies(HumanEntity entity); boolean applies(LivingEntity entity);
Effect effect(); Effect effect();
int weight(); int weight();
List<String> worlds(); List<String> worlds();
@ -18,7 +19,7 @@ public interface Policy {
nodes().add(node); nodes().add(node);
} }
default boolean matches(HumanEntity entity, Action action, Event event) { default boolean matches(LivingEntity entity, Action action, Event event) {
if (!worlds().contains(entity.getWorld().getName())) { if (!worlds().contains(entity.getWorld().getName())) {
return false; return false;
} }

View file

@ -2,6 +2,7 @@ package io.github.adrianvic.nemesiseye.policy;
import io.github.adrianvic.nemesiseye.DataShifter; import io.github.adrianvic.nemesiseye.DataShifter;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import java.util.ArrayList; import java.util.ArrayList;
@ -55,7 +56,7 @@ public record PolicyNode(List<Action> actions, List<Object> values) {
return handlers; return handlers;
} }
public boolean matches(HumanEntity entity, Action action, Event event) { public boolean matches(LivingEntity entity, Action action, Event event) {
if (!actions.contains(action)) { if (!actions.contains(action)) {
return false; return false;
} }

View file

@ -5,12 +5,13 @@ import io.github.adrianvic.nemesiseye.policy.Action;
import io.github.adrianvic.nemesiseye.policy.NodeHandler; import io.github.adrianvic.nemesiseye.policy.NodeHandler;
import io.github.adrianvic.nemesiseye.policy.PolicyNode; import io.github.adrianvic.nemesiseye.policy.PolicyNode;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockPlaceEvent;
public class bePlaced implements NodeHandler { public class BePlaced implements NodeHandler {
@Override @Override
public boolean check(HumanEntity entity, PolicyNode node, Action action, Event event) { public boolean check(LivingEntity entity, PolicyNode node, Action action, Event event) {
if (event instanceof BlockPlaceEvent bpe) { if (event instanceof BlockPlaceEvent bpe) {
String type = bpe.getBlock().getType().toString(); String type = bpe.getBlock().getType().toString();

View file

@ -6,6 +6,7 @@ import io.github.adrianvic.nemesiseye.policy.Action;
import io.github.adrianvic.nemesiseye.policy.NodeHandler; import io.github.adrianvic.nemesiseye.policy.NodeHandler;
import io.github.adrianvic.nemesiseye.policy.PolicyNode; import io.github.adrianvic.nemesiseye.policy.PolicyNode;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.ClickType;
@ -13,10 +14,10 @@ import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
public class equip implements NodeHandler { public class Equip implements NodeHandler {
@Override @Override
public boolean check(HumanEntity entity, PolicyNode node, Action action, Event event) { public boolean check(LivingEntity entity, PolicyNode node, Action action, Event event) {
ItemStack item = null; ItemStack item = null;
if (event instanceof PlayerArmorChangeEvent e) { if (event instanceof PlayerArmorChangeEvent e) {

View file

@ -4,11 +4,12 @@ import io.github.adrianvic.nemesiseye.policy.Action;
import io.github.adrianvic.nemesiseye.policy.NodeHandler; import io.github.adrianvic.nemesiseye.policy.NodeHandler;
import io.github.adrianvic.nemesiseye.policy.PolicyNode; import io.github.adrianvic.nemesiseye.policy.PolicyNode;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.Event; import org.bukkit.event.Event;
public class glyde implements NodeHandler { public class Glyde implements NodeHandler {
@Override @Override
public boolean check(HumanEntity entity, PolicyNode node, Action action, Event event) { public boolean check(LivingEntity entity, PolicyNode node, Action action, Event event) {
return true; return true;
} }
} }

View file

@ -0,0 +1,21 @@
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.LivingEntity;
import org.bukkit.event.Event;
import java.util.List;
public class Spawn implements NodeHandler {
@Override
public boolean check(LivingEntity entity, PolicyNode node, Action action, Event event) {
String type = entity.getType().name();
List<String> parsedValue = DataShifter.parseValueToStringList(node.values());
return DataShifter.safeMatches(parsedValue, type);
}
}

View file

@ -0,0 +1,33 @@
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;
import org.bukkit.entity.LivingEntity;
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(LivingEntity entity, PolicyNode node, Action action, Event event) {
if (entity instanceof HumanEntity e) {
ItemStack item = glim.getItemInMainHandHumanEntity(e);
if (!glim.hasItemMeta(item)) return false;
if (!glim.hasAnyEnchantment(item)) return false;
boolean matches = glim.hasEnchantment(item,
DataShifter.parseValueToStringMap(node.values()));
return matches;
}
return false;
}
}

View file

@ -7,21 +7,24 @@ import io.github.adrianvic.nemesiseye.policy.NodeHandler;
import io.github.adrianvic.nemesiseye.policy.PolicyNode; import io.github.adrianvic.nemesiseye.policy.PolicyNode;
import io.github.adrianvic.nemesiseye.reflection.Glimmer; import io.github.adrianvic.nemesiseye.reflection.Glimmer;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.Event; import org.bukkit.event.Event;
public class useItem implements NodeHandler { public class UseItem implements NodeHandler {
private final Glimmer glim = Nemesis.getInstance().getGlimmer(); private final Glimmer glim = Nemesis.getInstance().getGlimmer();
@Override @Override
public boolean check(HumanEntity entity, PolicyNode node, Action action, Event event) { public boolean check(LivingEntity entity, PolicyNode node, Action action, Event event) {
String type = glim.getItemInMainHandHumanEntity(entity).getType().toString(); if (entity instanceof HumanEntity e) {
String type = glim.getItemInMainHandHumanEntity(e).getType().toString();
for (String s : DataShifter.parseValueToStringList(node.values())) { for (String s : DataShifter.parseValueToStringList(node.values())) {
if (DataShifter.safeMatches(s, type)) { if (DataShifter.safeMatches(s, type)) {
return true; return true;
} }
} }
}
return false; return false;
} }

View file

@ -1,28 +0,0 @@
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;
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) {
ItemStack item = glim.getItemInMainHandHumanEntity(entity);
if (!glim.hasItemMeta(item)) return false;
if (!glim.hasAnyEnchantment(item)) return false;
boolean matches = glim.hasEnchantment(item,
DataShifter.parseValueToStringMap(node.values()));
return matches;
}
}

View file

@ -4,12 +4,13 @@ import io.github.adrianvic.nemesiseye.policy.Effect;
import io.github.adrianvic.nemesiseye.policy.Policy; import io.github.adrianvic.nemesiseye.policy.Policy;
import io.github.adrianvic.nemesiseye.policy.PolicyNode; import io.github.adrianvic.nemesiseye.policy.PolicyNode;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.LivingEntity;
import java.util.List; import java.util.List;
public record Core(String name, List<String> worlds, List<PolicyNode> nodes, boolean nodeAllowlist, boolean policyAllowList, Effect effect, int weight) implements Policy { public record Core(String name, List<String> worlds, List<PolicyNode> nodes, boolean nodeAllowlist, boolean policyAllowList, Effect effect, int weight) implements Policy {
@Override @Override
public boolean applies(HumanEntity entity) { public boolean applies(LivingEntity entity) {
return false; return false;
} }
} }

View file

@ -4,11 +4,12 @@ import io.github.adrianvic.nemesiseye.policy.Effect;
import io.github.adrianvic.nemesiseye.policy.Policy; import io.github.adrianvic.nemesiseye.policy.Policy;
import io.github.adrianvic.nemesiseye.policy.PolicyNode; import io.github.adrianvic.nemesiseye.policy.PolicyNode;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.LivingEntity;
import java.util.List; import java.util.List;
public record GlobalPolicy(String name, List<String> worlds, List<PolicyNode> nodes, boolean policyAllowList, Effect effect, int weight) implements Policy { public record GlobalPolicy(String name, List<String> worlds, List<PolicyNode> nodes, boolean policyAllowList, Effect effect, int weight) implements Policy {
public boolean applies(HumanEntity entity) { public boolean applies(LivingEntity entity) {
return true; return true;
} }
} }

View file

@ -5,12 +5,13 @@ import io.github.adrianvic.nemesiseye.policy.Policy;
import io.github.adrianvic.nemesiseye.policy.PolicyNode; import io.github.adrianvic.nemesiseye.policy.PolicyNode;
import io.github.adrianvic.nemesiseye.reflection.Glimmer; import io.github.adrianvic.nemesiseye.reflection.Glimmer;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.LivingEntity;
import java.util.List; import java.util.List;
public record LocationPolicy(String name, List<String> worlds, List<Glimmer.Box> locations, List<PolicyNode> nodes, boolean nodeAllowlist, boolean policyAllowList, Effect effect, int weight) implements Policy { public record LocationPolicy(String name, List<String> worlds, List<Glimmer.Box> locations, List<PolicyNode> nodes, boolean nodeAllowlist, boolean policyAllowList, Effect effect, int weight) implements Policy {
@Override @Override
public boolean applies(HumanEntity entity) { public boolean applies(LivingEntity entity) {
for (Glimmer.Box box : locations) { for (Glimmer.Box box : locations) {
if (box.contains(entity.getLocation().toVector(), entity.getWorld())) { if (box.contains(entity.getLocation().toVector(), entity.getWorld())) {
return !policyAllowList; return !policyAllowList;

View file

@ -4,13 +4,14 @@ import io.github.adrianvic.nemesiseye.policy.Effect;
import io.github.adrianvic.nemesiseye.policy.Policy; import io.github.adrianvic.nemesiseye.policy.Policy;
import io.github.adrianvic.nemesiseye.policy.PolicyNode; import io.github.adrianvic.nemesiseye.policy.PolicyNode;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.LivingEntity;
import java.util.List; import java.util.List;
public record PermissionPolicy(String name, List<String> worlds, List<String> permissions, List<PolicyNode> nodes, boolean policyAllowList, Effect effect, int weight) implements Policy { public record PermissionPolicy(String name, List<String> worlds, List<String> permissions, List<PolicyNode> nodes, boolean policyAllowList, Effect effect, int weight) implements Policy {
@Override @Override
public boolean applies(HumanEntity entity) { public boolean applies(LivingEntity entity) {
for (String perm : permissions) { for (String perm : permissions) {
if (entity.hasPermission(perm)) { if (entity.hasPermission(perm)) {
return true; return true;

View file

@ -4,13 +4,14 @@ import io.github.adrianvic.nemesiseye.policy.Effect;
import io.github.adrianvic.nemesiseye.policy.Policy; import io.github.adrianvic.nemesiseye.policy.Policy;
import io.github.adrianvic.nemesiseye.policy.PolicyNode; import io.github.adrianvic.nemesiseye.policy.PolicyNode;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.LivingEntity;
import java.util.List; import java.util.List;
public record PlayerNamePolicy(String name, List<String> worlds, List<String> playerName, List<PolicyNode> nodes, Effect effect, boolean policyAllowList, int weight) implements Policy { public record PlayerNamePolicy(String name, List<String> worlds, List<String> playerName, List<PolicyNode> nodes, Effect effect, boolean policyAllowList, int weight) implements Policy {
@Override @Override
public boolean applies(HumanEntity entity) { public boolean applies(LivingEntity entity) {
if (playerName.contains(entity.getName())) { if (playerName.contains(entity.getName())) {
return !policyAllowList(); return !policyAllowList();
} else { } else {

View file

@ -6,7 +6,9 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntitySpawnEvent;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerMoveEvent;
@ -37,4 +39,7 @@ public class EventListener implements Listener {
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onInventoryClickEvent(InventoryClickEvent event) { Events.onInventoryClickEvent(event); } public void onInventoryClickEvent(InventoryClickEvent event) { Events.onInventoryClickEvent(event); }
@EventHandler
public void onCreatureSpawnEvent(CreatureSpawnEvent event) { Events.onCreatureSpawnEvent(event); }
} }