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 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 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 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 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 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 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 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 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 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 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); - } - }); }