Skip to content

Commit c2c9154

Browse files
authored
Merge pull request #30 from Foxikle/feat/events
Update Event handling
2 parents b931533 + 5cf6621 commit c2c9154

File tree

5 files changed

+257
-20
lines changed

5 files changed

+257
-20
lines changed

build.gradle.kts

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@ repositories {
1818
}
1919

2020
dependencies {
21-
2221
implementation("com.github.Minestom", "Minestom", "6b8a4e4cc9") // minstom itself
2322
implementation("com.google.code.gson:gson:2.10.1") // serializing
2423
implementation("org.slf4j:slf4j-api:2.0.13") // logging
2524
implementation("net.kyori:adventure-text-minimessage:4.16.0")// better components
2625
implementation("mysql:mysql-connector-java:8.0.33") //mysql connector
26+
compileOnly("org.projectlombok:lombok:1.18.32") // lombok
27+
annotationProcessor("org.projectlombok:lombok:1.18.32") // lombok
2728
implementation("org.tomlj:tomlj:1.1.1") // Config lang
2829
implementation("com.rabbitmq:amqp-client:5.21.0") // Message broker
2930
}
@@ -48,6 +49,5 @@ tasks {
4849
}
4950
mergeServiceFiles()
5051
archiveFileName.set("cytosis.jar")
51-
//destinationDirectory.set(file(providers.gradleProperty("server_dir").get()))
5252
}
5353
}

src/main/java/net/cytonic/cytosis/Cytosis.java

