Finished r1_21 implementation.

- Better NodeHandler evaluation.
This commit is contained in:
天クマ 2025-12-12 17:31:28 -03:00
commit 90d43ac3de
20 changed files with 326 additions and 148 deletions

View file

@ -1,62 +1,38 @@
package io.github.adrianvic.nemesiseye;
import io.github.adrianvic.nemesiseye.policy.Policy;
import io.github.adrianvic.nemesiseye.policy.PolicyParsers;
import org.bukkit.configuration.file.YamlConfiguration;
import io.github.adrianvic.nemesiseye.reflection.Glimmer;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class Config {
private final static Config instance = new Config();
private static Config instance = new Config();
private Glimmer glim = Nemesis.getInstance().getGlimmer();
private File file;
private YamlConfiguration config;
private List<Policy> policies = new ArrayList<>();
private Config() {
}
private Config() {}
public void load() {
file = new File(Nemesis.getInstance().getDataFolder(), "settings.yml");
if (!file.exists())
Nemesis.getInstance().saveResource("settings.yml", false);
config = new YamlConfiguration();
config.options().parseComments(true);
try {
config.load(file);
} catch (Exception e) {
e.printStackTrace();
}
List<Map<?, ?>> rawPolicies = config.getMapList("Policies");
for (Map<?, ?> map : rawPolicies) {
for (Map.Entry<?, ?> entry : map.entrySet()) {
if (entry.getKey() instanceof String k && entry.getValue() instanceof List<?> v) {
List<Policy> parsed = PolicyParsers.get(k).parse(v);
policies.addAll(parsed);
}
}
}
List<Policy> newPolicies = glim.loadPoliciesFromFile(glim.loadConfigFile());
policies = newPolicies;
}
public void save() {
try {
config.save(file);
} catch (Exception e) {
e.printStackTrace();
}
}
public void set(String path, Object value) {
config.set(path, value);
save();
}
// public void save() {
// try {
// config.save(file);
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
//
// public void set(String path, Object value) {
// config.set(path, value);
// save();
// }
public List<Policy> getPolicies() {
return policies;

View file

@ -21,19 +21,23 @@ public class DataShifter {
return result;
}
public static Map<String, String> parseValueToStringMap(List<Object> values) {
Map<String, String> result = new HashMap<>();
public static Map<String,String> parseValueToStringMap(List<Object> raw) {
Map<String,String> out = new HashMap<>();
for (Object o : values) {
if (o instanceof Map<?, ?> raw) {
for (Map.Entry<?, ?> e : raw.entrySet()) {
if (e.getKey() instanceof String k && e.getValue() instanceof String v) {
result.put(k, v);
}
for (Object o : raw) {
if (o instanceof Map<?,?> map) {
for (Map.Entry<?,?> e : map.entrySet()) {
out.put(String.valueOf(e.getKey()), String.valueOf(e.getValue()));
}
} else if (o instanceof String s) {
String[] parts = s.split(":", 2);
if (parts.length == 2) {
out.put(parts[0].trim(), parts[1].trim());
}
}
}
return result;
return out;
}
public static List<Map<?, ?>> parseValueToListOfMaps(List<?> values) {

View file

@ -2,27 +2,22 @@ package io.github.adrianvic.nemesiseye;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
public class EventListener implements Listener {
@EventHandler
public void onBlockBreak(BlockBreakEvent event) {
public class Events {
public static void onBlockBreak(BlockBreakEvent event) {
event.setCancelled(!Validator.canBreak(event.getPlayer()));
}
@EventHandler
public void onInteractionEvent(PlayerInteractEvent event) {
public static void onInteractionEvent(PlayerInteractEvent event) {
if (event.getItem() != null) {
event.setCancelled(!Validator.canInteract(event.getPlayer()));
}
}
@EventHandler
public void onEntityDamageByEntityEvent(EntityDamageByEntityEvent event) {
public static void onEntityDamageByEntityEvent(EntityDamageByEntityEvent event) {
if (event.getDamager() instanceof Player) {
event.setCancelled(!Validator.canHit((HumanEntity) event.getDamager()));
}

View file

@ -1,7 +1,8 @@
package io.github.adrianvic.nemesiseye;
import io.github.adrianvic.nemesiseye.commands.Eye;
import io.github.adrianvic.nemesiseye.commands.EyeCore;
import io.github.adrianvic.nemesiseye.reflection.Glimmer;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.IOException;
@ -17,9 +18,8 @@ public final class Nemesis extends JavaPlugin {
public void onEnable() {
instance = this;
glim = loadGlim();
getServer().getPluginManager().registerEvents(new EventListener(), this);
Config.getInstance().load();
getCommand("eye").setExecutor(new Eye());
glim.onLoad();
}
private String readImplVersion() {
@ -59,9 +59,7 @@ public final class Nemesis extends JavaPlugin {
public void onDisable() {
}
public static Nemesis getInstance() {
return instance;
}
public static Nemesis getInstance() { return instance; }
public Glimmer getGlimmer() { return glim; }
public PluginManager getPluginManager() { return this.getServer().getPluginManager(); }
}

View file

@ -1,16 +1,17 @@
package io.github.adrianvic.nemesiseye;
import io.github.adrianvic.nemesiseye.policy.Action;
import io.github.adrianvic.nemesiseye.policy.policies.LocationPolicy;
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.util.BoundingBox;
import java.util.ArrayList;
import java.util.List;
public class Validator {
private final static Glimmer glim = Nemesis.getInstance().getGlimmer();
public static boolean canInteract(HumanEntity entity) {
return checkAgainstEntity(entity, Action.INTERACT);
}
@ -30,13 +31,11 @@ public class Validator {
for (PolicyNode n : nodes) {
if (!checkAgainstNode(entity, n, action)) return false;
}
return true;
}
public static boolean checkAgainstNode(HumanEntity entity, PolicyNode node, Action action) {
boolean allowed = node.getHandler().allows(entity, node, action);
return node.isWhitelist() != allowed;
return node.getHandler().allows(entity, node, action);
}
public static List<PolicyNode> getNodesForPolicies(List<Policy> policies) {
@ -49,18 +48,6 @@ public class Validator {
public static List<Policy> getPoliciesForEntity(HumanEntity entity) {
List<Policy> ps = Config.getInstance().getPolicies();
List<Policy> applyingLPS = new ArrayList<>();
for (Policy p : ps) {
if (p instanceof LocationPolicy lp) {
for (ArrayList<BoundingBox> boxes : lp.locations()) {
for (BoundingBox box : boxes) {
if (box.contains(entity.getLocation().toVector())) {
applyingLPS.add(lp);
}
}
}
}
}
return applyingLPS;
return glim.getApplyingPoliciesForEntity(entity, ps);
}
}

View file

@ -2,20 +2,14 @@ package io.github.adrianvic.nemesiseye.commands;
import io.github.adrianvic.nemesiseye.Nemesis;
import io.github.adrianvic.nemesiseye.commands.sub.*;
import org.bukkit.ChatColor;
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 Map<String, Subcommand> subs = new HashMap<>();
public class EyeCore {
public final Map<String, Subcommand> subs = new HashMap<>();
public Eye() {
public EyeCore() {
register(new Reload());
register(new ListPolicies());
register(new PolicyInfo());
@ -26,14 +20,13 @@ public class Eye implements CommandExecutor, TabCompleter {
subs.put(sub.name(), sub);
}
@Override
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String @NotNull [] strings) {
public boolean onCommand(CommandSender commandSender, Command command, String s, String [] strings) {
if (strings.length == 0) {
commandSender.sendMessage("""
%sEye of Nemesis%s version %s
Eye of Nemesis version %s
Usage: '/eye <command>'
Use '/eye help' for a list of available commands
""".formatted(ChatColor.RED, ChatColor.RESET, Nemesis.getInstance().getDescription().getVersion()));
""".formatted(Nemesis.getInstance().getDescription().getVersion()));
} else {
Subcommand sub = subs.get(strings[0].toLowerCase());
if (sub == null) {
@ -45,8 +38,7 @@ public class Eye implements CommandExecutor, TabCompleter {
return false;
}
@Override
public @Nullable List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String @NotNull [] strings) {
public List<String> onTabComplete(CommandSender commandSender, Command command, String s, String [] strings) {
if (strings.length == 1) {
return new ArrayList<>(subs.keySet());
}
@ -56,4 +48,6 @@ public class Eye implements CommandExecutor, TabCompleter {
}
return List.of();
}
public Map<String, Subcommand> getSubs() { return subs; };
}

View file

@ -20,11 +20,11 @@ public class PolicyInfo implements Subcommand {
for (Policy policy : policies) {
if (policy.name().equals(strings[0])) {
commandSender.sendMessage(String.format("""
Showing info for policy "%s%s%s":
Showing info for policy "%s":
Type: %s
Nodes: %s
%s
""", ChatColor.UNDERLINE, policy.name(), ChatColor.RESET, "location", policy.nodes().size(), policy.allowlist() ? "Is allowlist" : "Is blacklist"));
""", policy.name(), "location", policy.nodes().size(), policy.allowlist() ? "Is allowlist" : "Is blacklist"));
}
}
return true;

View file

@ -1,20 +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())) {
if (DataShifter.safeMatches(s, entity.getInventory().getItemInMainHand().getType().toString())) return false;
boolean matches = DataShifter.safeMatches(s, glim.getItemInMainHandHumanEntity(entity).getType().toString());
if (matches) return node.isWhitelist();
}
}
return true;
return !node.isWhitelist();
}
}

View file

@ -1,41 +1,27 @@
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 org.bukkit.enchantments.Enchantment;
import io.github.adrianvic.nemesiseye.reflection.Glimmer;
import org.bukkit.entity.HumanEntity;
import org.bukkit.inventory.ItemStack;
import java.util.Map;
public class useEnchantment implements NodeHandler {
private Glimmer glim = Nemesis.getInstance().getGlimmer();
@Override
public boolean allows(HumanEntity entity, PolicyNode node, Action action) {
ItemStack item = entity.getInventory().getItemInMainHand();
if (item.getItemMeta() == null) {
return !node.isWhitelist();
}
ItemStack item = glim.getItemInMainHandHumanEntity(entity);
Map<Enchantment, Integer> enchants = item.getItemMeta().getEnchants();
if (!glim.hasItemMeta(item)) return true;
if (!glim.hasAnyEnchantment(item)) return true;
if (enchants.isEmpty()) {
return !node.isWhitelist();
}
boolean matches = glim.hasEnchantment(item,
DataShifter.parseValueToStringMap(node.values()));
Map<String, String> valuesmap = DataShifter.parseValueToStringMap(node.values());
for (Map.Entry<Enchantment, Integer> e : enchants.entrySet()) {
String enchantment = e.getKey().getKey().getKey();
String level = e.getValue().toString();
for (Map.Entry<String, String> entry : valuesmap.entrySet()) {
if (DataShifter.safeMatches(entry.getKey().trim(), enchantment) && DataShifter.safeMatches(entry.getValue().trim(), level)) {
return false;
}
}
}
return true;
return matches ? node.isWhitelist() : !node.isWhitelist();
}
}

View file

@ -1,22 +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 useItem implements NodeHandler {
private Glimmer glim = Nemesis.getInstance().getGlimmer();
@Override
public boolean allows(HumanEntity entity, PolicyNode node, Action action) {
String type = entity.getInventory().getItemInMainHand().getType().toString();
String type = glim.getItemInMainHandHumanEntity(entity).getType().toString();
for (String s : DataShifter.parseValueToStringList(node.values())) {
if (DataShifter.safeMatches(s, type)) {
return false;
}
boolean matches = DataShifter.safeMatches(s, type);
if (matches) return node.isWhitelist();
}
return true;
return !node.isWhitelist();
}
}

View file

@ -1,17 +1,19 @@
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.LocationPolicy;
import org.bukkit.Bukkit;
import io.github.adrianvic.nemesiseye.reflection.Glimmer;
import org.bukkit.Location;
import org.bukkit.util.BoundingBox;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class LocationPolicyParser implements PolicyParser {
private Glimmer glim = Nemesis.getInstance().getGlimmer();
public List<Policy> parse(List<?> raw) {
List<Policy> out = new ArrayList<>(raw.size());
List<Map<?, ?>> parsedRawMap = DataShifter.parseValueToListOfMaps(raw);
@ -33,12 +35,12 @@ public class LocationPolicyParser implements PolicyParser {
List<PolicyNode> nodes = PolicyNode.parseNodes(nodeList, allowlist);
// Parsing locations
List<ArrayList<BoundingBox>> locations = new ArrayList<>();
List<ArrayList<Glimmer.Box>> locations = new ArrayList<>();
Object rawLocations = m.get("locations");
List<?> groups = rawLocations instanceof List ? (List<?>) rawLocations : List.of();
ArrayList<BoundingBox> boxes = new ArrayList<>(groups.size());
ArrayList<Glimmer.Box> boxes = new ArrayList<>(groups.size());
// Now iterate over regions
for (Object rObj : groups) {
@ -54,10 +56,10 @@ public class LocationPolicyParser implements PolicyParser {
double y2 = ((Number) c2.get("y")).doubleValue();
double z2 = ((Number) c2.get("z")).doubleValue();
Location loc1 = new Location(Bukkit.getWorlds().getFirst(), x1, y1, z1);
Location loc2 = new Location(Bukkit.getWorlds().getFirst(), x2, y2, z2);
Location loc1 = new Location(glim.getWorlds().getFirst(), x1, y1, z1);
Location loc2 = new Location(glim.getWorlds().getFirst(), x2, y2, z2);
boxes.add(BoundingBox.of(loc1, loc2));
boxes.add(Glimmer.Box.of(loc1, loc2));
}
locations.add(boxes);

View file

@ -2,9 +2,9 @@ package io.github.adrianvic.nemesiseye.policy.policies;
import io.github.adrianvic.nemesiseye.policy.Policy;
import io.github.adrianvic.nemesiseye.policy.PolicyNode;
import org.bukkit.util.BoundingBox;
import io.github.adrianvic.nemesiseye.reflection.Glimmer;
import java.util.ArrayList;
import java.util.List;
public record LocationPolicy(String name, List<ArrayList<BoundingBox>> locations, List<PolicyNode> nodes, boolean allowlist) implements Policy {}
public record LocationPolicy(String name, List<ArrayList<Glimmer.Box>> locations, List<PolicyNode> nodes, boolean allowlist) implements Policy {}

View file

@ -1,5 +1,52 @@
package io.github.adrianvic.nemesiseye.reflection;
import io.github.adrianvic.nemesiseye.policy.Policy;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.HumanEntity;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import java.io.File;
import java.util.List;
import java.util.Map;
public interface Glimmer {
File loadConfigFile();
List<Policy> loadPoliciesFromFile(File file);
List<Policy> getApplyingPoliciesForEntity(HumanEntity entity, List<Policy> policies);
void onLoad();
ItemStack getItemInMainHandHumanEntity(HumanEntity entity);
boolean hasItemMeta(ItemStack item);
List<World> getWorlds();
boolean hasEnchantment(ItemStack item, Map<String, String> valuesmap);
boolean hasAnyEnchantment(ItemStack itemStack);
class Box {
public final double x1, y1, z1, x2, y2, 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);
}
public boolean contains(double x, double y, double z) {
return x >= x1 && x <= x2
&& 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 static Box of(Location loc1, Location loc2) { return new Box(loc1.getX(), loc1.getY(), loc1.getZ(), loc2.getX(), loc2.getY(), loc2.getZ()); }
}
}