Merge pull request #1 from adrianvic/reflection
Add reflection with initial support to Bukkit CB1060 (b1.7.3)
This commit is contained in:
commit
0db49aba02
32 changed files with 772 additions and 234 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -2,3 +2,4 @@
|
||||||
build/
|
build/
|
||||||
out/
|
out/
|
||||||
.idea/
|
.idea/
|
||||||
|
libs/
|
||||||
35
README.md
35
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
|
||||||
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
|
## 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`.
|
- 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.
|
- This plugin is in a very early stage.
|
||||||
|
|
||||||
## Policies
|
## Motivations
|
||||||
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`.
|
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.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
## Performance
|
## 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.
|
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.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
|
||||||
55
build.gradle
55
build.gradle
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
93
build.gradle.kts
Normal file
93
build.gradle.kts
Normal file
|
|
@ -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<ProcessResources> {
|
||||||
|
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>("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<JavaCompile> {
|
||||||
|
options.encoding = "UTF-8"
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.runServer {
|
||||||
|
minecraftVersion("1.21")
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
41
src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/Log.java
Normal file
41
src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/Log.java
Normal file
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
110
src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/b1_7_3.java
Normal file
110
src/b1_7_3/java/io/github/adrianvic/nemesiseye/impl/b1_7_3.java
Normal file
|
|
@ -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<Policy> loadPoliciesFromFile(File file) {
|
||||||
|
List<?> rawPolicies = config.getList("Policies");
|
||||||
|
|
||||||
|
if (rawPolicies == null) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Map<?, ?>> result = new ArrayList<>(rawPolicies.size());
|
||||||
|
|
||||||
|
for (Object entry : rawPolicies) {
|
||||||
|
if (entry instanceof Map<?,?> m) {
|
||||||
|
result.add(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Policy> 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<Policy> parsed = PolicyParsers.get(k).parse(v);
|
||||||
|
allPolicies.addAll(parsed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allPolicies;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Policy> getApplyingPoliciesForEntity(HumanEntity entity, List<Policy> policies) {
|
||||||
|
List<Policy> result = new ArrayList<>();
|
||||||
|
for (Policy p : policies) {
|
||||||
|
if (p instanceof LocationPolicy lp) {
|
||||||
|
for (List<Box> 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<World> getWorlds() {
|
||||||
|
return plugin.getServer().getWorlds();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasEnchantment(ItemStack item, Map<String, String> valuesmap) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasAnyEnchantment(ItemStack itemStack) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
8
src/b1_7_3/resources/plugin.yml
Normal file
8
src/b1_7_3/resources/plugin.yml
Normal file
|
|
@ -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."
|
||||||
1
src/b1_7_3/resources/version.properties
Normal file
1
src/b1_7_3/resources/version.properties
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
impl.version=b1_7_3
|
||||||
|
|
@ -1,63 +1,38 @@
|
||||||
package io.github.adrianvic.nemesiseye;
|
package io.github.adrianvic.nemesiseye;
|
||||||
|
|
||||||
import io.github.adrianvic.nemesiseye.policy.Policy;
|
import io.github.adrianvic.nemesiseye.policy.Policy;
|
||||||
import io.github.adrianvic.nemesiseye.policy.PolicyParser;
|
import io.github.adrianvic.nemesiseye.reflection.Glimmer;
|
||||||
import io.github.adrianvic.nemesiseye.policy.PolicyParsers;
|
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class Config {
|
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 File file;
|
||||||
private YamlConfiguration config;
|
|
||||||
|
|
||||||
private List<Policy> policies = new ArrayList<>();
|
private List<Policy> policies = new ArrayList<>();
|
||||||
|
|
||||||
private Config() {
|
private Config() {}
|
||||||
}
|
|
||||||
|
|
||||||
public void load() {
|
public void load() {
|
||||||
file = new File(Nemesis.getInstance().getDataFolder(), "settings.yml");
|
List<Policy> newPolicies = glim.loadPoliciesFromFile(glim.loadConfigFile());
|
||||||
|
policies = newPolicies;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save() {
|
// public void save() {
|
||||||
try {
|
// try {
|
||||||
config.save(file);
|
// config.save(file);
|
||||||
} catch (Exception e) {
|
// } catch (Exception e) {
|
||||||
e.printStackTrace();
|
// e.printStackTrace();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public void set(String path, Object value) {
|
// public void set(String path, Object value) {
|
||||||
config.set(path, value);
|
// config.set(path, value);
|
||||||
save();
|
// save();
|
||||||
}
|
// }
|
||||||
|
|
||||||
public List<Policy> getPolicies() {
|
public List<Policy> getPolicies() {
|
||||||
return policies;
|
return policies;
|
||||||
|
|
|
||||||
|
|
@ -21,19 +21,23 @@ public class DataShifter {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<String, String> parseValueToStringMap(List<Object> values) {
|
public static Map<String,String> parseValueToStringMap(List<Object> raw) {
|
||||||
Map<String, String> result = new HashMap<>();
|
Map<String,String> out = new HashMap<>();
|
||||||
|
|
||||||
for (Object o : values) {
|
for (Object o : raw) {
|
||||||
if (o instanceof Map<?, ?> raw) {
|
if (o instanceof Map<?,?> map) {
|
||||||
for (Map.Entry<?, ?> e : raw.entrySet()) {
|
for (Map.Entry<?,?> e : map.entrySet()) {
|
||||||
if (e.getKey() instanceof String k && e.getValue() instanceof String v) {
|
out.put(String.valueOf(e.getKey()), String.valueOf(e.getValue()));
|
||||||
result.put(k, v);
|
}
|
||||||
}
|
} 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) {
|
public static List<Map<?, ?>> parseValueToListOfMaps(List<?> values) {
|
||||||
|
|
|
||||||
|
|
@ -2,27 +2,22 @@ package io.github.adrianvic.nemesiseye;
|
||||||
|
|
||||||
import org.bukkit.entity.HumanEntity;
|
import org.bukkit.entity.HumanEntity;
|
||||||
import org.bukkit.entity.Player;
|
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.block.BlockBreakEvent;
|
||||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
|
||||||
public class EventListener implements Listener {
|
public class Events {
|
||||||
@EventHandler
|
public static void onBlockBreak(BlockBreakEvent event) {
|
||||||
public void onBlockBreak(BlockBreakEvent event) {
|
|
||||||
event.setCancelled(!Validator.canBreak(event.getPlayer()));
|
event.setCancelled(!Validator.canBreak(event.getPlayer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
public static void onInteractionEvent(PlayerInteractEvent event) {
|
||||||
public void onInteractionEvent(PlayerInteractEvent event) {
|
|
||||||
if (event.getItem() != null) {
|
if (event.getItem() != null) {
|
||||||
event.setCancelled(!Validator.canInteract(event.getPlayer()));
|
event.setCancelled(!Validator.canInteract(event.getPlayer()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
public static void onEntityDamageByEntityEvent(EntityDamageByEntityEvent event) {
|
||||||
public void onEntityDamageByEntityEvent(EntityDamageByEntityEvent event) {
|
|
||||||
if (event.getDamager() instanceof Player) {
|
if (event.getDamager() instanceof Player) {
|
||||||
event.setCancelled(!Validator.canHit((HumanEntity) event.getDamager()));
|
event.setCancelled(!Validator.canHit((HumanEntity) event.getDamager()));
|
||||||
}
|
}
|
||||||
|
|
@ -1,23 +1,65 @@
|
||||||
package io.github.adrianvic.nemesiseye;
|
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 org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
public final class Nemesis extends JavaPlugin {
|
public final class Nemesis extends JavaPlugin {
|
||||||
|
private Glimmer glim;
|
||||||
|
private static final String VERSION_PROP = "impl.version";
|
||||||
|
private static Nemesis instance;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
getServer().getPluginManager().registerEvents(new EventListener(), this);
|
instance = this;
|
||||||
|
glim = loadGlim();
|
||||||
|
glim.onLoad();
|
||||||
Config.getInstance().load();
|
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
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
// Plugin shutdown logic
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Nemesis getInstance() {
|
public static Nemesis getInstance() { return instance; }
|
||||||
return getPlugin(Nemesis.class);
|
public Glimmer getGlimmer() { return glim; }
|
||||||
}
|
public PluginManager getPluginManager() { return this.getServer().getPluginManager(); }
|
||||||
}
|
}
|
||||||
|
|
@ -1,16 +1,17 @@
|
||||||
package io.github.adrianvic.nemesiseye;
|
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.policies.LocationPolicy;
|
|
||||||
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 io.github.adrianvic.nemesiseye.reflection.Glimmer;
|
||||||
import org.bukkit.entity.HumanEntity;
|
import org.bukkit.entity.HumanEntity;
|
||||||
import org.bukkit.util.BoundingBox;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class Validator {
|
public class Validator {
|
||||||
|
private final static Glimmer glim = Nemesis.getInstance().getGlimmer();
|
||||||
|
|
||||||
public static boolean canInteract(HumanEntity entity) {
|
public static boolean canInteract(HumanEntity entity) {
|
||||||
return checkAgainstEntity(entity, Action.INTERACT);
|
return checkAgainstEntity(entity, Action.INTERACT);
|
||||||
}
|
}
|
||||||
|
|
@ -30,13 +31,11 @@ public class Validator {
|
||||||
for (PolicyNode n : nodes) {
|
for (PolicyNode n : nodes) {
|
||||||
if (!checkAgainstNode(entity, n, action)) return false;
|
if (!checkAgainstNode(entity, n, action)) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean checkAgainstNode(HumanEntity entity, PolicyNode node, Action action) {
|
public static boolean checkAgainstNode(HumanEntity entity, PolicyNode node, Action action) {
|
||||||
boolean allowed = node.getHandler().allows(entity, node, action);
|
return node.getHandler().allows(entity, node, action);
|
||||||
return node.isWhitelist() != allowed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<PolicyNode> getNodesForPolicies(List<Policy> policies) {
|
public static List<PolicyNode> getNodesForPolicies(List<Policy> policies) {
|
||||||
|
|
@ -49,18 +48,6 @@ public class Validator {
|
||||||
|
|
||||||
public static List<Policy> getPoliciesForEntity(HumanEntity entity) {
|
public static List<Policy> getPoliciesForEntity(HumanEntity entity) {
|
||||||
List<Policy> ps = Config.getInstance().getPolicies();
|
List<Policy> ps = Config.getInstance().getPolicies();
|
||||||
List<Policy> applyingLPS = new ArrayList<>();
|
return glim.getApplyingPoliciesForEntity(entity, ps);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,20 +2,14 @@ package io.github.adrianvic.nemesiseye.commands;
|
||||||
|
|
||||||
import io.github.adrianvic.nemesiseye.Nemesis;
|
import io.github.adrianvic.nemesiseye.Nemesis;
|
||||||
import io.github.adrianvic.nemesiseye.commands.sub.*;
|
import io.github.adrianvic.nemesiseye.commands.sub.*;
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandExecutor;
|
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.TabCompleter;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class Eye implements CommandExecutor, TabCompleter {
|
public class EyeCore {
|
||||||
private final Map<String, Subcommand> subs = new HashMap<>();
|
public final Map<String, Subcommand> subs = new HashMap<>();
|
||||||
|
|
||||||
public Eye() {
|
public EyeCore() {
|
||||||
register(new Reload());
|
register(new Reload());
|
||||||
register(new ListPolicies());
|
register(new ListPolicies());
|
||||||
register(new PolicyInfo());
|
register(new PolicyInfo());
|
||||||
|
|
@ -26,14 +20,13 @@ public class Eye implements CommandExecutor, TabCompleter {
|
||||||
subs.put(sub.name(), sub);
|
subs.put(sub.name(), sub);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public boolean onCommand(CommandSender commandSender, Command command, String s, String [] strings) {
|
||||||
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String @NotNull [] strings) {
|
|
||||||
if (strings.length == 0) {
|
if (strings.length == 0) {
|
||||||
commandSender.sendMessage("""
|
commandSender.sendMessage("""
|
||||||
%sEye of Nemesis%s version %s
|
Eye of Nemesis version %s
|
||||||
Usage: '/eye <command>'
|
Usage: '/eye <command>'
|
||||||
Use '/eye help' for a list of available commands
|
Use '/eye help' for a list of available commands
|
||||||
""".formatted(ChatColor.RED, ChatColor.RESET, Nemesis.getInstance().getDescription().getVersion()));
|
""".formatted(Nemesis.getInstance().getDescription().getVersion()));
|
||||||
} else {
|
} else {
|
||||||
Subcommand sub = subs.get(strings[0].toLowerCase());
|
Subcommand sub = subs.get(strings[0].toLowerCase());
|
||||||
if (sub == null) {
|
if (sub == null) {
|
||||||
|
|
@ -45,8 +38,7 @@ public class Eye implements CommandExecutor, TabCompleter {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public List<String> onTabComplete(CommandSender commandSender, Command command, String s, String [] strings) {
|
||||||
public @Nullable List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String @NotNull [] strings) {
|
|
||||||
if (strings.length == 1) {
|
if (strings.length == 1) {
|
||||||
return new ArrayList<>(subs.keySet());
|
return new ArrayList<>(subs.keySet());
|
||||||
}
|
}
|
||||||
|
|
@ -56,4 +48,6 @@ public class Eye implements CommandExecutor, TabCompleter {
|
||||||
}
|
}
|
||||||
return List.of();
|
return List.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, Subcommand> getSubs() { return subs; };
|
||||||
}
|
}
|
||||||
|
|
@ -20,11 +20,11 @@ public class PolicyInfo implements Subcommand {
|
||||||
for (Policy policy : policies) {
|
for (Policy policy : policies) {
|
||||||
if (policy.name().equals(strings[0])) {
|
if (policy.name().equals(strings[0])) {
|
||||||
commandSender.sendMessage(String.format("""
|
commandSender.sendMessage(String.format("""
|
||||||
Showing info for policy "%s%s%s":
|
Showing info for policy "%s":
|
||||||
Type: %s
|
Type: %s
|
||||||
Nodes: %s
|
Nodes: %s
|
||||||
%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;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,25 @@
|
||||||
package io.github.adrianvic.nemesiseye.policy.handlers;
|
package io.github.adrianvic.nemesiseye.policy.handlers;
|
||||||
|
|
||||||
import io.github.adrianvic.nemesiseye.DataShifter;
|
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.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 io.github.adrianvic.nemesiseye.reflection.Glimmer;
|
||||||
import org.bukkit.entity.HumanEntity;
|
import org.bukkit.entity.HumanEntity;
|
||||||
|
|
||||||
public class attackWith implements NodeHandler {
|
public class attackWith implements NodeHandler {
|
||||||
|
|
||||||
|
private final static Glimmer glim = Nemesis.getInstance().getGlimmer();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean allows(HumanEntity entity, PolicyNode node, Action action) {
|
public boolean allows(HumanEntity entity, PolicyNode node, Action action) {
|
||||||
if (action == Action.HIT) {
|
if (action == Action.HIT) {
|
||||||
for (String s : DataShifter.parseValueToStringList(node.values())) {
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,41 +1,27 @@
|
||||||
package io.github.adrianvic.nemesiseye.policy.handlers;
|
package io.github.adrianvic.nemesiseye.policy.handlers;
|
||||||
|
|
||||||
import io.github.adrianvic.nemesiseye.DataShifter;
|
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.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.enchantments.Enchantment;
|
import io.github.adrianvic.nemesiseye.reflection.Glimmer;
|
||||||
import org.bukkit.entity.HumanEntity;
|
import org.bukkit.entity.HumanEntity;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class useEnchantment implements NodeHandler {
|
public class useEnchantment implements NodeHandler {
|
||||||
|
private Glimmer glim = Nemesis.getInstance().getGlimmer();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean allows(HumanEntity entity, PolicyNode node, Action action) {
|
public boolean allows(HumanEntity entity, PolicyNode node, Action action) {
|
||||||
ItemStack item = entity.getInventory().getItemInMainHand();
|
ItemStack item = glim.getItemInMainHandHumanEntity(entity);
|
||||||
if (item.getItemMeta() == null) {
|
|
||||||
return !node.isWhitelist();
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<Enchantment, Integer> enchants = item.getItemMeta().getEnchants();
|
if (!glim.hasItemMeta(item)) return true;
|
||||||
|
if (!glim.hasAnyEnchantment(item)) return true;
|
||||||
|
|
||||||
if (enchants.isEmpty()) {
|
boolean matches = glim.hasEnchantment(item,
|
||||||
return !node.isWhitelist();
|
DataShifter.parseValueToStringMap(node.values()));
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, String> valuesmap = DataShifter.parseValueToStringMap(node.values());
|
return matches ? node.isWhitelist() : !node.isWhitelist();
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,25 @@
|
||||||
package io.github.adrianvic.nemesiseye.policy.handlers;
|
package io.github.adrianvic.nemesiseye.policy.handlers;
|
||||||
|
|
||||||
import io.github.adrianvic.nemesiseye.DataShifter;
|
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.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 io.github.adrianvic.nemesiseye.reflection.Glimmer;
|
||||||
import org.bukkit.entity.HumanEntity;
|
import org.bukkit.entity.HumanEntity;
|
||||||
|
|
||||||
public class useItem implements NodeHandler {
|
public class useItem implements NodeHandler {
|
||||||
|
|
||||||
|
private Glimmer glim = Nemesis.getInstance().getGlimmer();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean allows(HumanEntity entity, PolicyNode node, Action action) {
|
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())) {
|
for (String s : DataShifter.parseValueToStringList(node.values())) {
|
||||||
if (DataShifter.safeMatches(s, type)) {
|
boolean matches = DataShifter.safeMatches(s, type);
|
||||||
return false;
|
if (matches) return node.isWhitelist();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return !node.isWhitelist();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,19 @@
|
||||||
package io.github.adrianvic.nemesiseye.policy.parser;
|
package io.github.adrianvic.nemesiseye.policy.parser;
|
||||||
|
|
||||||
import io.github.adrianvic.nemesiseye.DataShifter;
|
import io.github.adrianvic.nemesiseye.DataShifter;
|
||||||
|
import io.github.adrianvic.nemesiseye.Nemesis;
|
||||||
import io.github.adrianvic.nemesiseye.policy.*;
|
import io.github.adrianvic.nemesiseye.policy.*;
|
||||||
import io.github.adrianvic.nemesiseye.policy.policies.LocationPolicy;
|
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.Location;
|
||||||
import org.bukkit.util.BoundingBox;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class LocationPolicyParser implements PolicyParser {
|
public class LocationPolicyParser implements PolicyParser {
|
||||||
|
private Glimmer glim = Nemesis.getInstance().getGlimmer();
|
||||||
|
|
||||||
public List<Policy> parse(List<?> raw) {
|
public List<Policy> parse(List<?> raw) {
|
||||||
List<Policy> out = new ArrayList<>(raw.size());
|
List<Policy> out = new ArrayList<>(raw.size());
|
||||||
List<Map<?, ?>> parsedRawMap = DataShifter.parseValueToListOfMaps(raw);
|
List<Map<?, ?>> parsedRawMap = DataShifter.parseValueToListOfMaps(raw);
|
||||||
|
|
@ -33,12 +35,12 @@ public class LocationPolicyParser implements PolicyParser {
|
||||||
List<PolicyNode> nodes = PolicyNode.parseNodes(nodeList, allowlist);
|
List<PolicyNode> nodes = PolicyNode.parseNodes(nodeList, allowlist);
|
||||||
|
|
||||||
// Parsing locations
|
// Parsing locations
|
||||||
List<ArrayList<BoundingBox>> locations = new ArrayList<>();
|
List<ArrayList<Glimmer.Box>> locations = new ArrayList<>();
|
||||||
|
|
||||||
Object rawLocations = m.get("locations");
|
Object rawLocations = m.get("locations");
|
||||||
List<?> groups = rawLocations instanceof List ? (List<?>) rawLocations : List.of();
|
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
|
// Now iterate over regions
|
||||||
for (Object rObj : groups) {
|
for (Object rObj : groups) {
|
||||||
|
|
@ -54,10 +56,10 @@ public class LocationPolicyParser implements PolicyParser {
|
||||||
double y2 = ((Number) c2.get("y")).doubleValue();
|
double y2 = ((Number) c2.get("y")).doubleValue();
|
||||||
double z2 = ((Number) c2.get("z")).doubleValue();
|
double z2 = ((Number) c2.get("z")).doubleValue();
|
||||||
|
|
||||||
Location loc1 = new Location(Bukkit.getWorlds().getFirst(), x1, y1, z1);
|
Location loc1 = new Location(glim.getWorlds().getFirst(), x1, y1, z1);
|
||||||
Location loc2 = new Location(Bukkit.getWorlds().getFirst(), x2, y2, z2);
|
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);
|
locations.add(boxes);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@ package io.github.adrianvic.nemesiseye.policy.policies;
|
||||||
|
|
||||||
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.util.BoundingBox;
|
import io.github.adrianvic.nemesiseye.reflection.Glimmer;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
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 {}
|
||||||
|
|
@ -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<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()); }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -103,7 +103,7 @@ Policies:
|
||||||
- FISHING_ROD
|
- FISHING_ROD
|
||||||
- CLOCK
|
- CLOCK
|
||||||
- GLOWSTONE_DUST
|
- GLOWSTONE_DUST
|
||||||
- INK_SAC
|
- INK_SACw
|
||||||
- BONE_MEAL
|
- BONE_MEAL
|
||||||
- SUGAR
|
- SUGAR
|
||||||
- COOKIE
|
- COOKIE
|
||||||
|
|
@ -115,7 +115,7 @@ Policies:
|
||||||
- DIRT
|
- DIRT
|
||||||
- BREAD
|
- BREAD
|
||||||
- useEnchantment:
|
- useEnchantment:
|
||||||
"gibberish": 999999
|
"theresnoenchantmentwiththisname": "3"
|
||||||
locations:
|
locations:
|
||||||
- corner1: { x: 2100, y: 256, z: 1400 }
|
- corner1: { x: 2100, y: 256, z: 1400 }
|
||||||
corner2: { x: 1000, y: -64, z: 2200 }
|
corner2: { x: 1000, y: -64, z: 2200 }
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String @NotNull [] strings) {
|
||||||
|
return core.onTabComplete(commandSender, command, s, strings);
|
||||||
|
}
|
||||||
|
}
|
||||||
116
src/r1_21/java/io/github/adrianvic/nemesiseye/impl/r1_21.java
Normal file
116
src/r1_21/java/io/github/adrianvic/nemesiseye/impl/r1_21.java
Normal file
|
|
@ -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<Policy> loadPoliciesFromFile(File file) {
|
||||||
|
YamlConfiguration config = new YamlConfiguration();
|
||||||
|
config.options().parseComments(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
config.load(file);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Map<?, ?>> rawPolicies = config.getMapList("Policies");
|
||||||
|
List<Policy> 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<Policy> parsed = PolicyParsers.get(k).parse(v);
|
||||||
|
allPolicies.addAll(parsed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allPolicies;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Policy> getApplyingPoliciesForEntity(HumanEntity entity, List<Policy> policies) {
|
||||||
|
List<Policy> applyingLPS = new ArrayList<>();
|
||||||
|
for (Policy p : policies) {
|
||||||
|
if (p instanceof LocationPolicy lp) {
|
||||||
|
for (ArrayList<Box> 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<World> getWorlds() {
|
||||||
|
return Bukkit.getWorlds();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasEnchantment(ItemStack item, Map<String, String> valuesmap) {
|
||||||
|
Map<Enchantment, Integer> enchantmentList = item.getEnchantments();
|
||||||
|
for (Map.Entry<Enchantment, Integer> enchantmentEntry : enchantmentList.entrySet()) {
|
||||||
|
for (Map.Entry<String, String> 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
name: "Eye-of-Nemesis"
|
name: "Eye-of-Nemesis"
|
||||||
version: '1.0.2-SNAPSHOT'
|
version: '1.0.3-SNAPSHOT'
|
||||||
main: io.github.adrianvic.nemesiseye.Nemesis
|
main: io.github.adrianvic.nemesiseye.Nemesis
|
||||||
api-version: '1.21'
|
api-version: '1.21'
|
||||||
author: 'Adrian Victor'
|
author: 'Adrian Victor'
|
||||||
1
src/r1_21/resources/version.properties
Normal file
1
src/r1_21/resources/version.properties
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
impl.version=r1_21
|
||||||
Loading…
Add table
Add a link
Reference in a new issue