From 4d0122a8dc5dc46b1ef3d2b416fc537579e3827c Mon Sep 17 00:00:00 2001 From: sylviameows Date: Mon, 10 Mar 2025 00:10:54 -0500 Subject: [PATCH 1/2] create event dispatcher --- .idea/misc.xml | 6 + .../sylviameows/flask/api/FlaskAPI.java | 3 + .../flask/api/annotations/FlaskEvent.java | 11 ++ .../flask/api/events/FlaskDispatcher.java | 20 +++ .../flask/api/events/FlaskListener.java | 7 + .../sylviameows/flask/api/game/Lobby.java | 29 ++-- .../sylviameows/flask/api/game/Phase.java | 3 +- build.gradle.kts | 2 +- .../io/github/sylviameows/flask/Flask.java | 10 ++ .../components/variable/BooleanOption.java | 2 +- .../flask/listeners/FlaskDispatcherImpl.java | 134 ++++++++++++++++++ .../io/github/sylviameows/duels/Duels.java | 9 +- .../github/sylviameows/duels/TestingGame.java | 38 +++++ .../sylviameows/duels/TestingPhase.java | 29 ++++ .../duels/basic/ExampleEndingPhase.java | 12 +- .../duels/basic/ExamplePlayingPhase.java | 6 +- 16 files changed, 293 insertions(+), 28 deletions(-) create mode 100644 api/src/main/java/io/github/sylviameows/flask/api/annotations/FlaskEvent.java create mode 100644 api/src/main/java/io/github/sylviameows/flask/api/events/FlaskDispatcher.java create mode 100644 api/src/main/java/io/github/sylviameows/flask/api/events/FlaskListener.java create mode 100644 core/src/main/java/io/github/sylviameows/flask/listeners/FlaskDispatcherImpl.java create mode 100644 example/src/main/java/io/github/sylviameows/duels/TestingGame.java create mode 100644 example/src/main/java/io/github/sylviameows/duels/TestingPhase.java diff --git a/.idea/misc.xml b/.idea/misc.xml index 2758df8..e72e973 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,5 +1,11 @@ + + + + + + diff --git a/api/src/main/java/io/github/sylviameows/flask/api/FlaskAPI.java b/api/src/main/java/io/github/sylviameows/flask/api/FlaskAPI.java index 5d34bc6..d227c8c 100644 --- a/api/src/main/java/io/github/sylviameows/flask/api/FlaskAPI.java +++ b/api/src/main/java/io/github/sylviameows/flask/api/FlaskAPI.java @@ -1,5 +1,6 @@ package io.github.sylviameows.flask.api; +import io.github.sylviameows.flask.api.events.FlaskDispatcher; import io.github.sylviameows.flask.api.manager.PlayerManager; import io.github.sylviameows.flask.api.registry.GameRegistry; import io.github.sylviameows.flask.api.services.MessageService; @@ -14,6 +15,8 @@ public interface FlaskAPI { WorldService getWorldService(); MessageService getMessageService(); + FlaskDispatcher getDispatcher(); + Plugin getPlugin(); Location getSpawnLocation(); diff --git a/api/src/main/java/io/github/sylviameows/flask/api/annotations/FlaskEvent.java b/api/src/main/java/io/github/sylviameows/flask/api/annotations/FlaskEvent.java new file mode 100644 index 0000000..2913758 --- /dev/null +++ b/api/src/main/java/io/github/sylviameows/flask/api/annotations/FlaskEvent.java @@ -0,0 +1,11 @@ +package io.github.sylviameows.flask.api.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface FlaskEvent { +} diff --git a/api/src/main/java/io/github/sylviameows/flask/api/events/FlaskDispatcher.java b/api/src/main/java/io/github/sylviameows/flask/api/events/FlaskDispatcher.java new file mode 100644 index 0000000..7fdda1e --- /dev/null +++ b/api/src/main/java/io/github/sylviameows/flask/api/events/FlaskDispatcher.java @@ -0,0 +1,20 @@ +package io.github.sylviameows.flask.api.events; + +import io.github.sylviameows.flask.api.game.Lobby; +import org.bukkit.event.Event; +import org.bukkit.event.EventException; +import org.bukkit.event.Listener; +import org.bukkit.plugin.EventExecutor; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.Method; + +public interface FlaskDispatcher extends EventExecutor, Listener { + record ListenerInfo(Lobby lobby, Method method, FlaskListener listener) {} + + void registerEvent(Lobby lobby, FlaskListener listener); + void unregisterEvent(Lobby lobby, FlaskListener listener); + + @Override + void execute(@NotNull Listener listener, @NotNull Event event) throws EventException; +} diff --git a/api/src/main/java/io/github/sylviameows/flask/api/events/FlaskListener.java b/api/src/main/java/io/github/sylviameows/flask/api/events/FlaskListener.java new file mode 100644 index 0000000..2fc1d36 --- /dev/null +++ b/api/src/main/java/io/github/sylviameows/flask/api/events/FlaskListener.java @@ -0,0 +1,7 @@ +package io.github.sylviameows.flask.api.events; + +/** + * This type of listener will automatically filter out irrelevant events to its target game. + */ +public interface FlaskListener { +} diff --git a/api/src/main/java/io/github/sylviameows/flask/api/game/Lobby.java b/api/src/main/java/io/github/sylviameows/flask/api/game/Lobby.java index f4ef3da..fc40584 100644 --- a/api/src/main/java/io/github/sylviameows/flask/api/game/Lobby.java +++ b/api/src/main/java/io/github/sylviameows/flask/api/game/Lobby.java @@ -5,14 +5,13 @@ import org.bukkit.GameMode; import org.bukkit.World; import org.bukkit.entity.Player; -import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; -public class Lobby { +public class Lobby> { protected final G parent; public List players; @@ -21,36 +20,32 @@ public class Lobby { private World world; public Lobby(G parent) { - this.parent = parent; - this.players = new ArrayList<>(); - - this.phase = parent.initialPhase(); - Bukkit.getPluginManager().registerEvents(this.phase, parent.getPlugin()); - this.phase.onEnabled(this); + this(parent, new ArrayList<>()); } public Lobby(G parent, List players) { this.parent = parent; this.players = players; - var api = parent.getPlugin().getFlaskAPI(); + FlaskAPI api = parent.getPlugin().getFlaskAPI(); players.forEach(player -> api.getPlayerManager().get(player).setLobby(this)); this.phase = parent.initialPhase(); - Bukkit.getPluginManager().registerEvents(this.phase, parent.getPlugin()); + api.getPlugin().getLogger().info("registering"); + api.getDispatcher().registerEvent(this, this.phase); this.phase.onEnabled(this); } // todo: call function in phase public void addPlayer(Player player) { - var api = parent.getPlugin().getFlaskAPI(); + FlaskAPI api = parent.getPlugin().getFlaskAPI(); api.getPlayerManager().get(player).setLobby(this); players.add(player); phase.onPlayerJoin(player); } public void removePlayer(Player player) { - var api = parent.getPlugin().getFlaskAPI(); + FlaskAPI api = parent.getPlugin().getFlaskAPI(); api.getPlayerManager().get(player).setLobby(null); players.remove(player); phase.onPlayerLeave(player); @@ -58,7 +53,9 @@ public void removePlayer(Player player) { public void closeLobby() { phase.onDisabled(); - HandlerList.unregisterAll(phase); + + FlaskAPI.instance().getPlugin().getLogger().info("unregistering"); + FlaskAPI.instance().getDispatcher().unregisterEvent(this, phase); // todo: replace with a requeue feature? players.forEach(player -> { @@ -86,12 +83,14 @@ public Phase getPhase() { } public void updatePhase(@NotNull Phase phase) { this.phase.onDisabled(); - HandlerList.unregisterAll(this.phase); + FlaskAPI.instance().getPlugin().getLogger().info("unregistering"); + FlaskAPI.instance().getDispatcher().unregisterEvent(this, phase); this.phase = phase; this.phase.onEnabled(this); - Bukkit.getPluginManager().registerEvents(this.phase, parent.getPlugin()); + FlaskAPI.instance().getPlugin().getLogger().info("registering"); + FlaskAPI.instance().getDispatcher().registerEvent(this, phase); } public void nextPhase() { diff --git a/api/src/main/java/io/github/sylviameows/flask/api/game/Phase.java b/api/src/main/java/io/github/sylviameows/flask/api/game/Phase.java index 753bf3d..fa75004 100644 --- a/api/src/main/java/io/github/sylviameows/flask/api/game/Phase.java +++ b/api/src/main/java/io/github/sylviameows/flask/api/game/Phase.java @@ -1,9 +1,10 @@ package io.github.sylviameows.flask.api.game; +import io.github.sylviameows.flask.api.events.FlaskListener; import org.bukkit.entity.Player; import org.bukkit.event.Listener; -public interface Phase extends Listener { +public interface Phase extends FlaskListener { /* TODO */ void onEnabled(Lobby parent); diff --git a/build.gradle.kts b/build.gradle.kts index b3800e6..d06b550 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,4 @@ allprojects { group = "io.github.sylviameows" - version = "0.9.0-ALPHA" + version = "0.10.0-ALPHA" } \ No newline at end of file diff --git a/core/src/main/java/io/github/sylviameows/flask/Flask.java b/core/src/main/java/io/github/sylviameows/flask/Flask.java index 3b3464a..80163dd 100644 --- a/core/src/main/java/io/github/sylviameows/flask/Flask.java +++ b/core/src/main/java/io/github/sylviameows/flask/Flask.java @@ -2,6 +2,7 @@ import io.github.sylviameows.flask.api.FlaskAPI; import io.github.sylviameows.flask.api.FlaskPlugin; +import io.github.sylviameows.flask.api.events.FlaskDispatcher; import io.github.sylviameows.flask.api.manager.PlayerManager; import io.github.sylviameows.flask.api.registry.GameRegistry; import io.github.sylviameows.flask.api.services.MessageService; @@ -11,6 +12,7 @@ import io.github.sylviameows.flask.commands.hologram.HologramCommand; import io.github.sylviameows.flask.commands.queue.QueueCommand; import io.github.sylviameows.flask.hub.holograms.GameHologram; +import io.github.sylviameows.flask.listeners.FlaskDispatcherImpl; import io.github.sylviameows.flask.listeners.JoinListener; import io.github.sylviameows.flask.listeners.LeaveListener; import io.github.sylviameows.flask.listeners.RightClickEntity; @@ -44,6 +46,7 @@ public class Flask extends FlaskPlugin implements FlaskAPI { private static MessageServiceImpl messageService; private static WorldService worldService; private static Flask instance; + private static FlaskDispatcherImpl dispatcher; @Override public void onEnable() { @@ -60,8 +63,10 @@ public void onEnable() { JoinListener.register(this); LeaveListener.register(this); + Flask.dispatcher = new FlaskDispatcherImpl(); Flask.messageService = new MessageServiceImpl(this); Flask.worldService = new FileWorldService(); + // commands registerCommands(); @@ -156,6 +161,11 @@ public MessageService getMessageService() { return messageService; } + @Override + public FlaskDispatcher getDispatcher() { + return dispatcher; + } + @Override public Plugin getPlugin() { return this; diff --git a/core/src/main/java/io/github/sylviameows/flask/editor/book/components/variable/BooleanOption.java b/core/src/main/java/io/github/sylviameows/flask/editor/book/components/variable/BooleanOption.java index fe0dcc7..542e06e 100644 --- a/core/src/main/java/io/github/sylviameows/flask/editor/book/components/variable/BooleanOption.java +++ b/core/src/main/java/io/github/sylviameows/flask/editor/book/components/variable/BooleanOption.java @@ -44,7 +44,7 @@ protected Component value() { var component = Component.text(value ? "True" : "False").color(Palette.DARK_GRAY); if (isOptional()) { var d = (boolean) getDefault(); - if (value == d) return component.append(Component.text("(default)").color(Palette.GRAY)); + if (value == d) return component.append(Component.text(" (default)").color(Palette.GRAY)); } return component; diff --git a/core/src/main/java/io/github/sylviameows/flask/listeners/FlaskDispatcherImpl.java b/core/src/main/java/io/github/sylviameows/flask/listeners/FlaskDispatcherImpl.java new file mode 100644 index 0000000..ca87bb8 --- /dev/null +++ b/core/src/main/java/io/github/sylviameows/flask/listeners/FlaskDispatcherImpl.java @@ -0,0 +1,134 @@ +package io.github.sylviameows.flask.listeners; + +import io.github.sylviameows.flask.Flask; +import io.github.sylviameows.flask.api.FlaskAPI; +import io.github.sylviameows.flask.api.FlaskPlayer; +import io.github.sylviameows.flask.api.annotations.FlaskEvent; +import io.github.sylviameows.flask.api.events.FlaskDispatcher; +import io.github.sylviameows.flask.api.events.FlaskListener; +import io.github.sylviameows.flask.api.game.Game; +import io.github.sylviameows.flask.api.game.Lobby; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.EventException; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockEvent; +import org.bukkit.event.entity.EntityEvent; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.event.vehicle.VehicleEvent; +import org.bukkit.event.world.WorldEvent; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.*; + +public class FlaskDispatcherImpl implements FlaskDispatcher { + Map, ArrayList> methodMap = new HashMap<>(); + + @Override + public void registerEvent(Lobby lobby, FlaskListener listener) { + System.out.println("testing???"); + Flask.logger.info("registering event: "+listener.getClass().getName()); + for (Method method : listener.getClass().getMethods()) { + Flask.logger.info(method.getName() + " | " + Arrays.toString(method.getAnnotations())); + if (method.isAnnotationPresent(FlaskEvent.class)) { + Flask.logger.info("found method with event annotation "+method.getName()); + Parameter[] parameters = method.getParameters(); + if (parameters.length == 1) { + Class clazz = parameters[0].getType(); + + if (Event.class.isAssignableFrom(clazz)) { + Flask.logger.info("is event type"); + + //noinspection unchecked + Class eventClass = (Class) clazz; + + methodMap.computeIfAbsent(eventClass, k -> { + Flask.logger.info("registering"); + Bukkit.getPluginManager().registerEvent( + eventClass, + this, + EventPriority.HIGH, + this, + Flask.getInstance() + ); + + return new ArrayList<>(); + }).add(new ListenerInfo(lobby, method, listener)); + } + } + } + } + } + + @Override + public void unregisterEvent(Lobby lobby, FlaskListener listener) { + methodMap.forEach((clazz, listeners) -> { + Optional optional = listeners.stream().filter(info -> (info.listener() == listener && info.lobby() == lobby)).findFirst(); + if (optional.isEmpty()) return; + ListenerInfo info = optional.get(); + + listeners.remove(info); +// if (listeners.isEmpty()) todo(): remove empty listeners + }); + } + + @Override + public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException { + Flask.logger.info("running code: "+event.getEventName()); + ArrayList listeners = methodMap.get(event.getClass()); + if (listeners == null || listeners.isEmpty()) return; + + ListenerInfo info = null; + switch (event) { + case PlayerEvent playerEvent -> { + Player player = playerEvent.getPlayer(); + FlaskPlayer fp = Flask.getInstance().getPlayerManager().get(player); + + Lobby lobby = fp.getLobby(); + Optional optional = listeners.stream().filter(i -> i.lobby() == lobby).findFirst(); + if (optional.isEmpty()) return; + info = optional.get(); + } + case EntityEvent entityEvent -> { + Entity entity = entityEvent.getEntity(); + World world = entity.getWorld(); + + info = findListenerMatchingWorld(listeners, world); + } + case WorldEvent worldEvent -> { + World world = worldEvent.getWorld(); + info = findListenerMatchingWorld(listeners, world); + } + case BlockEvent blockEvent -> { + World world = blockEvent.getBlock().getWorld(); + info = findListenerMatchingWorld(listeners, world); + } + case VehicleEvent vehicleEvent -> { + World world = vehicleEvent.getVehicle().getWorld(); + info = findListenerMatchingWorld(listeners, world); + } + default -> { + } + } + + if (info == null) return; + + try { + info.method().invoke(info.listener(), event); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new EventException(e); + } + } + + private ListenerInfo findListenerMatchingWorld(ArrayList listeners, World world) { + Optional optional = listeners.stream().filter(i -> i.lobby().getWorld() == world).findFirst(); + return optional.orElse(null); + } +} diff --git a/example/src/main/java/io/github/sylviameows/duels/Duels.java b/example/src/main/java/io/github/sylviameows/duels/Duels.java index 5ec9cb8..992e4a5 100644 --- a/example/src/main/java/io/github/sylviameows/duels/Duels.java +++ b/example/src/main/java/io/github/sylviameows/duels/Duels.java @@ -3,8 +3,11 @@ import io.github.sylviameows.duels.basic.ExampleGame; import io.github.sylviameows.flask.api.FlaskAPI; import io.github.sylviameows.flask.api.FlaskPlugin; +import io.github.sylviameows.flask.api.game.Lobby; import org.bukkit.Bukkit; +import java.util.ArrayList; + public final class Duels extends FlaskPlugin { private FlaskAPI flask; @@ -16,8 +19,12 @@ public void onEnable() { flask = api; } - new ExampleGame(this).register("sword"); + new ExampleGame(this).register("duel"); + + TestingGame eg = new TestingGame(this); + eg.register("test"); + eg.createLobby(new ArrayList<>()); } @Override diff --git a/example/src/main/java/io/github/sylviameows/duels/TestingGame.java b/example/src/main/java/io/github/sylviameows/duels/TestingGame.java new file mode 100644 index 0000000..2ca7a7d --- /dev/null +++ b/example/src/main/java/io/github/sylviameows/duels/TestingGame.java @@ -0,0 +1,38 @@ +package io.github.sylviameows.duels; + +import io.github.sylviameows.flask.api.FlaskPlugin; +import io.github.sylviameows.flask.api.annotations.GameProperties; +import io.github.sylviameows.flask.api.game.Game; +import io.github.sylviameows.flask.api.game.Lobby; +import io.github.sylviameows.flask.api.game.Phase; +import io.github.sylviameows.flask.api.game.map.MapManager; +import io.github.sylviameows.flask.api.map.FlaskMap; +import org.bukkit.entity.Player; + +import java.util.List; + +@GameProperties( + name="testing", + min=1, + max=2 +) +public class TestingGame extends Game { + protected TestingGame(FlaskPlugin plugin) { + super(plugin); + } + + @Override + public Lobby createLobby(List players) { + return new Lobby(this); + } + + @Override + public Phase initialPhase() { + return new TestingPhase(); + } + + @Override + public MapManager getMapManager() { + return null; + } +} diff --git a/example/src/main/java/io/github/sylviameows/duels/TestingPhase.java b/example/src/main/java/io/github/sylviameows/duels/TestingPhase.java new file mode 100644 index 0000000..1c75fb6 --- /dev/null +++ b/example/src/main/java/io/github/sylviameows/duels/TestingPhase.java @@ -0,0 +1,29 @@ +package io.github.sylviameows.duels; + +import io.github.sylviameows.flask.api.annotations.FlaskEvent; +import io.github.sylviameows.flask.api.game.Lobby; +import io.github.sylviameows.flask.api.game.Phase; +import org.bukkit.event.player.PlayerDropItemEvent; + +public class TestingPhase implements Phase { + @FlaskEvent + public void dropItem(PlayerDropItemEvent event) { + event.setCancelled(true); + } + + @Override + public void onEnabled(Lobby parent) { + + } + + @Override + public void onDisabled() { + + } + + @Override + public Phase next() { + return null; + } + +} diff --git a/example/src/main/java/io/github/sylviameows/duels/basic/ExampleEndingPhase.java b/example/src/main/java/io/github/sylviameows/duels/basic/ExampleEndingPhase.java index 3245022..8f4adad 100644 --- a/example/src/main/java/io/github/sylviameows/duels/basic/ExampleEndingPhase.java +++ b/example/src/main/java/io/github/sylviameows/duels/basic/ExampleEndingPhase.java @@ -1,6 +1,7 @@ package io.github.sylviameows.duels.basic; import io.github.sylviameows.flask.api.Palette; +import io.github.sylviameows.flask.api.annotations.FlaskEvent; import io.github.sylviameows.flask.api.game.Lobby; import io.github.sylviameows.flask.api.game.Phase; import net.kyori.adventure.key.Key; @@ -12,7 +13,6 @@ import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; import org.bukkit.event.entity.EntityDamageEvent; import java.time.Duration; @@ -86,12 +86,10 @@ public void onDisabled() { } } - @EventHandler - private void damage(EntityDamageEvent event) { - if (event.getEntity() instanceof Player player) { - if (parent.players.contains(player)) { - event.setCancelled(true); - } + @FlaskEvent + public void damage(EntityDamageEvent event) { + if (event.getEntity() instanceof Player) { + event.setCancelled(true); } } diff --git a/example/src/main/java/io/github/sylviameows/duels/basic/ExamplePlayingPhase.java b/example/src/main/java/io/github/sylviameows/duels/basic/ExamplePlayingPhase.java index 3b282c4..6b0c3cc 100644 --- a/example/src/main/java/io/github/sylviameows/duels/basic/ExamplePlayingPhase.java +++ b/example/src/main/java/io/github/sylviameows/duels/basic/ExamplePlayingPhase.java @@ -1,11 +1,13 @@ package io.github.sylviameows.duels.basic; +import io.github.sylviameows.flask.api.annotations.FlaskEvent; import io.github.sylviameows.flask.api.game.Lobby; import io.github.sylviameows.flask.api.game.Phase; import org.bukkit.GameMode; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.player.PlayerDropItemEvent; import org.jetbrains.annotations.NotNull; public class ExamplePlayingPhase implements Phase { @@ -39,8 +41,8 @@ public void onPlayerLeave(Player player) { parent.nextPhase(); } - @EventHandler - private void onDeath(EntityDeathEvent event) { + @FlaskEvent + public void onDeath(EntityDeathEvent event) { if (event.getEntity() instanceof Player player) { if (player == playerA) { nextPhase.setWinner(playerB); From 1a99bfecb564aee8216f0eda169484e466e2b2a1 Mon Sep 17 00:00:00 2001 From: sylviameows Date: Mon, 10 Mar 2025 18:25:31 -0500 Subject: [PATCH 2/2] dispatcher improvements --- .../flask/listeners/FlaskDispatcherImpl.java | 48 +++++++++---------- .../duels/basic/ExamplePlayingPhase.java | 1 + 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/core/src/main/java/io/github/sylviameows/flask/listeners/FlaskDispatcherImpl.java b/core/src/main/java/io/github/sylviameows/flask/listeners/FlaskDispatcherImpl.java index ca87bb8..597d2de 100644 --- a/core/src/main/java/io/github/sylviameows/flask/listeners/FlaskDispatcherImpl.java +++ b/core/src/main/java/io/github/sylviameows/flask/listeners/FlaskDispatcherImpl.java @@ -1,21 +1,16 @@ package io.github.sylviameows.flask.listeners; import io.github.sylviameows.flask.Flask; -import io.github.sylviameows.flask.api.FlaskAPI; import io.github.sylviameows.flask.api.FlaskPlayer; import io.github.sylviameows.flask.api.annotations.FlaskEvent; import io.github.sylviameows.flask.api.events.FlaskDispatcher; import io.github.sylviameows.flask.api.events.FlaskListener; -import io.github.sylviameows.flask.api.game.Game; import io.github.sylviameows.flask.api.game.Lobby; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.bukkit.event.EventException; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; +import org.bukkit.event.*; import org.bukkit.event.block.BlockEvent; import org.bukkit.event.entity.EntityEvent; import org.bukkit.event.player.PlayerEvent; @@ -33,24 +28,18 @@ public class FlaskDispatcherImpl implements FlaskDispatcher { @Override public void registerEvent(Lobby lobby, FlaskListener listener) { - System.out.println("testing???"); - Flask.logger.info("registering event: "+listener.getClass().getName()); - for (Method method : listener.getClass().getMethods()) { - Flask.logger.info(method.getName() + " | " + Arrays.toString(method.getAnnotations())); + for (Method method : listener.getClass().getDeclaredMethods()) { if (method.isAnnotationPresent(FlaskEvent.class)) { - Flask.logger.info("found method with event annotation "+method.getName()); Parameter[] parameters = method.getParameters(); if (parameters.length == 1) { Class clazz = parameters[0].getType(); if (Event.class.isAssignableFrom(clazz)) { - Flask.logger.info("is event type"); - //noinspection unchecked Class eventClass = (Class) clazz; + method.setAccessible(true); methodMap.computeIfAbsent(eventClass, k -> { - Flask.logger.info("registering"); Bukkit.getPluginManager().registerEvent( eventClass, this, @@ -75,15 +64,20 @@ public void unregisterEvent(Lobby lobby, FlaskListener listener) { ListenerInfo info = optional.get(); listeners.remove(info); -// if (listeners.isEmpty()) todo(): remove empty listeners + if (listeners.isEmpty()) { + methodMap.remove(clazz); + // todo: find a way to unregister event fully + } }); } @Override public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException { - Flask.logger.info("running code: "+event.getEventName()); - ArrayList listeners = methodMap.get(event.getClass()); - if (listeners == null || listeners.isEmpty()) return; + ArrayList listeners = new ArrayList<>(); + + Class clazz = event.getClass(); + methodMap.forEach((e, i) -> {if (e.isAssignableFrom(clazz)) listeners.addAll(i);}); + if (listeners.isEmpty()) return; ListenerInfo info = null; switch (event) { @@ -92,14 +86,16 @@ public void execute(@NotNull Listener listener, @NotNull Event event) throws Eve FlaskPlayer fp = Flask.getInstance().getPlayerManager().get(player); Lobby lobby = fp.getLobby(); - Optional optional = listeners.stream().filter(i -> i.lobby() == lobby).findFirst(); - if (optional.isEmpty()) return; - info = optional.get(); + for (ListenerInfo i : listeners) { + if (i.lobby() == lobby) { + info = i; + break; + } + } } case EntityEvent entityEvent -> { Entity entity = entityEvent.getEntity(); World world = entity.getWorld(); - info = findListenerMatchingWorld(listeners, world); } case WorldEvent worldEvent -> { @@ -128,7 +124,11 @@ public void execute(@NotNull Listener listener, @NotNull Event event) throws Eve } private ListenerInfo findListenerMatchingWorld(ArrayList listeners, World world) { - Optional optional = listeners.stream().filter(i -> i.lobby().getWorld() == world).findFirst(); - return optional.orElse(null); + for (ListenerInfo info : listeners) { + if (info.lobby().getWorld().getName().equals(world.getName())) { + return info; + } + } + return null; } } diff --git a/example/src/main/java/io/github/sylviameows/duels/basic/ExamplePlayingPhase.java b/example/src/main/java/io/github/sylviameows/duels/basic/ExamplePlayingPhase.java index 6b0c3cc..9ebe800 100644 --- a/example/src/main/java/io/github/sylviameows/duels/basic/ExamplePlayingPhase.java +++ b/example/src/main/java/io/github/sylviameows/duels/basic/ExamplePlayingPhase.java @@ -7,6 +7,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.player.PlayerDropItemEvent; import org.jetbrains.annotations.NotNull;