diff --git a/.gitignore b/.gitignore index 1ac6f97..026e990 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .gradle/ build/ out/ -.idea/ \ No newline at end of file +.idea/ +libs/ \ No newline at end of file diff --git a/README.md b/README.md index 49ea53c..d221c72 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,12 @@ -> [!IMPORTANT] -> This project is in a very early stage, expect bugs until `Release 1.0`. -> -> Documentation will soon be moved from README.md. - # Eye of Nemesis -Eye of Nemesis is a plugin that allows server admins to write [policies](#Policies) that will deny or allow (black/whitelist) players to do specific things based on the value of [nodes](#Nodes). +Eye of Nemesis is a plugin that allows server admins to write policies that will deny or allow (black/whitelist) players to do specific things based on the value of nodes. ## Warnings - Even though running `/eye` will tell you to run `/eye help` to list all available commands, this is not implemented yet, however all commands are available as tab-complete of `/eye`. - This plugin is in a very early stage. -## Policies -Policy is a structure that holds nodes and tell them _where_ to act. For example, a Location policy will tell its child nodes that they work from coordinates `x1 y1 z1` to `x2 y2 z2`. - -Currently, the only policy type is Location. - -## Nodes -Nodes are specific rules that rely on it's value to know _when_ to act. For example, a useItem policy with value `cookie` will prevent users from doing anything with a cookie. - -### `useItem` -**Triggered:** breaking/placing/interacting with anything using this item. - -**Expects:** list of strings. - -### `useEnchantment` -**Triggered:** breaking/placing/interacting with anything using an item with the specified enchantment, **will allow items without enchantment even on allowlist mode**. - -**Expects:** map of _string: string_. - -### `attackWith` -**Triggered:** attacking with this item in hand. - -**Expects:** list of strings. +## Motivations +I made this plugin as an effort to preserve a village from my private server. Originally from beta 1.7.3 Betalands server, then transferred to RetroMC, and then finally we downloaded the chunks to merge into our server, I was afraid it would not have the same feeling after all the updates, so I had the idea to make a plugin that can block the newer features. ## Performance -This plugin is not scalable as it is and will run unoptimized checks when your players do certain things in the server if you have policies enabled, I made it for a server with a few friends. - -For every policy there's a check, for every matching policy there are its child nodes, each one introducing new checks. Keep that in mind. +This plugin is not scalable as it is and will end up running unoptimized checks when your players do things with policies in effect, I made it for a server with a few friends. I'll look forward into writing more performant code after all my other priorities are implemented. diff --git a/build.gradle b/build.gradle deleted file mode 100644 index ca8860c..0000000 --- a/build.gradle +++ /dev/null @@ -1,55 +0,0 @@ -plugins { - id 'java' - id("xyz.jpenilla.run-paper") version "2.3.1" -} - -group = 'io.github.adrianvic' -version = '1.0.2-SNAPSHOT' - -repositories { - mavenCentral() - maven { - name = "papermc-repo" - url = "https://repo.papermc.io/repository/maven-public/" - } -} - -dependencies { - compileOnly("io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT") -} - -tasks { - runServer { - // Configure the Minecraft version for our task. - // This is the only required configuration besides applying the plugin. - // Your plugin's jar (or shadowJar if present) will be used automatically. - minecraftVersion("1.21") - } -} - -def targetJavaVersion = 21 -java { - def javaVersion = JavaVersion.toVersion(targetJavaVersion) - sourceCompatibility = javaVersion - targetCompatibility = javaVersion - if (JavaVersion.current() < javaVersion) { - toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion) - } -} - -tasks.withType(JavaCompile).configureEach { - options.encoding = 'UTF-8' - - if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) { - options.release.set(targetJavaVersion) - } -} - -processResources { - def props = [version: version] - inputs.properties props - filteringCharset 'UTF-8' - filesMatching('plugin.yml') { - expand props - } -} diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..28061f0 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,93 @@ +plugins { + java + id("xyz.jpenilla.run-paper") version "2.3.1" +} + +group = "io.github.adrianvic" +version = "1.0.3-SNAPSHOT" + +repositories { + mavenCentral() + maven("https://repo.papermc.io/repository/maven-public/") +} + +/* ----------------------------------------- */ +/* SUPPORTED VERSIONS */ +/* ----------------------------------------- */ + +val mcVersions = listOf( + "b1_7_3", + "r1_21" +) + +/* ----------------------------------------- */ +/* CREATE SOURCE SET PER VERSION */ +/* ----------------------------------------- */ + +mcVersions.forEach { ver -> + val ss = sourceSets.create(ver) { + java.srcDir("src/$ver/java") + + resources.setSrcDirs(listOf("src/$ver/resources", "src/main/resources")) + + compileClasspath += sourceSets["main"].output + runtimeClasspath += output + compileClasspath + } + + tasks.withType { + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + } + + configurations[ss.implementationConfigurationName] + .extendsFrom(configurations["implementation"]) + + configurations[ss.compileOnlyConfigurationName] + .extendsFrom(configurations["compileOnly"]) + +} + +/* ----------------------------------------- */ +/* DEPENDENCIES */ +/* ----------------------------------------- */ + +dependencies { + add("compileOnly", "io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT") + add("r1_21CompileOnly", "io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT") + add("b1_7_3CompileOnly", files("libs/craftbukkit-1060.jar")) +} + +/* ----------------------------------------- */ +/* BUILD TASKS */ +/* ----------------------------------------- */ + +mcVersions.forEach { ver -> + tasks.register("jar${ver.replace(".", "_").replace("-", "_").replace("/", "_").capitalize()}") { + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + from(sourceSets["main"].output) + from(sourceSets[ver].output) + archiveClassifier.set(ver) + + manifest { + attributes( + "Nemesis-Impl-Version" to ver + ) + } + + } +} + +/* ----------------------------------------- */ +/* JAVA SETTINGS */ +/* ----------------------------------------- */ + +java { + toolchain.languageVersion.set(JavaLanguageVersion.of(21)) +} + +tasks.withType { + options.encoding = "UTF-8" +} + +tasks.runServer { + minecraftVersion("1.21") +} \ No newline at end of file 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 new file mode 100644 index 0000000..bcad2f3 --- /dev/null +++ b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/BlockEventListener.java @@ -0,0 +1,13 @@ +package io.github.adrianvic.nemesiseye.impl; + +import io.github.adrianvic.nemesiseye.Events; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockListener; + +public class BlockEventListener extends BlockListener { + @Override + public void onBlockBreak(BlockBreakEvent event) { + Events.onBlockBreak(event); + } + +} diff --git a/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/ConfigurationEx.java b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/ConfigurationEx.java new file mode 100644 index 0000000..a4b3327 --- /dev/null +++ b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/ConfigurationEx.java @@ -0,0 +1,89 @@ +package io.github.adrianvic.nemesiseye.impl; + +import io.github.adrianvic.nemesiseye.Nemesis; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.util.config.Configuration; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; + +public class ConfigurationEx extends Configuration { + private final File configFile; + private final Log logger; + JavaPlugin plugin; + + public ConfigurationEx(String fileName, Log _logger) { + super(new File(Nemesis.getInstance().getDataFolder(), fileName)); + this.plugin = Nemesis.getInstance(); + logger = _logger; + this.configFile = new File(plugin.getDataFolder(), fileName); + } + + @Override + public void load() { + createParentDirectories(); + + if (!configFile.exists()) { + copyDefaultConfig(); + } + + try { + super.load(); + } catch (Exception e) { + logger.severe(String.format("Failed to load config '%s': %s", configFile.getName(), e.getMessage())); + } + } + + private void createParentDirectories() { + try { + Files.createDirectories(configFile.getParentFile().toPath()); + } catch (IOException e) { + logger.severe(String.format("Failed to generate default config directory: %s", e.getMessage())); + } + } + + private void copyDefaultConfig() { + // Load the config from the JAR directly (it is located at the root level) + String resourcePath = "/" + configFile.getName(); // Root path of JAR + + try (InputStream input = plugin.getClass().getResourceAsStream(resourcePath)) { + if (input == null) { + logger.severe(String.format("Default config '%s' wasn't found in the JAR.", configFile.getName())); + return; + } + + Files.copy(input, configFile.toPath()); + if (Files.exists(configFile.toPath())) { + logger.info(String.format("Default config '%s' generated successfully.", configFile.getName())); + } else { + logger.warning("We tried to generate the default config file, but it was not found even after the creation. Maybe your permissions are broken?"); + } + } catch (IOException e) { + logger.severe(String.format("Failed to generate default config '%s': %s", configFile.getName(), e.getMessage())); + } + } + + public void loadConfig() { + try { + this.load(); + logger.info(String.format("Config '%s' loaded successfully.", configFile.getName())); + } catch (Exception e) { + logger.severe(String.format("Failed to load config '%s': %s", configFile.getName(), e.getMessage())); + } + } + + public void saveConfig() { + try { + this.save(); + logger.info(String.format("Config '%s' saved successfully.", configFile.getName())); + } catch (Exception e) { + logger.severe(String.format("Failed to save config '%s': %s", configFile.getName(), e.getMessage())); + } + } + + public File getConfig() { + return configFile; + } +} \ No newline at end of file diff --git a/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/EntityEventListener.java b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/EntityEventListener.java new file mode 100644 index 0000000..c1e8966 --- /dev/null +++ b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/EntityEventListener.java @@ -0,0 +1,13 @@ +package io.github.adrianvic.nemesiseye.impl; + +import io.github.adrianvic.nemesiseye.Events; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityListener; + +public class EntityEventListener extends EntityListener { + public void onEntityDamage(EntityDamageByEntityEvent event) { +// Events.onEntityDamageByEntityEvent(event); + event.setCancelled(true); + } +} + diff --git a/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/Log.java b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/Log.java new file mode 100644 index 0000000..ccba8b1 --- /dev/null +++ b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/Log.java @@ -0,0 +1,41 @@ +package io.github.adrianvic.nemesiseye.impl; + +import static org.bukkit.Bukkit.getServer; + +import io.github.adrianvic.nemesiseye.Nemesis; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.java.JavaPlugin; + +public class Log { + JavaPlugin plugin; + PluginDescriptionFile pdf; + + public Log() { + plugin = Nemesis.getInstance(); + pdf = plugin.getDescription(); + } + + public void info(String message) { + getServer().getLogger().info("[" + pdf.getName() + "] " + message); + } + + public void infoc(String message) { + getServer().getLogger().info("[" + pdf.getName() + "] " + message); + } + + public void warning(String message) { + getServer().getLogger().warning("[" + pdf.getName() + "] " + message); + } + + public void warningc(String message) { + getServer().getLogger().warning("[" + pdf.getName() + "] " + message); + } + + public void severe(String message) { + getServer().getLogger().severe("[" + pdf.getName() + "] " + message); + } + + public void severec(String message) { + getServer().getLogger().severe("[" + pdf.getName() + "] " + message); + } +} \ No newline at end of file diff --git a/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/PlayerEventListener.java b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/PlayerEventListener.java new file mode 100644 index 0000000..c45789a --- /dev/null +++ b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/PlayerEventListener.java @@ -0,0 +1,15 @@ +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.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerListener; + +public class PlayerEventListener extends PlayerListener { + @Override + public void onPlayerInteract(PlayerInteractEvent event) { + Events.onInteractionEvent(event); + } +} + diff --git a/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/b1_7_3.java b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/b1_7_3.java new file mode 100644 index 0000000..f8d6fc8 --- /dev/null +++ b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/b1_7_3.java @@ -0,0 +1,110 @@ +package io.github.adrianvic.nemesiseye.impl; + +import io.github.adrianvic.nemesiseye.Nemesis; +import io.github.adrianvic.nemesiseye.impl.commands.Eye; +import io.github.adrianvic.nemesiseye.policy.Policy; +import io.github.adrianvic.nemesiseye.policy.PolicyParsers; +import io.github.adrianvic.nemesiseye.policy.policies.LocationPolicy; +import io.github.adrianvic.nemesiseye.reflection.Glimmer; +import org.bukkit.World; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.Event; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class b1_7_3 implements Glimmer { + JavaPlugin plugin; + PluginManager pm; + ConfigurationEx config; + + @Override + public File loadConfigFile() { + config = new ConfigurationEx("settings.yml", new Log()); + config.load(); + return config.getConfig(); + } + + @Override + public List loadPoliciesFromFile(File file) { + List rawPolicies = config.getList("Policies"); + + if (rawPolicies == null) { + return new ArrayList<>(); + } + + List> result = new ArrayList<>(rawPolicies.size()); + + for (Object entry : rawPolicies) { + if (entry instanceof Map m) { + result.add(m); + } + } + + List allPolicies = new ArrayList<>(); + for (Map map : result) { + for (Map.Entry entry : map.entrySet()) { + if (entry.getKey() instanceof String k && entry.getValue() instanceof List v) { + List parsed = PolicyParsers.get(k).parse(v); + allPolicies.addAll(parsed); + } + } + } + return allPolicies; + } + + @Override + public List getApplyingPoliciesForEntity(HumanEntity entity, List policies) { + List result = new ArrayList<>(); + for (Policy p : policies) { + if (p instanceof LocationPolicy lp) { + for (List boxList : lp.locations()) { + for (Box b : boxList) { + if (b.contains(entity.getLocation().toVector())) result.add(p); + } + } + } + } + return result; + } + + @Override + public void onLoad() { + plugin = Nemesis.getInstance(); + pm = Nemesis.getInstance().getPluginManager(); + pm.registerEvent(Event.Type.ENTITY_DAMAGE, new EntityEventListener(), Event.Priority.Normal, plugin); + pm.registerEvent(Event.Type.BLOCK_BREAK, new BlockEventListener(), Event.Priority.Normal, plugin); + pm.registerEvent(Event.Type.PLAYER_INTERACT, new PlayerEventListener(), Event.Priority.Normal, plugin); + plugin.getCommand("eye").setExecutor(new Eye()); + } + + @Override + public ItemStack getItemInMainHandHumanEntity(HumanEntity entity) { + return entity.getItemInHand(); + } + + @Override + public boolean hasItemMeta(ItemStack item) { + return false; + } + + @Override + public List getWorlds() { + return plugin.getServer().getWorlds(); + } + + @Override + public boolean hasEnchantment(ItemStack item, Map valuesmap) { + return false; + } + + @Override + public boolean hasAnyEnchantment(ItemStack itemStack) { + return false; + } +} diff --git a/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/commands/Eye.java b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/commands/Eye.java new file mode 100644 index 0000000..c1f5da7 --- /dev/null +++ b/src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/commands/Eye.java @@ -0,0 +1,19 @@ +package io.github.adrianvic.nemesiseye.impl.commands; + +import io.github.adrianvic.nemesiseye.commands.EyeCore; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class Eye implements CommandExecutor { + private EyeCore core; + + public Eye() { + core = new EyeCore(); + } + + @Override + public boolean onCommand(CommandSender commandSender, Command command, String s, String [] strings) { + return core.onCommand(commandSender, command, s, strings); + } +} \ No newline at end of file diff --git a/src/b1_7_3/resources/plugin.yml b/src/b1_7_3/resources/plugin.yml new file mode 100644 index 0000000..e9c90d2 --- /dev/null +++ b/src/b1_7_3/resources/plugin.yml @@ -0,0 +1,8 @@ +name: "Eye-of-Nemesis" +version: '1.0.3-SNAPSHOT' +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." \ 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 56812df..5e286cd 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/Config.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/Config.java @@ -1,63 +1,38 @@ package io.github.adrianvic.nemesiseye; import io.github.adrianvic.nemesiseye.policy.Policy; -import io.github.adrianvic.nemesiseye.policy.PolicyParser; -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 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> 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 parsed = PolicyParsers.get(k).parse(v); - policies.addAll(parsed); - } - } - } + List 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 getPolicies() { return policies; diff --git a/src/main/java/io/github/adrianvic/nemesiseye/DataShifter.java b/src/main/java/io/github/adrianvic/nemesiseye/DataShifter.java index 026d6c5..b9edf4a 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/DataShifter.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/DataShifter.java @@ -21,19 +21,23 @@ public class DataShifter { return result; } - public static Map parseValueToStringMap(List values) { - Map result = new HashMap<>(); + public static Map parseValueToStringMap(List raw) { + Map 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> parseValueToListOfMaps(List values) { diff --git a/src/main/java/io/github/adrianvic/nemesiseye/EventListener.java b/src/main/java/io/github/adrianvic/nemesiseye/Events.java similarity index 62% rename from src/main/java/io/github/adrianvic/nemesiseye/EventListener.java rename to src/main/java/io/github/adrianvic/nemesiseye/Events.java index 4666861..07f0ed2 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/EventListener.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/Events.java @@ -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())); } diff --git a/src/main/java/io/github/adrianvic/nemesiseye/Nemesis.java b/src/main/java/io/github/adrianvic/nemesiseye/Nemesis.java index 03e95ef..b2bb00c 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/Nemesis.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/Nemesis.java @@ -1,23 +1,65 @@ 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; +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"; + private static Nemesis instance; @Override public void onEnable() { - getServer().getPluginManager().registerEvents(new EventListener(), this); + instance = this; + glim = loadGlim(); + glim.onLoad(); Config.getInstance().load(); - getCommand("eye").setExecutor(new Eye()); + } + + 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() { - // Plugin shutdown logic } - public static Nemesis getInstance() { - return getPlugin(Nemesis.class); - } + 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 b598b08..bd445cd 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/Validator.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/Validator.java @@ -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 getNodesForPolicies(List policies) { @@ -49,18 +48,6 @@ public class Validator { public static List getPoliciesForEntity(HumanEntity entity) { List ps = Config.getInstance().getPolicies(); - List applyingLPS = new ArrayList<>(); - for (Policy p : ps) { - if (p instanceof LocationPolicy lp) { - for (ArrayList boxes : lp.locations()) { - for (BoundingBox box : boxes) { - if (box.contains(entity.getLocation().toVector())) { - applyingLPS.add(lp); - } - } - } - } - } - return applyingLPS; + return glim.getApplyingPoliciesForEntity(entity, ps); } } diff --git a/src/main/java/io/github/adrianvic/nemesiseye/commands/Eye.java b/src/main/java/io/github/adrianvic/nemesiseye/commands/EyeCore.java similarity index 61% rename from src/main/java/io/github/adrianvic/nemesiseye/commands/Eye.java rename to src/main/java/io/github/adrianvic/nemesiseye/commands/EyeCore.java index 6929f18..666bfab 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/commands/Eye.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/commands/EyeCore.java @@ -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 subs = new HashMap<>(); +public class EyeCore { + public final Map 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 ' 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 onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String @NotNull [] strings) { + public List 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 getSubs() { return subs; }; } 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 178361f..d9460e5 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 @@ -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; 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 index f5b1d71..c4e159b 100644 --- a/src/main/java/io/github/adrianvic/nemesiseye/policy/handlers/attackWith.java +++ b/src/main/java/io/github/adrianvic/nemesiseye/policy/handlers/attackWith.java @@ -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(); } } 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 fd580fc..50df134 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 @@ -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 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 valuesmap = DataShifter.parseValueToStringMap(node.values()); - - for (Map.Entry e : enchants.entrySet()) { - String enchantment = e.getKey().getKey().getKey(); - String level = e.getValue().toString(); - - for (Map.Entry 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(); } } 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 cb97eca..d956816 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 @@ -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(); } } 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 26389fc..e96611f 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,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 parse(List raw) { List out = new ArrayList<>(raw.size()); List> parsedRawMap = DataShifter.parseValueToListOfMaps(raw); @@ -33,12 +35,12 @@ public class LocationPolicyParser implements PolicyParser { List nodes = PolicyNode.parseNodes(nodeList, allowlist); // Parsing locations - List> locations = new ArrayList<>(); + List> locations = new ArrayList<>(); Object rawLocations = m.get("locations"); List groups = rawLocations instanceof List ? (List) rawLocations : List.of(); - ArrayList boxes = new ArrayList<>(groups.size()); + ArrayList 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); 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 40a7e86..48c9a97 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 @@ -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> locations, List nodes, boolean allowlist) implements Policy {} \ No newline at end of file +public record LocationPolicy(String name, List> locations, List nodes, boolean allowlist) implements Policy {} \ 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 new file mode 100644 index 0000000..2509e39 --- /dev/null +++ b/src/main/java/io/github/adrianvic/nemesiseye/reflection/Glimmer.java @@ -0,0 +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 loadPoliciesFromFile(File file); + List getApplyingPoliciesForEntity(HumanEntity entity, List policies); + void onLoad(); + ItemStack getItemInMainHandHumanEntity(HumanEntity entity); + boolean hasItemMeta(ItemStack item); + List getWorlds(); + boolean hasEnchantment(ItemStack item, Map 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()); } + } + +} diff --git a/src/main/resources/settings.yml b/src/main/resources/settings.yml index 522c8ec..baf80f2 100644 --- a/src/main/resources/settings.yml +++ b/src/main/resources/settings.yml @@ -103,7 +103,7 @@ Policies: - FISHING_ROD - CLOCK - GLOWSTONE_DUST - - INK_SAC + - INK_SACw - BONE_MEAL - SUGAR - COOKIE @@ -115,7 +115,7 @@ Policies: - DIRT - BREAD - useEnchantment: - "gibberish": 999999 + "theresnoenchantmentwiththisname": "3" locations: - corner1: { x: 2100, y: 256, z: 1400 } - corner2: { x: 1000, y: -64, z: 2200 } \ No newline at end of file + corner2: { x: 1000, y: -64, z: 2200 } 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 new file mode 100644 index 0000000..d1afe2d --- /dev/null +++ b/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/EventListener.java @@ -0,0 +1,25 @@ +package io.github.adrianvic.nemesiseye.impl; + +import io.github.adrianvic.nemesiseye.Events; +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) { + Events.onBlockBreak(event); + } + + @EventHandler + public void onInteractionEvent(PlayerInteractEvent event) { + Events.onInteractionEvent(event); + } + + @EventHandler + public void onEntityDamageByEntityEvent(EntityDamageByEntityEvent event) { + Events.onEntityDamageByEntityEvent(event); + } +} diff --git a/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/commands/Eye.java b/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/commands/Eye.java new file mode 100644 index 0000000..ca8c0ac --- /dev/null +++ b/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/commands/Eye.java @@ -0,0 +1,30 @@ +package io.github.adrianvic.nemesiseye.impl.commands; + +import io.github.adrianvic.nemesiseye.commands.EyeCore; +import io.github.adrianvic.nemesiseye.commands.sub.*; +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 EyeCore core; + + public Eye() { + core = new EyeCore(); + } + + @Override + public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String @NotNull [] strings) { + return core.onCommand(commandSender, command, s, strings); + } + + @Override + public @Nullable List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String @NotNull [] strings) { + return core.onTabComplete(commandSender, command, s, strings); + } +} \ No newline at end of file diff --git a/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/r1_21.java b/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/r1_21.java new file mode 100644 index 0000000..43d65dc --- /dev/null +++ b/src/r1_21/java/io/github/adrianvic/nemesiseye/impl/r1_21.java @@ -0,0 +1,116 @@ +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; +import io.github.adrianvic.nemesiseye.policy.PolicyParsers; +import io.github.adrianvic.nemesiseye.policy.policies.LocationPolicy; +import io.github.adrianvic.nemesiseye.reflection.Glimmer; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.HumanEntity; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.PluginManager; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class r1_21 implements Glimmer { + @Override + public File loadConfigFile() { + File file = new File(Nemesis.getInstance().getDataFolder(), "settings.yml"); + + if (!file.exists()) + Nemesis.getInstance().saveResource("settings.yml", false); + + return file; + } + + @Override + public List loadPoliciesFromFile(File file) { + YamlConfiguration config = new YamlConfiguration(); + config.options().parseComments(true); + + try { + config.load(file); + } catch (Exception e) { + e.printStackTrace(); + } + + List> rawPolicies = config.getMapList("Policies"); + List allPolicies = new ArrayList<>(); + for (Map map : rawPolicies) { + for (Map.Entry entry : map.entrySet()) { + if (entry.getKey() instanceof String k && entry.getValue() instanceof List v) { + List parsed = PolicyParsers.get(k).parse(v); + allPolicies.addAll(parsed); + } + } + } + return allPolicies; + } + + @Override + public List getApplyingPoliciesForEntity(HumanEntity entity, List policies) { + List applyingLPS = new ArrayList<>(); + for (Policy p : policies) { + if (p instanceof LocationPolicy lp) { + for (ArrayList boxes : lp.locations()) { + for (Box box : boxes) { + if (box.contains(entity.getLocation().toVector())) { + applyingLPS.add(lp); + } + } + } + } + } + return applyingLPS; + } + + @Override + public void onLoad() { + PluginManager pm = Nemesis.getInstance().getPluginManager(); + Nemesis.getInstance().getCommand("eye").setExecutor(new Eye()); + pm.registerEvents(new EventListener(), Nemesis.getInstance()); + } + + @Override + public ItemStack getItemInMainHandHumanEntity(HumanEntity entity) { + return entity.getInventory().getItemInMainHand(); + } + + @Override + public boolean hasItemMeta(ItemStack item) { + if (item.getItemMeta() == null) { + return false; + } + return true; + } + + @Override + public List getWorlds() { + return Bukkit.getWorlds(); + } + + @Override + public boolean hasEnchantment(ItemStack item, Map valuesmap) { + 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; + } + } + } + return false; + } + + public boolean hasAnyEnchantment(ItemStack item) { + return !(item.getItemMeta().getEnchants().isEmpty()); + } +} diff --git a/src/main/resources/plugin.yml b/src/r1_21/resources/plugin.yml similarity index 92% rename from src/main/resources/plugin.yml rename to src/r1_21/resources/plugin.yml index 5db0296..ec04a6b 100644 --- a/src/main/resources/plugin.yml +++ b/src/r1_21/resources/plugin.yml @@ -1,5 +1,5 @@ name: "Eye-of-Nemesis" -version: '1.0.2-SNAPSHOT' +version: '1.0.3-SNAPSHOT' main: io.github.adrianvic.nemesiseye.Nemesis api-version: '1.21' author: 'Adrian Victor' 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