diff --git a/src/main/java/net/minestom/server/MinecraftServer.java b/src/main/java/net/minestom/server/MinecraftServer.java
index f3e907575..2a0e103c2 100644
--- a/src/main/java/net/minestom/server/MinecraftServer.java
+++ b/src/main/java/net/minestom/server/MinecraftServer.java
@@ -299,8 +299,7 @@ public final class MinecraftServer {
*
* @return the global event handler
*/
- @NotNull
- public static GlobalEventHandler getGlobalEventHandler() {
+ public static @NotNull GlobalEventHandler getGlobalEventHandler() {
return GLOBAL_EVENT_HANDLER;
}
diff --git a/src/main/java/net/minestom/server/command/CommandManager.java b/src/main/java/net/minestom/server/command/CommandManager.java
index 94c1adf05..ad9b5e5df 100644
--- a/src/main/java/net/minestom/server/command/CommandManager.java
+++ b/src/main/java/net/minestom/server/command/CommandManager.java
@@ -11,6 +11,7 @@ import net.minestom.server.command.builder.parser.ArgumentQueryResult;
import net.minestom.server.command.builder.parser.CommandParser;
import net.minestom.server.command.builder.parser.CommandQueryResult;
import net.minestom.server.entity.Player;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.player.PlayerCommandEvent;
import net.minestom.server.network.packet.server.play.DeclareCommandsPacket;
import net.minestom.server.utils.ArrayUtils;
@@ -104,7 +105,7 @@ public final class CommandManager {
Player player = (Player) sender;
PlayerCommandEvent playerCommandEvent = new PlayerCommandEvent(player, command);
- player.callEvent(PlayerCommandEvent.class, playerCommandEvent);
+ EventDispatcher.call(playerCommandEvent);
if (playerCommandEvent.isCancelled())
return CommandResult.of(CommandResult.Type.CANCELLED, command);
diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java
index f696f7f16..36b09b2e3 100644
--- a/src/main/java/net/minestom/server/entity/Entity.java
+++ b/src/main/java/net/minestom/server/entity/Entity.java
@@ -16,10 +16,13 @@ import net.minestom.server.collision.CollisionUtils;
import net.minestom.server.data.Data;
import net.minestom.server.data.DataContainer;
import net.minestom.server.entity.metadata.EntityMeta;
-import net.minestom.server.event.Event;
import net.minestom.server.event.EventCallback;
+import net.minestom.server.event.EventDispatcher;
+import net.minestom.server.event.EventFilter;
+import net.minestom.server.event.EventNode;
import net.minestom.server.event.entity.*;
import net.minestom.server.event.handler.EventHandler;
+import net.minestom.server.event.trait.EntityEvent;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.InstanceManager;
@@ -61,7 +64,7 @@ import java.util.function.UnaryOperator;
*
* To create your own entity you probably want to extends {@link LivingEntity} or {@link EntityCreature} instead.
*/
-public class Entity implements Viewable, Tickable, EventHandler, DataContainer, PermissionHandler, HoverEventSource {
+public class Entity implements Viewable, Tickable, EventHandler, DataContainer, PermissionHandler, HoverEventSource {
private static final Map ENTITY_BY_ID = new ConcurrentHashMap<>();
private static final Map ENTITY_BY_UUID = new ConcurrentHashMap<>();
@@ -116,8 +119,7 @@ public class Entity implements Viewable, Tickable, EventHandler, DataContainer,
private long lastAbsoluteSynchronizationTime;
// Events
- private final Map, Collection> eventCallbacks = new ConcurrentHashMap<>();
- private final Map>> extensionCallbacks = new ConcurrentHashMap<>();
+ private final EventNode eventNode;
protected Metadata metadata = new Metadata(this);
protected EntityMeta entityMeta;
@@ -154,6 +156,8 @@ public class Entity implements Viewable, Tickable, EventHandler, DataContainer,
Entity.ENTITY_BY_ID.put(id, this);
Entity.ENTITY_BY_UUID.put(uuid, this);
+
+ this.eventNode = EventNode.value("entity-" + uuid, EventFilter.ENTITY, this::equals);
}
public Entity(@NotNull EntityType entityType) {
@@ -642,7 +646,7 @@ public class Entity implements Viewable, Tickable, EventHandler, DataContainer,
update(time);
ticks++;
- callEvent(EntityTickEvent.class, tickEvent); // reuse tickEvent to avoid recreating it each tick
+ EventDispatcher.call(tickEvent); // reuse tickEvent to avoid recreating it each tick
// remove expired effects
if (!effects.isEmpty()) {
@@ -652,10 +656,7 @@ public class Entity implements Viewable, Tickable, EventHandler, DataContainer,
if (time >= timedPotion.getStartingTime() + potionTime) {
// Send the packet that the potion should no longer be applied
timedPotion.getPotion().sendRemovePacket(this);
- callEvent(EntityPotionRemoveEvent.class, new EntityPotionRemoveEvent(
- this,
- timedPotion.getPotion()
- ));
+ EventDispatcher.call(new EntityPotionRemoveEvent(this, timedPotion.getPotion()));
return true;
}
return false;
@@ -768,16 +769,17 @@ public class Entity implements Viewable, Tickable, EventHandler, DataContainer,
}
}
- @NotNull
@Override
- public Map, Collection> getEventCallbacksMap() {
- return eventCallbacks;
+ public @NotNull EventNode getEventNode() {
+ return eventNode;
}
- @NotNull
@Override
- public Collection> getExtensionCallbacks(String extension) {
- return extensionCallbacks.computeIfAbsent(extension, e -> new CopyOnWriteArrayList<>());
+ public synchronized boolean addEventCallback(@NotNull Class eventClass, @NotNull EventCallback eventCallback) {
+ if (eventNode.getParent() == null) {
+ MinecraftServer.getGlobalEventHandler().addChild(eventNode);
+ }
+ return EventHandler.super.addEventCallback(eventClass, eventCallback);
}
/**
@@ -913,8 +915,7 @@ public class Entity implements Viewable, Tickable, EventHandler, DataContainer,
refreshCurrentChunk(instance.getChunkAt(position.getX(), position.getZ()));
instance.UNSAFE_addEntity(this);
spawn();
- EntitySpawnEvent entitySpawnEvent = new EntitySpawnEvent(this, instance);
- callEvent(EntitySpawnEvent.class, entitySpawnEvent);
+ EventDispatcher.call(new EntitySpawnEvent(this, instance));
}
/**
@@ -947,7 +948,7 @@ public class Entity implements Viewable, Tickable, EventHandler, DataContainer,
*/
public void setVelocity(@NotNull Vector velocity) {
EntityVelocityEvent entityVelocityEvent = new EntityVelocityEvent(this, velocity);
- callCancellableEvent(EntityVelocityEvent.class, entityVelocityEvent, () -> {
+ EventDispatcher.callCancellable(entityVelocityEvent, () -> {
this.velocity.copy(entityVelocityEvent.getVelocity());
sendPacketToViewersAndSelf(getVelocityPacket());
});
@@ -1461,7 +1462,7 @@ public class Entity implements Viewable, Tickable, EventHandler, DataContainer,
removeEffect(potion.getEffect());
this.effects.add(new TimedPotion(potion, System.currentTimeMillis()));
potion.sendAddPacket(this);
- callEvent(EntityPotionAddEvent.class, new EntityPotionAddEvent(this, potion));
+ EventDispatcher.call(new EntityPotionAddEvent(this, potion));
}
/**
@@ -1473,10 +1474,7 @@ public class Entity implements Viewable, Tickable, EventHandler, DataContainer,
this.effects.removeIf(timedPotion -> {
if (timedPotion.getPotion().getEffect() == effect) {
timedPotion.getPotion().sendRemovePacket(this);
- callEvent(EntityPotionRemoveEvent.class, new EntityPotionRemoveEvent(
- this,
- timedPotion.getPotion()
- ));
+ EventDispatcher.call(new EntityPotionRemoveEvent(this, timedPotion.getPotion()));
return true;
}
return false;
@@ -1489,10 +1487,7 @@ public class Entity implements Viewable, Tickable, EventHandler, DataContainer,
public void clearEffects() {
for (TimedPotion timedPotion : effects) {
timedPotion.getPotion().sendRemovePacket(this);
- callEvent(EntityPotionRemoveEvent.class, new EntityPotionRemoveEvent(
- this,
- timedPotion.getPotion()
- ));
+ EventDispatcher.call(new EntityPotionRemoveEvent(this, timedPotion.getPotion()));
}
this.effects.clear();
}
diff --git a/src/main/java/net/minestom/server/entity/EntityCreature.java b/src/main/java/net/minestom/server/entity/EntityCreature.java
index 77de37bdf..e7f7e18be 100644
--- a/src/main/java/net/minestom/server/entity/EntityCreature.java
+++ b/src/main/java/net/minestom/server/entity/EntityCreature.java
@@ -6,6 +6,7 @@ import net.minestom.server.entity.ai.EntityAI;
import net.minestom.server.entity.ai.EntityAIGroup;
import net.minestom.server.entity.pathfinding.NavigableEntity;
import net.minestom.server.entity.pathfinding.Navigator;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.entity.EntityAttackEvent;
import net.minestom.server.instance.Instance;
import net.minestom.server.utils.Position;
@@ -146,7 +147,7 @@ public class EntityCreature extends LivingEntity implements NavigableEntity, Ent
if (swingHand)
swingMainHand();
EntityAttackEvent attackEvent = new EntityAttackEvent(this, target);
- callEvent(EntityAttackEvent.class, attackEvent);
+ EventDispatcher.call(attackEvent);
}
/**
diff --git a/src/main/java/net/minestom/server/entity/ItemEntity.java b/src/main/java/net/minestom/server/entity/ItemEntity.java
index 8ee4b7ea6..c110740a0 100644
--- a/src/main/java/net/minestom/server/entity/ItemEntity.java
+++ b/src/main/java/net/minestom/server/entity/ItemEntity.java
@@ -1,5 +1,6 @@
package net.minestom.server.entity;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.entity.EntityItemMergeEvent;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance;
@@ -112,7 +113,7 @@ public class ItemEntity extends ObjectEntity {
final ItemStack result = stackingRule.apply(itemStack, totalAmount);
EntityItemMergeEvent entityItemMergeEvent = new EntityItemMergeEvent(this, itemEntity, result);
- callCancellableEvent(EntityItemMergeEvent.class, entityItemMergeEvent, () -> {
+ EventDispatcher.callCancellable(entityItemMergeEvent, () -> {
setItemStack(entityItemMergeEvent.getResult());
itemEntity.remove();
});
diff --git a/src/main/java/net/minestom/server/entity/LivingEntity.java b/src/main/java/net/minestom/server/entity/LivingEntity.java
index 3267e0337..674acfc68 100644
--- a/src/main/java/net/minestom/server/entity/LivingEntity.java
+++ b/src/main/java/net/minestom/server/entity/LivingEntity.java
@@ -7,6 +7,7 @@ import net.minestom.server.attribute.Attributes;
import net.minestom.server.collision.BoundingBox;
import net.minestom.server.entity.damage.DamageType;
import net.minestom.server.entity.metadata.LivingEntityMeta;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.entity.EntityDamageEvent;
import net.minestom.server.event.entity.EntityDeathEvent;
import net.minestom.server.event.entity.EntityFireEvent;
@@ -17,7 +18,10 @@ import net.minestom.server.instance.block.Block;
import net.minestom.server.inventory.EquipmentHandler;
import net.minestom.server.item.ItemStack;
import net.minestom.server.network.ConnectionState;
-import net.minestom.server.network.packet.server.play.*;
+import net.minestom.server.network.packet.server.play.CollectItemPacket;
+import net.minestom.server.network.packet.server.play.EntityAnimationPacket;
+import net.minestom.server.network.packet.server.play.EntityPropertiesPacket;
+import net.minestom.server.network.packet.server.play.SoundEffectPacket;
import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.scoreboard.Team;
import net.minestom.server.sound.SoundEvent;
@@ -193,7 +197,7 @@ public class LivingEntity extends Entity implements EquipmentHandler {
private ItemStack getEquipmentItem(@NotNull ItemStack itemStack, @NotNull EquipmentSlot slot) {
EntityEquipEvent entityEquipEvent = new EntityEquipEvent(this, itemStack, slot);
- callEvent(EntityEquipEvent.class, entityEquipEvent);
+ EventDispatcher.call(entityEquipEvent);
return entityEquipEvent.getEquippedItem();
}
@@ -232,7 +236,7 @@ public class LivingEntity extends Entity implements EquipmentHandler {
if (itemEntity.shouldRemove() || itemEntity.isRemoveScheduled())
continue;
PickupItemEvent pickupItemEvent = new PickupItemEvent(this, itemEntity);
- callCancellableEvent(PickupItemEvent.class, pickupItemEvent, () -> {
+ EventDispatcher.callCancellable(pickupItemEvent, () -> {
final ItemStack item = itemEntity.getItemStack();
CollectItemPacket collectItemPacket = new CollectItemPacket();
@@ -305,7 +309,7 @@ public class LivingEntity extends Entity implements EquipmentHandler {
}
EntityDeathEvent entityDeathEvent = new EntityDeathEvent(this);
- callEvent(EntityDeathEvent.class, entityDeathEvent);
+ EventDispatcher.call(entityDeathEvent);
}
/**
@@ -329,7 +333,7 @@ public class LivingEntity extends Entity implements EquipmentHandler {
// Do not start fire event if the fire needs to be removed (< 0 duration)
if (duration > 0) {
- callCancellableEvent(EntityFireEvent.class, entityFireEvent, () -> {
+ EventDispatcher.callCancellable(entityFireEvent, () -> {
final long fireTime = entityFireEvent.getFireTime(TimeUnit.MILLISECOND);
setOnFire(true);
fireExtinguishTime = System.currentTimeMillis() + fireTime;
@@ -354,7 +358,7 @@ public class LivingEntity extends Entity implements EquipmentHandler {
}
EntityDamageEvent entityDamageEvent = new EntityDamageEvent(this, type, value);
- callCancellableEvent(EntityDamageEvent.class, entityDamageEvent, () -> {
+ EventDispatcher.callCancellable(entityDamageEvent, () -> {
// Set the last damage type since the event is not cancelled
this.lastDamageSource = entityDamageEvent.getDamageType();
@@ -602,7 +606,7 @@ public class LivingEntity extends Entity implements EquipmentHandler {
public void setFlyingWithElytra(boolean isFlying) {
this.entityMeta.setFlyingWithElytra(isFlying);
}
-
+
/**
* Used to change the {@code isDead} internal field.
*
diff --git a/src/main/java/net/minestom/server/entity/Player.java b/src/main/java/net/minestom/server/entity/Player.java
index 85cd9024f..0461591d7 100644
--- a/src/main/java/net/minestom/server/entity/Player.java
+++ b/src/main/java/net/minestom/server/entity/Player.java
@@ -30,6 +30,7 @@ import net.minestom.server.effects.Effects;
import net.minestom.server.entity.damage.DamageType;
import net.minestom.server.entity.fakeplayer.FakePlayer;
import net.minestom.server.entity.vehicle.PlayerVehicleInformation;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.inventory.InventoryOpenEvent;
import net.minestom.server.event.item.ItemDropEvent;
import net.minestom.server.event.item.ItemUpdateStateEvent;
@@ -250,7 +251,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
// Add player to list with spawning skin
PlayerSkinInitEvent skinInitEvent = new PlayerSkinInitEvent(this, skin);
- callEvent(PlayerSkinInitEvent.class, skinInitEvent);
+ EventDispatcher.call(skinInitEvent);
this.skin = skinInitEvent.getSkin();
// FIXME: when using Geyser, this line remove the skin of the client
playerConnection.sendPacket(getAddPlayerToList());
@@ -380,7 +381,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
if (experienceOrb.shouldRemove() || experienceOrb.isRemoveScheduled())
continue;
PickupExperienceEvent pickupExperienceEvent = new PickupExperienceEvent(experienceOrb);
- callCancellableEvent(PickupExperienceEvent.class, pickupExperienceEvent, () -> {
+ EventDispatcher.callCancellable(pickupExperienceEvent, () -> {
short experienceCount = pickupExperienceEvent.getExperienceCount(); // TODO give to player
entity.remove();
});
@@ -406,7 +407,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
if (isFood) {
PlayerEatEvent playerEatEvent = new PlayerEatEvent(this, foodItem, eatingHand);
- callEvent(PlayerEatEvent.class, playerEatEvent);
+ EventDispatcher.call(playerEatEvent);
}
refreshEating(null);
@@ -414,7 +415,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
}
// Tick event
- callEvent(PlayerTickEvent.class, playerTickEvent);
+ EventDispatcher.call(playerTickEvent);
}
@Override
@@ -444,7 +445,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
// Call player death event
PlayerDeathEvent playerDeathEvent = new PlayerDeathEvent(this, deathText, chatMessage);
- callEvent(PlayerDeathEvent.class, playerDeathEvent);
+ EventDispatcher.call(playerDeathEvent);
deathText = playerDeathEvent.getDeathText();
chatMessage = playerDeathEvent.getChatMessage();
@@ -480,7 +481,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
respawnPacket.isFlat = levelFlat;
getPlayerConnection().sendPacket(respawnPacket);
PlayerRespawnEvent respawnEvent = new PlayerRespawnEvent(this);
- callEvent(PlayerRespawnEvent.class, respawnEvent);
+ EventDispatcher.call(respawnEvent);
refreshIsDead(false);
// Runnable called when teleportation is successful (after loading and sending necessary chunk)
@@ -502,7 +503,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
if (isRemoved())
return;
- callEvent(PlayerDisconnectEvent.class, new PlayerDisconnectEvent(this));
+ EventDispatcher.call(new PlayerDisconnectEvent(this));
super.remove();
this.packets.clear();
@@ -660,7 +661,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
}
PlayerSpawnEvent spawnEvent = new PlayerSpawnEvent(this, instance, firstSpawn);
- callEvent(PlayerSpawnEvent.class, spawnEvent);
+ EventDispatcher.call(spawnEvent);
}
/**
@@ -1306,7 +1307,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
}
ItemDropEvent itemDropEvent = new ItemDropEvent(this, item);
- callEvent(ItemDropEvent.class, itemDropEvent);
+ EventDispatcher.call(itemDropEvent);
return !itemDropEvent.isCancelled();
}
@@ -1827,7 +1828,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
InventoryOpenEvent inventoryOpenEvent = new InventoryOpenEvent(inventory, this);
- callCancellableEvent(InventoryOpenEvent.class, inventoryOpenEvent, () -> {
+ EventDispatcher.callCancellable(inventoryOpenEvent, () -> {
Inventory openInventory = getOpenInventory();
if (openInventory != null) {
openInventory.removeViewer(this);
@@ -2196,7 +2197,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
this.onGround = onGround;
if (this.onGround && this.isFlyingWithElytra()) {
this.setFlyingWithElytra(false);
- this.callEvent(PlayerStopFlyingWithElytraEvent.class, new PlayerStopFlyingWithElytraEvent(this));
+ EventDispatcher.call(new PlayerStopFlyingWithElytraEvent(this));
}
}
@@ -2271,7 +2272,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
return null;
ItemUpdateStateEvent itemUpdateStateEvent = new ItemUpdateStateEvent(this, hand, updatedItem);
- callEvent(ItemUpdateStateEvent.class, itemUpdateStateEvent);
+ EventDispatcher.call(itemUpdateStateEvent);
return itemUpdateStateEvent;
}
diff --git a/src/main/java/net/minestom/server/entity/type/decoration/EntityArmorStand.java b/src/main/java/net/minestom/server/entity/type/decoration/EntityArmorStand.java
index 121146e7b..0942c646f 100644
--- a/src/main/java/net/minestom/server/entity/type/decoration/EntityArmorStand.java
+++ b/src/main/java/net/minestom/server/entity/type/decoration/EntityArmorStand.java
@@ -1,6 +1,7 @@
package net.minestom.server.entity.type.decoration;
import net.minestom.server.entity.*;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.item.EntityEquipEvent;
import net.minestom.server.inventory.EquipmentHandler;
import net.minestom.server.item.ItemStack;
@@ -237,7 +238,7 @@ public class EntityArmorStand extends ObjectEntity implements EquipmentHandler {
private ItemStack getEquipmentItem(@NotNull ItemStack itemStack, @NotNull EquipmentSlot slot) {
EntityEquipEvent entityEquipEvent = new EntityEquipEvent(this, itemStack, slot);
- callEvent(EntityEquipEvent.class, entityEquipEvent);
+ EventDispatcher.call(entityEquipEvent);
return entityEquipEvent.getEquippedItem();
}
}
diff --git a/src/main/java/net/minestom/server/entity/type/projectile/EntityProjectile.java b/src/main/java/net/minestom/server/entity/type/projectile/EntityProjectile.java
index 06576788c..1e5227d79 100644
--- a/src/main/java/net/minestom/server/entity/type/projectile/EntityProjectile.java
+++ b/src/main/java/net/minestom/server/entity/type/projectile/EntityProjectile.java
@@ -4,6 +4,7 @@ import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.LivingEntity;
import net.minestom.server.entity.metadata.ProjectileMeta;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.entity.EntityAttackEvent;
import net.minestom.server.event.entity.EntityShootEvent;
import net.minestom.server.instance.Chunk;
@@ -71,14 +72,14 @@ public class EntityProjectile extends Entity {
}
public void shoot(Position to, double power, double spread) {
- EntityShootEvent event = new EntityShootEvent(this.shooter, this, to, power, spread);
- this.shooter.callEvent(EntityShootEvent.class, event);
- if (event.isCancelled()) {
+ EntityShootEvent shootEvent = new EntityShootEvent(this.shooter, this, to, power, spread);
+ EventDispatcher.call(shootEvent);
+ if (shootEvent.isCancelled()) {
remove();
return;
}
Position from = this.shooter.getPosition().clone().add(0D, this.shooter.getEyeHeight(), 0D);
- shoot(from, to, event.getPower(), event.getSpread());
+ shoot(from, to, shootEvent.getPower(), shootEvent.getSpread());
}
private void shoot(@NotNull Position from, @NotNull Position to, double power, double spread) {
@@ -193,7 +194,7 @@ public class EntityProjectile extends Entity {
if (victimOptional.isPresent()) {
LivingEntity victim = (LivingEntity) victimOptional.get();
victim.setArrowCount(victim.getArrowCount() + 1);
- callEvent(EntityAttackEvent.class, new EntityAttackEvent(this, victim));
+ EventDispatcher.call(new EntityAttackEvent(this, victim));
remove();
return super.onGround;
}
diff --git a/src/main/java/net/minestom/server/event/EntityEvent.java b/src/main/java/net/minestom/server/event/EntityEvent.java
deleted file mode 100644
index 49485c1e2..000000000
--- a/src/main/java/net/minestom/server/event/EntityEvent.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package net.minestom.server.event;
-
-import net.minestom.server.entity.Entity;
-import org.jetbrains.annotations.NotNull;
-
-public class EntityEvent extends Event {
-
- protected final Entity entity;
-
- public EntityEvent(@NotNull Entity entity) {
- this.entity = entity;
- }
-
- /**
- * Gets the entity of this event.
- *
- * @return the entity
- */
- @NotNull
- public Entity getEntity() {
- return entity;
- }
-}
diff --git a/src/main/java/net/minestom/server/event/Event.java b/src/main/java/net/minestom/server/event/Event.java
index 047a6980e..a41a18286 100644
--- a/src/main/java/net/minestom/server/event/Event.java
+++ b/src/main/java/net/minestom/server/event/Event.java
@@ -1,11 +1,9 @@
package net.minestom.server.event;
-import net.minestom.server.event.handler.EventHandler;
-
/**
- * Object which can be listened to by an {@link EventHandler}.
+ * Event which can be listened to by an {@link EventNode} using {@link EventNode#addListener(EventListener)}.
*
- * Called using {@link EventHandler#callEvent(Class, Event)}.
+ * Called using {@link EventDispatcher#call(Event)}.
*/
-public class Event {
+public interface Event {
}
diff --git a/src/main/java/net/minestom/server/event/EventDispatcher.java b/src/main/java/net/minestom/server/event/EventDispatcher.java
new file mode 100644
index 000000000..2cbdeb130
--- /dev/null
+++ b/src/main/java/net/minestom/server/event/EventDispatcher.java
@@ -0,0 +1,16 @@
+package net.minestom.server.event;
+
+import net.minestom.server.MinecraftServer;
+import net.minestom.server.event.trait.CancellableEvent;
+import org.jetbrains.annotations.NotNull;
+
+public class EventDispatcher {
+
+ public static void call(@NotNull Event event) {
+ MinecraftServer.getGlobalEventHandler().call(event);
+ }
+
+ public static void callCancellable(@NotNull CancellableEvent event, @NotNull Runnable successCallback) {
+ MinecraftServer.getGlobalEventHandler().callCancellable(event, successCallback);
+ }
+}
diff --git a/src/main/java/net/minestom/server/event/EventFilter.java b/src/main/java/net/minestom/server/event/EventFilter.java
new file mode 100644
index 000000000..4a7740266
--- /dev/null
+++ b/src/main/java/net/minestom/server/event/EventFilter.java
@@ -0,0 +1,67 @@
+package net.minestom.server.event;
+
+import net.minestom.server.entity.Entity;
+import net.minestom.server.entity.Player;
+import net.minestom.server.event.trait.*;
+import net.minestom.server.instance.Instance;
+import net.minestom.server.inventory.Inventory;
+import net.minestom.server.item.ItemStack;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.function.Function;
+
+/**
+ * Represents a filter for a specific {@link Event} type.
+ *
+ * The handler represents a "target" of the event. This can be used
+ * to create filters for all events of a specific type using information
+ * about the target.
+ *
+ * For example, the target of a {@link PlayerEvent} is a {@link Player} so
+ * you could create a player event filter which checks if the target player
+ * is in creative mode.
+ *
+ * @param The event type to filter
+ * @param The handler type to filter on.
+ */
+public interface EventFilter {
+
+ EventFilter ALL = from(Event.class, null);
+ EventFilter ENTITY = from(EntityEvent.class, EntityEvent::getEntity);
+ EventFilter PLAYER = from(PlayerEvent.class, PlayerEvent::getPlayer);
+ EventFilter ITEM = from(ItemEvent.class, ItemEvent::getItemStack);
+ EventFilter INSTANCE = from(InstanceEvent.class, InstanceEvent::getInstance);
+ EventFilter INVENTORY = from(InventoryEvent.class, InventoryEvent::getInventory);
+
+ static EventFilter from(@NotNull Class eventType,
+ @Nullable Function handlerGetter) {
+ return new EventFilter<>() {
+ @Override
+ public @Nullable H getHandler(@NotNull E event) {
+ return handlerGetter != null ? handlerGetter.apply(event) : null;
+ }
+
+ @Override
+ public @NotNull Class getEventType() {
+ return eventType;
+ }
+ };
+ }
+
+ /**
+ * Gets the handler for the given event instance, or null if the event
+ * type has no handler.
+ *
+ * @param event The event instance
+ * @return The handler, if it exists for the given event
+ */
+ @Nullable H getHandler(@NotNull E event);
+
+ /**
+ * The event type to filter on.
+ *
+ * @return The event type.
+ */
+ @NotNull Class getEventType();
+}
diff --git a/src/main/java/net/minestom/server/event/EventListener.java b/src/main/java/net/minestom/server/event/EventListener.java
new file mode 100644
index 000000000..df6d7a1bd
--- /dev/null
+++ b/src/main/java/net/minestom/server/event/EventListener.java
@@ -0,0 +1,180 @@
+package net.minestom.server.event;
+
+import net.minestom.server.event.trait.CancellableEvent;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+
+/**
+ * Represents an event listener (handler) in an event graph.
+ *
+ * A listener is responsible for executing some action based on an event triggering.
+ *
+ * @param The event type being handled.
+ */
+public interface EventListener {
+
+ @NotNull Class getEventType();
+
+ @NotNull Result run(@NotNull T event);
+
+ @Contract(pure = true)
+ static EventListener.@NotNull Builder builder(@NotNull Class eventType) {
+ return new EventListener.Builder<>(eventType);
+ }
+
+ /**
+ * Create an event listener without any special options. The given listener will be executed
+ * if the event passes all parent filtering.
+ *
+ * @param eventType The event type to handle
+ * @param listener The handler function
+ * @param The event type to handle
+ * @return An event listener with the given properties
+ */
+ @Contract(pure = true)
+ static @NotNull EventListener of(@NotNull Class eventType, @NotNull Consumer<@NotNull T> listener) {
+ return new EventListener<>() {
+ @Override
+ public @NotNull Class getEventType() {
+ return eventType;
+ }
+
+ @Override
+ public @NotNull Result run(@NotNull T event) {
+ listener.accept(event);
+ return Result.SUCCESS;
+ }
+ };
+ }
+
+ class Builder {
+ private final Class eventType;
+ private final List> filters = new ArrayList<>();
+ private boolean ignoreCancelled = true;
+ private int expireCount;
+ private Predicate expireWhen;
+ private Consumer handler;
+
+ protected Builder(Class eventType) {
+ this.eventType = eventType;
+ }
+
+ /**
+ * Adds a filter to the executor of this listener. The executor will only
+ * be called if this condition passes on the given event.
+ */
+ @Contract(value = "_ -> this")
+ public @NotNull EventListener.Builder filter(Predicate filter) {
+ this.filters.add(filter);
+ return this;
+ }
+
+ /**
+ * Specifies if the handler should still be called if {@link CancellableEvent#isCancelled()} returns {@code true}.
+ *
+ * Default is set to {@code true}.
+ *
+ * @param ignoreCancelled True to stop processing the event when cancelled
+ */
+ @Contract(value = "_ -> this")
+ public @NotNull EventListener.Builder ignoreCancelled(boolean ignoreCancelled) {
+ this.ignoreCancelled = ignoreCancelled;
+ return this;
+ }
+
+ /**
+ * Removes this listener after it has been executed the given number of times.
+ *
+ * @param expireCount The number of times to execute
+ */
+ @Contract(value = "_ -> this")
+ public @NotNull EventListener.Builder expireCount(int expireCount) {
+ this.expireCount = expireCount;
+ return this;
+ }
+
+ /**
+ * Expires this listener when it passes the given condition. The expiration will
+ * happen before the event is executed.
+ *
+ * @param expireWhen The condition to test
+ */
+ @Contract(value = "_ -> this")
+ public @NotNull EventListener.Builder expireWhen(Predicate expireWhen) {
+ this.expireWhen = expireWhen;
+ return this;
+ }
+
+ /**
+ * Sets the handler for this event listener. This will be executed if the listener passes
+ * all conditions.
+ */
+ @Contract(value = "_ -> this")
+ public @NotNull EventListener.Builder handler(Consumer handler) {
+ this.handler = handler;
+ return this;
+ }
+
+ @Contract(value = "-> new", pure = true)
+ public @NotNull EventListener build() {
+ final boolean ignoreCancelled = this.ignoreCancelled;
+ AtomicInteger expirationCount = new AtomicInteger(this.expireCount);
+ final boolean hasExpirationCount = expirationCount.get() > 0;
+
+ final Predicate expireWhen = this.expireWhen;
+
+ final var filters = new ArrayList<>(this.filters);
+ final var handler = this.handler;
+ return new EventListener<>() {
+ @Override
+ public @NotNull Class getEventType() {
+ return eventType;
+ }
+
+ @Override
+ public @NotNull Result run(@NotNull T event) {
+ // Event cancellation
+ if (ignoreCancelled && event instanceof CancellableEvent &&
+ ((CancellableEvent) event).isCancelled()) {
+ return Result.INVALID;
+ }
+ // Expiration predicate
+ if (expireWhen != null && expireWhen.test(event)) {
+ return Result.EXPIRED;
+ }
+ // Filtering
+ if (!filters.isEmpty()) {
+ for (var filter : filters) {
+ if (!filter.test(event)) {
+ // Cancelled
+ return Result.INVALID;
+ }
+ }
+ }
+ // Handler
+ if (handler != null) {
+ handler.accept(event);
+ }
+ // Expiration count
+ if (hasExpirationCount && expirationCount.decrementAndGet() == 0) {
+ return Result.EXPIRED;
+ }
+ return Result.SUCCESS;
+ }
+ };
+ }
+ }
+
+ enum Result {
+ SUCCESS,
+ INVALID,
+ EXPIRED,
+ EXCEPTION
+ }
+}
diff --git a/src/main/java/net/minestom/server/event/EventNode.java b/src/main/java/net/minestom/server/event/EventNode.java
new file mode 100644
index 000000000..c6b359564
--- /dev/null
+++ b/src/main/java/net/minestom/server/event/EventNode.java
@@ -0,0 +1,555 @@
+package net.minestom.server.event;
+
+import net.minestom.server.MinecraftServer;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.tag.Tag;
+import net.minestom.server.tag.TagReadable;
+import net.minestom.server.utils.validate.Check;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+import java.util.function.BiPredicate;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+
+/**
+ * Represents a single node in an event graph.
+ *
+ * A node may contain any number of children and/or listeners. When an event is called,
+ * the node will filter it based on the parameters given at creation and then propagate
+ * it down to child nodes and listeners if it passes.
+ *
+ * @param The event type accepted by this node
+ */
+public class EventNode {
+
+ /**
+ * Creates an event node which accepts any event type with no filtering.
+ *
+ * @param name The name of the node
+ * @return An event node with no filtering
+ */
+ @Contract(value = "_ -> new", pure = true)
+ public static @NotNull EventNode all(@NotNull String name) {
+ return type(name, EventFilter.ALL);
+ }
+
+ /**
+ * Creates an event node which accepts any event of the given type. The type is provided
+ * by the {@link EventFilter}.
+ *
+ * For example, you could create an event filter which only accepts player events with the following
+ *
+ * var playerEventNode = EventNode.type("demo", EventFilter.PLAYER);
+ *
+ *
+ * @param name The name of the event node
+ * @param filter The event type filter to apply
+ * @param The resulting event type of the node
+ * @return A node with just an event type filter
+ */
+ @Contract(value = "_, _ -> new", pure = true)
+ public static @NotNull EventNode type(@NotNull String name,
+ @NotNull EventFilter filter) {
+ return create(name, filter, null);
+ }
+
+ /**
+ * Creates an event node which accepts any event of the given type which passes
+ * the provided condition. The condition is based on the event object itself.
+ *
+ * For example, you could create an event filter which only accepts player events
+ * where the player is in the pos x/z quadrant of the world.
+ *
{@code
+ * var playerInPosXZNode = EventNode.event("abc", EventFilter.PLAYER, event -> {
+ * var position = event.getPlayer().getPosition();
+ * return position.getX() > 0 && position.getZ() > 0;
+ * });
+ * }
+ *
+ * @param name The name of the event node
+ * @param filter The event type filter to apply
+ * @param predicate The event condition
+ * @param The resulting event type of the node
+ * @return A node with an event type filter as well as a condition on the event.
+ */
+ @Contract(value = "_, _, _ -> new", pure = true)
+ public static @NotNull EventNode event(@NotNull String name,
+ @NotNull EventFilter filter,
+ @NotNull Predicate predicate) {
+ return create(name, filter, (e, h) -> predicate.test(e));
+ }
+
+ /**
+ * Creates an event node which accepts any event of the given type which passes
+ * the provided condition. The condition is based on the event object as well as
+ * the event handler type defined in the {@link EventFilter}.
+ *
+ * For example, you could create an event filter which only accepts player events
+ * where the player is in the pos x/z quadrant of the world.
+ *
{@code
+ * var playerInPosXZNode = EventNode.type("abc", EventFilter.PLAYER, (event, player) -> {
+ * var position = player.getPosition();
+ * return position.getX() > 0 && position.getZ() > 0;
+ * });
+ * }
+ *
+ * @param name The name of the event node
+ * @param filter The event type filter to apply
+ * @param predicate The event condition
+ * @param The resulting event type of the node
+ * @param The handler type of the event filter
+ * @return A node with an event type filter as well as a condition on the event.
+ */
+ @Contract(value = "_, _, _ -> new", pure = true)
+ public static @NotNull EventNode type(@NotNull String name,
+ @NotNull EventFilter filter,
+ @NotNull BiPredicate predicate) {
+ return create(name, filter, predicate);
+ }
+
+ /**
+ * Creates an event node which accepts any event of the given type which passes
+ * the provided condition. The condition is based on the event handler defined
+ * by the {@link EventFilter}.
+ *
+ * For example, you could create an event filter which only accepts player events
+ * where the player is in creative mode.
+ *
+ * var playerIsCreative = EventNode.value("abc", EventFilter.PLAYER, Player::isCreative);
+ *
+ *
+ * @param name The name of the event node
+ * @param filter The event type filter to apply
+ * @param predicate The event condition
+ * @param The resulting event type of the node
+ * @param The handler type of the event filter
+ * @return A node with an event type filter as well as a condition on the event.
+ */
+ @Contract(value = "_, _, _ -> new", pure = true)
+ public static @NotNull EventNode value(@NotNull String name,
+ @NotNull EventFilter filter,
+ @NotNull Predicate predicate) {
+ return create(name, filter, (e, h) -> predicate.test(h));
+ }
+
+ /**
+ * Creates an event node which accepts any event of the given type which has a handler who
+ * has the given tag.
+ *
+ * The {@link EventFilter}'s resulting event type must be {@link TagReadable}.
+ *
+ * @param name The name of the event node
+ * @param filter The event type filter to apply
+ * @param tag The tag which must be contained on the event handler
+ * @param The resulting event type of the node
+ * @return A node with an event type filter as well as a handler with the provided tag
+ */
+ @Contract(value = "_, _, _ -> new", pure = true)
+ public static @NotNull EventNode tag(@NotNull String name,
+ @NotNull EventFilter filter,
+ @NotNull Tag> tag) {
+ return create(name, filter, (e, h) -> h.hasTag(tag));
+ }
+
+ /**
+ * Creates an event node which accepts any event of the given type which has a handler who
+ * has an applicable tag. An applicable tag means that it passes the given condition.
+ *
+ * @param name The name of the event node
+ * @param filter The event type filter to apply
+ * @param tag The tag which must be contained on the event handler
+ * @param consumer The condition to test against the tag, if it exists.
+ * @param The resulting event type of the node
+ * @return A node with an event type filter as well as a handler with the provided tag
+ */
+ @Contract(value = "_, _, _, _ -> new", pure = true)
+ public static @NotNull EventNode tag(@NotNull String name,
+ @NotNull EventFilter filter,
+ @NotNull Tag tag,
+ @NotNull Predicate<@Nullable V> consumer) {
+ return create(name, filter, (e, h) -> consumer.test(h.getTag(tag)));
+ }
+
+ private static EventNode create(@NotNull String name,
+ @NotNull EventFilter filter,
+ @Nullable BiPredicate predicate) {
+ return new EventNode<>(name, filter, predicate != null ? (e, o) -> predicate.test(e, (V) o) : null);
+ }
+
+ private static final Object GLOBAL_CHILD_LOCK = new Object();
+ private final Object lock = new Object();
+
+ private final Map, ListenerEntry> listenerMap = new ConcurrentHashMap<>();
+ private final Set> children = new CopyOnWriteArraySet<>();
+
+ protected final String name;
+ protected final EventFilter filter;
+ protected final BiPredicate predicate;
+ protected final Class eventType;
+ private volatile int priority;
+ private volatile EventNode super T> parent;
+
+ protected EventNode(@NotNull String name,
+ @NotNull EventFilter filter,
+ @Nullable BiPredicate predicate) {
+ this.name = name;
+ this.filter = filter;
+ this.predicate = predicate;
+ this.eventType = filter.getEventType();
+ }
+
+ /**
+ * Condition to enter the node.
+ *
+ * @param event the called event
+ * @return true to enter the node, false otherwise
+ */
+ protected boolean condition(@NotNull T event) {
+ if (predicate == null)
+ return true;
+ final var value = filter.getHandler(event);
+ try {
+ return predicate.test(event, value);
+ } catch (Exception e) {
+ MinecraftServer.getExceptionManager().handleException(e);
+ return false;
+ }
+ }
+
+ /**
+ * Executes the given event on this node. The event must pass all conditions before
+ * it will be forwarded to the listeners.
+ *
+ * Calling an event on a node will execute all child nodes, however, an event may be
+ * called anywhere on the event graph and it will propagate down from there only.
+ *
+ * @param event the event to execute
+ */
+ public void call(@NotNull T event) {
+ final var eventClass = event.getClass();
+ if (!eventType.isAssignableFrom(eventClass)) {
+ // Invalid event type
+ return;
+ }
+ if (!condition(event)) {
+ // Cancelled by superclass
+ return;
+ }
+ // Process listener list
+ final var entry = listenerMap.get(eventClass);
+ if (entry == null) {
+ // No listener nor children
+ return;
+ }
+
+ final var listeners = entry.listeners;
+ if (!listeners.isEmpty()) {
+ for (EventListener listener : listeners) {
+ EventListener.Result result;
+ try {
+ result = listener.run(event);
+ } catch (Exception e) {
+ result = EventListener.Result.EXCEPTION;
+ MinecraftServer.getExceptionManager().handleException(e);
+ }
+ if (result == EventListener.Result.EXPIRED) {
+ listeners.remove(listener);
+ }
+ }
+ }
+ // Process children
+ if (entry.childCount > 0) {
+ this.children.stream()
+ .sorted(Comparator.comparing(EventNode::getPriority))
+ .forEach(child -> child.call(event));
+ }
+ }
+
+ /**
+ * Execute a cancellable event with a callback to execute if the event is successful.
+ * Event conditions and propagation is the same as {@link #call(Event)}.
+ *
+ * @param event The event to execute
+ * @param successCallback A callback if the event is not cancelled
+ */
+ public void callCancellable(@NotNull T event, @NotNull Runnable successCallback) {
+ call(event);
+ if (!(event instanceof CancellableEvent) || !((CancellableEvent) event).isCancelled()) {
+ successCallback.run();
+ }
+ }
+
+ @Contract(pure = true)
+ public @NotNull String getName() {
+ return name;
+ }
+
+ @Contract(pure = true)
+ public int getPriority() {
+ return priority;
+ }
+
+ @Contract(value = "_ -> this")
+ public @NotNull EventNode setPriority(int priority) {
+ this.priority = priority;
+ return this;
+ }
+
+ @Contract(pure = true)
+ public @Nullable EventNode super T> getParent() {
+ return parent;
+ }
+
+ /**
+ * Returns an unmodifiable view of the children in this node.
+ *
+ * @see #addChild(EventNode)
+ * @see #removeChild(EventNode)
+ */
+ @Contract(pure = true)
+ public @NotNull Set<@NotNull EventNode> getChildren() {
+ return Collections.unmodifiableSet(children);
+ }
+
+ /**
+ * Locates all child nodes with the given name and event type recursively starting at this node.
+ *
+ * @param name The event node name to filter for
+ * @param eventType The event node type to filter for
+ * @return All matching event nodes
+ */
+ @Contract(pure = true)
+ public @NotNull List> findChildren(@NotNull String name, Class eventType) {
+ if (children.isEmpty()) {
+ return Collections.emptyList();
+ }
+ synchronized (GLOBAL_CHILD_LOCK) {
+ List> result = new ArrayList<>();
+ for (EventNode child : children) {
+ if (EventNode.equals(child, name, eventType)) {
+ result.add((EventNode) child);
+ }
+ result.addAll(child.findChildren(name, eventType));
+ }
+ return result;
+ }
+ }
+
+ /**
+ * Locates all child nodes with the given name and event type recursively starting at this node.
+ *
+ * @param name The event name to filter for
+ * @return All matching event nodes
+ */
+ @Contract(pure = true)
+ public @NotNull List> findChildren(@NotNull String name) {
+ return findChildren(name, eventType);
+ }
+
+ /**
+ * Replaces all children matching the given name and type recursively starting from this node.
+ *
+ * Node: The callee may not be replaced by this call.
+ *
+ * @param name The event name to filter for
+ * @param eventType The event node type to filter for
+ * @param eventNode The replacement node
+ */
+ public void replaceChildren(@NotNull String name, @NotNull Class eventType, @NotNull EventNode eventNode) {
+ if (children.isEmpty()) {
+ return;
+ }
+ synchronized (GLOBAL_CHILD_LOCK) {
+ for (EventNode child : children) {
+ if (EventNode.equals(child, name, eventType)) {
+ removeChild(child);
+ addChild(eventNode);
+ continue;
+ }
+ child.replaceChildren(name, eventType, eventNode);
+ }
+ }
+ }
+
+ /**
+ * Replaces all children matching the given name and type recursively starting from this node.
+ *
+ * Node: The callee may not be replaced by this call.
+ *
+ * @param name The node name to filter for
+ * @param eventNode The replacement node
+ */
+ public void replaceChildren(@NotNull String name, @NotNull EventNode eventNode) {
+ replaceChildren(name, eventType, eventNode);
+ }
+
+ /**
+ * Recursively removes children with the given name and type starting at this node.
+ *
+ * @param name The node name to filter for
+ * @param eventType The node type to filter for
+ */
+ public void removeChildren(@NotNull String name, @NotNull Class extends T> eventType) {
+ if (children.isEmpty()) {
+ return;
+ }
+ synchronized (GLOBAL_CHILD_LOCK) {
+ for (EventNode child : children) {
+ if (EventNode.equals(child, name, eventType)) {
+ removeChild(child);
+ continue;
+ }
+ child.removeChildren(name, eventType);
+ }
+ }
+ }
+
+ /**
+ * Recursively removes children with the given name starting at this node.
+ *
+ * @param name The node name to filter for
+ */
+ public void removeChildren(@NotNull String name) {
+ removeChildren(name, eventType);
+ }
+
+ /**
+ * Directly adds a child node to this node.
+ *
+ * @param child The child to add
+ * @return this, can be used for chaining
+ */
+ @Contract(value = "_ -> this")
+ public @NotNull EventNode addChild(@NotNull EventNode extends T> child) {
+ synchronized (GLOBAL_CHILD_LOCK) {
+ Check.stateCondition(child.parent != null, "Node already has a parent");
+ Check.stateCondition(Objects.equals(parent, child), "Cannot have a child as parent");
+ final boolean result = this.children.add((EventNode) child);
+ if (result) {
+ child.parent = this;
+ // Increase listener count
+ synchronized (lock) {
+ child.listenerMap.forEach((eventClass, eventListeners) -> {
+ final var entry = child.listenerMap.get(eventClass);
+ if (entry == null)
+ return;
+ final int childCount = entry.listeners.size() + entry.childCount;
+ increaseChildListenerCount(eventClass, childCount);
+ });
+ }
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Directly removes the given child from this node.
+ *
+ * @param child The child to remove
+ * @return this, can be used for chaining
+ */
+ @Contract(value = "_ -> this")
+ public @NotNull EventNode removeChild(@NotNull EventNode extends T> child) {
+ synchronized (GLOBAL_CHILD_LOCK) {
+ final boolean result = this.children.remove(child);
+ if (result) {
+ child.parent = null;
+ // Decrease listener count
+ synchronized (lock) {
+ child.listenerMap.forEach((eventClass, eventListeners) -> {
+ final var entry = child.listenerMap.get(eventClass);
+ if (entry == null)
+ return;
+ final int childCount = entry.listeners.size() + entry.childCount;
+ decreaseChildListenerCount(eventClass, childCount);
+ });
+ }
+ }
+ }
+ return this;
+ }
+
+ @Contract(value = "_ -> this")
+ public @NotNull EventNode addListener(@NotNull EventListener extends T> listener) {
+ synchronized (GLOBAL_CHILD_LOCK) {
+ final var eventType = listener.getEventType();
+ var entry = listenerMap.computeIfAbsent(eventType, aClass -> new ListenerEntry<>());
+ entry.listeners.add((EventListener) listener);
+ if (parent != null) {
+ synchronized (parent.lock) {
+ parent.increaseChildListenerCount(eventType, 1);
+ }
+ }
+ }
+ return this;
+ }
+
+ @Contract(value = "_, _ -> this")
+ public @NotNull EventNode addListener(@NotNull Class eventType, @NotNull Consumer<@NotNull E> listener) {
+ return addListener(EventListener.of(eventType, listener));
+ }
+
+ @Contract(value = "_ -> this")
+ public @NotNull EventNode removeListener(@NotNull EventListener extends T> listener) {
+ synchronized (GLOBAL_CHILD_LOCK) {
+ final var eventType = listener.getEventType();
+ var entry = listenerMap.get(eventType);
+ if (entry == null)
+ return this;
+ var listeners = entry.listeners;
+ final boolean removed = listeners.remove(listener);
+ if (removed && parent != null) {
+ synchronized (parent.lock) {
+ parent.decreaseChildListenerCount(eventType, 1);
+ }
+ }
+ }
+ return this;
+ }
+
+ private void increaseChildListenerCount(Class extends T> eventClass, int count) {
+ var entry = listenerMap.computeIfAbsent(eventClass, aClass -> new ListenerEntry<>());
+ ListenerEntry.addAndGet(entry, count);
+ if (parent != null) {
+ parent.increaseChildListenerCount(eventClass, count);
+ }
+ }
+
+ private void decreaseChildListenerCount(Class extends T> eventClass, int count) {
+ var entry = listenerMap.computeIfAbsent(eventClass, aClass -> new ListenerEntry<>());
+ final int result = ListenerEntry.addAndGet(entry, -count);
+ if (result == 0 && entry.listeners.isEmpty()) {
+ this.listenerMap.remove(eventClass);
+ } else if (result < 0) {
+ throw new IllegalStateException("Something wrong happened, listener count: " + result);
+ }
+ if (parent != null) {
+ parent.decreaseChildListenerCount(eventClass, count);
+ }
+ }
+
+ private static boolean equals(EventNode> node, String name, Class> eventType) {
+ final boolean nameCheck = node.getName().equals(name);
+ final boolean typeCheck = eventType.isAssignableFrom(node.eventType);
+ return nameCheck && typeCheck;
+ }
+
+ private static class ListenerEntry {
+ private static final AtomicIntegerFieldUpdater CHILD_UPDATER =
+ AtomicIntegerFieldUpdater.newUpdater(ListenerEntry.class, "childCount");
+
+ List> listeners = new CopyOnWriteArrayList<>();
+ volatile int childCount;
+
+ private static int addAndGet(ListenerEntry> entry, int add) {
+ return CHILD_UPDATER.addAndGet(entry, add);
+ }
+ }
+}
diff --git a/src/main/java/net/minestom/server/event/GlobalEventHandler.java b/src/main/java/net/minestom/server/event/GlobalEventHandler.java
index 69c2d12b4..0e1a8c94f 100644
--- a/src/main/java/net/minestom/server/event/GlobalEventHandler.java
+++ b/src/main/java/net/minestom/server/event/GlobalEventHandler.java
@@ -1,31 +1,23 @@
package net.minestom.server.event;
-import net.minestom.server.event.handler.EventHandler;
import org.jetbrains.annotations.NotNull;
-import java.util.Collection;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.function.Consumer;
/**
* Object containing all the global event listeners.
*/
-public final class GlobalEventHandler implements EventHandler {
-
- // Events
- private final Map, Collection> eventCallbacks = new ConcurrentHashMap<>();
- private final Map>> extensionCallbacks = new ConcurrentHashMap<>();
-
- @NotNull
- @Override
- public Map, Collection> getEventCallbacksMap() {
- return eventCallbacks;
+public final class GlobalEventHandler extends EventNode {
+ public GlobalEventHandler() {
+ super("global", EventFilter.ALL, null);
}
- @NotNull
- @Override
- public Collection> getExtensionCallbacks(String extension) {
- return extensionCallbacks.computeIfAbsent(extension, e -> new CopyOnWriteArrayList<>());
+ /**
+ * @deprecated use {@link #addListener(Class, Consumer)}
+ */
+ @Deprecated
+ public boolean addEventCallback(@NotNull Class eventClass, @NotNull EventCallback eventCallback) {
+ addListener(eventClass, eventCallback::run);
+ return true;
}
}
diff --git a/src/main/java/net/minestom/server/event/InstanceEvent.java b/src/main/java/net/minestom/server/event/InstanceEvent.java
deleted file mode 100644
index fc7ba05da..000000000
--- a/src/main/java/net/minestom/server/event/InstanceEvent.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package net.minestom.server.event;
-
-import net.minestom.server.instance.Instance;
-import org.jetbrains.annotations.NotNull;
-
-public class InstanceEvent extends Event {
-
- protected final Instance instance;
-
- public InstanceEvent(@NotNull Instance instance) {
- this.instance = instance;
- }
-
- /**
- * Gets the instance.
- *
- * @return instance
- */
- @NotNull
- public Instance getInstance() {
- return instance;
- }
-}
\ No newline at end of file
diff --git a/src/main/java/net/minestom/server/event/InventoryEvent.java b/src/main/java/net/minestom/server/event/InventoryEvent.java
deleted file mode 100644
index ada529220..000000000
--- a/src/main/java/net/minestom/server/event/InventoryEvent.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package net.minestom.server.event;
-
-import net.minestom.server.inventory.Inventory;
-import org.jetbrains.annotations.Nullable;
-
-public class InventoryEvent extends Event {
-
- protected Inventory inventory;
-
- public InventoryEvent(@Nullable Inventory inventory) {
- this.inventory = inventory;
- }
-
- /**
- * Gets the inventory.
- *
- * @return the inventory, null if this is a player's inventory
- */
- @Nullable
- public Inventory getInventory() {
- return inventory;
- }
-}
\ No newline at end of file
diff --git a/src/main/java/net/minestom/server/event/PlayerEvent.java b/src/main/java/net/minestom/server/event/PlayerEvent.java
deleted file mode 100644
index 21185ebbe..000000000
--- a/src/main/java/net/minestom/server/event/PlayerEvent.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package net.minestom.server.event;
-
-import net.minestom.server.entity.Player;
-import org.jetbrains.annotations.NotNull;
-
-public class PlayerEvent extends Event {
-
- protected final Player player;
-
- public PlayerEvent(@NotNull Player player) {
- this.player = player;
- }
-
- /**
- * Gets the player.
- *
- * @return the player
- */
- @NotNull
- public Player getPlayer() {
- return player;
- }
-}
diff --git a/src/main/java/net/minestom/server/event/entity/EntityAttackEvent.java b/src/main/java/net/minestom/server/event/entity/EntityAttackEvent.java
index 13b2a8ebc..b56323bfe 100644
--- a/src/main/java/net/minestom/server/event/entity/EntityAttackEvent.java
+++ b/src/main/java/net/minestom/server/event/entity/EntityAttackEvent.java
@@ -1,22 +1,28 @@
package net.minestom.server.event.entity;
import net.minestom.server.entity.Entity;
-import net.minestom.server.event.EntityEvent;
+import net.minestom.server.event.trait.EntityEvent;
import org.jetbrains.annotations.NotNull;
/**
* Called when a player does a left click on an entity or with
* {@link net.minestom.server.entity.EntityCreature#attack(Entity)}.
*/
-public class EntityAttackEvent extends EntityEvent {
+public class EntityAttackEvent implements EntityEvent {
+ private final Entity entity;
private final Entity target;
public EntityAttackEvent(@NotNull Entity source, @NotNull Entity target) {
- super(source);
+ this.entity = source;
this.target = target;
}
+ @Override
+ public @NotNull Entity getEntity() {
+ return entity;
+ }
+
/**
* @return the target of the attack
*/
diff --git a/src/main/java/net/minestom/server/event/entity/EntityDamageEvent.java b/src/main/java/net/minestom/server/event/entity/EntityDamageEvent.java
index 5ea4aad2b..2060c5238 100644
--- a/src/main/java/net/minestom/server/event/entity/EntityDamageEvent.java
+++ b/src/main/java/net/minestom/server/event/entity/EntityDamageEvent.java
@@ -1,23 +1,25 @@
package net.minestom.server.event.entity;
+import net.minestom.server.entity.Entity;
import net.minestom.server.entity.LivingEntity;
import net.minestom.server.entity.damage.DamageType;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.EntityEvent;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.EntityEvent;
import org.jetbrains.annotations.NotNull;
/**
* Called with {@link LivingEntity#damage(DamageType, float)}.
*/
-public class EntityDamageEvent extends EntityEvent implements CancellableEvent {
+public class EntityDamageEvent implements EntityEvent, CancellableEvent {
+ private final Entity entity;
private final DamageType damageType;
private float damage;
private boolean cancelled;
public EntityDamageEvent(@NotNull LivingEntity entity, @NotNull DamageType damageType, float damage) {
- super(entity);
+ this.entity = entity;
this.damageType = damageType;
this.damage = damage;
}
diff --git a/src/main/java/net/minestom/server/event/entity/EntityDeathEvent.java b/src/main/java/net/minestom/server/event/entity/EntityDeathEvent.java
index 7bb3c7b7a..875a84dea 100644
--- a/src/main/java/net/minestom/server/event/entity/EntityDeathEvent.java
+++ b/src/main/java/net/minestom/server/event/entity/EntityDeathEvent.java
@@ -1,14 +1,20 @@
package net.minestom.server.event.entity;
import net.minestom.server.entity.Entity;
-import net.minestom.server.event.EntityEvent;
+import net.minestom.server.event.trait.EntityEvent;
import org.jetbrains.annotations.NotNull;
-public class EntityDeathEvent extends EntityEvent {
+public class EntityDeathEvent implements EntityEvent {
// TODO cause
+ private final Entity entity;
public EntityDeathEvent(@NotNull Entity entity) {
- super(entity);
+ this.entity = entity;
+ }
+
+ @Override
+ public @NotNull Entity getEntity() {
+ return entity;
}
}
diff --git a/src/main/java/net/minestom/server/event/entity/EntityFireEvent.java b/src/main/java/net/minestom/server/event/entity/EntityFireEvent.java
index 8a1355af3..5ffdad699 100644
--- a/src/main/java/net/minestom/server/event/entity/EntityFireEvent.java
+++ b/src/main/java/net/minestom/server/event/entity/EntityFireEvent.java
@@ -1,19 +1,21 @@
package net.minestom.server.event.entity;
import net.minestom.server.entity.Entity;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.EntityEvent;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.EntityEvent;
import net.minestom.server.utils.time.TimeUnit;
+import org.jetbrains.annotations.NotNull;
-public class EntityFireEvent extends EntityEvent implements CancellableEvent {
+public class EntityFireEvent implements EntityEvent, CancellableEvent {
+ private final Entity entity;
private int duration;
private TimeUnit timeUnit;
private boolean cancelled;
public EntityFireEvent(Entity entity, int duration, TimeUnit timeUnit) {
- super(entity);
+ this.entity = entity;
setFireTime(duration, timeUnit);
}
@@ -43,4 +45,9 @@ public class EntityFireEvent extends EntityEvent implements CancellableEvent {
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
+
+ @Override
+ public @NotNull Entity getEntity() {
+ return entity;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/entity/EntityItemMergeEvent.java b/src/main/java/net/minestom/server/event/entity/EntityItemMergeEvent.java
index 09a155e84..3a5510890 100644
--- a/src/main/java/net/minestom/server/event/entity/EntityItemMergeEvent.java
+++ b/src/main/java/net/minestom/server/event/entity/EntityItemMergeEvent.java
@@ -1,23 +1,25 @@
package net.minestom.server.event.entity;
+import net.minestom.server.entity.Entity;
import net.minestom.server.entity.ItemEntity;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.EntityEvent;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.EntityEvent;
import net.minestom.server.item.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* Called when two {@link ItemEntity} are merging their {@link ItemStack} together to form a sole entity.
*/
-public class EntityItemMergeEvent extends EntityEvent implements CancellableEvent {
+public class EntityItemMergeEvent implements EntityEvent, CancellableEvent {
+ private Entity entity;
private final ItemEntity merged;
private ItemStack result;
private boolean cancelled;
public EntityItemMergeEvent(@NotNull ItemEntity source, @NotNull ItemEntity merged, @NotNull ItemStack result) {
- super(source);
+ this.entity = source;
this.merged = merged;
this.result = result;
}
diff --git a/src/main/java/net/minestom/server/event/entity/EntityPotionAddEvent.java b/src/main/java/net/minestom/server/event/entity/EntityPotionAddEvent.java
index cde952db5..ee5517b21 100644
--- a/src/main/java/net/minestom/server/event/entity/EntityPotionAddEvent.java
+++ b/src/main/java/net/minestom/server/event/entity/EntityPotionAddEvent.java
@@ -1,19 +1,26 @@
package net.minestom.server.event.entity;
import net.minestom.server.entity.Entity;
-import net.minestom.server.event.EntityEvent;
+import net.minestom.server.event.trait.EntityEvent;
import net.minestom.server.potion.Potion;
import org.jetbrains.annotations.NotNull;
-public class EntityPotionAddEvent extends EntityEvent {
+public class EntityPotionAddEvent implements EntityEvent {
+ private final Entity entity;
private final Potion potion;
public EntityPotionAddEvent(@NotNull Entity entity, @NotNull Potion potion) {
- super(entity);
+ this.entity = entity;
this.potion = potion;
}
+ @NotNull
+ @Override
+ public Entity getEntity() {
+ return entity;
+ }
+
/**
* Returns the potion that was added.
*
diff --git a/src/main/java/net/minestom/server/event/entity/EntityPotionRemoveEvent.java b/src/main/java/net/minestom/server/event/entity/EntityPotionRemoveEvent.java
index 1ca787a18..e320cf4be 100644
--- a/src/main/java/net/minestom/server/event/entity/EntityPotionRemoveEvent.java
+++ b/src/main/java/net/minestom/server/event/entity/EntityPotionRemoveEvent.java
@@ -1,16 +1,17 @@
package net.minestom.server.event.entity;
import net.minestom.server.entity.Entity;
-import net.minestom.server.event.EntityEvent;
+import net.minestom.server.event.trait.EntityEvent;
import net.minestom.server.potion.Potion;
import org.jetbrains.annotations.NotNull;
-public class EntityPotionRemoveEvent extends EntityEvent {
+public class EntityPotionRemoveEvent implements EntityEvent {
+ private final Entity entity;
private final Potion potion;
public EntityPotionRemoveEvent(@NotNull Entity entity, @NotNull Potion potion) {
- super(entity);
+ this.entity = entity;
this.potion = potion;
}
@@ -23,4 +24,9 @@ public class EntityPotionRemoveEvent extends EntityEvent {
public Potion getPotion() {
return potion;
}
+
+ @Override
+ public @NotNull Entity getEntity() {
+ return entity;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/entity/EntityShootEvent.java b/src/main/java/net/minestom/server/event/entity/EntityShootEvent.java
index 7ca2df360..034b64a88 100644
--- a/src/main/java/net/minestom/server/event/entity/EntityShootEvent.java
+++ b/src/main/java/net/minestom/server/event/entity/EntityShootEvent.java
@@ -1,16 +1,17 @@
package net.minestom.server.event.entity;
import net.minestom.server.entity.Entity;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.EntityEvent;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.EntityEvent;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
/**
* Called with {@link net.minestom.server.entity.type.projectile.EntityProjectile#shoot(Position, double, double)}
*/
-public class EntityShootEvent extends EntityEvent implements CancellableEvent {
+public class EntityShootEvent implements EntityEvent, CancellableEvent {
+ private final Entity entity;
private final Entity projectile;
private final Position to;
private double power;
@@ -19,7 +20,7 @@ public class EntityShootEvent extends EntityEvent implements CancellableEvent {
private boolean cancelled;
public EntityShootEvent(@NotNull Entity entity, @NotNull Entity projectile, @NotNull Position to, double power, double spread) {
- super(entity);
+ this.entity = entity;
this.projectile = projectile;
this.to = to;
this.power = power;
@@ -90,4 +91,8 @@ public class EntityShootEvent extends EntityEvent implements CancellableEvent {
this.cancelled = cancel;
}
+ @Override
+ public @NotNull Entity getEntity() {
+ return entity;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/entity/EntitySpawnEvent.java b/src/main/java/net/minestom/server/event/entity/EntitySpawnEvent.java
index a53b66ee4..1fa94e1b3 100644
--- a/src/main/java/net/minestom/server/event/entity/EntitySpawnEvent.java
+++ b/src/main/java/net/minestom/server/event/entity/EntitySpawnEvent.java
@@ -1,19 +1,20 @@
package net.minestom.server.event.entity;
import net.minestom.server.entity.Entity;
-import net.minestom.server.event.EntityEvent;
+import net.minestom.server.event.trait.EntityEvent;
import net.minestom.server.instance.Instance;
import org.jetbrains.annotations.NotNull;
/**
* Called when a new instance is set for an entity.
*/
-public class EntitySpawnEvent extends EntityEvent {
+public class EntitySpawnEvent implements EntityEvent {
+ private final Entity entity;
private final Instance spawnInstance;
public EntitySpawnEvent(@NotNull Entity entity, @NotNull Instance spawnInstance) {
- super(entity);
+ this.entity = entity;
this.spawnInstance = spawnInstance;
}
diff --git a/src/main/java/net/minestom/server/event/entity/EntityTickEvent.java b/src/main/java/net/minestom/server/event/entity/EntityTickEvent.java
index 0e81c3313..7ab2eb97b 100644
--- a/src/main/java/net/minestom/server/event/entity/EntityTickEvent.java
+++ b/src/main/java/net/minestom/server/event/entity/EntityTickEvent.java
@@ -1,17 +1,23 @@
package net.minestom.server.event.entity;
import net.minestom.server.entity.Entity;
-import net.minestom.server.event.EntityEvent;
+import net.minestom.server.event.trait.EntityEvent;
import org.jetbrains.annotations.NotNull;
/**
* Called when an entity ticks itself.
* Same event instance used for all tick events for the same entity.
*/
-public class EntityTickEvent extends EntityEvent {
+public class EntityTickEvent implements EntityEvent {
+
+ private final Entity entity;
public EntityTickEvent(@NotNull Entity entity) {
- super(entity);
+ this.entity = entity;
}
+ @Override
+ public @NotNull Entity getEntity() {
+ return entity;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/entity/EntityVelocityEvent.java b/src/main/java/net/minestom/server/event/entity/EntityVelocityEvent.java
index ae0024f99..9ccdf6377 100644
--- a/src/main/java/net/minestom/server/event/entity/EntityVelocityEvent.java
+++ b/src/main/java/net/minestom/server/event/entity/EntityVelocityEvent.java
@@ -1,22 +1,23 @@
package net.minestom.server.event.entity;
import net.minestom.server.entity.Entity;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.EntityEvent;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.EntityEvent;
import net.minestom.server.utils.Vector;
import org.jetbrains.annotations.NotNull;
/**
* Called when a velocity is applied to an entity using {@link Entity#setVelocity(Vector)}.
*/
-public class EntityVelocityEvent extends EntityEvent implements CancellableEvent {
+public class EntityVelocityEvent implements EntityEvent, CancellableEvent {
+ private final Entity entity;
private Vector velocity;
private boolean cancelled;
public EntityVelocityEvent(@NotNull Entity entity, @NotNull Vector velocity) {
- super(entity);
+ this.entity = entity;
this.velocity = velocity;
}
diff --git a/src/main/java/net/minestom/server/event/handler/EventHandler.java b/src/main/java/net/minestom/server/event/handler/EventHandler.java
index 36d19851d..0518e3a9b 100644
--- a/src/main/java/net/minestom/server/event/handler/EventHandler.java
+++ b/src/main/java/net/minestom/server/event/handler/EventHandler.java
@@ -1,184 +1,27 @@
package net.minestom.server.event.handler;
-import net.minestom.server.MinecraftServer;
-import net.minestom.server.entity.Entity;
-import net.minestom.server.event.CancellableEvent;
import net.minestom.server.event.Event;
import net.minestom.server.event.EventCallback;
-import net.minestom.server.event.GlobalEventHandler;
-import net.minestom.server.extensions.IExtensionObserver;
-import net.minestom.server.extras.selfmodification.MinestomRootClassLoader;
-import net.minestom.server.instance.Instance;
+import net.minestom.server.event.EventNode;
+import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
-import java.util.Collection;
-import java.util.Map;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.stream.Stream;
-
/**
* Represents an element which can have {@link Event} listeners assigned to it.
+ *
+ * Use {@link EventNode} directly.
*/
-public interface EventHandler extends IExtensionObserver {
+@Deprecated
+public interface EventHandler {
- /**
- * Gets a {@link Map} containing all the listeners assigned to a specific {@link Event} type.
- *
- * @return a {@link Map} with all the listeners
- */
- @NotNull
- Map, Collection> getEventCallbacksMap();
+ @ApiStatus.Internal
+ @Deprecated(forRemoval = true)
+ @NotNull EventNode getEventNode();
- /**
- * Gets a {@link Collection} containing all the listeners assigned to a specific extension (represented by its name).
- * Used to unload all callbacks when the extension is unloaded
- *
- * @return a {@link Collection} with all the listeners
- */
- @NotNull
- Collection> getExtensionCallbacks(String extension);
-
- /**
- * Adds a new event callback for the specified type {@code eventClass}.
- *
- * @param eventClass the event class
- * @param eventCallback the event callback
- * @param the event type
- * @return true if the callback collection changed as a result of the call
- */
- default boolean addEventCallback(@NotNull Class eventClass, @NotNull EventCallback eventCallback) {
- String extensionSource = MinestomRootClassLoader.findExtensionObjectOwner(eventCallback);
- if(extensionSource != null) {
- MinecraftServer.getExtensionManager().getExtension(extensionSource).observe(this);
- getExtensionCallbacks(extensionSource).add(eventCallback);
- }
-
- Collection callbacks = getEventCallbacks(eventClass);
- return callbacks.add(eventCallback);
+ @Deprecated
+ default boolean addEventCallback(@NotNull Class eventClass, @NotNull EventCallback eventCallback) {
+ var node = getEventNode();
+ node.addListener(eventClass, eventCallback::run);
+ return true;
}
-
- /**
- * Removes an event callback.
- *
- * @param eventClass the event class
- * @param eventCallback the event callback
- * @param the event type
- * @return true if the callback was removed as a result of this call
- */
- default boolean removeEventCallback(@NotNull Class eventClass, @NotNull EventCallback eventCallback) {
- Collection callbacks = getEventCallbacks(eventClass);
- String extensionSource = MinestomRootClassLoader.findExtensionObjectOwner(eventCallback);
- if(extensionSource != null) {
- getExtensionCallbacks(extensionSource).remove(eventCallback);
- }
-
- return callbacks.remove(eventCallback);
- }
-
- /**
- * Gets the event callbacks of a specific event type.
- *
- * @param eventClass the event class
- * @param the event type
- * @return all event callbacks for the specified type {@code eventClass}
- */
- @NotNull
- default Collection getEventCallbacks(@NotNull Class eventClass) {
- return getEventCallbacksMap().computeIfAbsent(eventClass, clazz -> new CopyOnWriteArraySet<>());
- }
-
- /**
- * Gets a {@link Stream} containing all the {@link EventCallback}, no matter to which {@link Event} they are linked.
- *
- * @return a {@link Stream} containing all the callbacks
- */
- @NotNull
- default Stream getEventCallbacks() {
- return getEventCallbacksMap().values().stream().flatMap(Collection::stream);
- }
-
- /**
- * Calls the specified {@link Event} with all the assigned {@link EventCallback}.
- *
- * Events are always called in the current thread.
- *
- * @param eventClass the event class
- * @param event the event object
- * @param the event type
- */
- default void callEvent(@NotNull Class eventClass, @NotNull E event) {
-
- try {
-
- // Global listeners
- if (!(this instanceof GlobalEventHandler)) {
- final GlobalEventHandler globalEventHandler = MinecraftServer.getGlobalEventHandler();
- runEvent(globalEventHandler.getEventCallbacks(eventClass), event);
- }
-
- // Local listeners
- final Collection eventCallbacks = getEventCallbacks(eventClass);
- runEvent(eventCallbacks, event);
-
- // Call the same event for the current entity instance
- if (this instanceof Entity) {
- final Instance instance = ((Entity) this).getInstance();
- if (instance != null) {
- runEvent(instance.getEventCallbacks(eventClass), event);
- }
- }
- } catch (Exception exception) {
- MinecraftServer.getExceptionManager().handleException(exception);
- }
- }
-
- /**
- * Calls a {@link CancellableEvent} and execute {@code successCallback} if the {@link Event} is not cancelled.
- *
- * Does call {@link #callEvent(Class, Event)} internally.
- *
- * @param eventClass the event class
- * @param event the event object
- * @param successCallback the callback called when the event is not cancelled
- * @param the event type
- * @see #callEvent(Class, Event)
- */
- default void callCancellableEvent(@NotNull Class eventClass,
- @NotNull E event,
- @NotNull Runnable successCallback) {
- callEvent(eventClass, event);
- if (!event.isCancelled()) {
- successCallback.run();
- }
- }
-
- /**
- * Remove all event callbacks owned by the given extension
- * @param extension the extension to remove callbacks from
- */
- default void removeCallbacksOwnedByExtension(String extension) {
- Collection> extensionCallbacks = getExtensionCallbacks(extension);
- for(EventCallback> callback : extensionCallbacks) {
-
- // try to remove this callback from all callback collections
- // we do this because we do not have information about the event class at this point
- for(Collection eventCallbacks : getEventCallbacksMap().values()) {
- eventCallbacks.remove(callback);
- }
- }
-
- extensionCallbacks.clear();
- }
-
- private void runEvent(@NotNull Collection eventCallbacks, @NotNull E event) {
- for (EventCallback eventCallback : eventCallbacks) {
- eventCallback.run(event);
- }
- }
-
- @Override
- default void onExtensionUnload(String extensionName) {
- removeCallbacksOwnedByExtension(extensionName);
- }
-
}
diff --git a/src/main/java/net/minestom/server/event/instance/AddEntityToInstanceEvent.java b/src/main/java/net/minestom/server/event/instance/AddEntityToInstanceEvent.java
index 861d6f891..d04ab4658 100644
--- a/src/main/java/net/minestom/server/event/instance/AddEntityToInstanceEvent.java
+++ b/src/main/java/net/minestom/server/event/instance/AddEntityToInstanceEvent.java
@@ -1,8 +1,9 @@
package net.minestom.server.event.instance;
import net.minestom.server.entity.Entity;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.InstanceEvent;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.EntityEvent;
+import net.minestom.server.event.trait.InstanceEvent;
import net.minestom.server.instance.Instance;
import org.jetbrains.annotations.NotNull;
@@ -10,17 +11,23 @@ import org.jetbrains.annotations.NotNull;
* Called by an Instance when an entity is added to it.
* Can be used attach data.
*/
-public class AddEntityToInstanceEvent extends InstanceEvent implements CancellableEvent {
+public class AddEntityToInstanceEvent implements InstanceEvent, EntityEvent, CancellableEvent {
+ private final Instance instance;
private final Entity entity;
private boolean cancelled;
public AddEntityToInstanceEvent(@NotNull Instance instance, @NotNull Entity entity) {
- super(instance);
+ this.instance = instance;
this.entity = entity;
}
+ @Override
+ public @NotNull Instance getInstance() {
+ return instance;
+ }
+
/**
* Entity being added.
*
diff --git a/src/main/java/net/minestom/server/event/instance/InstanceChunkLoadEvent.java b/src/main/java/net/minestom/server/event/instance/InstanceChunkLoadEvent.java
index c102d75b1..4b03ca434 100644
--- a/src/main/java/net/minestom/server/event/instance/InstanceChunkLoadEvent.java
+++ b/src/main/java/net/minestom/server/event/instance/InstanceChunkLoadEvent.java
@@ -1,22 +1,28 @@
package net.minestom.server.event.instance;
-import net.minestom.server.event.InstanceEvent;
+import net.minestom.server.event.trait.InstanceEvent;
import net.minestom.server.instance.Instance;
import org.jetbrains.annotations.NotNull;
/**
* Called when a chunk in an instance is loaded.
*/
-public class InstanceChunkLoadEvent extends InstanceEvent {
+public class InstanceChunkLoadEvent implements InstanceEvent {
+ private final Instance instance;
private final int chunkX, chunkZ;
public InstanceChunkLoadEvent(@NotNull Instance instance, int chunkX, int chunkZ) {
- super(instance);
+ this.instance = instance;
this.chunkX = chunkX;
this.chunkZ = chunkZ;
}
+ @Override
+ public @NotNull Instance getInstance() {
+ return instance;
+ }
+
/**
* Gets the chunk X.
*
diff --git a/src/main/java/net/minestom/server/event/instance/InstanceChunkUnloadEvent.java b/src/main/java/net/minestom/server/event/instance/InstanceChunkUnloadEvent.java
index 306aaf107..aa3ae7fa2 100644
--- a/src/main/java/net/minestom/server/event/instance/InstanceChunkUnloadEvent.java
+++ b/src/main/java/net/minestom/server/event/instance/InstanceChunkUnloadEvent.java
@@ -1,22 +1,28 @@
package net.minestom.server.event.instance;
-import net.minestom.server.event.InstanceEvent;
+import net.minestom.server.event.trait.InstanceEvent;
import net.minestom.server.instance.Instance;
import org.jetbrains.annotations.NotNull;
/**
* Called when a chunk in an instance is unloaded.
*/
-public class InstanceChunkUnloadEvent extends InstanceEvent {
+public class InstanceChunkUnloadEvent implements InstanceEvent {
+ private final Instance instance;
private final int chunkX, chunkZ;
public InstanceChunkUnloadEvent(@NotNull Instance instance, int chunkX, int chunkZ) {
- super(instance);
+ this.instance = instance;
this.chunkX = chunkX;
this.chunkZ = chunkZ;
}
+ @Override
+ public @NotNull Instance getInstance() {
+ return instance;
+ }
+
/**
* Gets the chunk X.
*
@@ -34,5 +40,4 @@ public class InstanceChunkUnloadEvent extends InstanceEvent {
public int getChunkZ() {
return chunkZ;
}
-
}
diff --git a/src/main/java/net/minestom/server/event/instance/InstanceTickEvent.java b/src/main/java/net/minestom/server/event/instance/InstanceTickEvent.java
index eef4c67a6..b689cd228 100644
--- a/src/main/java/net/minestom/server/event/instance/InstanceTickEvent.java
+++ b/src/main/java/net/minestom/server/event/instance/InstanceTickEvent.java
@@ -1,21 +1,27 @@
package net.minestom.server.event.instance;
-import net.minestom.server.event.InstanceEvent;
+import net.minestom.server.event.trait.InstanceEvent;
import net.minestom.server.instance.Instance;
import org.jetbrains.annotations.NotNull;
/**
* Called when an instance processes a tick.
*/
-public class InstanceTickEvent extends InstanceEvent {
+public class InstanceTickEvent implements InstanceEvent {
+ private final Instance instance;
private final int duration;
public InstanceTickEvent(@NotNull Instance instance, long time, long lastTickAge) {
- super(instance);
+ this.instance = instance;
this.duration = (int) (time - lastTickAge);
}
+ @Override
+ public @NotNull Instance getInstance() {
+ return instance;
+ }
+
/**
* Gets the duration of the tick in ms.
*
diff --git a/src/main/java/net/minestom/server/event/instance/RemoveEntityFromInstanceEvent.java b/src/main/java/net/minestom/server/event/instance/RemoveEntityFromInstanceEvent.java
index fe180ffea..134dc2d62 100644
--- a/src/main/java/net/minestom/server/event/instance/RemoveEntityFromInstanceEvent.java
+++ b/src/main/java/net/minestom/server/event/instance/RemoveEntityFromInstanceEvent.java
@@ -1,25 +1,32 @@
package net.minestom.server.event.instance;
import net.minestom.server.entity.Entity;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.InstanceEvent;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.EntityEvent;
+import net.minestom.server.event.trait.InstanceEvent;
import net.minestom.server.instance.Instance;
import org.jetbrains.annotations.NotNull;
/**
* Called by an Instance when an entity is removed from it.
*/
-public class RemoveEntityFromInstanceEvent extends InstanceEvent implements CancellableEvent {
+public class RemoveEntityFromInstanceEvent implements InstanceEvent, EntityEvent, CancellableEvent {
+ private final Instance instance;
private final Entity entity;
private boolean cancelled;
public RemoveEntityFromInstanceEvent(@NotNull Instance instance, @NotNull Entity entity) {
- super(instance);
+ this.instance = instance;
this.entity = entity;
}
+ @Override
+ public @NotNull Instance getInstance() {
+ return instance;
+ }
+
/**
* Gets the entity being removed.
*
diff --git a/src/main/java/net/minestom/server/event/inventory/InventoryClickEvent.java b/src/main/java/net/minestom/server/event/inventory/InventoryClickEvent.java
index b7e9a89bb..c7ce5381b 100644
--- a/src/main/java/net/minestom/server/event/inventory/InventoryClickEvent.java
+++ b/src/main/java/net/minestom/server/event/inventory/InventoryClickEvent.java
@@ -1,7 +1,8 @@
package net.minestom.server.event.inventory;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.InventoryEvent;
+import net.minestom.server.event.trait.InventoryEvent;
+import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.click.ClickType;
import net.minestom.server.item.ItemStack;
@@ -12,8 +13,9 @@ import org.jetbrains.annotations.Nullable;
* Called after {@link InventoryPreClickEvent}, this event cannot be cancelled and items related to the click
* are already moved.
*/
-public class InventoryClickEvent extends InventoryEvent {
+public class InventoryClickEvent implements InventoryEvent, PlayerEvent {
+ private final Inventory inventory;
private final Player player;
private final int slot;
private final ClickType clickType;
@@ -23,7 +25,7 @@ public class InventoryClickEvent extends InventoryEvent {
public InventoryClickEvent(@Nullable Inventory inventory, @NotNull Player player,
int slot, @NotNull ClickType clickType,
@NotNull ItemStack clicked, @NotNull ItemStack cursor) {
- super(inventory);
+ this.inventory = inventory;
this.player = player;
this.slot = slot;
this.clickType = clickType;
@@ -79,4 +81,9 @@ public class InventoryClickEvent extends InventoryEvent {
public ItemStack getCursorItem() {
return cursorItem;
}
+
+ @Override
+ public @Nullable Inventory getInventory() {
+ return inventory;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/inventory/InventoryCloseEvent.java b/src/main/java/net/minestom/server/event/inventory/InventoryCloseEvent.java
index 881d64e07..ec6579799 100644
--- a/src/main/java/net/minestom/server/event/inventory/InventoryCloseEvent.java
+++ b/src/main/java/net/minestom/server/event/inventory/InventoryCloseEvent.java
@@ -1,7 +1,8 @@
package net.minestom.server.event.inventory;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.InventoryEvent;
+import net.minestom.server.event.trait.InventoryEvent;
+import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -9,13 +10,14 @@ import org.jetbrains.annotations.Nullable;
/**
* Called when an {@link Inventory} is closed by a player.
*/
-public class InventoryCloseEvent extends InventoryEvent {
+public class InventoryCloseEvent implements InventoryEvent, PlayerEvent {
+ private final Inventory inventory;
private final Player player;
private Inventory newInventory;
public InventoryCloseEvent(@Nullable Inventory inventory, @NotNull Player player) {
- super(inventory);
+ this.inventory = inventory;
this.player = player;
}
@@ -47,4 +49,9 @@ public class InventoryCloseEvent extends InventoryEvent {
public void setNewInventory(@Nullable Inventory newInventory) {
this.newInventory = newInventory;
}
+
+ @Override
+ public @Nullable Inventory getInventory() {
+ return inventory;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/inventory/InventoryOpenEvent.java b/src/main/java/net/minestom/server/event/inventory/InventoryOpenEvent.java
index 6b02eb717..f4a30129b 100644
--- a/src/main/java/net/minestom/server/event/inventory/InventoryOpenEvent.java
+++ b/src/main/java/net/minestom/server/event/inventory/InventoryOpenEvent.java
@@ -1,8 +1,9 @@
package net.minestom.server.event.inventory;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.InventoryEvent;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.InventoryEvent;
+import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -12,14 +13,15 @@ import org.jetbrains.annotations.Nullable;
*
* Executed by {@link Player#openInventory(Inventory)}.
*/
-public class InventoryOpenEvent extends InventoryEvent implements CancellableEvent {
+public class InventoryOpenEvent implements InventoryEvent, PlayerEvent, CancellableEvent {
+ private Inventory inventory;
private final Player player;
private boolean cancelled;
public InventoryOpenEvent(@Nullable Inventory inventory, @NotNull Player player) {
- super(inventory);
+ this.inventory = inventory;
this.player = player;
}
diff --git a/src/main/java/net/minestom/server/event/inventory/InventoryPreClickEvent.java b/src/main/java/net/minestom/server/event/inventory/InventoryPreClickEvent.java
index ca4733b38..13abd19bb 100644
--- a/src/main/java/net/minestom/server/event/inventory/InventoryPreClickEvent.java
+++ b/src/main/java/net/minestom/server/event/inventory/InventoryPreClickEvent.java
@@ -1,8 +1,9 @@
package net.minestom.server.event.inventory;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.InventoryEvent;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.InventoryEvent;
+import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.click.ClickType;
import net.minestom.server.item.ItemStack;
@@ -12,8 +13,9 @@ import org.jetbrains.annotations.Nullable;
/**
* Called before {@link InventoryClickEvent}, used to potentially cancel the click.
*/
-public class InventoryPreClickEvent extends InventoryEvent implements CancellableEvent {
+public class InventoryPreClickEvent implements InventoryEvent, PlayerEvent, CancellableEvent {
+ private final Inventory inventory;
private final Player player;
private final int slot;
private final ClickType clickType;
@@ -26,7 +28,7 @@ public class InventoryPreClickEvent extends InventoryEvent implements Cancellabl
@NotNull Player player,
int slot, @NotNull ClickType clickType,
@NotNull ItemStack clicked, @NotNull ItemStack cursor) {
- super(inventory);
+ this.inventory = inventory;
this.player = player;
this.slot = slot;
this.clickType = clickType;
@@ -110,4 +112,9 @@ public class InventoryPreClickEvent extends InventoryEvent implements Cancellabl
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
+
+ @Override
+ public @Nullable Inventory getInventory() {
+ return inventory;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/item/EntityEquipEvent.java b/src/main/java/net/minestom/server/event/item/EntityEquipEvent.java
index 501273eaf..c761989d0 100644
--- a/src/main/java/net/minestom/server/event/item/EntityEquipEvent.java
+++ b/src/main/java/net/minestom/server/event/item/EntityEquipEvent.java
@@ -2,11 +2,12 @@ package net.minestom.server.event.item;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EquipmentSlot;
-import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.EntityEvent;
+import net.minestom.server.event.trait.ItemEvent;
import net.minestom.server.item.ItemStack;
import org.jetbrains.annotations.NotNull;
-public class EntityEquipEvent extends Event {
+public class EntityEquipEvent implements EntityEvent, ItemEvent {
private final Entity entity;
private ItemStack equippedItem;
@@ -18,13 +19,7 @@ public class EntityEquipEvent extends Event {
this.slot = slot;
}
- @NotNull
- public Entity getEntity() {
- return entity;
- }
-
- @NotNull
- public ItemStack getEquippedItem() {
+ public @NotNull ItemStack getEquippedItem() {
return equippedItem;
}
@@ -32,8 +27,20 @@ public class EntityEquipEvent extends Event {
this.equippedItem = armorItem;
}
- @NotNull
- public EquipmentSlot getSlot() {
+ public @NotNull EquipmentSlot getSlot() {
return slot;
}
+
+ /**
+ * Same as {@link #getEquippedItem()}.
+ */
+ @Override
+ public @NotNull ItemStack getItemStack() {
+ return equippedItem;
+ }
+
+ @Override
+ public @NotNull Entity getEntity() {
+ return entity;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/item/ItemDropEvent.java b/src/main/java/net/minestom/server/event/item/ItemDropEvent.java
index 4ec4591ab..0652d854d 100644
--- a/src/main/java/net/minestom/server/event/item/ItemDropEvent.java
+++ b/src/main/java/net/minestom/server/event/item/ItemDropEvent.java
@@ -1,12 +1,13 @@
package net.minestom.server.event.item;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.ItemEvent;
+import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.item.ItemStack;
import org.jetbrains.annotations.NotNull;
-public class ItemDropEvent extends Event implements CancellableEvent {
+public class ItemDropEvent implements PlayerEvent, ItemEvent, CancellableEvent {
private final Player player;
private final ItemStack itemStack;
@@ -18,8 +19,8 @@ public class ItemDropEvent extends Event implements CancellableEvent {
this.itemStack = itemStack;
}
- @NotNull
- public Player getPlayer() {
+ @Override
+ public @NotNull Player getPlayer() {
return player;
}
@@ -37,4 +38,5 @@ public class ItemDropEvent extends Event implements CancellableEvent {
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
+
}
diff --git a/src/main/java/net/minestom/server/event/item/ItemUpdateStateEvent.java b/src/main/java/net/minestom/server/event/item/ItemUpdateStateEvent.java
index 201602499..817f08b7c 100644
--- a/src/main/java/net/minestom/server/event/item/ItemUpdateStateEvent.java
+++ b/src/main/java/net/minestom/server/event/item/ItemUpdateStateEvent.java
@@ -1,11 +1,12 @@
package net.minestom.server.event.item;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.ItemEvent;
+import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.item.ItemStack;
import org.jetbrains.annotations.NotNull;
-public class ItemUpdateStateEvent extends Event {
+public class ItemUpdateStateEvent implements PlayerEvent, ItemEvent {
private final Player player;
private final Player.Hand hand;
@@ -18,21 +19,11 @@ public class ItemUpdateStateEvent extends Event {
this.itemStack = itemStack;
}
- @NotNull
- public Player getPlayer() {
- return player;
- }
-
@NotNull
public Player.Hand getHand() {
return hand;
}
- @NotNull
- public ItemStack getItemStack() {
- return itemStack;
- }
-
public void setHandAnimation(boolean handAnimation) {
this.handAnimation = handAnimation;
}
@@ -40,4 +31,14 @@ public class ItemUpdateStateEvent extends Event {
public boolean hasHandAnimation() {
return handAnimation;
}
+
+ @Override
+ public @NotNull ItemStack getItemStack() {
+ return itemStack;
+ }
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/item/PickupExperienceEvent.java b/src/main/java/net/minestom/server/event/item/PickupExperienceEvent.java
index a1fa19188..832ee6f52 100644
--- a/src/main/java/net/minestom/server/event/item/PickupExperienceEvent.java
+++ b/src/main/java/net/minestom/server/event/item/PickupExperienceEvent.java
@@ -1,11 +1,10 @@
package net.minestom.server.event.item;
import net.minestom.server.entity.ExperienceOrb;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.CancellableEvent;
import org.jetbrains.annotations.NotNull;
-public class PickupExperienceEvent extends Event implements CancellableEvent {
+public class PickupExperienceEvent implements CancellableEvent {
private final ExperienceOrb experienceOrb;
private short experienceCount;
diff --git a/src/main/java/net/minestom/server/event/item/PickupItemEvent.java b/src/main/java/net/minestom/server/event/item/PickupItemEvent.java
index 04347c412..de5310458 100644
--- a/src/main/java/net/minestom/server/event/item/PickupItemEvent.java
+++ b/src/main/java/net/minestom/server/event/item/PickupItemEvent.java
@@ -1,13 +1,15 @@
package net.minestom.server.event.item;
+import net.minestom.server.entity.Entity;
import net.minestom.server.entity.ItemEntity;
import net.minestom.server.entity.LivingEntity;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.EntityEvent;
+import net.minestom.server.event.trait.ItemEvent;
import net.minestom.server.item.ItemStack;
import org.jetbrains.annotations.NotNull;
-public class PickupItemEvent extends Event implements CancellableEvent {
+public class PickupItemEvent implements EntityEvent, ItemEvent, CancellableEvent {
private final LivingEntity livingEntity;
private final ItemEntity itemEntity;
@@ -29,10 +31,6 @@ public class PickupItemEvent extends Event implements CancellableEvent {
return itemEntity;
}
- /**
- * @deprecated use {@link #getItemEntity()} and {@link ItemEntity#getItemStack()}.
- */
- @Deprecated
@NotNull
public ItemStack getItemStack() {
return getItemEntity().getItemStack();
@@ -47,4 +45,9 @@ public class PickupItemEvent extends Event implements CancellableEvent {
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
+
+ @Override
+ public @NotNull Entity getEntity() {
+ return livingEntity;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/AdvancementTabEvent.java b/src/main/java/net/minestom/server/event/player/AdvancementTabEvent.java
index 6270b9887..8eea66777 100644
--- a/src/main/java/net/minestom/server/event/player/AdvancementTabEvent.java
+++ b/src/main/java/net/minestom/server/event/player/AdvancementTabEvent.java
@@ -2,20 +2,22 @@ package net.minestom.server.event.player;
import net.minestom.server.advancements.AdvancementAction;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
/**
* Called when a {@link Player} opens the advancement screens or switch the tab
* and when he closes the screen.
*/
-public class AdvancementTabEvent extends PlayerEvent {
+public class AdvancementTabEvent implements PlayerEvent {
+ private final Player player;
private final AdvancementAction action;
private final String tabId;
public AdvancementTabEvent(@NotNull Player player, @NotNull AdvancementAction action, @NotNull String tabId) {
- super(player);
+ this.player = player;
this.action = action;
this.tabId = tabId;
}
@@ -41,4 +43,9 @@ public class AdvancementTabEvent extends PlayerEvent {
public String getTabId() {
return tabId;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/AsyncPlayerPreLoginEvent.java b/src/main/java/net/minestom/server/event/player/AsyncPlayerPreLoginEvent.java
index 612dc063b..3b67b438d 100644
--- a/src/main/java/net/minestom/server/event/player/AsyncPlayerPreLoginEvent.java
+++ b/src/main/java/net/minestom/server/event/player/AsyncPlayerPreLoginEvent.java
@@ -1,7 +1,8 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
@@ -10,13 +11,14 @@ import java.util.UUID;
* Called before the player initialization, it can be used to kick the player before any connection
* or to change his final username/uuid.
*/
-public class AsyncPlayerPreLoginEvent extends PlayerEvent {
+public class AsyncPlayerPreLoginEvent implements PlayerEvent {
+ private final Player player;
private String username;
private UUID playerUuid;
public AsyncPlayerPreLoginEvent(@NotNull Player player, @NotNull String username, @NotNull UUID playerUuid) {
- super(player);
+ this.player = player;
this.username = username;
this.playerUuid = playerUuid;
}
@@ -58,4 +60,9 @@ public class AsyncPlayerPreLoginEvent extends PlayerEvent {
public void setPlayerUuid(@NotNull UUID playerUuid) {
this.playerUuid = playerUuid;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerBlockBreakEvent.java b/src/main/java/net/minestom/server/event/player/PlayerBlockBreakEvent.java
index 57c370c44..82909ff1a 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerBlockBreakEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerBlockBreakEvent.java
@@ -2,8 +2,8 @@ package net.minestom.server.event.player;
import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.instance.block.BlockManager;
import net.minestom.server.instance.block.CustomBlock;
import net.minestom.server.utils.BlockPosition;
@@ -11,10 +11,11 @@ import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-public class PlayerBlockBreakEvent extends PlayerEvent implements CancellableEvent {
+public class PlayerBlockBreakEvent implements PlayerEvent, CancellableEvent {
private static final BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager();
+ private final Player player;
private final BlockPosition blockPosition;
private final short blockStateId;
@@ -28,7 +29,7 @@ public class PlayerBlockBreakEvent extends PlayerEvent implements CancellableEve
public PlayerBlockBreakEvent(@NotNull Player player, @NotNull BlockPosition blockPosition,
short blockStateId, @Nullable CustomBlock customBlock,
short resultBlockStateId, short resultCustomBlockId) {
- super(player);
+ this.player = player;
this.blockPosition = blockPosition;
@@ -151,4 +152,9 @@ public class PlayerBlockBreakEvent extends PlayerEvent implements CancellableEve
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerBlockInteractEvent.java b/src/main/java/net/minestom/server/event/player/PlayerBlockInteractEvent.java
index da1075a34..af17b6bec 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerBlockInteractEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerBlockInteractEvent.java
@@ -1,8 +1,8 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.instance.block.BlockFace;
import net.minestom.server.utils.BlockPosition;
import org.jetbrains.annotations.NotNull;
@@ -11,8 +11,9 @@ import org.jetbrains.annotations.NotNull;
* Called when a player interacts with a block (right-click).
* This is also called when a block is placed.
*/
-public class PlayerBlockInteractEvent extends PlayerEvent implements CancellableEvent {
+public class PlayerBlockInteractEvent implements PlayerEvent, CancellableEvent {
+ private final Player player;
private final BlockPosition blockPosition;
private final Player.Hand hand;
private final BlockFace blockFace;
@@ -27,7 +28,7 @@ public class PlayerBlockInteractEvent extends PlayerEvent implements Cancellable
public PlayerBlockInteractEvent(@NotNull Player player,
@NotNull BlockPosition blockPosition, @NotNull Player.Hand hand, @NotNull BlockFace blockFace) {
- super(player);
+ this.player = player;
this.blockPosition = blockPosition;
this.hand = hand;
this.blockFace = blockFace;
@@ -85,4 +86,9 @@ public class PlayerBlockInteractEvent extends PlayerEvent implements Cancellable
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerBlockPlaceEvent.java b/src/main/java/net/minestom/server/event/player/PlayerBlockPlaceEvent.java
index 2651b92d5..37bd54e95 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerBlockPlaceEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerBlockPlaceEvent.java
@@ -3,8 +3,8 @@ package net.minestom.server.event.player;
import net.minestom.server.MinecraftServer;
import net.minestom.server.data.Data;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockManager;
import net.minestom.server.instance.block.CustomBlock;
@@ -16,10 +16,11 @@ import org.jetbrains.annotations.Nullable;
/**
* Called when a player tries placing a block.
*/
-public class PlayerBlockPlaceEvent extends PlayerEvent implements CancellableEvent {
+public class PlayerBlockPlaceEvent implements PlayerEvent, CancellableEvent {
private static final BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager();
+ private final Player player;
private short blockStateId;
private short customBlockId;
private Data blockData;
@@ -32,7 +33,7 @@ public class PlayerBlockPlaceEvent extends PlayerEvent implements CancellableEve
public PlayerBlockPlaceEvent(@NotNull Player player, @NotNull Block block,
@NotNull BlockPosition blockPosition, @NotNull Player.Hand hand) {
- super(player);
+ this.player = player;
this.blockStateId = block.getBlockId();
this.blockPosition = blockPosition;
this.hand = hand;
@@ -176,4 +177,9 @@ public class PlayerBlockPlaceEvent extends PlayerEvent implements CancellableEve
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerChangeHeldSlotEvent.java b/src/main/java/net/minestom/server/event/player/PlayerChangeHeldSlotEvent.java
index d3c0a0c48..1f37650d3 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerChangeHeldSlotEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerChangeHeldSlotEvent.java
@@ -1,8 +1,8 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
@@ -10,14 +10,15 @@ import org.jetbrains.annotations.NotNull;
/**
* Called when a player change his held slot (by pressing 1-9 keys).
*/
-public class PlayerChangeHeldSlotEvent extends PlayerEvent implements CancellableEvent {
+public class PlayerChangeHeldSlotEvent implements PlayerEvent, CancellableEvent {
+ private final Player player;
private byte slot;
private boolean cancelled;
public PlayerChangeHeldSlotEvent(@NotNull Player player, byte slot) {
- super(player);
+ this.player = player;
this.slot = slot;
}
@@ -50,4 +51,9 @@ public class PlayerChangeHeldSlotEvent extends PlayerEvent implements Cancellabl
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerChatEvent.java b/src/main/java/net/minestom/server/event/player/PlayerChatEvent.java
index b840e81e2..2b0c196a5 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerChatEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerChatEvent.java
@@ -3,8 +3,8 @@ package net.minestom.server.event.player;
import net.kyori.adventure.text.Component;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -17,8 +17,9 @@ import java.util.function.Supplier;
* Called every time a {@link Player} write and send something in the chat.
* The event can be cancelled to do not send anything, and the format can be changed.
*/
-public class PlayerChatEvent extends PlayerEvent implements CancellableEvent {
+public class PlayerChatEvent implements PlayerEvent, CancellableEvent {
+ private final Player player;
private final Collection recipients;
private final Supplier defaultChatFormat;
private String message;
@@ -29,7 +30,7 @@ public class PlayerChatEvent extends PlayerEvent implements CancellableEvent {
public PlayerChatEvent(@NotNull Player player, @NotNull Collection recipients,
@NotNull Supplier defaultChatFormat,
@NotNull String message) {
- super(player);
+ this.player = player;
this.recipients = new ArrayList<>(recipients);
this.defaultChatFormat = defaultChatFormat;
this.message = message;
@@ -108,4 +109,9 @@ public class PlayerChatEvent extends PlayerEvent implements CancellableEvent {
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerChunkLoadEvent.java b/src/main/java/net/minestom/server/event/player/PlayerChunkLoadEvent.java
index b312ae85d..ff3c66851 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerChunkLoadEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerChunkLoadEvent.java
@@ -1,18 +1,20 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
/**
* Called when a player receive a new chunk data.
*/
-public class PlayerChunkLoadEvent extends PlayerEvent {
+public class PlayerChunkLoadEvent implements PlayerEvent {
+ private final Player player;
private final int chunkX, chunkZ;
public PlayerChunkLoadEvent(@NotNull Player player, int chunkX, int chunkZ) {
- super(player);
+ this.player = player;
this.chunkX = chunkX;
this.chunkZ = chunkZ;
}
@@ -34,4 +36,9 @@ public class PlayerChunkLoadEvent extends PlayerEvent {
public int getChunkZ() {
return chunkZ;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerChunkUnloadEvent.java b/src/main/java/net/minestom/server/event/player/PlayerChunkUnloadEvent.java
index e8ab23be5..5a11e9d95 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerChunkUnloadEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerChunkUnloadEvent.java
@@ -1,7 +1,8 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
/**
@@ -9,12 +10,13 @@ import org.jetbrains.annotations.NotNull;
*
* Could be used to unload the chunk internally in order to save memory.
*/
-public class PlayerChunkUnloadEvent extends PlayerEvent {
+public class PlayerChunkUnloadEvent implements PlayerEvent {
+ private final Player player;
private final int chunkX, chunkZ;
public PlayerChunkUnloadEvent(@NotNull Player player, int chunkX, int chunkZ) {
- super(player);
+ this.player = player;
this.chunkX = chunkX;
this.chunkZ = chunkZ;
}
@@ -36,4 +38,9 @@ public class PlayerChunkUnloadEvent extends PlayerEvent {
public int getChunkZ() {
return chunkZ;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerCommandEvent.java b/src/main/java/net/minestom/server/event/player/PlayerCommandEvent.java
index 6e977c067..648c68975 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerCommandEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerCommandEvent.java
@@ -1,21 +1,22 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
/**
* Called every time a player send a message starting by '/'.
*/
-public class PlayerCommandEvent extends PlayerEvent implements CancellableEvent {
+public class PlayerCommandEvent implements PlayerEvent, CancellableEvent {
+ private final Player player;
private String command;
private boolean cancelled;
public PlayerCommandEvent(@NotNull Player player, @NotNull String command) {
- super(player);
+ this.player = player;
this.command = command;
}
@@ -47,4 +48,9 @@ public class PlayerCommandEvent extends PlayerEvent implements CancellableEvent
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerDeathEvent.java b/src/main/java/net/minestom/server/event/player/PlayerDeathEvent.java
index 466c26d62..c1d06195f 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerDeathEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerDeathEvent.java
@@ -3,15 +3,17 @@ package net.minestom.server.event.player;
import net.kyori.adventure.text.Component;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Called when a player die in {@link Player#kill()}.
*/
-public class PlayerDeathEvent extends PlayerEvent {
+public class PlayerDeathEvent implements PlayerEvent {
+ private final Player player;
private Component deathText;
private Component chatMessage;
@@ -24,7 +26,7 @@ public class PlayerDeathEvent extends PlayerEvent {
}
public PlayerDeathEvent(@NotNull Player player, Component deathText, Component chatMessage) {
- super(player);
+ this.player = player;
this.deathText = deathText;
this.chatMessage = chatMessage;
}
@@ -112,4 +114,9 @@ public class PlayerDeathEvent extends PlayerEvent {
public void setChatMessage(@Nullable Component chatMessage) {
this.chatMessage = chatMessage;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerDisconnectEvent.java b/src/main/java/net/minestom/server/event/player/PlayerDisconnectEvent.java
index 93335cbb3..acfe4898d 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerDisconnectEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerDisconnectEvent.java
@@ -1,15 +1,23 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
/**
* Called when a player disconnect.
*/
-public class PlayerDisconnectEvent extends PlayerEvent {
+public class PlayerDisconnectEvent implements PlayerEvent {
+
+ private final Player player;
public PlayerDisconnectEvent(@NotNull Player player) {
- super(player);
+ this.player = player;
+ }
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
}
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerEatEvent.java b/src/main/java/net/minestom/server/event/player/PlayerEatEvent.java
index 41009774a..9983a4159 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerEatEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerEatEvent.java
@@ -1,20 +1,22 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.item.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* Called when a player is finished eating.
*/
-public class PlayerEatEvent extends PlayerEvent {
+public class PlayerEatEvent implements PlayerEvent {
+ private final Player player;
private final ItemStack foodItem;
private final Player.Hand hand;
public PlayerEatEvent(@NotNull Player player, @NotNull ItemStack foodItem, @NotNull Player.Hand hand) {
- super(player);
+ this.player = player;
this.foodItem = foodItem;
this.hand = hand;
}
@@ -31,4 +33,9 @@ public class PlayerEatEvent extends PlayerEvent {
public @NotNull Player.Hand getHand() {
return hand;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerEntityInteractEvent.java b/src/main/java/net/minestom/server/event/player/PlayerEntityInteractEvent.java
index d5c8da5e9..a3f4f3c44 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerEntityInteractEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerEntityInteractEvent.java
@@ -2,19 +2,21 @@ package net.minestom.server.event.player;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
/**
* Called when a {@link Player} interacts (right-click) with an {@link Entity}.
*/
-public class PlayerEntityInteractEvent extends PlayerEvent {
+public class PlayerEntityInteractEvent implements PlayerEvent {
+ private final Player player;
private final Entity entityTarget;
private final Player.Hand hand;
public PlayerEntityInteractEvent(@NotNull Player player, @NotNull Entity entityTarget, @NotNull Player.Hand hand) {
- super(player);
+ this.player = player;
this.entityTarget = entityTarget;
this.hand = hand;
}
@@ -38,4 +40,9 @@ public class PlayerEntityInteractEvent extends PlayerEvent {
public Player.Hand getHand() {
return hand;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/net/minestom/server/event/player/PlayerHandAnimationEvent.java b/src/main/java/net/minestom/server/event/player/PlayerHandAnimationEvent.java
index 7d9ba9d21..598e00d77 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerHandAnimationEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerHandAnimationEvent.java
@@ -1,21 +1,22 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
/**
* Called when the player swings his hand.
*/
-public class PlayerHandAnimationEvent extends PlayerEvent implements CancellableEvent {
+public class PlayerHandAnimationEvent implements PlayerEvent, CancellableEvent {
+ private final Player player;
private final Player.Hand hand;
private boolean cancelled;
public PlayerHandAnimationEvent(@NotNull Player player, @NotNull Player.Hand hand) {
- super(player);
+ this.player = player;
this.hand = hand;
}
@@ -38,4 +39,9 @@ public class PlayerHandAnimationEvent extends PlayerEvent implements Cancellable
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerItemAnimationEvent.java b/src/main/java/net/minestom/server/event/player/PlayerItemAnimationEvent.java
index 335108736..0c0b7661c 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerItemAnimationEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerItemAnimationEvent.java
@@ -1,8 +1,8 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
/**
@@ -10,14 +10,15 @@ import org.jetbrains.annotations.NotNull;
*
* @see ItemAnimationType
*/
-public class PlayerItemAnimationEvent extends PlayerEvent implements CancellableEvent {
+public class PlayerItemAnimationEvent implements PlayerEvent, CancellableEvent {
+ private final Player player;
private final ItemAnimationType armAnimationType;
private boolean cancelled;
public PlayerItemAnimationEvent(@NotNull Player player, @NotNull ItemAnimationType armAnimationType) {
- super(player);
+ this.player = player;
this.armAnimationType = armAnimationType;
}
@@ -31,6 +32,11 @@ public class PlayerItemAnimationEvent extends PlayerEvent implements Cancellable
return armAnimationType;
}
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
+
public enum ItemAnimationType {
BOW,
CROSSBOW,
diff --git a/src/main/java/net/minestom/server/event/player/PlayerLoginEvent.java b/src/main/java/net/minestom/server/event/player/PlayerLoginEvent.java
index 817e8a94c..7de2e246d 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerLoginEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerLoginEvent.java
@@ -1,7 +1,8 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.instance.Instance;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -16,12 +17,13 @@ import org.jetbrains.annotations.Nullable;
*
* WARNING: defining the spawning instance is MANDATORY.
*/
-public class PlayerLoginEvent extends PlayerEvent {
+public class PlayerLoginEvent implements PlayerEvent {
+ private final Player player;
private Instance spawningInstance;
public PlayerLoginEvent(@NotNull Player player) {
- super(player);
+ this.player = player;
}
/**
@@ -44,4 +46,9 @@ public class PlayerLoginEvent extends PlayerEvent {
public void setSpawningInstance(@NotNull Instance instance) {
this.spawningInstance = instance;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerMoveEvent.java b/src/main/java/net/minestom/server/event/player/PlayerMoveEvent.java
index 2190a7dbe..2d7bf046d 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerMoveEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerMoveEvent.java
@@ -1,22 +1,23 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
/**
* Called when a player is modifying his position.
*/
-public class PlayerMoveEvent extends PlayerEvent implements CancellableEvent {
+public class PlayerMoveEvent implements PlayerEvent, CancellableEvent {
+ private final Player player;
private Position newPosition;
private boolean cancelled;
public PlayerMoveEvent(@NotNull Player player, @NotNull Position newPosition) {
- super(player);
+ this.player = player;
this.newPosition = newPosition;
}
@@ -48,4 +49,9 @@ public class PlayerMoveEvent extends PlayerEvent implements CancellableEvent {
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerPacketEvent.java b/src/main/java/net/minestom/server/event/player/PlayerPacketEvent.java
new file mode 100644
index 000000000..e2ff8fe2a
--- /dev/null
+++ b/src/main/java/net/minestom/server/event/player/PlayerPacketEvent.java
@@ -0,0 +1,38 @@
+package net.minestom.server.event.player;
+
+import net.minestom.server.entity.Player;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.PlayerEvent;
+import net.minestom.server.network.packet.client.ClientPacket;
+import org.jetbrains.annotations.NotNull;
+
+public class PlayerPacketEvent implements PlayerEvent, CancellableEvent {
+
+ private final Player player;
+ private final ClientPacket packet;
+ private boolean cancelled;
+
+ public PlayerPacketEvent(Player player, ClientPacket packet) {
+ this.player = player;
+ this.packet = packet;
+ }
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
+
+ public @NotNull ClientPacket getPacket() {
+ return packet;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+ @Override
+ public void setCancelled(boolean cancel) {
+ this.cancelled = cancel;
+ }
+}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerPluginMessageEvent.java b/src/main/java/net/minestom/server/event/player/PlayerPluginMessageEvent.java
index 6f14dd180..297829653 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerPluginMessageEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerPluginMessageEvent.java
@@ -1,19 +1,21 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
/**
* Called when a player send {@link net.minestom.server.network.packet.client.play.ClientPluginMessagePacket}.
*/
-public class PlayerPluginMessageEvent extends PlayerEvent {
+public class PlayerPluginMessageEvent implements PlayerEvent {
+ private final Player player;
private final String identifier;
private final byte[] message;
public PlayerPluginMessageEvent(@NotNull Player player, @NotNull String identifier, @NotNull byte[] message) {
- super(player);
+ this.player = player;
this.identifier = identifier;
this.message = message;
}
@@ -47,4 +49,9 @@ public class PlayerPluginMessageEvent extends PlayerEvent {
public String getMessageString() {
return new String(message);
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerPreEatEvent.java b/src/main/java/net/minestom/server/event/player/PlayerPreEatEvent.java
index f2d909c1e..ee6638de5 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerPreEatEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerPreEatEvent.java
@@ -1,8 +1,8 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.item.ItemStack;
import org.jetbrains.annotations.NotNull;
@@ -11,8 +11,9 @@ import org.jetbrains.annotations.NotNull;
* or to cancel its processing, cancelling the event means that the player will
* continue the animation indefinitely.
*/
-public class PlayerPreEatEvent extends PlayerEvent implements CancellableEvent {
+public class PlayerPreEatEvent implements PlayerEvent, CancellableEvent {
+ private final Player player;
private final ItemStack foodItem;
private final Player.Hand hand;
private long eatingTime;
@@ -20,7 +21,7 @@ public class PlayerPreEatEvent extends PlayerEvent implements CancellableEvent {
private boolean cancelled;
public PlayerPreEatEvent(@NotNull Player player, @NotNull ItemStack foodItem, @NotNull Player.Hand hand, long eatingTime) {
- super(player);
+ this.player = player;
this.foodItem = foodItem;
this.hand = hand;
this.eatingTime = eatingTime;
@@ -68,4 +69,9 @@ public class PlayerPreEatEvent extends PlayerEvent implements CancellableEvent {
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerResourcePackStatusEvent.java b/src/main/java/net/minestom/server/event/player/PlayerResourcePackStatusEvent.java
index 1d367e846..f9d00430e 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerResourcePackStatusEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerResourcePackStatusEvent.java
@@ -1,19 +1,21 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.resourcepack.ResourcePackStatus;
import org.jetbrains.annotations.NotNull;
/**
* Called when a player warns the server of a resource pack status.
*/
-public class PlayerResourcePackStatusEvent extends PlayerEvent {
+public class PlayerResourcePackStatusEvent implements PlayerEvent {
+ private final Player player;
private final ResourcePackStatus status;
public PlayerResourcePackStatusEvent(@NotNull Player player, @NotNull ResourcePackStatus status) {
- super(player);
+ this.player = player;
this.status = status;
}
@@ -26,4 +28,9 @@ public class PlayerResourcePackStatusEvent extends PlayerEvent {
public ResourcePackStatus getStatus() {
return status;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerRespawnEvent.java b/src/main/java/net/minestom/server/event/player/PlayerRespawnEvent.java
index 598a9d729..a064e0efb 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerRespawnEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerRespawnEvent.java
@@ -1,7 +1,8 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
@@ -9,12 +10,13 @@ import org.jetbrains.annotations.NotNull;
* Called when {@link Player#respawn()} is executed (for custom respawn or as a result of
* {@link net.minestom.server.network.packet.client.play.ClientStatusPacket}
*/
-public class PlayerRespawnEvent extends PlayerEvent {
+public class PlayerRespawnEvent implements PlayerEvent {
+ private final Player player;
private Position respawnPosition;
public PlayerRespawnEvent(@NotNull Player player) {
- super(player);
+ this.player = player;
this.respawnPosition = player.getRespawnPoint();
}
@@ -38,4 +40,9 @@ public class PlayerRespawnEvent extends PlayerEvent {
public void setRespawnPosition(@NotNull Position respawnPosition) {
this.respawnPosition = respawnPosition;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerSettingsChangeEvent.java b/src/main/java/net/minestom/server/event/player/PlayerSettingsChangeEvent.java
index d876c4d4d..18cb592ac 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerSettingsChangeEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerSettingsChangeEvent.java
@@ -1,16 +1,19 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
/**
* Called after the player signals the server that his settings has been modified.
*/
-public class PlayerSettingsChangeEvent extends PlayerEvent {
+public class PlayerSettingsChangeEvent implements PlayerEvent {
+
+ private final Player player;
public PlayerSettingsChangeEvent(@NotNull Player player) {
- super(player);
+ this.player = player;
}
/**
diff --git a/src/main/java/net/minestom/server/event/player/PlayerSkinInitEvent.java b/src/main/java/net/minestom/server/event/player/PlayerSkinInitEvent.java
index d8cb40644..0104d3dac 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerSkinInitEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerSkinInitEvent.java
@@ -2,19 +2,21 @@ package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.PlayerSkin;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Called at the player connection to initialize his skin.
*/
-public class PlayerSkinInitEvent extends PlayerEvent {
+public class PlayerSkinInitEvent implements PlayerEvent {
+ private final Player player;
private PlayerSkin skin;
public PlayerSkinInitEvent(@NotNull Player player, @Nullable PlayerSkin currentSkin) {
- super(player);
+ this.player = player;
this.skin = currentSkin;
}
@@ -36,4 +38,9 @@ public class PlayerSkinInitEvent extends PlayerEvent {
public void setSkin(@Nullable PlayerSkin skin) {
this.skin = skin;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerSpawnEvent.java b/src/main/java/net/minestom/server/event/player/PlayerSpawnEvent.java
index 6c4f393a2..e975dc55a 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerSpawnEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerSpawnEvent.java
@@ -1,20 +1,22 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.instance.Instance;
import org.jetbrains.annotations.NotNull;
/**
* Called when a new instance is set for a player.
*/
-public class PlayerSpawnEvent extends PlayerEvent {
+public class PlayerSpawnEvent implements PlayerEvent {
+ private final Player player;
private final Instance spawnInstance;
private final boolean firstSpawn;
public PlayerSpawnEvent(@NotNull Player player, @NotNull Instance spawnInstance, boolean firstSpawn) {
- super(player);
+ this.player = player;
this.spawnInstance = spawnInstance;
this.firstSpawn = firstSpawn;
}
@@ -37,4 +39,9 @@ public class PlayerSpawnEvent extends PlayerEvent {
public boolean isFirstSpawn() {
return firstSpawn;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerStartDiggingEvent.java b/src/main/java/net/minestom/server/event/player/PlayerStartDiggingEvent.java
index a8b00c515..10d0a6dc6 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerStartDiggingEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerStartDiggingEvent.java
@@ -1,8 +1,8 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.utils.BlockPosition;
import org.jetbrains.annotations.NotNull;
@@ -14,8 +14,9 @@ import org.jetbrains.annotations.NotNull;
* (could be because of high latency or a modified client) so cancelling {@link PlayerBlockBreakEvent} is also necessary.
* Could be fixed in future Minestom version.
*/
-public class PlayerStartDiggingEvent extends PlayerEvent implements CancellableEvent {
+public class PlayerStartDiggingEvent implements PlayerEvent, CancellableEvent {
+ private final Player player;
private final BlockPosition blockPosition;
private final int blockStateId;
private final int customBlockId;
@@ -23,7 +24,7 @@ public class PlayerStartDiggingEvent extends PlayerEvent implements CancellableE
private boolean cancelled;
public PlayerStartDiggingEvent(@NotNull Player player, @NotNull BlockPosition blockPosition, int blockStateId, int customBlockId) {
- super(player);
+ this.player = player;
this.blockPosition = blockPosition;
this.blockStateId = blockStateId;
this.customBlockId = customBlockId;
@@ -66,4 +67,9 @@ public class PlayerStartDiggingEvent extends PlayerEvent implements CancellableE
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerStartFlyingEvent.java b/src/main/java/net/minestom/server/event/player/PlayerStartFlyingEvent.java
index aefdf9ee0..5ab26e589 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerStartFlyingEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerStartFlyingEvent.java
@@ -1,15 +1,23 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
/**
* Called when a player start flying.
*/
-public class PlayerStartFlyingEvent extends PlayerEvent {
+public class PlayerStartFlyingEvent implements PlayerEvent {
+
+ private final Player player;
public PlayerStartFlyingEvent(@NotNull Player player) {
- super(player);
+ this.player = player;
+ }
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
}
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerStartFlyingWithElytraEvent.java b/src/main/java/net/minestom/server/event/player/PlayerStartFlyingWithElytraEvent.java
index 28ca41575..9b29bd1c2 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerStartFlyingWithElytraEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerStartFlyingWithElytraEvent.java
@@ -1,12 +1,20 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
-public class PlayerStartFlyingWithElytraEvent extends PlayerEvent {
+public class PlayerStartFlyingWithElytraEvent implements PlayerEvent {
+
+ private final Player player;
public PlayerStartFlyingWithElytraEvent(@NotNull Player player) {
- super(player);
+ this.player = player;
+ }
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
}
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerStartSneakingEvent.java b/src/main/java/net/minestom/server/event/player/PlayerStartSneakingEvent.java
index 198ca1093..2e2c334ec 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerStartSneakingEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerStartSneakingEvent.java
@@ -1,15 +1,23 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
/**
* Called when a player starts sneaking.
*/
-public class PlayerStartSneakingEvent extends PlayerEvent {
+public class PlayerStartSneakingEvent implements PlayerEvent {
+
+ private final Player player;
public PlayerStartSneakingEvent(@NotNull Player player) {
- super(player);
+ this.player = player;
+ }
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
}
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerStartSprintingEvent.java b/src/main/java/net/minestom/server/event/player/PlayerStartSprintingEvent.java
index e517a80e3..0f5e27ccd 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerStartSprintingEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerStartSprintingEvent.java
@@ -1,15 +1,23 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
/**
* Called when a player starts sprinting.
*/
-public class PlayerStartSprintingEvent extends PlayerEvent {
+public class PlayerStartSprintingEvent implements PlayerEvent {
+
+ private final Player player;
public PlayerStartSprintingEvent(@NotNull Player player) {
- super(player);
+ this.player = player;
+ }
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
}
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerStopFlyingEvent.java b/src/main/java/net/minestom/server/event/player/PlayerStopFlyingEvent.java
index 027de80c9..c2b8f449d 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerStopFlyingEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerStopFlyingEvent.java
@@ -1,15 +1,23 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
/**
* Called when a player stop flying.
*/
-public class PlayerStopFlyingEvent extends PlayerEvent {
+public class PlayerStopFlyingEvent implements PlayerEvent {
+
+ private final Player player;
public PlayerStopFlyingEvent(@NotNull Player player) {
- super(player);
+ this.player = player;
+ }
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
}
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerStopFlyingWithElytraEvent.java b/src/main/java/net/minestom/server/event/player/PlayerStopFlyingWithElytraEvent.java
index 314f16e22..d0715943a 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerStopFlyingWithElytraEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerStopFlyingWithElytraEvent.java
@@ -1,12 +1,20 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
-public class PlayerStopFlyingWithElytraEvent extends PlayerEvent {
+public class PlayerStopFlyingWithElytraEvent implements PlayerEvent {
+
+ private final Player player;
public PlayerStopFlyingWithElytraEvent(@NotNull Player player) {
- super(player);
+ this.player = player;
+ }
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
}
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerStopSneakingEvent.java b/src/main/java/net/minestom/server/event/player/PlayerStopSneakingEvent.java
index 9601bd7e6..47c461ed3 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerStopSneakingEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerStopSneakingEvent.java
@@ -1,15 +1,23 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
/**
* Called when a player stops sneaking.
*/
-public class PlayerStopSneakingEvent extends PlayerEvent {
+public class PlayerStopSneakingEvent implements PlayerEvent {
+
+ private final Player player;
public PlayerStopSneakingEvent(@NotNull Player player) {
- super(player);
+ this.player = player;
+ }
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
}
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerStopSprintingEvent.java b/src/main/java/net/minestom/server/event/player/PlayerStopSprintingEvent.java
index cd15590e8..6e1e05b26 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerStopSprintingEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerStopSprintingEvent.java
@@ -1,15 +1,23 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
/**
* Called when a player stops sprinting.
*/
-public class PlayerStopSprintingEvent extends PlayerEvent {
+public class PlayerStopSprintingEvent implements PlayerEvent {
+
+ private final Player player;
public PlayerStopSprintingEvent(@NotNull Player player) {
- super(player);
+ this.player = player;
+ }
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
}
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerSwapItemEvent.java b/src/main/java/net/minestom/server/event/player/PlayerSwapItemEvent.java
index 2aff53cb0..e7cfef32d 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerSwapItemEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerSwapItemEvent.java
@@ -1,23 +1,24 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.item.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* Called when a player is trying to swap his main and off hand item.
*/
-public class PlayerSwapItemEvent extends PlayerEvent implements CancellableEvent {
+public class PlayerSwapItemEvent implements PlayerEvent, CancellableEvent {
+ private final Player player;
private ItemStack mainHandItem;
private ItemStack offHandItem;
private boolean cancelled;
public PlayerSwapItemEvent(@NotNull Player player, @NotNull ItemStack mainHandItem, @NotNull ItemStack offHandItem) {
- super(player);
+ this.player = player;
this.mainHandItem = mainHandItem;
this.offHandItem = offHandItem;
}
@@ -69,4 +70,9 @@ public class PlayerSwapItemEvent extends PlayerEvent implements CancellableEvent
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerTickEvent.java b/src/main/java/net/minestom/server/event/player/PlayerTickEvent.java
index 1872fa2da..57472ba7a 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerTickEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerTickEvent.java
@@ -1,15 +1,22 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;
/**
* Called at each player tick.
*/
-public class PlayerTickEvent extends PlayerEvent {
+public class PlayerTickEvent implements PlayerEvent {
+
+ private final Player player;
public PlayerTickEvent(@NotNull Player player) {
- super(player);
+ this.player = player;
+ }
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
}
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerUseItemEvent.java b/src/main/java/net/minestom/server/event/player/PlayerUseItemEvent.java
index d32567e45..2e1db2ce1 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerUseItemEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerUseItemEvent.java
@@ -1,23 +1,25 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.trait.CancellableEvent;
+import net.minestom.server.event.trait.ItemEvent;
+import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.item.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* Event when an item is used without clicking on a block.
*/
-public class PlayerUseItemEvent extends PlayerEvent implements CancellableEvent {
+public class PlayerUseItemEvent implements PlayerEvent, ItemEvent, CancellableEvent {
+ private final Player player;
private final Player.Hand hand;
private final ItemStack itemStack;
private boolean cancelled;
public PlayerUseItemEvent(@NotNull Player player, @NotNull Player.Hand hand, @NotNull ItemStack itemStack) {
- super(player);
+ this.player = player;
this.hand = hand;
this.itemStack = itemStack;
}
@@ -51,4 +53,9 @@ public class PlayerUseItemEvent extends PlayerEvent implements CancellableEvent
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/PlayerUseItemOnBlockEvent.java b/src/main/java/net/minestom/server/event/player/PlayerUseItemOnBlockEvent.java
index 88dbcfb32..7a6f243f2 100644
--- a/src/main/java/net/minestom/server/event/player/PlayerUseItemOnBlockEvent.java
+++ b/src/main/java/net/minestom/server/event/player/PlayerUseItemOnBlockEvent.java
@@ -1,7 +1,8 @@
package net.minestom.server.event.player;
import net.minestom.server.entity.Player;
-import net.minestom.server.event.PlayerEvent;
+import net.minestom.server.event.trait.ItemEvent;
+import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.item.ItemStack;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.Direction;
@@ -10,8 +11,9 @@ import org.jetbrains.annotations.NotNull;
/**
* Used when a player is clicking on a block with an item (but is not a block in item form).
*/
-public class PlayerUseItemOnBlockEvent extends PlayerEvent {
+public class PlayerUseItemOnBlockEvent implements PlayerEvent, ItemEvent {
+ private final Player player;
private final Player.Hand hand;
private final ItemStack itemStack;
private final BlockPosition position;
@@ -20,7 +22,7 @@ public class PlayerUseItemOnBlockEvent extends PlayerEvent {
public PlayerUseItemOnBlockEvent(@NotNull Player player, @NotNull Player.Hand hand,
@NotNull ItemStack itemStack,
@NotNull BlockPosition position, @NotNull Direction blockFace) {
- super(player);
+ this.player = player;
this.hand = hand;
this.itemStack = itemStack;
this.position = position;
@@ -66,4 +68,9 @@ public class PlayerUseItemOnBlockEvent extends PlayerEvent {
public ItemStack getItemStack() {
return itemStack;
}
+
+ @Override
+ public @NotNull Player getPlayer() {
+ return player;
+ }
}
diff --git a/src/main/java/net/minestom/server/event/player/UpdateTagListEvent.java b/src/main/java/net/minestom/server/event/player/UpdateTagListEvent.java
index ab8ee0233..540985584 100644
--- a/src/main/java/net/minestom/server/event/player/UpdateTagListEvent.java
+++ b/src/main/java/net/minestom/server/event/player/UpdateTagListEvent.java
@@ -5,7 +5,7 @@ import net.minestom.server.network.packet.server.play.TagsPacket;
import org.jetbrains.annotations.NotNull;
@Deprecated
-public class UpdateTagListEvent extends Event {
+public class UpdateTagListEvent implements Event {
private TagsPacket packet;
diff --git a/src/main/java/net/minestom/server/event/server/ClientPingServerEvent.java b/src/main/java/net/minestom/server/event/server/ClientPingServerEvent.java
index 8571001c5..f1cddd191 100644
--- a/src/main/java/net/minestom/server/event/server/ClientPingServerEvent.java
+++ b/src/main/java/net/minestom/server/event/server/ClientPingServerEvent.java
@@ -1,7 +1,6 @@
package net.minestom.server.event.server;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.CancellableEvent;
import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.utils.time.TimeUnit;
import net.minestom.server.utils.time.UpdateOption;
@@ -14,7 +13,7 @@ import org.jetbrains.annotations.NotNull;
*
* @see ServerListPingEvent
*/
-public class ClientPingServerEvent extends Event implements CancellableEvent {
+public class ClientPingServerEvent implements CancellableEvent {
private static final UpdateOption DEFAULT_DELAY = new UpdateOption(0, TimeUnit.MILLISECOND);
private final PlayerConnection connection;
@@ -27,7 +26,7 @@ public class ClientPingServerEvent extends Event implements CancellableEvent {
* Creates a new client ping server event with 0 delay
*
* @param connection the player connection
- * @param payload the payload the client sent
+ * @param payload the payload the client sent
*/
public ClientPingServerEvent(@NotNull PlayerConnection connection, long payload) {
this.connection = connection;
@@ -39,7 +38,7 @@ public class ClientPingServerEvent extends Event implements CancellableEvent {
* Creates a new client ping server event with 0 delay
*
* @param connection the player connection
- * @param payload the payload the client sent
+ * @param payload the payload the client sent
*/
public ClientPingServerEvent(@NotNull PlayerConnection connection, long payload, UpdateOption delay) {
this.connection = connection;
@@ -69,8 +68,9 @@ public class ClientPingServerEvent extends Event implements CancellableEvent {
/**
* Sets the payload to respond with.
- *
+ *
* Note: This should be the same as the client sent, however vanilla 1.17 seems to be OK with a different payload.
+ *
* @param payload the payload
*/
public void setPayload(long payload) {
diff --git a/src/main/java/net/minestom/server/event/server/ServerListPingEvent.java b/src/main/java/net/minestom/server/event/server/ServerListPingEvent.java
index bc5f81f54..633a0ea14 100644
--- a/src/main/java/net/minestom/server/event/server/ServerListPingEvent.java
+++ b/src/main/java/net/minestom/server/event/server/ServerListPingEvent.java
@@ -1,8 +1,7 @@
package net.minestom.server.event.server;
import net.minestom.server.MinecraftServer;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.CancellableEvent;
import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.ping.ResponseData;
import net.minestom.server.ping.ResponseDataConsumer;
@@ -16,7 +15,7 @@ import java.util.Objects;
* Called when a {@link PlayerConnection} sends a status packet,
* usually to display information on the server list.
*/
-public class ServerListPingEvent extends Event implements CancellableEvent {
+public class ServerListPingEvent implements CancellableEvent {
private final PlayerConnection connection;
private final ServerListPingType type;
@@ -36,7 +35,7 @@ public class ServerListPingEvent extends Event implements CancellableEvent {
* Creates a new server list ping event.
*
* @param connection the player connection, if the ping type is modern
- * @param type the ping type to respond with
+ * @param type the ping type to respond with
*/
public ServerListPingEvent(@Nullable PlayerConnection connection, @NotNull ServerListPingType type) {
//noinspection deprecation we need to continue doing this until the consumer is removed - todo remove
@@ -86,7 +85,7 @@ public class ServerListPingEvent extends Event implements CancellableEvent {
* @return the ping type
*/
public @NotNull ServerListPingType getPingType() {
- return type;
+ return type;
}
@Override
diff --git a/src/main/java/net/minestom/server/event/CancellableEvent.java b/src/main/java/net/minestom/server/event/trait/CancellableEvent.java
similarity index 61%
rename from src/main/java/net/minestom/server/event/CancellableEvent.java
rename to src/main/java/net/minestom/server/event/trait/CancellableEvent.java
index e04d9ea5b..e75efce9c 100644
--- a/src/main/java/net/minestom/server/event/CancellableEvent.java
+++ b/src/main/java/net/minestom/server/event/trait/CancellableEvent.java
@@ -1,9 +1,13 @@
-package net.minestom.server.event;
+package net.minestom.server.event.trait;
+
+import net.minestom.server.event.Event;
+import net.minestom.server.event.EventDispatcher;
/**
* Represents an {@link Event} which can be cancelled.
+ * Called using {@link EventDispatcher#callCancellable(CancellableEvent, Runnable)}.
*/
-public interface CancellableEvent {
+public interface CancellableEvent extends Event {
/**
* Gets if the {@link Event} should be cancelled or not.
@@ -18,5 +22,4 @@ public interface CancellableEvent {
* @param cancel true if the event should be cancelled, false otherwise
*/
void setCancelled(boolean cancel);
-
}
diff --git a/src/main/java/net/minestom/server/event/trait/EntityEvent.java b/src/main/java/net/minestom/server/event/trait/EntityEvent.java
new file mode 100644
index 000000000..dd78a2027
--- /dev/null
+++ b/src/main/java/net/minestom/server/event/trait/EntityEvent.java
@@ -0,0 +1,18 @@
+package net.minestom.server.event.trait;
+
+import net.minestom.server.entity.Entity;
+import net.minestom.server.event.Event;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Represents any event called on an {@link Entity}.
+ */
+public interface EntityEvent extends Event {
+
+ /**
+ * Gets the entity of this event.
+ *
+ * @return the entity
+ */
+ @NotNull Entity getEntity();
+}
diff --git a/src/main/java/net/minestom/server/event/trait/InstanceEvent.java b/src/main/java/net/minestom/server/event/trait/InstanceEvent.java
new file mode 100644
index 000000000..7defc9b03
--- /dev/null
+++ b/src/main/java/net/minestom/server/event/trait/InstanceEvent.java
@@ -0,0 +1,18 @@
+package net.minestom.server.event.trait;
+
+import net.minestom.server.event.Event;
+import net.minestom.server.instance.Instance;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Represents any event targeting an {@link Instance}.
+ */
+public interface InstanceEvent extends Event {
+
+ /**
+ * Gets the instance.
+ *
+ * @return instance
+ */
+ @NotNull Instance getInstance();
+}
diff --git a/src/main/java/net/minestom/server/event/trait/InventoryEvent.java b/src/main/java/net/minestom/server/event/trait/InventoryEvent.java
new file mode 100644
index 000000000..726741531
--- /dev/null
+++ b/src/main/java/net/minestom/server/event/trait/InventoryEvent.java
@@ -0,0 +1,18 @@
+package net.minestom.server.event.trait;
+
+import net.minestom.server.event.Event;
+import net.minestom.server.inventory.Inventory;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Represents any event inside an {@link Inventory}.
+ */
+public interface InventoryEvent extends Event {
+
+ /**
+ * Gets the inventory.
+ *
+ * @return the inventory, null if this is a player's inventory
+ */
+ @Nullable Inventory getInventory();
+}
diff --git a/src/main/java/net/minestom/server/event/trait/ItemEvent.java b/src/main/java/net/minestom/server/event/trait/ItemEvent.java
new file mode 100644
index 000000000..fc30a769d
--- /dev/null
+++ b/src/main/java/net/minestom/server/event/trait/ItemEvent.java
@@ -0,0 +1,12 @@
+package net.minestom.server.event.trait;
+
+import net.minestom.server.event.Event;
+import net.minestom.server.item.ItemStack;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Represents any event called about an {@link ItemStack}.
+ */
+public interface ItemEvent extends Event {
+ @NotNull ItemStack getItemStack();
+}
diff --git a/src/main/java/net/minestom/server/event/trait/PlayerEvent.java b/src/main/java/net/minestom/server/event/trait/PlayerEvent.java
new file mode 100644
index 000000000..8ca030995
--- /dev/null
+++ b/src/main/java/net/minestom/server/event/trait/PlayerEvent.java
@@ -0,0 +1,25 @@
+package net.minestom.server.event.trait;
+
+import net.minestom.server.entity.Player;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Represents any event called on a {@link Player}.
+ */
+public interface PlayerEvent extends EntityEvent {
+
+ /**
+ * Gets the player.
+ *
+ * @return the player
+ */
+ @NotNull Player getPlayer();
+
+ /**
+ * Returns {@link #getPlayer()}.
+ */
+ @Override
+ default @NotNull Player getEntity() {
+ return getPlayer();
+ }
+}
diff --git a/src/main/java/net/minestom/server/extensions/Extension.java b/src/main/java/net/minestom/server/extensions/Extension.java
index 1272751cc..f3cbac22e 100644
--- a/src/main/java/net/minestom/server/extensions/Extension.java
+++ b/src/main/java/net/minestom/server/extensions/Extension.java
@@ -1,5 +1,7 @@
package net.minestom.server.extensions;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.EventNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
@@ -14,7 +16,9 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
-import java.util.*;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
@@ -25,6 +29,9 @@ public abstract class Extension {
// Set by reflection
@SuppressWarnings("unused")
private Logger logger;
+ // Set by reflection
+ @SuppressWarnings("unused")
+ private EventNode eventNode;
/**
* Observers that will be notified of events related to this extension.
@@ -78,6 +85,7 @@ public abstract class Extension {
/**
* Gets the logger for the extension
+ *
* @return The logger for the extension
*/
@NotNull
@@ -85,6 +93,10 @@ public abstract class Extension {
return logger;
}
+ public @NotNull EventNode getEventNode() {
+ return eventNode;
+ }
+
public @NotNull Path getDataDirectory() {
return getOrigin().getDataDirectory();
}
@@ -209,6 +221,7 @@ public abstract class Extension {
/**
* Calls some action on all valid observers of this extension
+ *
* @param action code to execute on each observer
*/
public void triggerChange(Consumer action) {
@@ -234,7 +247,7 @@ public abstract class Extension {
*/
public void cleanupObservers() {
Reference extends IExtensionObserver> ref;
- while((ref = observerReferenceQueue.poll()) != null) {
+ while ((ref = observerReferenceQueue.poll()) != null) {
observers.remove(ref);
}
}
diff --git a/src/main/java/net/minestom/server/extensions/ExtensionManager.java b/src/main/java/net/minestom/server/extensions/ExtensionManager.java
index 95ca6452e..53ca4e7f7 100644
--- a/src/main/java/net/minestom/server/extensions/ExtensionManager.java
+++ b/src/main/java/net/minestom/server/extensions/ExtensionManager.java
@@ -5,6 +5,8 @@ import net.minestom.dependencies.DependencyGetter;
import net.minestom.dependencies.ResolvedDependency;
import net.minestom.dependencies.maven.MavenRepository;
import net.minestom.server.MinecraftServer;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.EventNode;
import net.minestom.server.extras.selfmodification.MinestomExtensionClassLoader;
import net.minestom.server.extras.selfmodification.MinestomRootClassLoader;
import net.minestom.server.ping.ResponseDataConsumer;
@@ -25,7 +27,6 @@ import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipFile;
@@ -280,6 +281,22 @@ public class ExtensionManager {
LOGGER.error("Main class '{}' in '{}' has no logger field.", mainClass, extensionName, e);
}
+ // Set event node
+ try {
+ EventNode eventNode = EventNode.all(extensionName); // Use the extension name
+ Field loggerField = Extension.class.getDeclaredField("eventNode");
+ loggerField.setAccessible(true);
+ loggerField.set(extension, eventNode);
+
+ MinecraftServer.getGlobalEventHandler().addChild(eventNode);
+ } catch (IllegalAccessException e) {
+ // We made it accessible, should not occur
+ MinecraftServer.getExceptionManager().handleException(e);
+ } catch (NoSuchFieldException e) {
+ // This should also not occur
+ LOGGER.error("Main class '{}' in '{}' has no event node field.", mainClass, extensionName, e);
+ }
+
// add dependents to pre-existing extensions, so that they can easily be found during reloading
for (String dependencyName : discoveredExtension.getDependencies()) {
Extension dependency = extensions.get(dependencyName.toLowerCase());
@@ -660,6 +677,10 @@ public class ExtensionManager {
ext.triggerChange(observer -> observer.onExtensionUnload(extensionName));
// TODO: more callback types
+ // Remove event node
+ EventNode eventNode = ext.getEventNode();
+ MinecraftServer.getGlobalEventHandler().removeChild(eventNode);
+
ext.postTerminate();
ext.unload();
diff --git a/src/main/java/net/minestom/server/extras/lan/OpenToLAN.java b/src/main/java/net/minestom/server/extras/lan/OpenToLAN.java
index 247852250..85a713ea8 100644
--- a/src/main/java/net/minestom/server/extras/lan/OpenToLAN.java
+++ b/src/main/java/net/minestom/server/extras/lan/OpenToLAN.java
@@ -1,6 +1,7 @@
package net.minestom.server.extras.lan;
import net.minestom.server.MinecraftServer;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.server.ServerListPingEvent;
import net.minestom.server.timer.Task;
import net.minestom.server.utils.NetworkUtils;
@@ -25,6 +26,7 @@ import static net.minestom.server.ping.ServerListPingType.OPEN_TO_LAN;
* Instead it simply sends the packets needed to trick the Minecraft client into thinking
* that this is a single-player world that has been opened to LANfor it to be displayed on
* the bottom of the server list.
+ *
* @see wiki.vg
*/
public class OpenToLAN {
@@ -37,7 +39,8 @@ public class OpenToLAN {
private static volatile DatagramPacket packet = null;
private static volatile Task task = null;
- private OpenToLAN() { }
+ private OpenToLAN() {
+ }
/**
* Opens the server to LAN with the default config.
@@ -121,7 +124,7 @@ public class OpenToLAN {
if (MinecraftServer.getNettyServer().getPort() != 0) {
if (packet == null || eventCooldown.isReady(System.currentTimeMillis())) {
final ServerListPingEvent event = new ServerListPingEvent(OPEN_TO_LAN);
- MinecraftServer.getGlobalEventHandler().callEvent(ServerListPingEvent.class, event);
+ EventDispatcher.call(event);
final byte[] data = OPEN_TO_LAN.getPingResponse(event.getResponseData()).getBytes(StandardCharsets.UTF_8);
packet = new DatagramPacket(data, data.length, PING_ADDRESS);
diff --git a/src/main/java/net/minestom/server/extras/query/Query.java b/src/main/java/net/minestom/server/extras/query/Query.java
index 5d301aca2..a99225607 100644
--- a/src/main/java/net/minestom/server/extras/query/Query.java
+++ b/src/main/java/net/minestom/server/extras/query/Query.java
@@ -6,6 +6,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.minestom.server.MinecraftServer;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.extras.query.event.BasicQueryEvent;
import net.minestom.server.extras.query.event.FullQueryEvent;
import net.minestom.server.timer.Task;
@@ -28,6 +29,7 @@ import java.util.Random;
/**
* Utility class to manage responses to the GameSpy4 Query Protocol.
+ *
* @see wiki.vg
*/
public class Query {
@@ -41,7 +43,8 @@ public class Query {
private static volatile Thread thread;
private static volatile Task task;
- private Query() { }
+ private Query() {
+ }
/**
* Starts the query system, responding to queries on a random port, logging if it could not be started.
@@ -190,12 +193,12 @@ public class Query {
if (remaining == 0) { // basic
BasicQueryEvent event = new BasicQueryEvent(sender, sessionID);
- MinecraftServer.getGlobalEventHandler().callCancellableEvent(BasicQueryEvent.class, event,
- () -> sendResponse(event.getQueryResponse(), sessionID, sender));
+ EventDispatcher.callCancellable(event, () ->
+ sendResponse(event.getQueryResponse(), sessionID, sender));
} else if (remaining == 5) { // full
FullQueryEvent event = new FullQueryEvent(sender, sessionID);
- MinecraftServer.getGlobalEventHandler().callCancellableEvent(FullQueryEvent.class, event,
- () -> sendResponse(event.getQueryResponse(), sessionID, sender));
+ EventDispatcher.callCancellable(event, () ->
+ sendResponse(event.getQueryResponse(), sessionID, sender));
}
}
}
diff --git a/src/main/java/net/minestom/server/extras/query/event/QueryEvent.java b/src/main/java/net/minestom/server/extras/query/event/QueryEvent.java
index d8365c1ba..6db13d118 100644
--- a/src/main/java/net/minestom/server/extras/query/event/QueryEvent.java
+++ b/src/main/java/net/minestom/server/extras/query/event/QueryEvent.java
@@ -1,7 +1,6 @@
package net.minestom.server.extras.query.event;
-import net.minestom.server.event.CancellableEvent;
-import net.minestom.server.event.Event;
+import net.minestom.server.event.trait.CancellableEvent;
import net.minestom.server.utils.binary.Writeable;
import org.jetbrains.annotations.NotNull;
@@ -13,7 +12,7 @@ import java.util.Objects;
*
* @param the type of the response
*/
-public abstract class QueryEvent extends Event implements CancellableEvent {
+public abstract class QueryEvent implements CancellableEvent {
private final SocketAddress sender;
private final int sessionID;
@@ -23,9 +22,9 @@ public abstract class QueryEvent extends Event implements C
/**
* Creates a new query event.
*
- * @param sender the sender
+ * @param sender the sender
* @param sessionID the session ID of the query sender
- * @param response the initial response
+ * @param response the initial response
*/
public QueryEvent(@NotNull SocketAddress sender, int sessionID, @NotNull T response) {
this.sender = sender;
diff --git a/src/main/java/net/minestom/server/instance/Chunk.java b/src/main/java/net/minestom/server/instance/Chunk.java
index 127842b3c..18bb9d98c 100644
--- a/src/main/java/net/minestom/server/instance/Chunk.java
+++ b/src/main/java/net/minestom/server/instance/Chunk.java
@@ -7,6 +7,7 @@ import net.minestom.server.data.Data;
import net.minestom.server.data.DataContainer;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.pathfinding.PFColumnarSpace;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.player.PlayerChunkLoadEvent;
import net.minestom.server.event.player.PlayerChunkUnloadEvent;
import net.minestom.server.instance.block.Block;
@@ -445,7 +446,7 @@ public abstract class Chunk implements Viewable, Tickable, DataContainer {
if (result) {
PlayerChunkLoadEvent playerChunkLoadEvent = new PlayerChunkLoadEvent(player, chunkX, chunkZ);
- player.callEvent(PlayerChunkLoadEvent.class, playerChunkLoadEvent);
+ EventDispatcher.call(playerChunkLoadEvent);
}
return result;
@@ -467,7 +468,7 @@ public abstract class Chunk implements Viewable, Tickable, DataContainer {
if (result) {
PlayerChunkUnloadEvent playerChunkUnloadEvent = new PlayerChunkUnloadEvent(player, chunkX, chunkZ);
- player.callEvent(PlayerChunkUnloadEvent.class, playerChunkUnloadEvent);
+ EventDispatcher.call(playerChunkUnloadEvent);
}
return result;
diff --git a/src/main/java/net/minestom/server/instance/Instance.java b/src/main/java/net/minestom/server/instance/Instance.java
index 5392143fa..3e7c81261 100644
--- a/src/main/java/net/minestom/server/instance/Instance.java
+++ b/src/main/java/net/minestom/server/instance/Instance.java
@@ -12,12 +12,15 @@ import net.minestom.server.entity.EntityCreature;
import net.minestom.server.entity.ExperienceOrb;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.pathfinding.PFInstanceSpace;
-import net.minestom.server.event.Event;
import net.minestom.server.event.EventCallback;
+import net.minestom.server.event.EventDispatcher;
+import net.minestom.server.event.EventFilter;
+import net.minestom.server.event.EventNode;
import net.minestom.server.event.handler.EventHandler;
import net.minestom.server.event.instance.AddEntityToInstanceEvent;
import net.minestom.server.event.instance.InstanceTickEvent;
import net.minestom.server.event.instance.RemoveEntityFromInstanceEvent;
+import net.minestom.server.event.trait.InstanceEvent;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockManager;
import net.minestom.server.instance.block.CustomBlock;
@@ -42,7 +45,6 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer;
/**
@@ -56,7 +58,7 @@ import java.util.function.Consumer;
* you need to be sure to signal the {@link UpdateManager} of the changes using
* {@link UpdateManager#signalChunkLoad(Chunk)} and {@link UpdateManager#signalChunkUnload(Chunk)}.
*/
-public abstract class Instance implements BlockModifier, Tickable, EventHandler, DataContainer, PacketGroupingAudience {
+public abstract class Instance implements BlockModifier, Tickable, EventHandler, DataContainer, PacketGroupingAudience {
protected static final BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager();
protected static final UpdateManager UPDATE_MANAGER = MinecraftServer.getUpdateManager();
@@ -79,8 +81,7 @@ public abstract class Instance implements BlockModifier, Tickable, EventHandler,
// Field for tick events
private long lastTickAge = System.currentTimeMillis();
- private final Map, Collection> eventCallbacks = new ConcurrentHashMap<>();
- private final Map>> extensionCallbacks = new ConcurrentHashMap<>();
+ private final EventNode eventNode;
// Entities present in this instance
protected final Set entities = ConcurrentHashMap.newKeySet();
@@ -119,6 +120,8 @@ public abstract class Instance implements BlockModifier, Tickable, EventHandler,
this.dimensionType = dimensionType;
this.worldBorder = new WorldBorder(this);
+
+ this.eventNode = EventNode.value("instance-" + uniqueId, EventFilter.INSTANCE, this::equals);
}
/**
@@ -833,16 +836,17 @@ public abstract class Instance implements BlockModifier, Tickable, EventHandler,
this.data = data;
}
- @NotNull
@Override
- public Map, Collection> getEventCallbacksMap() {
- return eventCallbacks;
+ public @NotNull EventNode getEventNode() {
+ return eventNode;
}
- @NotNull
@Override
- public Collection> getExtensionCallbacks(String extension) {
- return extensionCallbacks.computeIfAbsent(extension, e -> new CopyOnWriteArrayList<>());
+ public synchronized boolean addEventCallback(@NotNull Class eventClass, @NotNull EventCallback eventCallback) {
+ if (eventNode.getParent() == null) {
+ MinecraftServer.getGlobalEventHandler().addChild(eventNode);
+ }
+ return EventHandler.super.addEventCallback(eventClass, eventCallback);
}
// UNSAFE METHODS (need most of time to be synchronized)
@@ -862,7 +866,7 @@ public abstract class Instance implements BlockModifier, Tickable, EventHandler,
lastInstance.UNSAFE_removeEntity(entity); // If entity is in another instance, remove it from there and add it to this
}
AddEntityToInstanceEvent event = new AddEntityToInstanceEvent(this, entity);
- callCancellableEvent(AddEntityToInstanceEvent.class, event, () -> {
+ EventDispatcher.callCancellable(event, () -> {
final Position entityPosition = entity.getPosition();
final boolean isPlayer = entity instanceof Player;
@@ -907,7 +911,7 @@ public abstract class Instance implements BlockModifier, Tickable, EventHandler,
return;
RemoveEntityFromInstanceEvent event = new RemoveEntityFromInstanceEvent(this, entity);
- callCancellableEvent(RemoveEntityFromInstanceEvent.class, event, () -> {
+ EventDispatcher.callCancellable(event, () -> {
// Remove this entity from players viewable list and send delete entities packet
entity.getViewers().forEach(entity::removeViewer);
@@ -1039,7 +1043,7 @@ public abstract class Instance implements BlockModifier, Tickable, EventHandler,
{
// Process tick events
InstanceTickEvent chunkTickEvent = new InstanceTickEvent(this, time, lastTickAge);
- callEvent(InstanceTickEvent.class, chunkTickEvent);
+ EventDispatcher.call(chunkTickEvent);
// Set last tick age
lastTickAge = time;
diff --git a/src/main/java/net/minestom/server/instance/InstanceContainer.java b/src/main/java/net/minestom/server/instance/InstanceContainer.java
index b5f97d99d..aa3451643 100644
--- a/src/main/java/net/minestom/server/instance/InstanceContainer.java
+++ b/src/main/java/net/minestom/server/instance/InstanceContainer.java
@@ -4,6 +4,7 @@ import net.minestom.server.MinecraftServer;
import net.minestom.server.data.Data;
import net.minestom.server.data.SerializableData;
import net.minestom.server.entity.Player;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.instance.InstanceChunkLoadEvent;
import net.minestom.server.event.instance.InstanceChunkUnloadEvent;
import net.minestom.server.event.player.PlayerBlockBreakEvent;
@@ -384,7 +385,7 @@ public class InstanceContainer extends Instance {
final CustomBlock customBlock = getCustomBlock(x, y, z);
PlayerBlockBreakEvent blockBreakEvent = new PlayerBlockBreakEvent(player, blockPosition, blockStateId, customBlock, (short) 0, (short) 0);
- player.callEvent(PlayerBlockBreakEvent.class, blockBreakEvent);
+ EventDispatcher.call(blockBreakEvent);
final boolean allowed = !blockBreakEvent.isCancelled();
if (allowed) {
// Break or change the broken block based on event result
@@ -835,11 +836,11 @@ public class InstanceContainer extends Instance {
private void callChunkLoadEvent(int chunkX, int chunkZ) {
InstanceChunkLoadEvent chunkLoadEvent = new InstanceChunkLoadEvent(this, chunkX, chunkZ);
- callEvent(InstanceChunkLoadEvent.class, chunkLoadEvent);
+ EventDispatcher.call(chunkLoadEvent);
}
private void callChunkUnloadEvent(int chunkX, int chunkZ) {
InstanceChunkUnloadEvent chunkUnloadEvent = new InstanceChunkUnloadEvent(this, chunkX, chunkZ);
- callEvent(InstanceChunkUnloadEvent.class, chunkUnloadEvent);
+ EventDispatcher.call(chunkUnloadEvent);
}
}
\ No newline at end of file
diff --git a/src/main/java/net/minestom/server/inventory/InventoryClickHandler.java b/src/main/java/net/minestom/server/inventory/InventoryClickHandler.java
index 8aeb712e3..d851a00f6 100644
--- a/src/main/java/net/minestom/server/inventory/InventoryClickHandler.java
+++ b/src/main/java/net/minestom/server/inventory/InventoryClickHandler.java
@@ -1,6 +1,7 @@
package net.minestom.server.inventory;
import net.minestom.server.entity.Player;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.inventory.InventoryClickEvent;
import net.minestom.server.inventory.click.ClickType;
import net.minestom.server.item.ItemStack;
@@ -78,7 +79,7 @@ public interface InventoryClickHandler {
default void callClickEvent(@NotNull Player player, Inventory inventory, int slot,
@NotNull ClickType clickType, @NotNull ItemStack clicked, @NotNull ItemStack cursor) {
InventoryClickEvent inventoryClickEvent = new InventoryClickEvent(inventory, player, slot, clickType, clicked, cursor);
- player.callEvent(InventoryClickEvent.class, inventoryClickEvent);
+ EventDispatcher.call(inventoryClickEvent);
}
}
diff --git a/src/main/java/net/minestom/server/inventory/PlayerInventory.java b/src/main/java/net/minestom/server/inventory/PlayerInventory.java
index ce6b32dae..34d88ef63 100644
--- a/src/main/java/net/minestom/server/inventory/PlayerInventory.java
+++ b/src/main/java/net/minestom/server/inventory/PlayerInventory.java
@@ -2,6 +2,7 @@ package net.minestom.server.inventory;
import net.minestom.server.entity.EquipmentSlot;
import net.minestom.server.entity.Player;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.item.EntityEquipEvent;
import net.minestom.server.inventory.click.ClickType;
import net.minestom.server.inventory.click.InventoryClickResult;
@@ -189,7 +190,7 @@ public class PlayerInventory extends AbstractInventory implements EquipmentHandl
if (equipmentSlot != null) {
EntityEquipEvent entityEquipEvent = new EntityEquipEvent(player, itemStack, equipmentSlot);
- player.callEvent(EntityEquipEvent.class, entityEquipEvent);
+ EventDispatcher.call(entityEquipEvent);
itemStack = entityEquipEvent.getEquippedItem();
}
diff --git a/src/main/java/net/minestom/server/inventory/click/InventoryClickProcessor.java b/src/main/java/net/minestom/server/inventory/click/InventoryClickProcessor.java
index 95236daed..3d6ed0888 100644
--- a/src/main/java/net/minestom/server/inventory/click/InventoryClickProcessor.java
+++ b/src/main/java/net/minestom/server/inventory/click/InventoryClickProcessor.java
@@ -4,6 +4,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectFunction;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import net.minestom.server.entity.Player;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.inventory.InventoryClickEvent;
import net.minestom.server.event.inventory.InventoryPreClickEvent;
import net.minestom.server.inventory.AbstractInventory;
@@ -187,7 +188,7 @@ public class InventoryClickProcessor {
var pair = TransactionType.ADD.process(targetInventory, clicked, (index, itemStack) -> {
InventoryClickResult result = startCondition(targetInventory, player, index, ClickType.SHIFT_CLICK, itemStack, cursor);
- if(result.isCancel()){
+ if (result.isCancel()) {
clickResult.setRefresh(true);
return false;
}
@@ -214,7 +215,7 @@ public class InventoryClickProcessor {
if (index == slot) // Prevent item lose/duplication
return false;
InventoryClickResult result = startCondition(targetInventory, player, index, ClickType.SHIFT_CLICK, itemStack, cursor);
- if(result.isCancel()){
+ if (result.isCancel()) {
clickResult.setRefresh(true);
return false;
}
@@ -553,7 +554,7 @@ public class InventoryClickProcessor {
{
InventoryPreClickEvent inventoryPreClickEvent = new InventoryPreClickEvent(inventory, player, slot, clickType,
clickResult.getClicked(), clickResult.getCursor());
- player.callEvent(InventoryPreClickEvent.class, inventoryPreClickEvent);
+ EventDispatcher.call(inventoryPreClickEvent);
clickResult.setCursor(inventoryPreClickEvent.getCursorItem());
clickResult.setClicked(inventoryPreClickEvent.getClickedItem());
@@ -609,7 +610,7 @@ public class InventoryClickProcessor {
private void callClickEvent(@NotNull Player player, @Nullable Inventory inventory, int slot,
@NotNull ClickType clickType, @NotNull ItemStack clicked, @NotNull ItemStack cursor) {
InventoryClickEvent inventoryClickEvent = new InventoryClickEvent(inventory, player, slot, clickType, clicked, cursor);
- player.callEvent(InventoryClickEvent.class, inventoryClickEvent);
+ EventDispatcher.call(inventoryClickEvent);
}
public void clearCache(@NotNull Player player) {
diff --git a/src/main/java/net/minestom/server/listener/AbilitiesListener.java b/src/main/java/net/minestom/server/listener/AbilitiesListener.java
index aa71a60bc..c2894465d 100644
--- a/src/main/java/net/minestom/server/listener/AbilitiesListener.java
+++ b/src/main/java/net/minestom/server/listener/AbilitiesListener.java
@@ -1,6 +1,7 @@
package net.minestom.server.listener;
import net.minestom.server.entity.Player;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.player.PlayerStartFlyingEvent;
import net.minestom.server.event.player.PlayerStopFlyingEvent;
import net.minestom.server.network.packet.client.play.ClientPlayerAbilitiesPacket;
@@ -17,10 +18,10 @@ public class AbilitiesListener {
if (isFlying) {
PlayerStartFlyingEvent startFlyingEvent = new PlayerStartFlyingEvent(player);
- player.callEvent(PlayerStartFlyingEvent.class, startFlyingEvent);
+ EventDispatcher.call(startFlyingEvent);
} else {
PlayerStopFlyingEvent stopFlyingEvent = new PlayerStopFlyingEvent(player);
- player.callEvent(PlayerStopFlyingEvent.class, stopFlyingEvent);
+ EventDispatcher.call(stopFlyingEvent);
}
}
}
diff --git a/src/main/java/net/minestom/server/listener/AdvancementTabListener.java b/src/main/java/net/minestom/server/listener/AdvancementTabListener.java
index 1802f6732..5e917f7ae 100644
--- a/src/main/java/net/minestom/server/listener/AdvancementTabListener.java
+++ b/src/main/java/net/minestom/server/listener/AdvancementTabListener.java
@@ -2,6 +2,7 @@ package net.minestom.server.listener;
import net.minestom.server.advancements.AdvancementAction;
import net.minestom.server.entity.Player;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.player.AdvancementTabEvent;
import net.minestom.server.network.packet.client.play.ClientAdvancementTabPacket;
@@ -12,6 +13,6 @@ public class AdvancementTabListener {
final String tabId = packet.tabIdentifier;
AdvancementTabEvent advancementTabEvent = new AdvancementTabEvent(player, action, tabId);
- player.callEvent(AdvancementTabEvent.class, advancementTabEvent);
+ EventDispatcher.call(advancementTabEvent);
}
}
diff --git a/src/main/java/net/minestom/server/listener/AnimationListener.java b/src/main/java/net/minestom/server/listener/AnimationListener.java
index c40511a3b..6058e7b45 100644
--- a/src/main/java/net/minestom/server/listener/AnimationListener.java
+++ b/src/main/java/net/minestom/server/listener/AnimationListener.java
@@ -1,6 +1,7 @@
package net.minestom.server.listener;
import net.minestom.server.entity.Player;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.player.PlayerHandAnimationEvent;
import net.minestom.server.item.ItemStack;
import net.minestom.server.network.packet.client.play.ClientAnimationPacket;
@@ -12,7 +13,7 @@ public class AnimationListener {
final ItemStack itemStack = player.getItemInHand(hand);
//itemStack.onLeftClick(player, hand);
PlayerHandAnimationEvent handAnimationEvent = new PlayerHandAnimationEvent(player, hand);
- player.callCancellableEvent(PlayerHandAnimationEvent.class, handAnimationEvent, () -> {
+ EventDispatcher.callCancellable(handAnimationEvent, () -> {
switch (hand) {
case MAIN:
player.swingMainHand();
diff --git a/src/main/java/net/minestom/server/listener/BlockPlacementListener.java b/src/main/java/net/minestom/server/listener/BlockPlacementListener.java
index 2eab9562a..79c2d4cd0 100644
--- a/src/main/java/net/minestom/server/listener/BlockPlacementListener.java
+++ b/src/main/java/net/minestom/server/listener/BlockPlacementListener.java
@@ -6,6 +6,7 @@ import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.player.PlayerBlockInteractEvent;
import net.minestom.server.event.player.PlayerBlockPlaceEvent;
import net.minestom.server.event.player.PlayerUseItemOnBlockEvent;
@@ -57,7 +58,7 @@ public class BlockPlacementListener {
PlayerBlockInteractEvent playerBlockInteractEvent = new PlayerBlockInteractEvent(player, blockPosition, hand, blockFace);
playerBlockInteractEvent.setCancelled(cancel);
playerBlockInteractEvent.setBlockingItemUse(cancel);
- player.callCancellableEvent(PlayerBlockInteractEvent.class, playerBlockInteractEvent, () -> {
+ EventDispatcher.callCancellable(playerBlockInteractEvent, () -> {
final CustomBlock customBlock = instance.getCustomBlock(blockPosition);
if (customBlock != null) {
final Data data = instance.getBlockData(blockPosition);
@@ -146,7 +147,7 @@ public class BlockPlacementListener {
PlayerBlockPlaceEvent playerBlockPlaceEvent = new PlayerBlockPlaceEvent(player, block, blockPosition, packet.hand);
playerBlockPlaceEvent.consumeBlock(player.getGameMode() != GameMode.CREATIVE);
- player.callEvent(PlayerBlockPlaceEvent.class, playerBlockPlaceEvent);
+ EventDispatcher.call(playerBlockPlaceEvent);
if (!playerBlockPlaceEvent.isCancelled()) {
// BlockPlacementRule check
@@ -189,7 +190,7 @@ public class BlockPlacementListener {
// Player didn't try to place a block but interacted with one
final BlockPosition usePosition = blockPosition.clone().subtract(offsetX, offsetY, offsetZ);
PlayerUseItemOnBlockEvent event = new PlayerUseItemOnBlockEvent(player, hand, usedItem, usePosition, direction);
- player.callEvent(PlayerUseItemOnBlockEvent.class, event);
+ EventDispatcher.call(event);
refreshChunk = true;
}
diff --git a/src/main/java/net/minestom/server/listener/ChatMessageListener.java b/src/main/java/net/minestom/server/listener/ChatMessageListener.java
index cc1f491df..bc251f7a5 100644
--- a/src/main/java/net/minestom/server/listener/ChatMessageListener.java
+++ b/src/main/java/net/minestom/server/listener/ChatMessageListener.java
@@ -5,6 +5,7 @@ import net.kyori.adventure.text.event.ClickEvent;
import net.minestom.server.MinecraftServer;
import net.minestom.server.command.CommandManager;
import net.minestom.server.entity.Player;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.player.PlayerChatEvent;
import net.minestom.server.message.ChatPosition;
import net.minestom.server.message.Messenger;
@@ -49,7 +50,7 @@ public class ChatMessageListener {
PlayerChatEvent playerChatEvent = new PlayerChatEvent(player, players, () -> buildDefaultChatMessage(player, message), message);
// Call the event
- player.callCancellableEvent(PlayerChatEvent.class, playerChatEvent, () -> {
+ EventDispatcher.callCancellable(playerChatEvent, () -> {
final Function formatFunction = playerChatEvent.getChatFormatFunction();
Component textObject;
diff --git a/src/main/java/net/minestom/server/listener/EntityActionListener.java b/src/main/java/net/minestom/server/listener/EntityActionListener.java
index dea235c90..7ca503080 100644
--- a/src/main/java/net/minestom/server/listener/EntityActionListener.java
+++ b/src/main/java/net/minestom/server/listener/EntityActionListener.java
@@ -1,6 +1,7 @@
package net.minestom.server.listener;
import net.minestom.server.entity.Player;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.player.*;
import net.minestom.server.network.packet.client.play.ClientEntityActionPacket;
@@ -35,9 +36,9 @@ public class EntityActionListener {
if (oldState != sneaking) {
if (sneaking) {
- player.callEvent(PlayerStartSneakingEvent.class, new PlayerStartSneakingEvent(player));
+ EventDispatcher.call(new PlayerStartSneakingEvent(player));
} else {
- player.callEvent(PlayerStopSneakingEvent.class, new PlayerStopSneakingEvent(player));
+ EventDispatcher.call(new PlayerStopSneakingEvent(player));
}
}
}
@@ -49,15 +50,15 @@ public class EntityActionListener {
if (oldState != sprinting) {
if (sprinting) {
- player.callEvent(PlayerStartSprintingEvent.class, new PlayerStartSprintingEvent(player));
+ EventDispatcher.call(new PlayerStartSprintingEvent(player));
} else {
- player.callEvent(PlayerStopSprintingEvent.class, new PlayerStopSprintingEvent(player));
+ EventDispatcher.call(new PlayerStopSprintingEvent(player));
}
}
}
private static void startFlyingElytra(Player player) {
player.setFlyingWithElytra(true);
- player.callEvent(PlayerStartFlyingWithElytraEvent.class, new PlayerStartFlyingWithElytraEvent(player));
+ EventDispatcher.call(new PlayerStartFlyingWithElytraEvent(player));
}
}
diff --git a/src/main/java/net/minestom/server/listener/PlayerDiggingListener.java b/src/main/java/net/minestom/server/listener/PlayerDiggingListener.java
index e1e2971f4..3c04ee9e4 100644
--- a/src/main/java/net/minestom/server/listener/PlayerDiggingListener.java
+++ b/src/main/java/net/minestom/server/listener/PlayerDiggingListener.java
@@ -2,6 +2,7 @@ package net.minestom.server.listener;
import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.item.ItemUpdateStateEvent;
import net.minestom.server.event.player.PlayerStartDiggingEvent;
import net.minestom.server.event.player.PlayerSwapItemEvent;
@@ -67,7 +68,7 @@ public class PlayerDiggingListener {
final int customBlockId = customBlock == null ? 0 : customBlock.getCustomBlockId();
PlayerStartDiggingEvent playerStartDiggingEvent = new PlayerStartDiggingEvent(player, blockPosition, blockStateId, customBlockId);
- player.callEvent(PlayerStartDiggingEvent.class, playerStartDiggingEvent);
+ EventDispatcher.call(playerStartDiggingEvent);
if (playerStartDiggingEvent.isCancelled()) {
addEffect(player);
@@ -163,7 +164,7 @@ public class PlayerDiggingListener {
final ItemStack offHand = playerInventory.getItemInOffHand();
PlayerSwapItemEvent swapItemEvent = new PlayerSwapItemEvent(player, offHand, mainHand);
- player.callCancellableEvent(PlayerSwapItemEvent.class, swapItemEvent, () -> {
+ EventDispatcher.callCancellable(swapItemEvent, () -> {
playerInventory.setItemInMainHand(swapItemEvent.getMainHandItem());
playerInventory.setItemInOffHand(swapItemEvent.getOffHandItem());
});
diff --git a/src/main/java/net/minestom/server/listener/PlayerHeldListener.java b/src/main/java/net/minestom/server/listener/PlayerHeldListener.java
index 7bd713ac1..196df6c24 100644
--- a/src/main/java/net/minestom/server/listener/PlayerHeldListener.java
+++ b/src/main/java/net/minestom/server/listener/PlayerHeldListener.java
@@ -1,6 +1,7 @@
package net.minestom.server.listener;
import net.minestom.server.entity.Player;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.player.PlayerChangeHeldSlotEvent;
import net.minestom.server.network.packet.client.play.ClientHeldItemChangePacket;
import net.minestom.server.utils.MathUtils;
@@ -16,7 +17,7 @@ public class PlayerHeldListener {
final byte slot = (byte) packet.slot;
PlayerChangeHeldSlotEvent changeHeldSlotEvent = new PlayerChangeHeldSlotEvent(player, slot);
- player.callEvent(PlayerChangeHeldSlotEvent.class, changeHeldSlotEvent);
+ EventDispatcher.call(changeHeldSlotEvent);
if (!changeHeldSlotEvent.isCancelled()) {
// Event hasn't been canceled, process it
diff --git a/src/main/java/net/minestom/server/listener/PlayerPositionListener.java b/src/main/java/net/minestom/server/listener/PlayerPositionListener.java
index aea47ba8b..aadbe5a17 100644
--- a/src/main/java/net/minestom/server/listener/PlayerPositionListener.java
+++ b/src/main/java/net/minestom/server/listener/PlayerPositionListener.java
@@ -1,6 +1,7 @@
package net.minestom.server.listener;
import net.minestom.server.entity.Player;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.instance.Instance;
import net.minestom.server.network.packet.client.play.*;
@@ -74,7 +75,7 @@ public class PlayerPositionListener {
final Position cachedPosition = newPosition.clone();
PlayerMoveEvent playerMoveEvent = new PlayerMoveEvent(player, newPosition);
- player.callEvent(PlayerMoveEvent.class, playerMoveEvent);
+ EventDispatcher.call(playerMoveEvent);
// True if the event call changed the player position (possibly a teleport)
final boolean positionChanged = !currentPosition.equals(player.getPosition());
diff --git a/src/main/java/net/minestom/server/listener/PluginMessageListener.java b/src/main/java/net/minestom/server/listener/PluginMessageListener.java
index 9bd798614..22d3e4d04 100644
--- a/src/main/java/net/minestom/server/listener/PluginMessageListener.java
+++ b/src/main/java/net/minestom/server/listener/PluginMessageListener.java
@@ -1,6 +1,7 @@
package net.minestom.server.listener;
import net.minestom.server.entity.Player;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.player.PlayerPluginMessageEvent;
import net.minestom.server.network.packet.client.play.ClientPluginMessagePacket;
@@ -8,7 +9,7 @@ public class PluginMessageListener {
public static void listener(ClientPluginMessagePacket packet, Player player) {
PlayerPluginMessageEvent pluginMessageEvent = new PlayerPluginMessageEvent(player, packet.channel, packet.data);
- player.callEvent(PlayerPluginMessageEvent.class, pluginMessageEvent);
+ EventDispatcher.call(pluginMessageEvent);
}
}
diff --git a/src/main/java/net/minestom/server/listener/ResourcePackListener.java b/src/main/java/net/minestom/server/listener/ResourcePackListener.java
index 8af588f63..5bbaa1368 100644
--- a/src/main/java/net/minestom/server/listener/ResourcePackListener.java
+++ b/src/main/java/net/minestom/server/listener/ResourcePackListener.java
@@ -1,6 +1,7 @@
package net.minestom.server.listener;
import net.minestom.server.entity.Player;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.player.PlayerResourcePackStatusEvent;
import net.minestom.server.network.packet.client.play.ClientResourcePackStatusPacket;
import net.minestom.server.resourcepack.ResourcePackStatus;
@@ -10,6 +11,6 @@ public class ResourcePackListener {
public static void listener(ClientResourcePackStatusPacket packet, Player player) {
final ResourcePackStatus result = packet.result;
PlayerResourcePackStatusEvent resourcePackStatusEvent = new PlayerResourcePackStatusEvent(player, result);
- player.callEvent(PlayerResourcePackStatusEvent.class, resourcePackStatusEvent);
+ EventDispatcher.call(resourcePackStatusEvent);
}
}
diff --git a/src/main/java/net/minestom/server/listener/SettingsListener.java b/src/main/java/net/minestom/server/listener/SettingsListener.java
index 3099a8226..0dcd01db3 100644
--- a/src/main/java/net/minestom/server/listener/SettingsListener.java
+++ b/src/main/java/net/minestom/server/listener/SettingsListener.java
@@ -1,6 +1,7 @@
package net.minestom.server.listener;
import net.minestom.server.entity.Player;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.player.PlayerSettingsChangeEvent;
import net.minestom.server.network.packet.client.play.ClientSettingsPacket;
@@ -11,7 +12,7 @@ public class SettingsListener {
settings.refresh(packet.locale, packet.viewDistance, packet.chatMessageType, packet.chatColors, packet.displayedSkinParts, packet.mainHand);
PlayerSettingsChangeEvent playerSettingsChangeEvent = new PlayerSettingsChangeEvent(player);
- player.callEvent(PlayerSettingsChangeEvent.class, playerSettingsChangeEvent);
+ EventDispatcher.call(playerSettingsChangeEvent);
}
}
diff --git a/src/main/java/net/minestom/server/listener/UseEntityListener.java b/src/main/java/net/minestom/server/listener/UseEntityListener.java
index 321f6eb78..3628797a2 100644
--- a/src/main/java/net/minestom/server/listener/UseEntityListener.java
+++ b/src/main/java/net/minestom/server/listener/UseEntityListener.java
@@ -3,6 +3,7 @@ package net.minestom.server.listener;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.LivingEntity;
import net.minestom.server.entity.Player;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.entity.EntityAttackEvent;
import net.minestom.server.event.player.PlayerEntityInteractEvent;
import net.minestom.server.network.packet.client.play.ClientInteractEntityPacket;
@@ -24,10 +25,10 @@ public class UseEntityListener {
return;
EntityAttackEvent entityAttackEvent = new EntityAttackEvent(player, entity);
- player.callEvent(EntityAttackEvent.class, entityAttackEvent);
+ EventDispatcher.call(entityAttackEvent);
} else if (type == ClientInteractEntityPacket.Type.INTERACT) {
PlayerEntityInteractEvent playerEntityInteractEvent = new PlayerEntityInteractEvent(player, entity, packet.hand);
- player.callEvent(PlayerEntityInteractEvent.class, playerEntityInteractEvent);
+ EventDispatcher.call(playerEntityInteractEvent);
} else {
// TODO find difference with INTERACT
//PlayerEntityInteractEvent playerEntityInteractEvent = new PlayerEntityInteractEvent(player, entity, packet.hand);
diff --git a/src/main/java/net/minestom/server/listener/UseItemListener.java b/src/main/java/net/minestom/server/listener/UseItemListener.java
index a72bba3ef..8a29466e8 100644
--- a/src/main/java/net/minestom/server/listener/UseItemListener.java
+++ b/src/main/java/net/minestom/server/listener/UseItemListener.java
@@ -1,6 +1,7 @@
package net.minestom.server.listener;
import net.minestom.server.entity.Player;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.player.PlayerItemAnimationEvent;
import net.minestom.server.event.player.PlayerPreEatEvent;
import net.minestom.server.event.player.PlayerUseItemEvent;
@@ -17,7 +18,7 @@ public class UseItemListener {
ItemStack itemStack = hand == Player.Hand.MAIN ? inventory.getItemInMainHand() : inventory.getItemInOffHand();
//itemStack.onRightClick(player, hand);
PlayerUseItemEvent useItemEvent = new PlayerUseItemEvent(player, hand, itemStack);
- player.callEvent(PlayerUseItemEvent.class, useItemEvent);
+ EventDispatcher.call(useItemEvent);
final PlayerInventory playerInventory = player.getInventory();
if (useItemEvent.isCancelled()) {
@@ -65,7 +66,7 @@ public class UseItemListener {
// Eating code, contains the eating time customisation
PlayerPreEatEvent playerPreEatEvent = new PlayerPreEatEvent(player, itemStack, hand, player.getDefaultEatingTime());
- player.callCancellableEvent(PlayerPreEatEvent.class, playerPreEatEvent, () -> player.refreshEating(hand, playerPreEatEvent.getEatingTime()));
+ EventDispatcher.callCancellable(playerPreEatEvent, () -> player.refreshEating(hand, playerPreEatEvent.getEatingTime()));
if (playerPreEatEvent.isCancelled()) {
cancelAnimation = true;
@@ -74,7 +75,7 @@ public class UseItemListener {
if (!cancelAnimation && itemAnimationType != null) {
PlayerItemAnimationEvent playerItemAnimationEvent = new PlayerItemAnimationEvent(player, itemAnimationType);
- player.callCancellableEvent(PlayerItemAnimationEvent.class, playerItemAnimationEvent, () -> {
+ EventDispatcher.callCancellable(playerItemAnimationEvent, () -> {
player.refreshActiveHand(true, hand == Player.Hand.OFF, riptideSpinAttack);
player.sendPacketToViewers(player.getMetadataPacket());
});
diff --git a/src/main/java/net/minestom/server/listener/WindowListener.java b/src/main/java/net/minestom/server/listener/WindowListener.java
index 08bc7998c..142dfebaa 100644
--- a/src/main/java/net/minestom/server/listener/WindowListener.java
+++ b/src/main/java/net/minestom/server/listener/WindowListener.java
@@ -1,6 +1,7 @@
package net.minestom.server.listener;
import net.minestom.server.entity.Player;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.inventory.InventoryCloseEvent;
import net.minestom.server.inventory.AbstractInventory;
import net.minestom.server.inventory.Inventory;
@@ -94,7 +95,7 @@ public class WindowListener {
public static void closeWindowListener(ClientCloseWindowPacket packet, Player player) {
// if windowId == 0 then it is player's inventory, meaning that they hadn't been any open inventory packet
InventoryCloseEvent inventoryCloseEvent = new InventoryCloseEvent(player.getOpenInventory(), player);
- player.callEvent(InventoryCloseEvent.class, inventoryCloseEvent);
+ EventDispatcher.call(inventoryCloseEvent);
player.closeInventory();
diff --git a/src/main/java/net/minestom/server/listener/manager/PacketListenerManager.java b/src/main/java/net/minestom/server/listener/manager/PacketListenerManager.java
index 79af9499d..a76894151 100644
--- a/src/main/java/net/minestom/server/listener/manager/PacketListenerManager.java
+++ b/src/main/java/net/minestom/server/listener/manager/PacketListenerManager.java
@@ -2,6 +2,8 @@ package net.minestom.server.listener.manager;
import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.Player;
+import net.minestom.server.event.EventDispatcher;
+import net.minestom.server.event.player.PlayerPacketEvent;
import net.minestom.server.listener.*;
import net.minestom.server.network.ConnectionManager;
import net.minestom.server.network.packet.client.ClientPlayPacket;
@@ -74,13 +76,23 @@ public final class PacketListenerManager {
LOGGER.warn("Packet " + clazz + " does not have any default listener! (The issue comes from Minestom)");
}
- final PacketController packetController = new PacketController();
- for (ClientPacketConsumer clientPacketConsumer : CONNECTION_MANAGER.getReceivePacketConsumers()) {
- clientPacketConsumer.accept(player, packetController, packet);
+ // TODO remove legacy
+ {
+ final PacketController packetController = new PacketController();
+ for (ClientPacketConsumer clientPacketConsumer : CONNECTION_MANAGER.getReceivePacketConsumers()) {
+ clientPacketConsumer.accept(player, packetController, packet);
+ }
+
+ if (packetController.isCancel())
+ return;
}
- if (packetController.isCancel())
+ // Event
+ PlayerPacketEvent playerPacketEvent = new PlayerPacketEvent(player, packet);
+ EventDispatcher.call(playerPacketEvent);
+ if (playerPacketEvent.isCancelled()) {
return;
+ }
// Finally execute the listener
if (packetListenerConsumer != null) {
diff --git a/src/main/java/net/minestom/server/network/ConnectionManager.java b/src/main/java/net/minestom/server/network/ConnectionManager.java
index 67ae73556..66024bb5c 100644
--- a/src/main/java/net/minestom/server/network/ConnectionManager.java
+++ b/src/main/java/net/minestom/server/network/ConnectionManager.java
@@ -9,6 +9,7 @@ import net.minestom.server.adventure.audience.Audiences;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.fakeplayer.FakePlayer;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.player.AsyncPlayerPreLoginEvent;
import net.minestom.server.event.player.PlayerLoginEvent;
import net.minestom.server.instance.Instance;
@@ -187,9 +188,7 @@ public final class ConnectionManager {
* Gets all the listeners which are called for each packet received.
*
* @return a list of packet's consumers
- * @deprecated all packet listening methods will ultimately be removed.
- * May or may not work depending on the packet.
- * It is instead recommended to use a proxy, improving scalability and increasing server performance
+ * @deprecated see {@link net.minestom.server.event.player.PlayerPacketEvent}
*/
@NotNull
@Deprecated
@@ -201,9 +200,7 @@ public final class ConnectionManager {
* Adds a consumer to call once a packet is received.
*
* @param clientPacketConsumer the packet consumer
- * @deprecated all packet listening methods will ultimately be removed.
- * May or may not work depending on the packet.
- * It is instead recommended to use a proxy, improving scalability and increasing server performance
+ * @deprecated listen to {@link net.minestom.server.event.player.PlayerPacketEvent}
*/
@Deprecated
public void onPacketReceive(@NotNull ClientPacketConsumer clientPacketConsumer) {
@@ -419,7 +416,7 @@ public final class ConnectionManager {
// Call pre login event
AsyncPlayerPreLoginEvent asyncPlayerPreLoginEvent = new AsyncPlayerPreLoginEvent(player, username, uuid);
- player.callEvent(AsyncPlayerPreLoginEvent.class, asyncPlayerPreLoginEvent);
+ EventDispatcher.call(asyncPlayerPreLoginEvent);
// Close the player channel if he has been disconnected (kick)
final boolean online = player.isOnline();
@@ -543,7 +540,7 @@ public final class ConnectionManager {
while ((waitingPlayer = waitingPlayers.poll()) != null) {
PlayerLoginEvent loginEvent = new PlayerLoginEvent(waitingPlayer);
- waitingPlayer.callEvent(PlayerLoginEvent.class, loginEvent);
+ EventDispatcher.call(loginEvent);
final Instance spawningInstance = loginEvent.getSpawningInstance();
Check.notNull(spawningInstance, "You need to specify a spawning instance in the PlayerLoginEvent");
diff --git a/src/main/java/net/minestom/server/network/netty/codec/LegacyPingHandler.java b/src/main/java/net/minestom/server/network/netty/codec/LegacyPingHandler.java
index b54e8cffa..f94ea785c 100644
--- a/src/main/java/net/minestom/server/network/netty/codec/LegacyPingHandler.java
+++ b/src/main/java/net/minestom/server/network/netty/codec/LegacyPingHandler.java
@@ -6,6 +6,7 @@ import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import net.minestom.server.MinecraftServer;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.server.ServerListPingEvent;
import net.minestom.server.ping.ServerListPingType;
import org.jetbrains.annotations.NotNull;
@@ -138,12 +139,12 @@ public class LegacyPingHandler extends ChannelInboundHandlerAdapter {
* Calls a {@link ServerListPingEvent} and sends the response, if the event was not cancelled.
*
* @param version the version
- * @param ctx the context
+ * @param ctx the context
* @return {@code true} if the response was cancelled, {@code false} otherwise
*/
private static boolean trySendResponse(@NotNull ServerListPingType version, @NotNull ChannelHandlerContext ctx) {
final ServerListPingEvent event = new ServerListPingEvent(version);
- MinecraftServer.getGlobalEventHandler().callEvent(ServerListPingEvent.class, event);
+ EventDispatcher.call(event);
if (event.isCancelled()) {
return true;
diff --git a/src/main/java/net/minestom/server/network/packet/client/status/PingPacket.java b/src/main/java/net/minestom/server/network/packet/client/status/PingPacket.java
index 6a8b4599d..b5b1dd779 100644
--- a/src/main/java/net/minestom/server/network/packet/client/status/PingPacket.java
+++ b/src/main/java/net/minestom/server/network/packet/client/status/PingPacket.java
@@ -1,7 +1,7 @@
package net.minestom.server.network.packet.client.status;
-import net.kyori.adventure.text.Component;
import net.minestom.server.MinecraftServer;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.server.ClientPingServerEvent;
import net.minestom.server.network.packet.client.ClientPreplayPacket;
import net.minestom.server.network.packet.server.status.PongPacket;
@@ -14,12 +14,13 @@ public class PingPacket implements ClientPreplayPacket {
private long number;
- public PingPacket() {}
+ public PingPacket() {
+ }
@Override
public void process(@NotNull PlayerConnection connection) {
final ClientPingServerEvent clientPingEvent = new ClientPingServerEvent(connection, number);
- MinecraftServer.getGlobalEventHandler().callEvent(ClientPingServerEvent.class, clientPingEvent);
+ EventDispatcher.call(clientPingEvent);
if (clientPingEvent.isCancelled()) {
connection.disconnect();
diff --git a/src/main/java/net/minestom/server/network/packet/client/status/StatusRequestPacket.java b/src/main/java/net/minestom/server/network/packet/client/status/StatusRequestPacket.java
index 5a6f908b0..94128833d 100644
--- a/src/main/java/net/minestom/server/network/packet/client/status/StatusRequestPacket.java
+++ b/src/main/java/net/minestom/server/network/packet/client/status/StatusRequestPacket.java
@@ -1,6 +1,6 @@
package net.minestom.server.network.packet.client.status;
-import net.minestom.server.MinecraftServer;
+import net.minestom.server.event.EventDispatcher;
import net.minestom.server.event.server.ServerListPingEvent;
import net.minestom.server.network.packet.client.ClientPreplayPacket;
import net.minestom.server.network.packet.server.handshake.ResponsePacket;
@@ -16,7 +16,7 @@ public class StatusRequestPacket implements ClientPreplayPacket {
public void process(@NotNull PlayerConnection connection) {
final ServerListPingType pingVersion = ServerListPingType.fromModernProtocolVersion(connection.getProtocolVersion());
final ServerListPingEvent statusRequestEvent = new ServerListPingEvent(connection, pingVersion);
- MinecraftServer.getGlobalEventHandler().callCancellableEvent(ServerListPingEvent.class, statusRequestEvent, () -> {
+ EventDispatcher.callCancellable(statusRequestEvent, () -> {
final ResponsePacket responsePacket = new ResponsePacket();
responsePacket.jsonResponse = pingVersion.getPingResponse(statusRequestEvent.getResponseData());
diff --git a/src/test/java/demo/PlayerInit.java b/src/test/java/demo/PlayerInit.java
index 6ac680612..485347368 100644
--- a/src/test/java/demo/PlayerInit.java
+++ b/src/test/java/demo/PlayerInit.java
@@ -5,33 +5,31 @@ import demo.generator.NoiseTestGenerator;
import net.kyori.adventure.text.Component;
import net.minestom.server.MinecraftServer;
import net.minestom.server.adventure.audience.Audiences;
-import net.minestom.server.chat.ColoredText;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.ItemEntity;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.damage.DamageType;
-import net.minestom.server.event.GlobalEventHandler;
+import net.minestom.server.event.Event;
+import net.minestom.server.event.EventFilter;
+import net.minestom.server.event.EventNode;
import net.minestom.server.event.entity.EntityAttackEvent;
import net.minestom.server.event.item.ItemDropEvent;
import net.minestom.server.event.item.PickupItemEvent;
import net.minestom.server.event.player.*;
-import net.minestom.server.instance.Chunk;
+import net.minestom.server.event.trait.PlayerEvent;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.InstanceContainer;
import net.minestom.server.instance.InstanceManager;
import net.minestom.server.instance.block.Block;
-import net.minestom.server.instance.block.CustomBlock;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.InventoryType;
-import net.minestom.server.inventory.PlayerInventory;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.ItemTag;
import net.minestom.server.item.Material;
import net.minestom.server.item.metadata.CompassMeta;
import net.minestom.server.monitoring.BenchmarkManager;
import net.minestom.server.monitoring.TickMonitor;
-import net.minestom.server.network.ConnectionManager;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.Vector;
@@ -39,7 +37,6 @@ import net.minestom.server.utils.time.TimeUnit;
import net.minestom.server.world.DimensionType;
import java.util.Collection;
-import java.util.Collections;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
@@ -49,6 +46,70 @@ public class PlayerInit {
private static final Inventory inventory;
+ private static final EventNode DEMO_NODE = EventNode.all("demo")
+ .addListener(EntityAttackEvent.class, event -> {
+ final Entity source = event.getEntity();
+ final Entity entity = event.getTarget();
+ if (entity instanceof Player) {
+ Player target = (Player) entity;
+ Vector velocity = source.getPosition().clone().getDirection().multiply(4);
+ velocity.setY(3.5f);
+ target.setVelocity(velocity);
+ target.damage(DamageType.fromEntity(source), 5);
+ } else {
+ Vector velocity = source.getPosition().clone().getDirection().multiply(3);
+ velocity.setY(3f);
+ entity.setVelocity(velocity);
+ }
+
+ if (source instanceof Player) {
+ ((Player) source).sendMessage("You attacked something!");
+ }
+ })
+ .addListener(PlayerDeathEvent.class, event -> event.setChatMessage(Component.text("custom death message")))
+ .addListener(PickupItemEvent.class, event -> {
+ final Entity entity = event.getLivingEntity();
+ if (entity instanceof Player) {
+ // Cancel event if player does not have enough inventory space
+ final ItemStack itemStack = event.getItemEntity().getItemStack();
+ event.setCancelled(!((Player) entity).getInventory().addItemStack(itemStack));
+ }
+ })
+ .addListener(ItemDropEvent.class, event -> {
+ final Player player = event.getPlayer();
+ ItemStack droppedItem = event.getItemStack();
+
+ Position position = player.getPosition().clone().add(0, 1.5f, 0);
+ ItemEntity itemEntity = new ItemEntity(droppedItem, position);
+ itemEntity.setPickupDelay(500, TimeUnit.MILLISECOND);
+ itemEntity.setInstance(player.getInstance());
+ Vector velocity = player.getPosition().clone().getDirection().multiply(6);
+ itemEntity.setVelocity(velocity);
+ })
+ .addListener(PlayerDisconnectEvent.class, event -> System.out.println("DISCONNECTION " + event.getPlayer().getUsername()))
+ .addListener(PlayerLoginEvent.class, event -> {
+ final Player player = event.getPlayer();
+
+ var instances = MinecraftServer.getInstanceManager().getInstances();
+ Instance instance = instances.stream().skip(new Random().nextInt(instances.size())).findFirst().orElse(null);
+ event.setSpawningInstance(instance);
+ int x = Math.abs(ThreadLocalRandom.current().nextInt()) % 500 - 250;
+ int z = Math.abs(ThreadLocalRandom.current().nextInt()) % 500 - 250;
+ player.setRespawnPoint(new Position(0, 42f, 0));
+ })
+ .addListener(PlayerSpawnEvent.class, event -> {
+ final Player player = event.getPlayer();
+ player.setGameMode(GameMode.CREATIVE);
+ player.setPermissionLevel(4);
+ ItemStack itemStack = ItemStack.builder(Material.STONE)
+ .amount(64)
+ .meta(itemMetaBuilder ->
+ itemMetaBuilder.canPlaceOn(Set.of(Block.STONE))
+ .canDestroy(Set.of(Block.DIAMOND_ORE)))
+ .build();
+ player.getInventory().addItemStack(itemStack);
+ });
+
static {
InstanceManager instanceManager = MinecraftServer.getInstanceManager();
//StorageLocation storageLocation = MinecraftServer.getStorageManager().getLocation("instance_data", new StorageOptions().setCompression(true));
@@ -92,16 +153,18 @@ public class PlayerInit {
private static AtomicReference LAST_TICK = new AtomicReference<>();
public static void init() {
- ConnectionManager connectionManager = MinecraftServer.getConnectionManager();
- BenchmarkManager benchmarkManager = MinecraftServer.getBenchmarkManager();
+ var eventHandler = MinecraftServer.getGlobalEventHandler();
+ eventHandler.addChild(DEMO_NODE);
+ var children = eventHandler.findChildren("demo", Event.class);
+
+ eventHandler.replaceChildren("demo", PlayerEvent.class, EventNode.type("random", EventFilter.PLAYER));
MinecraftServer.getUpdateManager().addTickMonitor(tickMonitor ->
LAST_TICK.set(tickMonitor));
+ BenchmarkManager benchmarkManager = MinecraftServer.getBenchmarkManager();
MinecraftServer.getSchedulerManager().buildTask(() -> {
-
- Collection players = connectionManager.getOnlinePlayers();
-
+ Collection players = MinecraftServer.getConnectionManager().getOnlinePlayers();
if (players.isEmpty())
return;
@@ -109,7 +172,6 @@ public class PlayerInit {
ramUsage /= 1e6; // bytes to MB
TickMonitor tickMonitor = LAST_TICK.get();
-
final Component header = Component.text("RAM USAGE: " + ramUsage + " MB")
.append(Component.newline())
.append(Component.text("TICK TIME: " + MathUtils.round(tickMonitor.getTickTime(), 2) + "ms"))
@@ -117,183 +179,7 @@ public class PlayerInit {
.append(Component.text("ACQ TIME: " + MathUtils.round(tickMonitor.getAcquisitionTime(), 2) + "ms"));
final Component footer = benchmarkManager.getCpuMonitoringMessage();
Audiences.players().sendPlayerListHeaderAndFooter(header, footer);
-
}).repeat(10, TimeUnit.TICK).schedule();
-
- connectionManager.onPacketReceive((player, packetController, packet) -> {
- // Listen to all received packet
- //System.out.println("PACKET: "+packet.getClass().getSimpleName());
- packetController.setCancel(false);
- });
-
- connectionManager.onPacketSend((players, packetController, packet) -> {
- // Listen to all sent packet
- //System.out.println("PACKET: " + packet.getClass().getSimpleName());
- packetController.setCancel(false);
- });
-
- // EVENT REGISTERING
-
- GlobalEventHandler globalEventHandler = MinecraftServer.getGlobalEventHandler();
-
- globalEventHandler.addEventCallback(EntityAttackEvent.class, event -> {
- final Entity source = event.getEntity();
- final Entity entity = event.getTarget();
- if (entity instanceof Player) {
- Player target = (Player) entity;
- Vector velocity = source.getPosition().clone().getDirection().multiply(4);
- velocity.setY(3.5f);
- target.setVelocity(velocity);
- target.damage(DamageType.fromEntity(source), 5);
- } else {
- Vector velocity = source.getPosition().clone().getDirection().multiply(3);
- velocity.setY(3f);
- entity.setVelocity(velocity);
- }
-
- if (source instanceof Player) {
- ((Player) source).sendMessage("You attacked something!");
- }
- });
-
- globalEventHandler.addEventCallback(PlayerDeathEvent.class, event -> {
- event.setChatMessage(ColoredText.of("custom death message"));
- });
-
- globalEventHandler.addEventCallback(PlayerBlockPlaceEvent.class, event -> {
- if (event.getHand() != Player.Hand.MAIN)
- return;
-
- final Block block = Block.fromStateId(event.getBlockStateId());
-
- if (block == Block.STONE) {
- event.setCustomBlock("custom_block");
- System.out.println("custom stone");
- }
- if (block == Block.TORCH) {
- event.setCustomBlock((short) 3); // custom torch block
- }
-
- });
-
- globalEventHandler.addEventCallback(PlayerBlockInteractEvent.class, event -> {
- if (event.getHand() != Player.Hand.MAIN)
- return;
- final Player player = event.getPlayer();
-
- final short blockStateId = player.getInstance().getBlockStateId(event.getBlockPosition());
- final CustomBlock customBlock = player.getInstance().getCustomBlock(event.getBlockPosition());
- final Block block = Block.fromStateId(blockStateId);
- player.sendMessage("You clicked at the block " + block + " " + customBlock);
- player.sendMessage("CHUNK COUNT " + player.getInstance().getChunks().size());
- });
-
- globalEventHandler.addEventCallback(PickupItemEvent.class, event -> {
- final Entity entity = event.getLivingEntity();
- if (entity instanceof Player) {
- // Cancel event if player does not have enough inventory space
- final ItemStack itemStack = event.getItemEntity().getItemStack();
- event.setCancelled(!((Player) entity).getInventory().addItemStack(itemStack));
- }
- });
-
- globalEventHandler.addEventCallback(ItemDropEvent.class, event -> {
- final Player player = event.getPlayer();
- ItemStack droppedItem = event.getItemStack();
-
- Position position = player.getPosition().clone().add(0, 1.5f, 0);
- ItemEntity itemEntity = new ItemEntity(droppedItem, position);
- itemEntity.setPickupDelay(500, TimeUnit.MILLISECOND);
- itemEntity.setInstance(player.getInstance());
- Vector velocity = player.getPosition().clone().getDirection().multiply(6);
- itemEntity.setVelocity(velocity);
- });
-
- globalEventHandler.addEventCallback(PlayerDisconnectEvent.class, event -> {
- final Player player = event.getPlayer();
- System.out.println("DISCONNECTION " + player.getUsername());
- });
-
- globalEventHandler.addEventCallback(PlayerLoginEvent.class, event -> {
- final Player player = event.getPlayer();
-
- var instances = MinecraftServer.getInstanceManager().getInstances();
- Instance instance = instances.stream().skip(new Random().nextInt(instances.size())).findFirst().orElse(null);
- event.setSpawningInstance(instance);
- int x = Math.abs(ThreadLocalRandom.current().nextInt()) % 500 - 250;
- int z = Math.abs(ThreadLocalRandom.current().nextInt()) % 500 - 250;
- player.setRespawnPoint(new Position(0, 42f, 0));
-
- player.getInventory().addInventoryCondition((p, slot, clickType, inventoryConditionResult) -> {
- if (slot == -999)
- return;
- //ItemStack itemStack = p.getInventory().getItemStack(slot);
- //System.out.println("test " + itemStack.getIdentifier() + " " + itemStack.getData());
- });
- });
-
- globalEventHandler.addEventCallback(PlayerSpawnEvent.class, event -> {
- final Player player = event.getPlayer();
- player.setGameMode(GameMode.CREATIVE);
-
- player.setPermissionLevel(4);
-
- PlayerInventory inventory = player.getInventory();
- ItemStack itemStack = ItemStack.builder(Material.STONE)
- .amount(64)
- .meta(itemMetaBuilder ->
- itemMetaBuilder.canPlaceOn(Set.of(Block.STONE))
- .canDestroy(Set.of(Block.DIAMOND_ORE)))
- .build();
-
- //itemStack = itemStack.withStore(storeBuilder -> storeBuilder.set("key2", 25, Integer::sum));
-
- inventory.addItemStack(itemStack);
-
- {
- ItemStack item = ItemStack.builder(Material.DIAMOND_CHESTPLATE)
- .displayName(Component.text("test"))
- .lore(Component.text("lore"))
- .build();
-
- //inventory.setChestplate(item);
-
- inventory.setChestplate(item.with(itemStackBuilder -> {
- itemStackBuilder.lore(Collections.emptyList());
- }));
- }
- });
-
- globalEventHandler.addEventCallback(PlayerBlockBreakEvent.class, event -> {
- final short blockStateId = event.getBlockStateId();
- System.out.println("broke " + blockStateId + " " + Block.fromStateId(blockStateId));
- });
-
- globalEventHandler.addEventCallback(PlayerUseItemEvent.class, useEvent -> {
- final Player player = useEvent.getPlayer();
- player.sendMessage("Using item in air: " + useEvent.getItemStack().getMaterial());
- });
-
- globalEventHandler.addEventCallback(PlayerUseItemOnBlockEvent.class, useEvent -> {
- final Player player = useEvent.getPlayer();
- player.sendMessage("Main item: " + player.getInventory().getItemInMainHand().getMaterial());
- player.sendMessage("Using item on block: " + useEvent.getItemStack().getMaterial() + " at " + useEvent.getPosition() + " on face " + useEvent.getBlockFace());
- });
-
- globalEventHandler.addEventCallback(PlayerChunkUnloadEvent.class, event -> {
- final Player player = event.getPlayer();
- final Instance instance = player.getInstance();
-
- Chunk chunk = instance.getChunk(event.getChunkX(), event.getChunkZ());
-
- if (chunk == null)
- return;
-
- // Unload the chunk (save memory) if it has no remaining viewer
- if (chunk.getViewers().isEmpty()) {
- //player.getInstance().unloadChunk(chunk);
- }
- });
}