+1
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ public static void completeNonEssentialTasks(long start) {
154154

155155
Logger.info("Setting up event handlers");
156156
EVENT_HANDLER = new EventHandler(MinecraftServer.getGlobalEventHandler());
157+
EVENT_HANDLER.init();
157158

158159
Logger.info("Initializing server events");
159160
ServerEventListeners.initServerEvents();
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,196 @@
11
package net.cytonic.cytosis.events;
22

33
import net.minestom.server.event.Event;
4-
import net.minestom.server.event.EventListener;
5-
import net.minestom.server.event.EventNode;
64
import net.minestom.server.event.GlobalEventHandler;
7-
import org.jetbrains.annotations.NotNull;
8-
import java.util.function.Consumer;
5+
import net.minestom.server.event.book.EditBookEvent;
6+
import net.minestom.server.event.entity.*;
7+
import net.minestom.server.event.entity.projectile.ProjectileCollideWithBlockEvent;
8+
import net.minestom.server.event.entity.projectile.ProjectileCollideWithEntityEvent;
9+
import net.minestom.server.event.entity.projectile.ProjectileUncollideEvent;
10+
import net.minestom.server.event.instance.*;
11+
import net.minestom.server.event.inventory.*;
12+
import net.minestom.server.event.item.*;
13+
import net.minestom.server.event.player.*;
14+
import net.minestom.server.event.server.ClientPingServerEvent;
15+
import net.minestom.server.event.server.ServerListPingEvent;
16+
import net.minestom.server.event.server.ServerTickMonitorEvent;
17+
import net.minestom.server.event.trait.CancellableEvent;
918

19+
import java.util.*;
20+
21+
/**
22+
* EventHandler class is responsible for handling events and managing listeners.
23+
* It provides methods to register, unregister listeners and to handle global events.
24+
*
25+
* @author Foxikle
26+
*/
1027
public class EventHandler {
1128
private final GlobalEventHandler GLOBAL_HANDLER;
29+
private final Map<String, EventListener<? extends Event>> NAMESPACED_HANDLERS = new HashMap<>();
30+
private boolean initialized = false;
1231

32+
/**
33+
* Constructor for EventHandler.
34+
* Initializes the GlobalEventHandler instance.
35+
*
36+
* @param globalHandler The GlobalEventHandler instance to be used.
37+
*/
1338
public EventHandler(GlobalEventHandler globalHandler) {
1439
GLOBAL_HANDLER = globalHandler;
1540
}
1641

17-
public <T extends Event> EventNode<Event> registerGlobalEvent(EventListener<T> listener) {
18-
return GLOBAL_HANDLER.addListener(listener);
42+
public void init() {
43+
if (initialized) throw new IllegalStateException("The event handler has already been initialized!");
44+
setupInternalListeners();
45+
initialized = true;
46+
}
47+
48+
/**
49+
* Unregisters a listener by its namespace.
50+
*
51+
* @param listener The listener to be unregistered.
52+
* @return True if the listener was successfully unregistered, false otherwise.
53+
*/
54+
public boolean unregisterListener(EventListener<? extends Event> listener) {
55+
return NAMESPACED_HANDLERS.remove(listener.getNamespace()) != null;
56+
}
57+
58+
/**
59+
* Unregisters a listener by its namespace.
60+
*
61+
* @param namespace The namespace of the listener to be unregistered.
62+
* @return True if the listener was successfully unregistered, false otherwise.
63+
*/
64+
public boolean unregisterListener(String namespace) {
65+
return NAMESPACED_HANDLERS.remove(namespace) != null;
1966
}
2067

21-
public <E extends Event> @NotNull EventNode<Event> registerGlobalEvent(@NotNull Class<E> clazz, @NotNull Consumer<E> listener) {
22-
return GLOBAL_HANDLER.addListener(EventListener.of(clazz, listener));
68+
/**
69+
* Registers a listener.
70+
*
71+
* @param listener The listener to be registered.
72+
* @return True if the listener was successfully registered, false otherwise.
73+
*/
74+
public boolean registerListener(EventListener<? extends Event> listener) {
75+
return NAMESPACED_HANDLERS.putIfAbsent(listener.getNamespace(), listener) == listener;
76+
}
77+
78+
public <T extends Event> void handleEvent(T event) {
79+
List<EventListener<? extends Event>> matchingListeners = new ArrayList<>();
80+
81+
for (EventListener<? extends Event> listener : NAMESPACED_HANDLERS.values()) {
82+
if (listener.getEventClass() == event.getClass() &&
83+
!(event instanceof CancellableEvent && ((CancellableEvent) event).isCancelled())) {
84+
matchingListeners.add(listener);
85+
}
86+
}
87+
88+
// Sort listeners by priority
89+
matchingListeners.sort(Comparator.comparingInt(EventListener::getPriority));
90+
91+
for (EventListener<? extends Event> listener : matchingListeners) {
92+
if (!(event instanceof CancellableEvent && ((CancellableEvent) event).isCancelled()))
93+
listener.complete(event);
94+
}
95+
}
96+
97+
98+
private void setupInternalListeners() {
99+
//book events
100+
GLOBAL_HANDLER.addListener(EditBookEvent.class, (this::handleEvent));
101+
// entity events
102+
GLOBAL_HANDLER.addListener(EntityAttackEvent.class, (this::handleEvent));
103+
GLOBAL_HANDLER.addListener(EntityDamageEvent.class, (this::handleEvent));
104+
GLOBAL_HANDLER.addListener(EntityDeathEvent.class, (this::handleEvent));
105+
GLOBAL_HANDLER.addListener(EntityDespawnEvent.class, (this::handleEvent));
106+
GLOBAL_HANDLER.addListener(EntityFireEvent.class, (this::handleEvent));
107+
GLOBAL_HANDLER.addListener(EntityItemMergeEvent.class, (this::handleEvent));
108+
GLOBAL_HANDLER.addListener(EntityPotionAddEvent.class, (this::handleEvent));
109+
GLOBAL_HANDLER.addListener(EntityPotionRemoveEvent.class, (this::handleEvent));
110+
GLOBAL_HANDLER.addListener(EntityShootEvent.class, (this::handleEvent));
111+
GLOBAL_HANDLER.addListener(EntitySpawnEvent.class, (this::handleEvent));
112+
GLOBAL_HANDLER.addListener(EntityTickEvent.class, (this::handleEvent));
113+
GLOBAL_HANDLER.addListener(EntityVelocityEvent.class, (this::handleEvent));
114+
115+
//projectile events
116+
GLOBAL_HANDLER.addListener(ProjectileCollideWithBlockEvent.class, (this::handleEvent));
117+
GLOBAL_HANDLER.addListener(ProjectileCollideWithEntityEvent.class, (this::handleEvent));
118+
GLOBAL_HANDLER.addListener(ProjectileUncollideEvent.class, (this::handleEvent));
119+
120+
// Instance events
121+
GLOBAL_HANDLER.addListener(AddEntityToInstanceEvent.class, (this::handleEvent));
122+
GLOBAL_HANDLER.addListener(InstanceChunkLoadEvent.class, (this::handleEvent));
123+
GLOBAL_HANDLER.addListener(InstanceChunkUnloadEvent.class, (this::handleEvent));
124+
GLOBAL_HANDLER.addListener(InstanceRegisterEvent.class, (this::handleEvent));
125+
GLOBAL_HANDLER.addListener(InstanceTickEvent.class, (this::handleEvent));
126+
GLOBAL_HANDLER.addListener(InstanceUnregisterEvent.class, (this::handleEvent));
127+
GLOBAL_HANDLER.addListener(RemoveEntityFromInstanceEvent.class, (this::handleEvent));
128+
129+
// Inventory Events
130+
GLOBAL_HANDLER.addListener(InventoryClickEvent.class, (this::handleEvent));
131+
GLOBAL_HANDLER.addListener(InventoryCloseEvent.class, (this::handleEvent));
132+
GLOBAL_HANDLER.addListener(InventoryItemChangeEvent.class, (this::handleEvent));
133+
GLOBAL_HANDLER.addListener(InventoryOpenEvent.class, (this::handleEvent));
134+
GLOBAL_HANDLER.addListener(InventoryPreClickEvent.class, (this::handleEvent));
135+
GLOBAL_HANDLER.addListener(PlayerInventoryItemChangeEvent.class, (this::handleEvent));
136+
137+
// Item Events
138+
GLOBAL_HANDLER.addListener(EntityEquipEvent.class, (this::handleEvent));
139+
GLOBAL_HANDLER.addListener(ItemDropEvent.class, (this::handleEvent));
140+
GLOBAL_HANDLER.addListener(ItemUpdateStateEvent.class, (this::handleEvent));
141+
GLOBAL_HANDLER.addListener(PickupExperienceEvent.class, (this::handleEvent));
142+
GLOBAL_HANDLER.addListener(PickupItemEvent.class, (this::handleEvent));
143+
144+
// player events
145+
GLOBAL_HANDLER.addListener(AdvancementTabEvent.class, (this::handleEvent));
146+
GLOBAL_HANDLER.addListener(AsyncPlayerConfigurationEvent.class, (this::handleEvent));
147+
GLOBAL_HANDLER.addListener(AsyncPlayerPreLoginEvent.class, (this::handleEvent));
148+
GLOBAL_HANDLER.addListener(PlayerBlockBreakEvent.class, (this::handleEvent));
149+
GLOBAL_HANDLER.addListener(PlayerBlockInteractEvent.class, (this::handleEvent));
150+
GLOBAL_HANDLER.addListener(PlayerBlockPlaceEvent.class, (this::handleEvent));
151+
GLOBAL_HANDLER.addListener(PlayerCancelDiggingEvent.class, (this::handleEvent));
152+
GLOBAL_HANDLER.addListener(PlayerChangeHeldSlotEvent.class, (this::handleEvent));
153+
GLOBAL_HANDLER.addListener(PlayerChatEvent.class, (this::handleEvent));
154+
GLOBAL_HANDLER.addListener(PlayerChunkLoadEvent.class, (this::handleEvent));
155+
GLOBAL_HANDLER.addListener(PlayerChunkUnloadEvent.class, (this::handleEvent));
156+
GLOBAL_HANDLER.addListener(PlayerCommandEvent.class, (this::handleEvent));
157+
GLOBAL_HANDLER.addListener(PlayerDeathEvent.class, (this::handleEvent));
158+
GLOBAL_HANDLER.addListener(PlayerDisconnectEvent.class, (this::handleEvent));
159+
GLOBAL_HANDLER.addListener(PlayerEatEvent.class, (this::handleEvent));
160+
GLOBAL_HANDLER.addListener(PlayerEntityInteractEvent.class, (this::handleEvent));
161+
GLOBAL_HANDLER.addListener(PlayerFinishDiggingEvent.class, (this::handleEvent));
162+
GLOBAL_HANDLER.addListener(PlayerGameModeChangeEvent.class, (this::handleEvent));
163+
GLOBAL_HANDLER.addListener(PlayerHandAnimationEvent.class, (this::handleEvent));
164+
GLOBAL_HANDLER.addListener(PlayerItemAnimationEvent.class, (this::handleEvent));
165+
GLOBAL_HANDLER.addListener(PlayerMoveEvent.class, (this::handleEvent));
166+
GLOBAL_HANDLER.addListener(PlayerPacketEvent.class, (this::handleEvent));
167+
GLOBAL_HANDLER.addListener(PlayerPacketOutEvent.class, (this::handleEvent));
168+
GLOBAL_HANDLER.addListener(PlayerPluginMessageEvent.class, (this::handleEvent));
169+
GLOBAL_HANDLER.addListener(PlayerPreEatEvent.class, (this::handleEvent));
170+
GLOBAL_HANDLER.addListener(PlayerResourcePackStatusEvent.class, (this::handleEvent));
171+
GLOBAL_HANDLER.addListener(PlayerRespawnEvent.class, (this::handleEvent));
172+
GLOBAL_HANDLER.addListener(PlayerSettingsChangeEvent.class, (this::handleEvent));
173+
GLOBAL_HANDLER.addListener(PlayerSkinInitEvent.class, (this::handleEvent));
174+
GLOBAL_HANDLER.addListener(PlayerSpawnEvent.class, (this::handleEvent));
175+
GLOBAL_HANDLER.addListener(PlayerSpectateEvent.class, (this::handleEvent));
176+
GLOBAL_HANDLER.addListener(PlayerStartDiggingEvent.class, (this::handleEvent));
177+
GLOBAL_HANDLER.addListener(PlayerStartFlyingEvent.class, (this::handleEvent));
178+
GLOBAL_HANDLER.addListener(PlayerStartFlyingWithElytraEvent.class, (this::handleEvent));
179+
GLOBAL_HANDLER.addListener(PlayerStartSprintingEvent.class, (this::handleEvent));
180+
GLOBAL_HANDLER.addListener(PlayerStartSneakingEvent.class, (this::handleEvent));
181+
GLOBAL_HANDLER.addListener(PlayerStopFlyingEvent.class, (this::handleEvent));
182+
GLOBAL_HANDLER.addListener(PlayerStopFlyingWithElytraEvent.class, (this::handleEvent));
183+
GLOBAL_HANDLER.addListener(PlayerStopSprintingEvent.class, (this::handleEvent));
184+
GLOBAL_HANDLER.addListener(PlayerStopSneakingEvent.class, (this::handleEvent));
185+
GLOBAL_HANDLER.addListener(PlayerSwapItemEvent.class, (this::handleEvent));
186+
GLOBAL_HANDLER.addListener(PlayerTickEvent.class, (this::handleEvent));
187+
GLOBAL_HANDLER.addListener(PlayerUseItemEvent.class, (this::handleEvent));
188+
GLOBAL_HANDLER.addListener(PlayerUseItemOnBlockEvent.class, (this::handleEvent));
189+
GLOBAL_HANDLER.addListener(UpdateTagListEvent.class, (this::handleEvent)); // deprecated
190+
191+
// Server
192+
GLOBAL_HANDLER.addListener(ClientPingServerEvent.class, (this::handleEvent));
193+
GLOBAL_HANDLER.addListener(ServerListPingEvent.class, (this::handleEvent));
194+
GLOBAL_HANDLER.addListener(ServerTickMonitorEvent.class, (this::handleEvent));
23195
}
24-
}
196+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package net.cytonic.cytosis.events;
2+
3+
import lombok.Getter;
4+
import net.minestom.server.event.Event;
5+
6+
import java.util.function.Consumer;
7+
8+
@Getter
9+
public class EventListener<T extends Event> {
10+
private final Class<T> eventClass;
11+
private final Consumer<T> consumer;
12+
private final boolean async;
13+
private final int priority;
14+
private final String namespace;
15+
16+
/**
17+
* Constructs a new instance of {@link EventListener} with the specified namespace, priority, and consumer.
18+
*
19+
* @param namespace The namespace of the event listener.
20+
* @param eventClass The class of the event that the listener will be triggered for.
21+
* @param async A boolean value indicating whether the event listener should run asynchronously.
22+
* @param priority The priority of the event listener.
23+
* @param consumer The consumer that will be called when the event is triggered.
24+
* @since 1.0.0
25+
*/
26+
public EventListener(String namespace, boolean async, int priority, Class<T> eventClass, Consumer<T> consumer) {
27+
this.consumer = consumer;
28+
this.eventClass = eventClass;
29+
this.async = async;
30+
this.priority = priority;
31+
this.namespace = namespace;
32+
}
33+
34+
35+
/**
36+
* Constructs a new instance of {@link EventListener} with the specified namespace, priority, and consumer. It will be executed synchronously.
37+
*
38+
* @param namespace The namespace of the event listener.
39+
* @param priority The priority of the event listener.
40+
* @param consumer The consumer that will be called when the event is triggered.
41+
* @param eventClass The class of the event that the listener will be triggered for.
42+
* @since 1.0.0
43+
*/
44+
public EventListener(String namespace, int priority, Class<T> eventClass, Consumer<T> consumer) {
45+
this.consumer = consumer;
46+
this.async = false;
47+
this.eventClass = eventClass;
48+
this.priority = priority;
49+
this.namespace = namespace;
50+
}
51+
52+
/**
53+
* Completes the EventListener's consumer with the provided event object.
54+
*
55+
* @param event The event to complete the consumer with.
56+
* @since 1.0.0
57+
*/
58+
public void complete(Object event) {
59+
if (!eventClass.isInstance(event))
60+
throw new IllegalArgumentException(STR."The specified event object isn't an instance of \{eventClass.getName()}");
61+
consumer.accept(eventClass.cast(event));
62+
}
63+
}

src/main/java/net/cytonic/cytosis/events/ServerEventListeners.java

+10-9
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,36 @@
55
import net.cytonic.cytosis.logging.Logger;
66
import net.minestom.server.coordinate.Pos;
77
import net.minestom.server.entity.Player;
8+
import net.minestom.server.event.Event;
89
import net.minestom.server.event.player.AsyncPlayerConfigurationEvent;
910
import net.minestom.server.event.player.PlayerChatEvent;
11+
import net.minestom.server.event.player.PlayerChatEvent;
1012
import net.minestom.server.event.player.PlayerSpawnEvent;
1113

1214
public class ServerEventListeners {
1315

1416
public static void initServerEvents() {
1517

1618
Logger.info("Registering player configuration event.");
17-
Cytosis.getEventHandler().registerGlobalEvent(AsyncPlayerConfigurationEvent.class, event -> {
19+
Cytosis.getEventHandler().registerListener(new EventListener<>("core:player-configuration", true, 1, AsyncPlayerConfigurationEvent.class, (event -> {
1820
final Player player = event.getPlayer();
1921
event.setSpawningInstance(Cytosis.getDefaultInstance());
2022
player.setRespawnPoint(new Pos(0, 45, 0));
21-
});
23+
})));
2224

2325
Logger.info("Registering player spawn event.");
24-
Cytosis.getEventHandler().registerGlobalEvent(PlayerSpawnEvent.class, event -> {
26+
Cytosis.getEventHandler().registerListener(new EventListener<>("core:player-spawn", false, 1, PlayerSpawnEvent.class, (event -> {
2527
final Player player = event.getPlayer();
2628
if (CytosisSettings.LOG_PLAYER_IPS)
2729
Logger.info(STR."\{event.getPlayer().getUsername()} (\{event.getPlayer().getUuid()}) joined with the ip: \{player.getPlayerConnection().getServerAddress()}");
28-
else
29-
Logger.info(STR."\{event.getPlayer().getUsername()} (\{event.getPlayer().getUuid()}) joined.");
30-
player.sendMessage("Hello!");
31-
});
30+
else Logger.info(STR."\{event.getPlayer().getUsername()} (\{event.getPlayer().getUuid()}) joined.");
31+
})));
32+
3233
Logger.info("Registering player chat event.");
33-
Cytosis.getEventHandler().registerGlobalEvent(PlayerChatEvent.class, event -> {
34+
Cytosis.getEventHandler().registerListener(new EventListener<PlayerChatEvent>("core:player-chat", false, 1, PlayerChatEvent.class,event ->{
3435
final Player player = event.getPlayer();
3536
if (CytosisSettings.LOG_PLAYER_CHAT)
3637
Cytosis.getDatabaseManager().getDatabase().addChat(player.getUuid(),event.getMessage());
37-
});
38+
}));
3839
}
3940
}

0 commit comments

Comments
 (0)