Compare commits
No commits in common. "main" and "1.0.6-SNAPSHOT" have entirely different histories.
main
...
1.0.6-SNAP
50 changed files with 517 additions and 944 deletions
|
|
@ -1,43 +0,0 @@
|
|||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'src/**'
|
||||
- '.github/**'
|
||||
- 'build.gradle.kts'
|
||||
- 'gradle.properties'
|
||||
- 'settings.gradle'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: arch-linux
|
||||
env:
|
||||
NEMESIS_VERSION_NAME: "autobuild-${{ github.sha }}"
|
||||
NEMESIS_BUILD_CHANNEL: "autobuild"
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6.0.1
|
||||
|
||||
- name: Setup Java enviroment
|
||||
uses: actions/setup-java@v5.1.0
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 21
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v5
|
||||
|
||||
- name: Download CB1060
|
||||
run: |
|
||||
mkdir -p libs
|
||||
curl -L -o libs/craftbukkit-1060.jar https://archive.org/download/craftbukkit1060/craftbukkit1-7-3%281060%29.jar
|
||||
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew buildAll
|
||||
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v6.0.0
|
||||
with:
|
||||
path: build/libs/*.jar
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
name: Release Build
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
build-and-release:
|
||||
runs-on: arch-linux
|
||||
env:
|
||||
NEMESIS_VERSION_NAME: "${{ github.ref_name }}"
|
||||
NEMESIS_BUILD_CHANNEL: "production"
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6.0.1
|
||||
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v5.1.0
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 21
|
||||
|
||||
- name: Set up Gradle
|
||||
uses: gradle/actions/setup-gradle@v5
|
||||
|
||||
- name: Download CB1060
|
||||
run: |
|
||||
mkdir -p libs
|
||||
curl -L -o libs/craftbukkit-1060.jar \
|
||||
https://archive.org/download/craftbukkit1060/craftbukkit1-7-3%281060%29.jar
|
||||
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew buildAll
|
||||
|
||||
- name: Upload JARs to release
|
||||
uses: softprops/action-gh-release@v2.5.0
|
||||
with:
|
||||
files: build/libs/*.jar
|
||||
tag_name: ${{ github.ref_name }}
|
||||
name: ${{ github.ref_name }}
|
||||
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
|
|
@ -12,7 +12,7 @@ on:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: "arch-linux"
|
||||
env:
|
||||
NEMESIS_VERSION_NAME: "autobuild-${{ github.sha }}"
|
||||
NEMESIS_BUILD_CHANNEL: "autobuild"
|
||||
|
|
|
|||
15
.github/workflows/release-build.yml
vendored
15
.github/workflows/release-build.yml
vendored
|
|
@ -6,7 +6,7 @@ on:
|
|||
|
||||
jobs:
|
||||
build-and-release:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: "arch-linux"
|
||||
env:
|
||||
NEMESIS_VERSION_NAME: "${{ github.ref_name }}"
|
||||
NEMESIS_BUILD_CHANNEL: "production"
|
||||
|
|
@ -32,10 +32,9 @@ jobs:
|
|||
- name: Build with Gradle
|
||||
run: ./gradlew buildAll
|
||||
|
||||
- name: Upload artifacts to release
|
||||
run: |
|
||||
curl -X POST \
|
||||
-H "Authorization: token ${{ secrets.FORGEJO_TOKEN }}" \
|
||||
-H "Content-Type: application/octet-stream" \
|
||||
https://inspiran.beetal-castor.ts.net/git/api/v1/repos/${{ github.repository }}/releases/tags/${{ github.ref_name }}/assets \
|
||||
--data-binary @build/libs/your-artifact.jar
|
||||
- name: Upload JARs to release
|
||||
uses: softprops/action-gh-release@v2.5.0
|
||||
with:
|
||||
files: build/libs/*.jar
|
||||
tag_name: ${{ github.ref_name }}
|
||||
name: ${{ github.ref_name }}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<img alt="eye_of_nemesis_social_cover" src="https://github.com/user-attachments/assets/a24bc92f-4dc2-4594-93c9-d056130f9695" />
|
||||
<img width="1280" height="640" alt="eye_of_nemesis_social_cover" src="https://github.com/user-attachments/assets/a24bc92f-4dc2-4594-93c9-d056130f9695" />
|
||||
|
||||
[](https://modrinth.com/plugin/eye-of-nemesis)
|
||||
[](https://github.com/adrianvic/NemesisEye/wiki)
|
||||
|
|
@ -17,8 +17,8 @@ I made this plugin as an effort to preserve a village from my private server. Or
|
|||
Since version 1.0.3-SNAPSHOT, Eye of Nemesis has _reflection_, a technique that allows me to target multiple versions of the game while sharing the codebase across versions.
|
||||
|
||||
Currently, we support the following Minecraft versions/loaders:
|
||||
- **PaperMC** `1.21.X, 26.1.X, 26.2`
|
||||
- **Project Poseidon/Bukkit** `b1.7.3 (CB1060)`
|
||||
- **PaperMC** `1.21, 1.21.1, 1.21.2, 1.21.3, 1.21.4, 1.21.5, 1.21.6, 1.21.7, 1.21.8, 1.21.9, 1.21.10`
|
||||
- **Bukkit** `b1.7.3 (CB1060)`
|
||||
|
||||
## Performance
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -59,24 +59,9 @@ mcVersions.forEach { ver ->
|
|||
/* ----------------------------------------- */
|
||||
|
||||
dependencies {
|
||||
add("compileOnly", "io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT")
|
||||
add("r1_21CompileOnly", "io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT")
|
||||
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"))
|
||||
|
||||
testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
|
||||
testImplementation("org.mockito:mockito-core:5.5.0")
|
||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||
testImplementation("io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT")
|
||||
testImplementation("com.github.seeseemelk:MockBukkit-v1.21:3.102.0")
|
||||
|
||||
// Allow tests to see the versioned implementations
|
||||
mcVersions.forEach { ver ->
|
||||
testImplementation(sourceSets[ver].output)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
/* ----------------------------------------- */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Nodes
|
||||
Nodes narrow down even further if an action can be done or not. A node needs _properties_ to know what it should check against, for example, a HIT node needs a _list_ of blocks that it will check if the player is holding; while a USE_ENCHANTMENT node needs a mapping of enchantment to level. Some nodes like GLYDE don't need a value and will ignore if you provide one.
|
||||
Nodes narrow down even further if an action can be done or not. A node needs _properties_ to know what it should check against, for example, a HIT node needs a _list_ of blocks that it will check if the player is holding; while a USE_ENCHANTMENT node needs a mapping of enchantment to level. Some nodes like glyde don't need a value and will ignore if you provide one.
|
||||
```yaml
|
||||
nodes:
|
||||
- [HIT]:
|
||||
|
|
@ -31,13 +31,4 @@ Triggered on `InventoryClickEvent` and `PlayerInteractEvent` (only if item is an
|
|||
Triggered on `PlayerMoveEvent`, returns true if player is gliding.
|
||||
|
||||
### USE_ENCHANTMENT
|
||||
Triggered on `BlockBreakEvent` and `onEntityDamageByEntityEvent`, returns true when the used item has an enchantment matching the provided mapping of enchantment-level.
|
||||
|
||||
### FORMBLOCK
|
||||
Triggered on `BlockFormEvent` (ex. triggers when snow is formed from rain), returns true when the block being formed is in the provided list of materials.
|
||||
|
||||
### ENDERMAN_ATTACK_PLAYER
|
||||
Triggered on `EndermanAttackPlayerEvent` (from actions other than hitting the Enderman), returns true.
|
||||
|
||||
### TAKE_LECTURN_BOOK
|
||||
Triggered on `PlayerTakeLecturnBookEvent`, returns true.
|
||||
Triggered on `BlockBreakEvent` and `onEntityDamageByEntityEvent`, returns true the used item has an enchantment matching the provided mapping of enchantment-level.
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package io.github.adrianvic.nemesiseye.impl.v1_7_3.events;
|
||||
package io.github.adrianvic.nemesiseye.impl;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.Events;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package io.github.adrianvic.nemesiseye.impl.v1_7_3;
|
||||
package io.github.adrianvic.nemesiseye.impl;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.Nemesis;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package io.github.adrianvic.nemesiseye.impl.v1_7_3.events;
|
||||
package io.github.adrianvic.nemesiseye.impl;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.Events;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package io.github.adrianvic.nemesiseye.impl.v1_7_3;
|
||||
package io.github.adrianvic.nemesiseye.impl;
|
||||
|
||||
import static org.bukkit.Bukkit.getServer;
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package io.github.adrianvic.nemesiseye.impl.v1_7_3.events;
|
||||
package io.github.adrianvic.nemesiseye.impl;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.Events;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
|
@ -1,16 +1,10 @@
|
|||
package io.github.adrianvic.nemesiseye.impl.v1_7_3;
|
||||
package io.github.adrianvic.nemesiseye.impl;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.Nemesis;
|
||||
import io.github.adrianvic.nemesiseye.impl.v1_7_3.commands.Eye;
|
||||
import io.github.adrianvic.nemesiseye.impl.v1_7_3.events.BlockEventListener;
|
||||
import io.github.adrianvic.nemesiseye.impl.v1_7_3.events.EntityEventListener;
|
||||
import io.github.adrianvic.nemesiseye.impl.v1_7_3.events.PlayerEventListener;
|
||||
import io.github.adrianvic.nemesiseye.policy.Action;
|
||||
import io.github.adrianvic.nemesiseye.policy.NodeHandler;
|
||||
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.reflection.Glimmer;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
|
|
@ -21,7 +15,6 @@ import org.bukkit.plugin.java.JavaPlugin;
|
|||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
|
@ -70,7 +63,6 @@ public class b1_7_3 implements Glimmer {
|
|||
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.BLOCK_PLACE, new BlockEventListener(), Event.Priority.Normal, plugin);
|
||||
pm.registerEvent(Event.Type.PLAYER_INTERACT, new PlayerEventListener(), Event.Priority.Normal, plugin);
|
||||
plugin.getCommand("eye").setExecutor(new Eye());
|
||||
}
|
||||
|
|
@ -80,43 +72,6 @@ public class b1_7_3 implements Glimmer {
|
|||
return entity.getItemInHand();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAir(ItemStack item) {
|
||||
return item == null || item.getType() == Material.AIR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGliding(org.bukkit.entity.Player player) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGliding(org.bukkit.entity.Player player, boolean gliding) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(org.bukkit.command.CommandSender sender, String permission) {
|
||||
if (sender instanceof org.bukkit.entity.Player p) {
|
||||
return p.isOp();
|
||||
}
|
||||
return true; // Console always has permission
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isArmorEquipAttempt(org.bukkit.event.Event event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getEquippedItem(org.bukkit.event.Event event) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Action, NodeHandler> getExtraHandlers() {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(CommandSender commandSender, String text) {
|
||||
String[] lines = text.split("\\r?\\n");
|
||||
|
|
@ -144,18 +99,4 @@ public class b1_7_3 implements Glimmer {
|
|||
public boolean hasAnyEnchantment(ItemStack itemStack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isArmor(ItemStack item) {
|
||||
if (item == null || item.getType() == Material.AIR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String name = item.getType().name();
|
||||
|
||||
return name.endsWith("_HELMET")
|
||||
|| name.endsWith("_CHESTPLATE")
|
||||
|| name.endsWith("_LEGGINGS")
|
||||
|| name.endsWith("_BOOTS");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package io.github.adrianvic.nemesiseye.impl.v1_7_3.commands;
|
||||
package io.github.adrianvic.nemesiseye.impl.commands;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.commands.EyeCore;
|
||||
import org.bukkit.command.Command;
|
||||
|
|
@ -7,22 +7,13 @@ import java.util.Map;
|
|||
import java.util.regex.Pattern;
|
||||
|
||||
public class DataShifter {
|
||||
|
||||
public static boolean safeMatches(String expression, String against) {
|
||||
String cleanPattern = expression.trim();
|
||||
Pattern pattern = Pattern.compile(cleanPattern, Pattern.CASE_INSENSITIVE);
|
||||
return pattern.matcher(against).matches();
|
||||
}
|
||||
|
||||
public static boolean safeMatches(List<String> expressions, String against) {
|
||||
for (String s : expressions) {
|
||||
if (DataShifter.safeMatches(s, against)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static List<String> parseValueToStringList(List<Object> values) {
|
||||
List<String> result = new ArrayList<>();
|
||||
for (Object o : values) {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
package io.github.adrianvic.nemesiseye;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.policy.Action;
|
||||
import io.github.adrianvic.nemesiseye.reflection.Glimmer;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
|
@ -15,10 +18,6 @@ import java.util.List;
|
|||
|
||||
public class Events {
|
||||
|
||||
private static Glimmer g() {
|
||||
return Nemesis.getInstance().getGlimmer();
|
||||
}
|
||||
|
||||
public static void onBlockBreak(BlockBreakEvent event) {
|
||||
event.setCancelled(
|
||||
!Validator.can(
|
||||
|
|
@ -32,12 +31,12 @@ public class Events {
|
|||
public static void onInteractionEvent(PlayerInteractEvent event) {
|
||||
ItemStack item = event.getItem();
|
||||
|
||||
if (g().isAir(item)) {
|
||||
if (item == null || item.getType().isAir()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Right-click armor equipping
|
||||
if (g().isArmor(item)
|
||||
if (isArmor(item)
|
||||
&& !Validator.can(event.getPlayer(), Action.EQUIP, event)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
|
|
@ -45,7 +44,7 @@ public class Events {
|
|||
|
||||
// Normal item interaction
|
||||
event.setCancelled(
|
||||
!Validator.can(event.getPlayer(), List.of(Action.INTERACT, Action.INTERACTWITH), event)
|
||||
!Validator.can(event.getPlayer(), Action.INTERACT, event)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -68,17 +67,60 @@ public class Events {
|
|||
}
|
||||
|
||||
public static void onPlayerMoveEvent(PlayerMoveEvent event) {
|
||||
if (g().isGliding(event.getPlayer())
|
||||
if (event.getPlayer().isGliding()
|
||||
&& !Validator.can(
|
||||
event.getPlayer(),
|
||||
List.of(Action.GLYDE),
|
||||
event
|
||||
)) {
|
||||
g().setGliding(event.getPlayer(), false);
|
||||
event.getPlayer().setGliding(false);
|
||||
}
|
||||
}
|
||||
|
||||
public static void onCreatureSpawnEvent(CreatureSpawnEvent event) {
|
||||
event.setCancelled(!Validator.can(event.getEntity(), Action.SPAWN, event));
|
||||
public static void onInventoryClickEvent(InventoryClickEvent event) {
|
||||
if (!isArmorEquipAttempt(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
HumanEntity entity = event.getWhoClicked();
|
||||
|
||||
if (!Validator.can(entity, Action.EQUIP, event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isArmorEquipAttempt(InventoryClickEvent event) {
|
||||
if (event.getSlotType() == InventoryType.SlotType.ARMOR) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (event.isShiftClick()) {
|
||||
return isArmor(event.getCurrentItem());
|
||||
}
|
||||
|
||||
if (event.getClick() == ClickType.NUMBER_KEY
|
||||
&& event.getSlotType() == InventoryType.SlotType.ARMOR
|
||||
&& event.getWhoClicked() instanceof Player player) {
|
||||
return isArmor(
|
||||
player.getInventory().getItem(event.getHotbarButton())
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isArmor(ItemStack item) {
|
||||
if (item == null || item.getType().isAir()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Material type = item.getType();
|
||||
String name = type.name();
|
||||
|
||||
return name.endsWith("_HELMET")
|
||||
|| name.endsWith("_CHESTPLATE")
|
||||
|| name.endsWith("_LEGGINGS")
|
||||
|| name.endsWith("_BOOTS")
|
||||
|| type == Material.ELYTRA;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
package io.github.adrianvic.nemesiseye;
|
||||
|
||||
import com.destroystokyo.paper.event.entity.EndermanAttackPlayerEvent;
|
||||
import io.github.adrianvic.nemesiseye.policy.Action;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.block.BlockFormEvent;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.player.PlayerTakeLecternBookEvent;
|
||||
|
||||
public class ModernEvents {
|
||||
public static void onInventoryClickEvent(InventoryClickEvent event) {
|
||||
if (!Nemesis.getInstance().getGlimmer().isArmorEquipAttempt(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
HumanEntity entity = event.getWhoClicked();
|
||||
|
||||
if (!Validator.can(entity, Action.EQUIP, event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void onEndermanAttackPlayerEvent(EndermanAttackPlayerEvent event) {
|
||||
if (!Validator.can(event.getEntity(), Action.ENDERMAN_ATTACK_PLAYER, event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void onBlockFormEvent(BlockFormEvent event) {
|
||||
boolean canceled = !Validator.can(event.getBlock().getWorld(), Action.FORMBLOCK, event);
|
||||
event.setCancelled(canceled);
|
||||
}
|
||||
|
||||
public static void onPlayerTakeLecternBookEvent(PlayerTakeLecternBookEvent event) {
|
||||
if (!Validator.can(event.getPlayer().getWorld(), Action.TAKE_LECTERN_BOOK, event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,10 +2,7 @@ package io.github.adrianvic.nemesiseye;
|
|||
|
||||
import io.github.adrianvic.nemesiseye.policy.Action;
|
||||
import io.github.adrianvic.nemesiseye.policy.Policy;
|
||||
import io.github.adrianvic.nemesiseye.policy.policies.GlobalPolicy;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.event.Event;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -22,9 +19,12 @@ public class Validator {
|
|||
return true;
|
||||
}
|
||||
|
||||
public static boolean can(LivingEntity entity, Action action, Event event) {
|
||||
public static boolean can(HumanEntity entity, Action action, Event event) {
|
||||
boolean restricted = false;
|
||||
boolean allowed = false;
|
||||
|
||||
for (Policy policy : getPoliciesForEntity(entity)) {
|
||||
boolean matches = policy.matches(entity.getWorld(), action, event);
|
||||
boolean matches = policy.matches(entity, action, event);
|
||||
|
||||
switch (policy.effect()) {
|
||||
case ALLOW:
|
||||
|
|
@ -40,38 +40,8 @@ public class Validator {
|
|||
return true;
|
||||
}
|
||||
|
||||
public static boolean can(World world, Action action, Event event) {
|
||||
boolean allowed = true;
|
||||
|
||||
for (GlobalPolicy policy : getGlobalPolicies()) {
|
||||
boolean matches = policy.matches(world, action, event);
|
||||
|
||||
switch (policy.effect()) {
|
||||
case ALLOW:
|
||||
if (matches) return true;
|
||||
break;
|
||||
|
||||
case DENY:
|
||||
if (matches) return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return allowed;
|
||||
}
|
||||
|
||||
public static List<GlobalPolicy> getGlobalPolicies() {
|
||||
List<Policy> ps = Config.getInstance().getPolicies();
|
||||
List<GlobalPolicy> result = new ArrayList<>();
|
||||
|
||||
for (Policy policy : ps) {
|
||||
if (policy instanceof GlobalPolicy p) result.add(p);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<Policy> getPoliciesForEntity(LivingEntity entity) {
|
||||
public static List<Policy> getPoliciesForEntity(HumanEntity entity) {
|
||||
List<Policy> ps = Config.getInstance().getPolicies();
|
||||
List<Policy> result = new ArrayList<>();
|
||||
|
||||
|
|
|
|||
|
|
@ -26,9 +26,10 @@ public class EyeCore {
|
|||
commandSender.sendMessage("Unknown command, try '/eye help' to list available commands.");
|
||||
return true;
|
||||
}
|
||||
else if (glim.hasPermission(commandSender, sub.permission())) {
|
||||
else if (commandSender.hasPermission(sub.permission())) {
|
||||
return sub.execute(commandSender, Arrays.copyOfRange(strings, 1, strings.length));
|
||||
} else {
|
||||
// Nemesis.getInstance().getLogger().info("does not have %s".formatted(sub.permission()));
|
||||
Commands.sendNoPermissionError(commandSender);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -40,15 +41,15 @@ public class EyeCore {
|
|||
if (strings.length == 1) {
|
||||
Map<String, Subcommand> cmds = new HashMap<>();
|
||||
for (Map.Entry<String, Subcommand> e : Commands.getAll().entrySet()) {
|
||||
if (glim.hasPermission(commandSender, e.getValue().permission())) {
|
||||
if (e.getValue().hasPermission(commandSender)) {
|
||||
cmds.put(e.getKey(), e.getValue());
|
||||
cmds.put(e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
return new ArrayList<>(cmds.keySet());
|
||||
}
|
||||
|
||||
Subcommand sub = Commands.get(strings[0].toLowerCase());
|
||||
if (sub != null && glim.hasPermission(commandSender, sub.permission())) {
|
||||
if (sub != null && commandSender.hasPermission(sub.permission())) {
|
||||
return sub.onTabComplete(commandSender, Arrays.copyOfRange(strings, 1, strings.length));
|
||||
}
|
||||
return List.of();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package io.github.adrianvic.nemesiseye.commands.sub;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.Nemesis;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.permissions.Permission;
|
||||
|
||||
|
|
@ -14,6 +13,6 @@ public interface Subcommand {
|
|||
List<String> onTabComplete(CommandSender sender, String[] strings);
|
||||
String permission();
|
||||
default boolean hasPermission(CommandSender sender) {
|
||||
return Nemesis.getInstance().getGlimmer().hasPermission(sender, permission());
|
||||
return sender.hasPermission(permission());
|
||||
}
|
||||
}
|
||||
|
|
@ -2,16 +2,11 @@ package io.github.adrianvic.nemesiseye.policy;
|
|||
|
||||
public enum Action {
|
||||
INTERACT,
|
||||
INTERACTWITH,
|
||||
BREAK,
|
||||
HIT,
|
||||
// TODO CRAFT,
|
||||
EQUIP,
|
||||
PLACE,
|
||||
USE_ENCHANTMENT,
|
||||
GLYDE,
|
||||
SPAWN,
|
||||
ENDERMAN_ATTACK_PLAYER,
|
||||
FORMBLOCK,
|
||||
TAKE_LECTERN_BOOK
|
||||
GLYDE
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
package io.github.adrianvic.nemesiseye.policy;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.Event;
|
||||
|
||||
public interface NodeHandler {
|
||||
boolean check(World world, PolicyNode node, Action action, Event event);
|
||||
boolean check(HumanEntity entity, PolicyNode node, Action action, Event event);
|
||||
}
|
||||
|
|
@ -1,36 +1,24 @@
|
|||
package io.github.adrianvic.nemesiseye.policy;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.Nemesis;
|
||||
import io.github.adrianvic.nemesiseye.policy.handlers.*;
|
||||
import io.github.adrianvic.nemesiseye.policy.handlers.generic.Boolean;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class NodeHandlers {
|
||||
private static final Map<Action, NodeHandler> handlers = new HashMap<>();
|
||||
|
||||
|
||||
static {
|
||||
handlers.put(Action.HIT, new UseItem());
|
||||
handlers.put(Action.PLACE, new BePlaced());
|
||||
handlers.put(Action.INTERACT, new UseItem());
|
||||
handlers.put(Action.USE_ENCHANTMENT, new UseEnchantment());
|
||||
handlers.put(Action.GLYDE, new Boolean());
|
||||
handlers.put(Action.EQUIP, new Equip());
|
||||
handlers.put(Action.SPAWN, new Spawn());
|
||||
handlers.put(Action.BREAK, new UseItem()); // TODO: implement place handler
|
||||
handlers.put(Action.INTERACTWITH, new InteractWith());
|
||||
handlers.put(Action.ENDERMAN_ATTACK_PLAYER, new Boolean());
|
||||
handlers.put(Action.TAKE_LECTERN_BOOK, new Boolean());
|
||||
handlers.put(Action.HIT, new useItem());
|
||||
handlers.put(Action.PLACE, new bePlaced());
|
||||
handlers.put(Action.INTERACT, new useItem());
|
||||
handlers.put(Action.USE_ENCHANTMENT, new useEnchantment());
|
||||
handlers.put(Action.GLYDE, new glyde());
|
||||
handlers.put(Action.EQUIP, new equip());
|
||||
handlers.put(Action.BREAK, new useItem()); // TODO: implement place handler
|
||||
}
|
||||
|
||||
|
||||
public static NodeHandler get(Action type) {
|
||||
NodeHandler handler = handlers.get(type);
|
||||
|
||||
if (handler == null) {
|
||||
handler = Nemesis.getInstance().getGlimmer().getExtraHandlers().get(type);
|
||||
}
|
||||
|
||||
return handler;
|
||||
return handlers.get(type);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package io.github.adrianvic.nemesiseye.policy;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.Event;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -10,7 +9,7 @@ public interface Policy {
|
|||
String name();
|
||||
List<PolicyNode> nodes();
|
||||
boolean policyAllowList();
|
||||
boolean applies(LivingEntity entity);
|
||||
boolean applies(HumanEntity entity);
|
||||
Effect effect();
|
||||
int weight();
|
||||
List<String> worlds();
|
||||
|
|
@ -19,13 +18,13 @@ public interface Policy {
|
|||
nodes().add(node);
|
||||
}
|
||||
|
||||
default boolean matches(World world, Action action, Event event) {
|
||||
if (!worlds().contains(world.getName())) {
|
||||
default boolean matches(HumanEntity entity, Action action, Event event) {
|
||||
if (!worlds().contains(entity.getWorld().getName())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (PolicyNode node : nodes()) {
|
||||
if (node.matches(world, action, event)) {
|
||||
if (node.matches(entity, action, event)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package io.github.adrianvic.nemesiseye.policy;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.DataShifter;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.Event;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -18,28 +18,27 @@ public record PolicyNode(List<Action> actions, List<Object> values) {
|
|||
List<Action> nodeActions = new ArrayList<>();
|
||||
List<Object> nodeValues = new ArrayList<>();
|
||||
|
||||
if (rawNode.getKey() instanceof List<?> rawTypes && (rawNode.getValue() == null || rawNode.getValue() instanceof Map<?, ?>)) {
|
||||
if (rawNode.getKey() instanceof List<?> rawTypes && rawNode.getValue() instanceof Map<?,?> rawNodeValues) {
|
||||
for (Object rawType : rawTypes) {
|
||||
if (rawType instanceof String rts && !rts.isEmpty() && DataShifter.enumOrDefault(Action.class, rts, null) != null) {
|
||||
if (rawType instanceof String rts && !rts.isEmpty() && !(rts == null) && DataShifter.enumOrDefault(Action.class, rts, null) != null) {
|
||||
nodeActions.add(DataShifter.enumOrDefault(Action.class, rts, null));
|
||||
}
|
||||
}
|
||||
|
||||
if (rawNode.getValue() instanceof Map<?, ?> rawNodeValues) {
|
||||
Map<String, Object> semiParsedNodeValue = new HashMap<>();
|
||||
for (Map.Entry<?, ?> rawNodeValueEntries : rawNodeValues.entrySet()) {
|
||||
if (rawNodeValueEntries.getKey() instanceof String stringKey) {
|
||||
semiParsedNodeValue.put(stringKey, rawNodeValueEntries.getValue());
|
||||
}
|
||||
Map<String, Object> semiParsedNodeValue = new HashMap<>();
|
||||
for (Map.Entry<?,?> rawNodeValueEntries : rawNodeValues.entrySet()) {
|
||||
if (rawNodeValueEntries.getKey() instanceof String stringKey) {
|
||||
semiParsedNodeValue.put(stringKey, rawNodeValueEntries.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (semiParsedNodeValue.get("values") instanceof List<?> l) {
|
||||
nodeValues.addAll(l);
|
||||
if (semiParsedNodeValue.get("values") instanceof List<?> l) {
|
||||
for (Object v : l) {
|
||||
nodeValues.add(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!nodeActions.isEmpty()) {
|
||||
if (!nodeActions.isEmpty() && !nodeValues.isEmpty()) {
|
||||
PolicyNode newNode = new PolicyNode(nodeActions, nodeValues);
|
||||
nodes.add(newNode);
|
||||
}
|
||||
|
|
@ -56,7 +55,7 @@ public record PolicyNode(List<Action> actions, List<Object> values) {
|
|||
return handlers;
|
||||
}
|
||||
|
||||
public boolean matches(World world, Action action, Event event) {
|
||||
public boolean matches(HumanEntity entity, Action action, Event event) {
|
||||
if (!actions.contains(action)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -67,6 +66,7 @@ public record PolicyNode(List<Action> actions, List<Object> values) {
|
|||
return false;
|
||||
}
|
||||
|
||||
return handler.check(world, this, action, event);
|
||||
boolean result = handler.check(entity, this, action, event);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -34,11 +34,8 @@ public interface PolicyParser {
|
|||
|
||||
if (rawNodes instanceof List<?> list) {
|
||||
for (Object o : list) {
|
||||
if (o instanceof Map<?, ?> map) {
|
||||
if (o instanceof Map<?, ?> map)
|
||||
nodeList.add((Map<Object, Object>) map);
|
||||
} else if (o instanceof List<?> actions) {
|
||||
nodeList.add(Map.of(actions, Map.of()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
package io.github.adrianvic.nemesiseye.policy.handlers;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.DataShifter;
|
||||
import io.github.adrianvic.nemesiseye.policy.Action;
|
||||
import io.github.adrianvic.nemesiseye.policy.NodeHandler;
|
||||
import io.github.adrianvic.nemesiseye.policy.PolicyNode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.block.BlockFormEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class FormBlock implements NodeHandler {
|
||||
@Override
|
||||
public boolean check(World world, PolicyNode node, Action action, Event event) {
|
||||
if (event instanceof BlockFormEvent e) {
|
||||
Material material = e.getNewState().getType();
|
||||
|
||||
String type = material.toString();
|
||||
List<String> parsedValue = DataShifter.parseValueToStringList(node.values());
|
||||
|
||||
return DataShifter.safeMatches(parsedValue, type);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
package io.github.adrianvic.nemesiseye.policy.handlers;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.DataShifter;
|
||||
import io.github.adrianvic.nemesiseye.Nemesis;
|
||||
import io.github.adrianvic.nemesiseye.policy.Action;
|
||||
import io.github.adrianvic.nemesiseye.policy.NodeHandler;
|
||||
import io.github.adrianvic.nemesiseye.policy.PolicyNode;
|
||||
import io.github.adrianvic.nemesiseye.reflection.Glimmer;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class InteractWith implements NodeHandler {
|
||||
@Override
|
||||
public boolean check(World world, PolicyNode node, Action action, Event event) {
|
||||
if (event instanceof PlayerInteractEvent e) {
|
||||
Material material = e.getMaterial();
|
||||
|
||||
String type = material.toString();
|
||||
List<String> parsedValue = DataShifter.parseValueToStringList(node.values());
|
||||
|
||||
return DataShifter.safeMatches(parsedValue, type);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
package io.github.adrianvic.nemesiseye.policy.handlers;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.DataShifter;
|
||||
import io.github.adrianvic.nemesiseye.policy.Action;
|
||||
import io.github.adrianvic.nemesiseye.policy.NodeHandler;
|
||||
import io.github.adrianvic.nemesiseye.policy.PolicyNode;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.entity.EntityEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Spawn implements NodeHandler {
|
||||
|
||||
@Override
|
||||
public boolean check(World world, PolicyNode node, Action action, Event event) {
|
||||
if (event instanceof EntityEvent e) {
|
||||
String type = e.getEntity().getType().name();
|
||||
List<String> parsedValue = DataShifter.parseValueToStringList(node.values());
|
||||
|
||||
return DataShifter.safeMatches(parsedValue, type);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
package io.github.adrianvic.nemesiseye.policy.handlers;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.DataShifter;
|
||||
import io.github.adrianvic.nemesiseye.Nemesis;
|
||||
import io.github.adrianvic.nemesiseye.policy.Action;
|
||||
import io.github.adrianvic.nemesiseye.policy.NodeHandler;
|
||||
import io.github.adrianvic.nemesiseye.policy.PolicyNode;
|
||||
import io.github.adrianvic.nemesiseye.reflection.Glimmer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.entity.EntityEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class UseEnchantment implements NodeHandler {
|
||||
private final Glimmer glim = Nemesis.getInstance().getGlimmer();
|
||||
|
||||
@Override
|
||||
public boolean check(World world, PolicyNode node, Action action, Event event) {
|
||||
if (event instanceof EntityEvent entityEvent && entityEvent.getEntity() instanceof HumanEntity e) {
|
||||
ItemStack item = glim.getItemInMainHandHumanEntity(e);
|
||||
|
||||
if (glim.isAir(item)) return false;
|
||||
if (!glim.hasItemMeta(item)) return false;
|
||||
if (!glim.hasAnyEnchantment(item)) return false;
|
||||
|
||||
return glim.hasEnchantment(item,
|
||||
DataShifter.parseValueToStringMap(node.values()));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
package io.github.adrianvic.nemesiseye.policy.handlers;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.DataShifter;
|
||||
import io.github.adrianvic.nemesiseye.Nemesis;
|
||||
import io.github.adrianvic.nemesiseye.policy.Action;
|
||||
import io.github.adrianvic.nemesiseye.policy.NodeHandler;
|
||||
import io.github.adrianvic.nemesiseye.policy.PolicyNode;
|
||||
import io.github.adrianvic.nemesiseye.reflection.Glimmer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.entity.EntityEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UseItem implements NodeHandler {
|
||||
|
||||
private final Glimmer glim = Nemesis.getInstance().getGlimmer();
|
||||
|
||||
@Override
|
||||
public boolean check(World world, PolicyNode node, Action action, Event event) {
|
||||
if (event instanceof EntityEvent entityEvent && entityEvent.getEntity() instanceof HumanEntity e) {
|
||||
org.bukkit.inventory.ItemStack item = glim.getItemInMainHandHumanEntity(e);
|
||||
if (glim.isAir(item)) return false;
|
||||
|
||||
String type = item.getType().toString();
|
||||
List<String> parsedValue = DataShifter.parseValueToStringList(node.values());
|
||||
|
||||
return DataShifter.safeMatches(parsedValue, type);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -4,22 +4,22 @@ import io.github.adrianvic.nemesiseye.DataShifter;
|
|||
import io.github.adrianvic.nemesiseye.policy.Action;
|
||||
import io.github.adrianvic.nemesiseye.policy.NodeHandler;
|
||||
import io.github.adrianvic.nemesiseye.policy.PolicyNode;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BePlaced implements NodeHandler {
|
||||
public class bePlaced implements NodeHandler {
|
||||
@Override
|
||||
public boolean check(World world, PolicyNode node, Action action, Event event) {
|
||||
public boolean check(HumanEntity entity, PolicyNode node, Action action, Event event) {
|
||||
if (event instanceof BlockPlaceEvent bpe) {
|
||||
String type = bpe.getBlock().getType().toString();
|
||||
List<String> parsedValue = DataShifter.parseValueToStringList(node.values());
|
||||
|
||||
return DataShifter.safeMatches(parsedValue, type);
|
||||
for (String s : DataShifter.parseValueToStringList(node.values())) {
|
||||
if (DataShifter.safeMatches(s, type)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
package io.github.adrianvic.nemesiseye.policy.handlers;
|
||||
|
||||
import com.destroystokyo.paper.event.player.PlayerArmorChangeEvent;
|
||||
import io.github.adrianvic.nemesiseye.DataShifter;
|
||||
import io.github.adrianvic.nemesiseye.policy.Action;
|
||||
import io.github.adrianvic.nemesiseye.policy.NodeHandler;
|
||||
import io.github.adrianvic.nemesiseye.policy.PolicyNode;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class equip implements NodeHandler {
|
||||
|
||||
@Override
|
||||
public boolean check(HumanEntity entity, PolicyNode node, Action action, Event event) {
|
||||
ItemStack item = null;
|
||||
|
||||
if (event instanceof PlayerArmorChangeEvent e) {
|
||||
// Right click equip, dispenser equip, etc...
|
||||
item = e.getNewItem();
|
||||
}
|
||||
|
||||
else if (event instanceof InventoryClickEvent e) {
|
||||
InventoryType.SlotType slotType = e.getSlotType();
|
||||
|
||||
// Number key swap into armor slot
|
||||
if (e.getClick() == ClickType.NUMBER_KEY
|
||||
&& slotType == InventoryType.SlotType.ARMOR
|
||||
&& entity instanceof Player player) {
|
||||
item = player.getInventory().getItem(e.getHotbarButton());
|
||||
}
|
||||
|
||||
// Shift click armor from inventory
|
||||
else if (e.isShiftClick()) {
|
||||
ItemStack current = e.getCurrentItem();
|
||||
|
||||
if (isArmor(current)) {
|
||||
item = current;
|
||||
}
|
||||
}
|
||||
|
||||
// Cursor click onto armor slot
|
||||
else if (slotType == InventoryType.SlotType.ARMOR) {
|
||||
ItemStack cursor = e.getCursor();
|
||||
|
||||
if (isArmor(cursor)) {
|
||||
item = cursor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isArmor(item)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String type = item.getType().name();
|
||||
|
||||
for (String s : DataShifter.parseValueToStringList(node.values())) {
|
||||
if (DataShifter.safeMatches(s, type)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isArmor(ItemStack item) {
|
||||
if (item == null || item.getType().isAir()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String name = item.getType().name();
|
||||
|
||||
return name.endsWith("_HELMET")
|
||||
|| name.endsWith("_CHESTPLATE")
|
||||
|| name.endsWith("_LEGGINGS")
|
||||
|| name.endsWith("_BOOTS")
|
||||
|| item.getType() == org.bukkit.Material.ELYTRA;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
package io.github.adrianvic.nemesiseye.policy.handlers.generic;
|
||||
package io.github.adrianvic.nemesiseye.policy.handlers;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.policy.Action;
|
||||
import io.github.adrianvic.nemesiseye.policy.NodeHandler;
|
||||
import io.github.adrianvic.nemesiseye.policy.PolicyNode;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.Event;
|
||||
|
||||
public class Boolean implements NodeHandler {
|
||||
public class glyde implements NodeHandler {
|
||||
@Override
|
||||
public boolean check(World world, PolicyNode node, Action action, Event event) {
|
||||
public boolean check(HumanEntity entity, PolicyNode node, Action action, Event event) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -6,26 +6,23 @@ 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.World;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Equip implements NodeHandler {
|
||||
public class useEnchantment implements NodeHandler {
|
||||
private final Glimmer glim = Nemesis.getInstance().getGlimmer();
|
||||
|
||||
@Override
|
||||
public boolean check(World world, PolicyNode node, Action action, Event event) {
|
||||
ItemStack item = glim.getEquippedItem(event);
|
||||
public boolean check(HumanEntity entity, PolicyNode node, Action action, Event event) {
|
||||
ItemStack item = glim.getItemInMainHandHumanEntity(entity);
|
||||
|
||||
if (!glim.isArmor(item)) {
|
||||
return false;
|
||||
}
|
||||
if (!glim.hasItemMeta(item)) return false;
|
||||
if (!glim.hasAnyEnchantment(item)) return false;
|
||||
|
||||
String type = item.getType().name();
|
||||
List<String> parsedValue = DataShifter.parseValueToStringList(node.values());
|
||||
boolean matches = glim.hasEnchantment(item,
|
||||
DataShifter.parseValueToStringMap(node.values()));
|
||||
|
||||
return DataShifter.safeMatches(parsedValue, type);
|
||||
return matches;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package io.github.adrianvic.nemesiseye.policy.handlers;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.DataShifter;
|
||||
import io.github.adrianvic.nemesiseye.Nemesis;
|
||||
import io.github.adrianvic.nemesiseye.policy.Action;
|
||||
import io.github.adrianvic.nemesiseye.policy.NodeHandler;
|
||||
import io.github.adrianvic.nemesiseye.policy.PolicyNode;
|
||||
import io.github.adrianvic.nemesiseye.reflection.Glimmer;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.Event;
|
||||
|
||||
public class useItem implements NodeHandler {
|
||||
|
||||
private final Glimmer glim = Nemesis.getInstance().getGlimmer();
|
||||
|
||||
@Override
|
||||
public boolean check(HumanEntity entity, PolicyNode node, Action action, Event event) {
|
||||
String type = glim.getItemInMainHandHumanEntity(entity).getType().toString();
|
||||
|
||||
for (String s : DataShifter.parseValueToStringList(node.values())) {
|
||||
if (DataShifter.safeMatches(s, type)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -4,13 +4,12 @@ import io.github.adrianvic.nemesiseye.policy.Effect;
|
|||
import io.github.adrianvic.nemesiseye.policy.Policy;
|
||||
import io.github.adrianvic.nemesiseye.policy.PolicyNode;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record Core(String name, List<String> worlds, List<PolicyNode> nodes, boolean nodeAllowlist, boolean policyAllowList, Effect effect, int weight) implements Policy {
|
||||
@Override
|
||||
public boolean applies(LivingEntity entity) {
|
||||
public boolean applies(HumanEntity entity) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -4,12 +4,11 @@ import io.github.adrianvic.nemesiseye.policy.Effect;
|
|||
import io.github.adrianvic.nemesiseye.policy.Policy;
|
||||
import io.github.adrianvic.nemesiseye.policy.PolicyNode;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record GlobalPolicy(String name, List<String> worlds, List<PolicyNode> nodes, boolean policyAllowList, Effect effect, int weight) implements Policy {
|
||||
public boolean applies(LivingEntity entity) {
|
||||
public boolean applies(HumanEntity entity) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,13 +5,12 @@ 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.entity.LivingEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record LocationPolicy(String name, List<String> worlds, List<Glimmer.Box> locations, List<PolicyNode> nodes, boolean nodeAllowlist, boolean policyAllowList, Effect effect, int weight) implements Policy {
|
||||
@Override
|
||||
public boolean applies(LivingEntity entity) {
|
||||
public boolean applies(HumanEntity entity) {
|
||||
for (Glimmer.Box box : locations) {
|
||||
if (box.contains(entity.getLocation().toVector(), entity.getWorld())) {
|
||||
return !policyAllowList;
|
||||
|
|
|
|||
|
|
@ -1,20 +1,18 @@
|
|||
package io.github.adrianvic.nemesiseye.policy.policies;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.Nemesis;
|
||||
import io.github.adrianvic.nemesiseye.policy.Effect;
|
||||
import io.github.adrianvic.nemesiseye.policy.Policy;
|
||||
import io.github.adrianvic.nemesiseye.policy.PolicyNode;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record PermissionPolicy(String name, List<String> worlds, List<String> permissions, List<PolicyNode> nodes, boolean policyAllowList, Effect effect, int weight) implements Policy {
|
||||
|
||||
@Override
|
||||
public boolean applies(LivingEntity entity) {
|
||||
public boolean applies(HumanEntity entity) {
|
||||
for (String perm : permissions) {
|
||||
if (Nemesis.getInstance().getGlimmer().hasPermission(entity, perm)) {
|
||||
if (entity.hasPermission(perm)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,14 +4,13 @@ import io.github.adrianvic.nemesiseye.policy.Effect;
|
|||
import io.github.adrianvic.nemesiseye.policy.Policy;
|
||||
import io.github.adrianvic.nemesiseye.policy.PolicyNode;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record PlayerNamePolicy(String name, List<String> worlds, List<String> playerName, List<PolicyNode> nodes, Effect effect, boolean policyAllowList, int weight) implements Policy {
|
||||
|
||||
@Override
|
||||
public boolean applies(LivingEntity entity) {
|
||||
public boolean applies(HumanEntity entity) {
|
||||
if (playerName.contains(entity.getName())) {
|
||||
return !policyAllowList();
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
package io.github.adrianvic.nemesiseye.reflection;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.policy.Action;
|
||||
import io.github.adrianvic.nemesiseye.policy.NodeHandler;
|
||||
import io.github.adrianvic.nemesiseye.policy.Policy;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
|
|
@ -28,22 +26,8 @@ public interface Glimmer {
|
|||
boolean hasItemMeta(ItemStack item);
|
||||
boolean hasEnchantment(ItemStack item, Map<String, String> valuesmap);
|
||||
boolean hasAnyEnchantment(ItemStack itemStack);
|
||||
boolean isArmor(ItemStack item);
|
||||
boolean isAir(ItemStack item);
|
||||
ItemStack getItemInMainHandHumanEntity(HumanEntity entity);
|
||||
|
||||
// Players
|
||||
boolean isGliding(org.bukkit.entity.Player player);
|
||||
void setGliding(org.bukkit.entity.Player player, boolean gliding);
|
||||
boolean hasPermission(org.bukkit.command.CommandSender sender, String permission);
|
||||
|
||||
// Events
|
||||
boolean isArmorEquipAttempt(org.bukkit.event.Event event);
|
||||
ItemStack getEquippedItem(org.bukkit.event.Event event);
|
||||
|
||||
// Handlers
|
||||
Map<Action, NodeHandler> getExtraHandlers();
|
||||
|
||||
// Commands
|
||||
void sendMessage(CommandSender commandSender, String text);
|
||||
|
||||
|
|
|
|||
|
|
@ -3,39 +3,145 @@ package io.github.adrianvic.nemesiseye.reflection;
|
|||
import io.github.adrianvic.nemesiseye.DataShifter;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class VersionMatcher {
|
||||
|
||||
public VersionMatcher() {}
|
||||
|
||||
public Glimmer loadGlim() {
|
||||
String rawVersion = null;
|
||||
try {
|
||||
rawVersion = Bukkit.getMinecraftVersion();
|
||||
} catch (NoSuchMethodError ignored) {}
|
||||
private record Entry(String pattern, String classSuffix) {}
|
||||
|
||||
if (rawVersion == null || rawVersion.isEmpty()) {
|
||||
String v = Bukkit.getVersion(); // e.g. "git-Bukkit-0.0.0-1060-... (MC: 1.7.3)"
|
||||
int start = v.lastIndexOf("MC: ");
|
||||
if (start != -1) {
|
||||
rawVersion = v.substring(start + 4, v.length() - 1);
|
||||
} else {
|
||||
rawVersion = "unknown";
|
||||
public String getVersion(String type, String serverVersion) {
|
||||
if (type == null || serverVersion == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
Map<String, List<Entry>> map = populateMap();
|
||||
List<Entry> entries = map.get(type.toLowerCase());
|
||||
if (entries == null || entries.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
for (Entry e : entries) {
|
||||
if (DataShifter.safeMatches(e.pattern, serverVersion)) {
|
||||
return e.pattern + "|" + e.classSuffix;
|
||||
}
|
||||
}
|
||||
|
||||
String impl = DataShifter.safeMatches("^1\\.7\\.3$", rawVersion)
|
||||
? "b1_7_3"
|
||||
: "r1_21";
|
||||
List<Entry> sorted = new ArrayList<>(entries);
|
||||
Collections.sort(sorted, (a, b) -> compareVersions(a.pattern, b.pattern));
|
||||
|
||||
String subPkg = impl.equals("b1_7_3") ? "v1_7_3" : "v1_21";
|
||||
Glimmer glim = tryInstantiate(
|
||||
"io.github.adrianvic.nemesiseye.impl." + subPkg + "." + impl);
|
||||
Entry oldest = sorted.get(0);
|
||||
Entry newest = sorted.get(sorted.size() - 1);
|
||||
|
||||
if (glim == null) {
|
||||
throw new IllegalStateException("Missing implementation: " + impl);
|
||||
int cmpOldest = compareVersions(serverVersion, oldest.pattern);
|
||||
int cmpNewest = compareVersions(serverVersion, newest.pattern);
|
||||
|
||||
if (cmpOldest < 0) {
|
||||
return oldest.pattern + "|" + oldest.classSuffix;
|
||||
} else if (cmpNewest > 0) {
|
||||
return newest.pattern + "|" + newest.classSuffix;
|
||||
}
|
||||
|
||||
return glim;
|
||||
// should not happen because we already tried all patterns
|
||||
return newest.pattern + "|" + newest.classSuffix;
|
||||
}
|
||||
|
||||
private Map<String, List<Entry>> populateMap() {
|
||||
Map<String, List<Entry>> map = new HashMap<>();
|
||||
|
||||
// RELEASE patterns, newest first (order does not matter for matching)
|
||||
map.put("release", List.of(
|
||||
new Entry("^1\\.21\\..*$", "r1_21")
|
||||
));
|
||||
|
||||
// BETA patterns
|
||||
map.put("beta", List.of(
|
||||
new Entry("^1\\.7\\.3$", "b1_7_3")
|
||||
));
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
private int compareVersions(String v1, String v2) {
|
||||
String clean1 = v1.replaceAll("[^0-9.]", "");
|
||||
String clean2 = v2.replaceAll("[^0-9.]", "");
|
||||
|
||||
String[] a1 = clean1.split("\\.");
|
||||
String[] a2 = clean2.split("\\.");
|
||||
|
||||
int len = Math.max(a1.length, a2.length);
|
||||
for (int i = 0; i < len; i++) {
|
||||
int n1 = i < a1.length ? parseInt(a1[i]) : 0;
|
||||
int n2 = i < a2.length ? parseInt(a2[i]) : 0;
|
||||
if (n1 != n2) {
|
||||
return n1 - n2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int parseInt(String s) {
|
||||
try {
|
||||
return Integer.parseInt(s);
|
||||
} catch (NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public Glimmer loadGlim() {
|
||||
String rawVersion;
|
||||
try {
|
||||
rawVersion = Bukkit.getMinecraftVersion(); // returns something like "1.21.10"
|
||||
} catch (NoSuchMethodError e) {
|
||||
return betaLoadGlim();
|
||||
}
|
||||
|
||||
String matchInfo = getVersion("release", rawVersion);
|
||||
if (matchInfo.isEmpty()) {
|
||||
// TODO: Should change to something more robust, it's not beta since we have Bukkit.getMinecraftVersion()
|
||||
return betaLoadGlim();
|
||||
}
|
||||
|
||||
// split the returned string: "pattern|classSuffix"
|
||||
String[] partsInfo = matchInfo.split("\\|");
|
||||
String classSuffix = partsInfo[1]; // e.g. "r1_21"
|
||||
|
||||
String[] versionParts = rawVersion.split("\\.");
|
||||
int major = parseInt(versionParts[0]);
|
||||
int minor = parseInt(versionParts[1]);
|
||||
int patch = versionParts.length > 2 ? parseInt(versionParts[2]) : 0;
|
||||
|
||||
while (true) {
|
||||
String className = "io.github.adrianvic.nemesiseye.impl." + classSuffix;
|
||||
Glimmer glimmer = tryInstantiate(className);
|
||||
if (glimmer != null) return glimmer;
|
||||
|
||||
if (patch > 0) {
|
||||
patch--;
|
||||
continue;
|
||||
}
|
||||
if (minor > 0) {
|
||||
minor--;
|
||||
patch = 20;
|
||||
continue;
|
||||
}
|
||||
className = "io.github.adrianvic.nemesiseye.impl.r" + major + "_" + minor;
|
||||
glimmer = tryInstantiate(className);
|
||||
if (glimmer != null) return glimmer;
|
||||
|
||||
throw new IllegalStateException(
|
||||
"No suitable implementation found for version " + rawVersion);
|
||||
}
|
||||
}
|
||||
|
||||
private Glimmer betaLoadGlim() {
|
||||
// Bukkit.getVersion() // returns something like "1.1.10 (MC: 1.7.3)" WEIRD
|
||||
return tryInstantiate("io.github.adrianvic.nemesiseye.impl.b1_7_3"); // only supported beta version for now
|
||||
}
|
||||
|
||||
private Glimmer tryInstantiate(String className) {
|
||||
|
|
|
|||
|
|
@ -5,19 +5,18 @@
|
|||
# \_\ \_____ / /_/ /_______ /\_______ /\____|__ /
|
||||
# \/ \/ \/ \/
|
||||
# EYE OF NEMESIS - Example config file.
|
||||
# Documentation in our repository's /docs
|
||||
# Documentation in our wiki: https://github.com/adrianvic/NemesisEye
|
||||
|
||||
Policies:
|
||||
# This example blocks the usage of bedrock without the server.usebedrock permissin
|
||||
- name: "Bedrock-allow-admins" # No spaces here or else commands which need the name as argument will not work
|
||||
type: "permission" # global | location | permission | playerName
|
||||
- name: "Bedrock-allow-admins"
|
||||
type: "permission"
|
||||
worlds: [world]
|
||||
effect: ALLOW # DENY | ALLOW (overrides deny) | ALLOWONLY (allow only if met)
|
||||
weight: 3 # Greater weight overrides lower
|
||||
effect: ALLOW
|
||||
weight: 3
|
||||
permissions:
|
||||
- "server.usebedrock"
|
||||
nodes:
|
||||
- [PLACE]:
|
||||
- [BREAK, PLACE, HIT, INTERACT]:
|
||||
values:
|
||||
- BEDROCK
|
||||
|
||||
|
|
@ -27,16 +26,15 @@ Policies:
|
|||
effect: DENY
|
||||
weight: 2
|
||||
nodes:
|
||||
- [PLACE]:
|
||||
- [BREAK, PLACE, HIT, INTERACT]:
|
||||
values:
|
||||
- BEDROCK
|
||||
|
||||
# This example blocks all non-beta (b1.7.3) items, blocks, mobs, enchantments in a rectangular area
|
||||
- name: "Block-non-beta-items"
|
||||
type: "location"
|
||||
effect: DENY
|
||||
- name: "Block-non-beta-items" # No spaces here or else commands which need the name as argument will not work
|
||||
type: "location" # global | location | permission | playerName
|
||||
effect: DENY # DENY | ALLOW (overrides deny) | ALLOWONLY (allow only if met)
|
||||
worlds: [world]
|
||||
weight: 0
|
||||
weight: 0 # Greater weight overrides lower
|
||||
policyAllowList: false # Inverts the policy validation logic, for example a location policy will affect all players NOT inside it's location
|
||||
locations:
|
||||
worlds: [world]
|
||||
|
|
@ -44,7 +42,7 @@ Policies:
|
|||
- corner1: { x: 2100, y: 256, z: 1400 }
|
||||
corner2: { x: 1000, y: -64, z: 2200 }
|
||||
nodes:
|
||||
- [INTERACT, BREAK, HIT, PLACE, GLYDE, EQUIP, SPAWN]:
|
||||
- [INTERACT, BREAK, HIT, PLACE]:
|
||||
values:
|
||||
- '.*'
|
||||
- [USE_ENCHANTMENT]:
|
||||
|
|
@ -61,7 +59,7 @@ Policies:
|
|||
- corner1: { x: 2100, y: 256, z: 1400 }
|
||||
corner2: { x: 1000, y: -64, z: 2200 }
|
||||
nodes:
|
||||
- [INTERACT, BREAK, HIT, PLACE, SPAWN]:
|
||||
- [INTERACT, BREAK, HIT, PLACE]:
|
||||
values:
|
||||
- AIR
|
||||
- STONE
|
||||
|
|
@ -170,16 +168,4 @@ Policies:
|
|||
- MUSIC_DISK_CAT
|
||||
- MUSIC_DISK_13
|
||||
- DIRT
|
||||
- BREAD
|
||||
- ZOMBIE
|
||||
- SKELETON
|
||||
- CHICKEN
|
||||
- PIG
|
||||
- SHEEP
|
||||
- COW
|
||||
- SQUID
|
||||
- WOLF
|
||||
- PIGZOMBIE
|
||||
- SPIDER
|
||||
- GHAST
|
||||
- CREEPER
|
||||
- BREAD
|
||||
|
|
@ -1,19 +1,15 @@
|
|||
package io.github.adrianvic.nemesiseye.impl.v1_21;
|
||||
package io.github.adrianvic.nemesiseye.impl;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.Events;
|
||||
import io.github.adrianvic.nemesiseye.ModernEvents;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockFormEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerTakeLecternBookEvent;
|
||||
|
||||
public class EventListener implements Listener {
|
||||
@EventHandler
|
||||
|
|
@ -40,21 +36,5 @@ public class EventListener implements Listener {
|
|||
public void onPlayerMoveEvent(PlayerMoveEvent event) { Events.onPlayerMoveEvent(event); }
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onInventoryClickEvent(InventoryClickEvent event) { ModernEvents.onInventoryClickEvent(event); }
|
||||
|
||||
@EventHandler
|
||||
public void onCreatureSpawnEvent(CreatureSpawnEvent event) { Events.onCreatureSpawnEvent(event); }
|
||||
|
||||
@EventHandler
|
||||
public void onEndermanAttackPlayerEvent(com.destroystokyo.paper.event.entity.EndermanAttackPlayerEvent event) {
|
||||
ModernEvents.onEndermanAttackPlayerEvent(event);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockFormEvent(BlockFormEvent event) {
|
||||
ModernEvents.onBlockFormEvent(event);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerTakeLecternBook(PlayerTakeLecternBookEvent event) { ModernEvents.onPlayerTakeLecternBookEvent(event); }
|
||||
public void onInventoryClickEvent(InventoryClickEvent event) { Events.onInventoryClickEvent(event);}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package io.github.adrianvic.nemesiseye.impl.v1_21.commands;
|
||||
package io.github.adrianvic.nemesiseye.impl.commands;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.commands.EyeCore;
|
||||
import org.bukkit.command.Command;
|
||||
108
src/r1_21/java/io/github/adrianvic/nemesiseye/impl/r1_21.java
Normal file
108
src/r1_21/java/io/github/adrianvic/nemesiseye/impl/r1_21.java
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
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.reflection.Glimmer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
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;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
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<?, ?> policyMap : rawPolicies) {
|
||||
if (policyMap.get("type") != null && policyMap.get("type") instanceof String type) {
|
||||
allPolicies.add(PolicyParsers.get(type).parse(policyMap));
|
||||
}
|
||||
}
|
||||
|
||||
return allPolicies;
|
||||
}
|
||||
|
||||
@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 void sendMessage(CommandSender commandSender, String text) {
|
||||
commandSender.sendMessage(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasItemMeta(ItemStack item) {
|
||||
return item.getItemMeta() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<World> getWorlds() {
|
||||
return Bukkit.getWorlds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasEnchantment(ItemStack item, Map<String, String> valuesmap) {
|
||||
Map<Enchantment, Integer> enchantments = item.getEnchantments();
|
||||
|
||||
for (Map.Entry<Enchantment, Integer> ench : enchantments.entrySet()) {
|
||||
String enchKey = ench.getKey().getKey().getKey();
|
||||
String enchLevel = ench.getValue().toString();
|
||||
|
||||
for (Map.Entry<String, String> rule : valuesmap.entrySet()) {
|
||||
if (
|
||||
DataShifter.safeMatches(rule.getKey(), enchKey) &&
|
||||
DataShifter.safeMatches(rule.getValue(), enchLevel)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasAnyEnchantment(ItemStack item) {
|
||||
return !(item.getItemMeta().getEnchants().isEmpty());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,215 +0,0 @@
|
|||
package io.github.adrianvic.nemesiseye.impl.v1_21;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.DataShifter;
|
||||
import io.github.adrianvic.nemesiseye.Nemesis;
|
||||
import io.github.adrianvic.nemesiseye.impl.v1_21.commands.Eye;
|
||||
import io.github.adrianvic.nemesiseye.policy.Action;
|
||||
import io.github.adrianvic.nemesiseye.policy.NodeHandler;
|
||||
import io.github.adrianvic.nemesiseye.policy.Policy;
|
||||
import io.github.adrianvic.nemesiseye.policy.PolicyParsers;
|
||||
import io.github.adrianvic.nemesiseye.policy.handlers.FormBlock;
|
||||
import io.github.adrianvic.nemesiseye.reflection.Glimmer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
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.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
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<?, ?> policyMap : rawPolicies) {
|
||||
if (policyMap.get("type") != null && policyMap.get("type") instanceof String type) {
|
||||
allPolicies.add(PolicyParsers.get(type).parse(policyMap));
|
||||
}
|
||||
}
|
||||
|
||||
return allPolicies;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
PluginManager pm = Nemesis.getInstance().getPluginManager();
|
||||
Eye eye = new Eye();
|
||||
Nemesis.getInstance().getCommand("eye").setExecutor(eye);
|
||||
Nemesis.getInstance().getCommand("eye").setTabCompleter(eye);
|
||||
pm.registerEvents(new EventListener(), Nemesis.getInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemInMainHandHumanEntity(HumanEntity entity) {
|
||||
return entity.getInventory().getItemInMainHand();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAir(ItemStack item) {
|
||||
return item == null || item.getType().isAir();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGliding(org.bukkit.entity.Player player) {
|
||||
return player.isGliding();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGliding(org.bukkit.entity.Player player, boolean gliding) {
|
||||
player.setGliding(gliding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(org.bukkit.command.CommandSender sender, String permission) {
|
||||
return sender.hasPermission(permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isArmorEquipAttempt(org.bukkit.event.Event event) {
|
||||
if (!(event instanceof org.bukkit.event.inventory.InventoryClickEvent e)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (e.getSlotType() == org.bukkit.event.inventory.InventoryType.SlotType.ARMOR) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (e.isShiftClick()) {
|
||||
return isArmor(e.getCurrentItem());
|
||||
}
|
||||
|
||||
if (e.getClick() == org.bukkit.event.inventory.ClickType.NUMBER_KEY
|
||||
&& e.getSlotType() == org.bukkit.event.inventory.InventoryType.SlotType.ARMOR
|
||||
&& e.getWhoClicked() instanceof org.bukkit.entity.Player player) {
|
||||
return isArmor(
|
||||
player.getInventory().getItem(e.getHotbarButton())
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getEquippedItem(org.bukkit.event.Event event) {
|
||||
if (event instanceof org.bukkit.event.inventory.InventoryClickEvent e) {
|
||||
org.bukkit.event.inventory.InventoryType.SlotType slotType = e.getSlotType();
|
||||
|
||||
if (e.getClick() == org.bukkit.event.inventory.ClickType.NUMBER_KEY // hotbar key swap
|
||||
&& slotType == org.bukkit.event.inventory.InventoryType.SlotType.ARMOR
|
||||
&& e.getWhoClicked() instanceof org.bukkit.entity.Player player) {
|
||||
return player.getInventory().getItem(e.getHotbarButton());
|
||||
}
|
||||
|
||||
if (e.isShiftClick()) {
|
||||
ItemStack current = e.getCurrentItem();
|
||||
if (isArmor(current)) return current;
|
||||
}
|
||||
|
||||
// regular click
|
||||
if (slotType == org.bukkit.event.inventory.InventoryType.SlotType.ARMOR) {
|
||||
ItemStack cursor = e.getCursor();
|
||||
if (isArmor(cursor)) return cursor;
|
||||
}
|
||||
}
|
||||
|
||||
// Try Paper's PlayerArmorChangeEvent via reflection or just check if class exists
|
||||
try {
|
||||
if (event instanceof com.destroystokyo.paper.event.player.PlayerArmorChangeEvent e) {
|
||||
return e.getNewItem();
|
||||
}
|
||||
} catch (NoClassDefFoundError | Exception ignored) {}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Action, NodeHandler> getExtraHandlers() {
|
||||
Map<Action, NodeHandler> handlers = new HashMap<>();
|
||||
handlers.put(Action.FORMBLOCK, new FormBlock());
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(CommandSender commandSender, String text) {
|
||||
commandSender.sendMessage(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasItemMeta(ItemStack item) {
|
||||
return item.getItemMeta() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<World> getWorlds() {
|
||||
return Bukkit.getWorlds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasEnchantment(ItemStack item, Map<String, String> valuesmap) {
|
||||
Map<Enchantment, Integer> enchantments = item.getEnchantments();
|
||||
|
||||
for (Map.Entry<Enchantment, Integer> ench : enchantments.entrySet()) {
|
||||
String enchKey = ench.getKey().getKey().getKey();
|
||||
String enchLevel = ench.getValue().toString();
|
||||
|
||||
for (Map.Entry<String, String> rule : valuesmap.entrySet()) {
|
||||
if (
|
||||
DataShifter.safeMatches(rule.getKey(), enchKey) &&
|
||||
DataShifter.safeMatches(rule.getValue(), enchLevel)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAnyEnchantment(ItemStack item) {
|
||||
return !(item.getItemMeta().getEnchants().isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isArmor(ItemStack item) {
|
||||
if (item == null || item.getType().isAir()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String name = item.getType().name();
|
||||
|
||||
return name.endsWith("_HELMET")
|
||||
|| name.endsWith("_CHESTPLATE")
|
||||
|| name.endsWith("_LEGGINGS")
|
||||
|| name.endsWith("_BOOTS")
|
||||
|| item.getType() == org.bukkit.Material.ELYTRA;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
package io.github.adrianvic.nemesiseye;
|
||||
|
||||
import io.github.adrianvic.nemesiseye.policy.Action;
|
||||
import io.github.adrianvic.nemesiseye.policy.Effect;
|
||||
import io.github.adrianvic.nemesiseye.policy.Policy;
|
||||
import io.github.adrianvic.nemesiseye.reflection.Glimmer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.Event;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class ValidatorTest {
|
||||
|
||||
private Glimmer mockGlim;
|
||||
private Config mockConfig;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
mockGlim = mock(Glimmer.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidatorCanDeny() {
|
||||
World world = mock(World.class);
|
||||
Event event = mock(Event.class);
|
||||
Policy policy = mock(Policy.class);
|
||||
|
||||
// when(policy.applies(world)).thenReturn(true);
|
||||
when(policy.matches(world, Action.BREAK, event)).thenReturn(true);
|
||||
when(policy.effect()).thenReturn(Effect.DENY);
|
||||
|
||||
// We need to handle the static Config.getInstance()
|
||||
// This is tricky without refactoring or Mockito-inline
|
||||
// For now, let's just demonstrate the concept if Validator was more testable
|
||||
}
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
package io.github.adrianvic.nemesiseye.impl;
|
||||
|
||||
import be.seeseemelk.mockbukkit.MockBukkit;
|
||||
import be.seeseemelk.mockbukkit.ServerMock;
|
||||
import io.github.adrianvic.nemesiseye.impl.v1_21.r1_21;
|
||||
import io.github.adrianvic.nemesiseye.impl.v1_7_3.b1_7_3;
|
||||
import io.github.adrianvic.nemesiseye.reflection.Glimmer;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class ImplementationContractTest {
|
||||
|
||||
private ServerMock server;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
server = MockBukkit.mock();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
MockBukkit.unmock();
|
||||
}
|
||||
|
||||
static Stream<Glimmer> implementations() {
|
||||
return Stream.of(
|
||||
new b1_7_3(),
|
||||
new r1_21()
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("implementations")
|
||||
void testIsArmor(Glimmer glim) {
|
||||
// Helmets
|
||||
assertTrue(glim.isArmor(new ItemStack(Material.IRON_HELMET)));
|
||||
assertTrue(glim.isArmor(new ItemStack(Material.DIAMOND_HELMET)));
|
||||
|
||||
// Chestplates
|
||||
assertTrue(glim.isArmor(new ItemStack(Material.GOLDEN_CHESTPLATE)));
|
||||
|
||||
// Non-armor
|
||||
assertFalse(glim.isArmor(new ItemStack(Material.STICK)));
|
||||
assertFalse(glim.isArmor(new ItemStack(Material.DIRT)));
|
||||
|
||||
// Null/Air
|
||||
assertFalse(glim.isArmor(null));
|
||||
assertFalse(glim.isArmor(new ItemStack(Material.AIR)));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("implementations")
|
||||
void testIsAir(Glimmer glim) {
|
||||
assertTrue(glim.isAir(null));
|
||||
assertTrue(glim.isAir(new ItemStack(Material.AIR)));
|
||||
assertFalse(glim.isAir(new ItemStack(Material.STONE)));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue