From 3ba1ecb6bacd56af8a2054dc8b59e63769acb36b Mon Sep 17 00:00:00 2001 From: Paul Kindler Date: Sun, 19 Jan 2025 21:41:37 +0100 Subject: [PATCH 01/27] add player death event --- .../core/mixin/player/MixinServerPlayer.java | 37 +++++++++++++++++++ .../silkmc/silk/core/event/PlayerEvents.kt | 9 +++++ .../src/main/resources/silk-core.mixins.json | 1 + .../paper/events/internal/PlayerEvents.kt | 27 ++++++++++++++ 4 files changed, 74 insertions(+) create mode 100644 silk-core/src/main/java/net/silkmc/silk/core/mixin/player/MixinServerPlayer.java diff --git a/silk-core/src/main/java/net/silkmc/silk/core/mixin/player/MixinServerPlayer.java b/silk-core/src/main/java/net/silkmc/silk/core/mixin/player/MixinServerPlayer.java new file mode 100644 index 00000000..ef9dab36 --- /dev/null +++ b/silk-core/src/main/java/net/silkmc/silk/core/mixin/player/MixinServerPlayer.java @@ -0,0 +1,37 @@ +package net.silkmc.silk.core.mixin.player; + +import com.llamalad7.mixinextras.sugar.Local; +import com.llamalad7.mixinextras.sugar.ref.LocalRef; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.damagesource.DamageSource; +import net.silkmc.silk.core.event.EventScopeProperty; +import net.silkmc.silk.core.event.PlayerEvents; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ServerPlayer.class) +public class MixinServerPlayer { + + @Inject( + method = "die", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/network/ServerGamePacketListenerImpl;send(Lnet/minecraft/network/protocol/Packet;Lnet/minecraft/network/PacketSendListener;)V", + shift = At.Shift.BEFORE + ) + ) + private void die(DamageSource damageSource, CallbackInfo ci, @Local LocalRef component) { + var event = new PlayerEvents.PlayerDeathEvent( + (ServerPlayer) (Object) this, + damageSource, + new EventScopeProperty<>(component.get())); + + PlayerEvents.INSTANCE.getOnDeath().invoke(event); + + component.set(event.getDeathMessage().get()); + } + +} diff --git a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt index 41941a09..1b19ceb6 100644 --- a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt +++ b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt @@ -3,6 +3,7 @@ package net.silkmc.silk.core.event import com.mojang.authlib.GameProfile import net.minecraft.network.chat.Component import net.minecraft.server.level.ServerPlayer +import net.minecraft.world.damagesource.DamageSource import net.minecraft.world.entity.player.Player import net.silkmc.silk.core.annotations.ExperimentalSilkApi @@ -60,4 +61,12 @@ object PlayerEvents { * @see preQuit */ val quitDuringConfiguration = Event.syncAsync() + + open class PlayerDeathEvent( + val player: Player, + val source: DamageSource, + var deathMessage: EventScopeProperty, + ) + + val onDeath = Event.syncAsync() } diff --git a/silk-core/src/main/resources/silk-core.mixins.json b/silk-core/src/main/resources/silk-core.mixins.json index ec54db7e..460d3d30 100644 --- a/silk-core/src/main/resources/silk-core.mixins.json +++ b/silk-core/src/main/resources/silk-core.mixins.json @@ -6,6 +6,7 @@ "block.AbstractBlockAccessor", "entity.MixinEntity", "entity.MixinLivingEntity", + "player.MixinServerPlayer", "server.MixinMinecraftServer", "server.MixinPlayerList", "server.MixinServerConfigurationPacketListenerImpl", diff --git a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt index 14b6a3ac..5000c294 100644 --- a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt +++ b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt @@ -1,9 +1,17 @@ package net.silkmc.silk.paper.events.internal import io.papermc.paper.adventure.AdventureComponent +import net.minecraft.core.Holder +import net.minecraft.world.damagesource.DamageEffects +import net.minecraft.world.damagesource.DamageScaling +import net.minecraft.world.damagesource.DamageSource +import net.minecraft.world.damagesource.DamageType +import net.silkmc.silk.core.event.EventScopeProperty import net.silkmc.silk.core.event.PlayerEvents +import net.silkmc.silk.paper.conversions.mcEntity import net.silkmc.silk.paper.conversions.mcPlayer import net.silkmc.silk.paper.events.listenSilk +import org.bukkit.event.entity.PlayerDeathEvent import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.event.player.PlayerLoginEvent import org.bukkit.event.player.PlayerQuitEvent @@ -18,4 +26,23 @@ fun PlayerEvents.setupPaper() { listenSilk { preQuit.invoke(PlayerEvents.PlayerQuitEvent(it.player.mcPlayer, AdventureComponent(it.quitMessage()))) } + + listenSilk { + onDeath.invoke( + PlayerEvents.PlayerDeathEvent( + it.player.mcPlayer, DamageSource( + Holder.direct( + DamageType( + it.damageSource.damageType.key.key, + DamageScaling.WHEN_CAUSED_BY_LIVING_NON_PLAYER, //TODO: Use DamageTypeRegistryEntry in 1.21.4 + it.damageSource.foodExhaustion, + DamageEffects.valueOf(it.damageSource.damageType.damageEffect.toString()) + ) + ), + it.entity.mcEntity, + null + ), EventScopeProperty(AdventureComponent(it.deathMessage())) + ) + ) + } } From 6f9c9afd53078fa5fd67b6e2139176e75b944e5b Mon Sep 17 00:00:00 2001 From: Paul Kindler Date: Sun, 19 Jan 2025 21:50:10 +0100 Subject: [PATCH 02/27] update paper implementation for death event --- .../net/silkmc/silk/paper/events/internal/PlayerEvents.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt index 5000c294..97eb035b 100644 --- a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt +++ b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt @@ -6,6 +6,7 @@ import net.minecraft.world.damagesource.DamageEffects import net.minecraft.world.damagesource.DamageScaling import net.minecraft.world.damagesource.DamageSource import net.minecraft.world.damagesource.DamageType +import net.minecraft.world.phys.Vec3 import net.silkmc.silk.core.event.EventScopeProperty import net.silkmc.silk.core.event.PlayerEvents import net.silkmc.silk.paper.conversions.mcEntity @@ -28,6 +29,7 @@ fun PlayerEvents.setupPaper() { } listenSilk { + val pos = it.player.location.toVector() onDeath.invoke( PlayerEvents.PlayerDeathEvent( it.player.mcPlayer, DamageSource( @@ -40,7 +42,8 @@ fun PlayerEvents.setupPaper() { ) ), it.entity.mcEntity, - null + it.entity.mcEntity, + Vec3(pos.x, pos.y, pos.z), ), EventScopeProperty(AdventureComponent(it.deathMessage())) ) ) From 337a5061491e79da8b5486c32b4c9ba2aef1ec6c Mon Sep 17 00:00:00 2001 From: Paul Kindler Date: Mon, 20 Jan 2025 12:56:04 +0100 Subject: [PATCH 03/27] changed Player to ServerPlayer --- .../main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt index 1b19ceb6..37098e1b 100644 --- a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt +++ b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt @@ -62,8 +62,11 @@ object PlayerEvents { */ val quitDuringConfiguration = Event.syncAsync() + /** + * Called when a player dies. + */ open class PlayerDeathEvent( - val player: Player, + val player: ServerPlayer, val source: DamageSource, var deathMessage: EventScopeProperty, ) From 07f4edebb21cb6cdfab6c1fff428012c3afe8e52 Mon Sep 17 00:00:00 2001 From: Paul Kindler Date: Mon, 20 Jan 2025 17:17:56 +0100 Subject: [PATCH 04/27] set correct death message in the paper impl --- .../paper/events/internal/PlayerEvents.kt | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt index 97eb035b..dd791171 100644 --- a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt +++ b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt @@ -1,6 +1,7 @@ package net.silkmc.silk.paper.events.internal import io.papermc.paper.adventure.AdventureComponent +import net.kyori.adventure.text.Component import net.minecraft.core.Holder import net.minecraft.world.damagesource.DamageEffects import net.minecraft.world.damagesource.DamageScaling @@ -30,22 +31,22 @@ fun PlayerEvents.setupPaper() { listenSilk { val pos = it.player.location.toVector() - onDeath.invoke( - PlayerEvents.PlayerDeathEvent( - it.player.mcPlayer, DamageSource( - Holder.direct( - DamageType( - it.damageSource.damageType.key.key, - DamageScaling.WHEN_CAUSED_BY_LIVING_NON_PLAYER, //TODO: Use DamageTypeRegistryEntry in 1.21.4 - it.damageSource.foodExhaustion, - DamageEffects.valueOf(it.damageSource.damageType.damageEffect.toString()) - ) - ), - it.entity.mcEntity, - it.entity.mcEntity, - Vec3(pos.x, pos.y, pos.z), - ), EventScopeProperty(AdventureComponent(it.deathMessage())) - ) + val event = PlayerEvents.PlayerDeathEvent( + it.player.mcPlayer, DamageSource( + Holder.direct( + DamageType( + it.damageSource.damageType.key.key, + DamageScaling.WHEN_CAUSED_BY_LIVING_NON_PLAYER, //TODO: Use DamageTypeRegistryEntry in 1.21.4 + it.damageSource.foodExhaustion, + DamageEffects.valueOf(it.damageSource.damageType.damageEffect.toString()) + ) + ), + it.entity.mcEntity, + it.entity.mcEntity, + Vec3(pos.x, pos.y, pos.z), + ), EventScopeProperty(AdventureComponent(it.deathMessage())) ) + onDeath.invoke(event) + it.deathMessage(Component.text(event.deathMessage.get().string)) } } From 3fdd33a4abeef9a78ae644b72fb8220adec1fdc5 Mon Sep 17 00:00:00 2001 From: Paul Kindler Date: Mon, 20 Jan 2025 17:24:16 +0100 Subject: [PATCH 05/27] implement PlayerEvent in PlayerDeathEvent --- .../main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt index 37098e1b..22af602f 100644 --- a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt +++ b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt @@ -66,10 +66,10 @@ object PlayerEvents { * Called when a player dies. */ open class PlayerDeathEvent( - val player: ServerPlayer, + player: ServerPlayer, val source: DamageSource, var deathMessage: EventScopeProperty, - ) + ) : PlayerEvent(player) val onDeath = Event.syncAsync() } From 7674ea310dee8a44e4e75118f59c6d8bffb48ef7 Mon Sep 17 00:00:00 2001 From: Paul Kindler Date: Mon, 20 Jan 2025 17:30:47 +0100 Subject: [PATCH 06/27] add entity death event --- .../core/mixin/entity/MixinLivingEntity.java | 17 +++++++++++ .../silkmc/silk/core/event/EntityEvents.kt | 10 +++++++ .../paper/events/internal/EntityEvents.kt | 28 +++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/silk-core/src/main/java/net/silkmc/silk/core/mixin/entity/MixinLivingEntity.java b/silk-core/src/main/java/net/silkmc/silk/core/mixin/entity/MixinLivingEntity.java index 53ca6a01..8cd2f2a9 100644 --- a/silk-core/src/main/java/net/silkmc/silk/core/mixin/entity/MixinLivingEntity.java +++ b/silk-core/src/main/java/net/silkmc/silk/core/mixin/entity/MixinLivingEntity.java @@ -23,4 +23,21 @@ private void onActuallyHurt(ServerLevel serverLevel, EntityEvents.INSTANCE.getDamageLivingEntity() .invoke(new EntityEvents.EntityDamageEvent((LivingEntity) (Object) this, amount, damageSource)); } + + @Inject( + method = "die", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/damagesource/DamageSource;getEntity()Lnet/minecraft/world/entity/Entity;", + shift = At.Shift.BEFORE + ) + ) + private void die(DamageSource damageSource, CallbackInfo ci) { + var event = new EntityEvents.EntityDeathEvent( + (LivingEntity) (Object) this, + damageSource + ); + + EntityEvents.INSTANCE.getOnDeath().invoke(event); + } } diff --git a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/EntityEvents.kt b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/EntityEvents.kt index 7c95085f..fb668b92 100644 --- a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/EntityEvents.kt +++ b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/EntityEvents.kt @@ -42,4 +42,14 @@ object EntityEvents { * event, since Minecraft performs its checks more than one time */ val checkInvulnerability = Event.onlySync() + + /** + * Called when a [LivingEntity] dies. + */ + open class EntityDeathEvent( + entity: LivingEntity, + val damageSource: DamageSource + ) : EntityEvent(entity) + + val onDeath = Event.syncAsync() } diff --git a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/EntityEvents.kt b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/EntityEvents.kt index 9a69a1ad..0952591a 100644 --- a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/EntityEvents.kt +++ b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/EntityEvents.kt @@ -1,12 +1,19 @@ package net.silkmc.silk.paper.events.internal +import net.minecraft.core.Holder +import net.minecraft.world.damagesource.DamageEffects +import net.minecraft.world.damagesource.DamageScaling +import net.minecraft.world.damagesource.DamageSource +import net.minecraft.world.damagesource.DamageType import net.minecraft.world.entity.LivingEntity +import net.minecraft.world.phys.Vec3 import net.silkmc.silk.core.event.EntityEvents import net.silkmc.silk.core.event.EventScopeProperty import net.silkmc.silk.paper.conversions.mcEntity import net.silkmc.silk.paper.events.listenSilk import org.bukkit.craftbukkit.damage.CraftDamageSource import org.bukkit.event.entity.EntityDamageEvent +import org.bukkit.event.entity.PlayerDeathEvent fun EntityEvents.setupPaper() { listenSilk { paperEvent -> @@ -30,4 +37,25 @@ fun EntityEvents.setupPaper() { source = mcDamageSource)) } } + + listenSilk { + val pos = it.entity.location + val event = EntityEvents.EntityDeathEvent( + it.entity.mcEntity as LivingEntity, + DamageSource( + Holder.direct( + DamageType( + it.damageSource.damageType.key.key, + DamageScaling.WHEN_CAUSED_BY_LIVING_NON_PLAYER, //TODO: Use DamageTypeRegistryEntry in 1.21.4 + it.damageSource.foodExhaustion, + DamageEffects.valueOf(it.damageSource.damageType.damageEffect.toString()) + ) + ), + it.entity.mcEntity, + it.entity.mcEntity, + Vec3(pos.x, pos.y, pos.z), + ) + ) + onDeath.invoke(event) + } } From 1d389ddb71ea9231eaa45cf775bb40aa6c383e20 Mon Sep 17 00:00:00 2001 From: Paul Kindler Date: Mon, 20 Jan 2025 17:31:31 +0100 Subject: [PATCH 07/27] removed toVector + updated docs for ServerPlayer --- .../src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt | 2 +- .../net/silkmc/silk/paper/events/internal/PlayerEvents.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt index 22af602f..3af94839 100644 --- a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt +++ b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt @@ -63,7 +63,7 @@ object PlayerEvents { val quitDuringConfiguration = Event.syncAsync() /** - * Called when a player dies. + * Called when a [ServerPlayer] dies. */ open class PlayerDeathEvent( player: ServerPlayer, diff --git a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt index dd791171..0e0d0ca6 100644 --- a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt +++ b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt @@ -30,7 +30,7 @@ fun PlayerEvents.setupPaper() { } listenSilk { - val pos = it.player.location.toVector() + val pos = it.player.location val event = PlayerEvents.PlayerDeathEvent( it.player.mcPlayer, DamageSource( Holder.direct( From fddf2e5ac9d4c08d4cf172e1eef9f0358db34460 Mon Sep 17 00:00:00 2001 From: Paul Kindler Date: Mon, 20 Jan 2025 22:41:55 +0100 Subject: [PATCH 08/27] moved comment to the right place --- .../kotlin/net/silkmc/silk/core/event/EntityEvents.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/EntityEvents.kt b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/EntityEvents.kt index fb668b92..9e06f82b 100644 --- a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/EntityEvents.kt +++ b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/EntityEvents.kt @@ -43,13 +43,13 @@ object EntityEvents { */ val checkInvulnerability = Event.onlySync() - /** - * Called when a [LivingEntity] dies. - */ open class EntityDeathEvent( entity: LivingEntity, - val damageSource: DamageSource + val damageSource: DamageSource, ) : EntityEvent(entity) + /** + * Called when a [LivingEntity] dies. + */ val onDeath = Event.syncAsync() } From 567a7ae59e2bc1a217032b6730c9b0992368b343 Mon Sep 17 00:00:00 2001 From: Paul Kindler Date: Mon, 20 Jan 2025 22:51:39 +0100 Subject: [PATCH 09/27] moved player onDeath comment --- .../kotlin/net/silkmc/silk/core/event/PlayerEvents.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt index 3af94839..f256089a 100644 --- a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt +++ b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt @@ -62,14 +62,16 @@ object PlayerEvents { */ val quitDuringConfiguration = Event.syncAsync() - /** - * Called when a [ServerPlayer] dies. - */ open class PlayerDeathEvent( player: ServerPlayer, val source: DamageSource, var deathMessage: EventScopeProperty, ) : PlayerEvent(player) + /** + * Called when a [ServerPlayer] dies. + */ val onDeath = Event.syncAsync() + + } From ff4be407e29d78f5d052bde70a3b2050fd2a5a36 Mon Sep 17 00:00:00 2001 From: Paul Kindler Date: Mon, 20 Jan 2025 23:08:37 +0100 Subject: [PATCH 10/27] adding Player/Entity-EventTests to testmod --- .../main/kotlin/net/silkmc/silk/test/Manager.kt | 5 +++++ .../silkmc/silk/test/events/EntityEventTest.kt | 15 +++++++++++++++ .../silkmc/silk/test/events/PlayerEventTest.kt | 15 +++++++++++++++ .../silkmc/silk/test/events/ServerEventTest.kt | 5 +++++ 4 files changed, 40 insertions(+) create mode 100644 silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/EntityEventTest.kt create mode 100644 silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/PlayerEventTest.kt diff --git a/silk-testmod/src/main/kotlin/net/silkmc/silk/test/Manager.kt b/silk-testmod/src/main/kotlin/net/silkmc/silk/test/Manager.kt index 2271e9f4..8e4e94eb 100644 --- a/silk-testmod/src/main/kotlin/net/silkmc/silk/test/Manager.kt +++ b/silk-testmod/src/main/kotlin/net/silkmc/silk/test/Manager.kt @@ -7,7 +7,10 @@ import net.silkmc.silk.commands.ClientCommandSourceStack import net.silkmc.silk.commands.LiteralCommandBuilder import net.silkmc.silk.commands.clientCommand import net.silkmc.silk.commands.command +import net.silkmc.silk.core.event.PlayerEvents import net.silkmc.silk.test.commands.* +import net.silkmc.silk.test.events.EntityEventTest +import net.silkmc.silk.test.events.PlayerEventTest import net.silkmc.silk.test.events.ServerEventTest import net.silkmc.silk.test.network.NetworkTest @@ -27,6 +30,8 @@ object Manager : ModInitializer, ClientModInitializer { executeCommandTestCommand ServerEventTest.init() + PlayerEventTest.init() + EntityEventTest.init() NetworkTest.initServer() command("testmod") { diff --git a/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/EntityEventTest.kt b/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/EntityEventTest.kt new file mode 100644 index 00000000..0c9d1b14 --- /dev/null +++ b/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/EntityEventTest.kt @@ -0,0 +1,15 @@ +package net.silkmc.silk.test.events + +import net.silkmc.silk.core.annotations.ExperimentalSilkApi +import net.silkmc.silk.core.event.Entity +import net.silkmc.silk.core.event.Events +import net.silkmc.silk.core.logging.logInfo + +@OptIn(ExperimentalSilkApi::class) +object EntityEventTest { + fun init() { + Events.Entity.onDeath.listen { + logInfo("received Entity.onDeath event") + } + } +} \ No newline at end of file diff --git a/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/PlayerEventTest.kt b/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/PlayerEventTest.kt new file mode 100644 index 00000000..69125cb1 --- /dev/null +++ b/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/PlayerEventTest.kt @@ -0,0 +1,15 @@ +package net.silkmc.silk.test.events + +import net.silkmc.silk.core.annotations.ExperimentalSilkApi +import net.silkmc.silk.core.event.Events +import net.silkmc.silk.core.event.Player +import net.silkmc.silk.core.logging.logInfo + +@OptIn(ExperimentalSilkApi::class) +object PlayerEventTest { + fun init() { + Events.Player.onDeath.listen { + logInfo("received Player.onDeath event") + } + } +} \ No newline at end of file diff --git a/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/ServerEventTest.kt b/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/ServerEventTest.kt index fe6cb28d..9108495d 100644 --- a/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/ServerEventTest.kt +++ b/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/ServerEventTest.kt @@ -1,9 +1,14 @@ package net.silkmc.silk.test.events +import net.silkmc.silk.core.Silk import net.silkmc.silk.core.annotations.ExperimentalSilkApi +import net.silkmc.silk.core.event.Entity import net.silkmc.silk.core.event.Events +import net.silkmc.silk.core.event.Player import net.silkmc.silk.core.event.Server import net.silkmc.silk.core.logging.logInfo +import net.silkmc.silk.core.text.broadcastText +import java.awt.Color @OptIn(ExperimentalSilkApi::class) object ServerEventTest { From 37206ae3ad213e183e04725f8d0f082f9bde6ab0 Mon Sep 17 00:00:00 2001 From: Paul Kindler Date: Tue, 21 Jan 2025 22:43:53 +0100 Subject: [PATCH 11/27] add conversion from paper DamageSource to mc DamageSource --- .../silkmc/silk/paper/conversions/NativeMcConversions.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/conversions/NativeMcConversions.kt b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/conversions/NativeMcConversions.kt index 71c3ac09..8dc8c7a1 100644 --- a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/conversions/NativeMcConversions.kt +++ b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/conversions/NativeMcConversions.kt @@ -6,8 +6,10 @@ import net.minecraft.server.level.ServerEntity import net.minecraft.server.level.ServerPlayer import org.bukkit.Server import org.bukkit.craftbukkit.CraftServer +import org.bukkit.craftbukkit.damage.CraftDamageSource import org.bukkit.craftbukkit.entity.CraftEntity import org.bukkit.craftbukkit.entity.CraftPlayer +import org.bukkit.damage.DamageSource import org.bukkit.entity.Entity import org.bukkit.entity.Player @@ -29,3 +31,10 @@ val Player.mcPlayer: ServerPlayer */ val Entity.mcEntity: net.minecraft.world.entity.Entity get() = (this as CraftEntity).handle + +@Suppress("UnstableApiUsage") + /** + * Converts a Paper [DamageSource] to a native [net.minecraft.world.damagesource.DamageSource]. + */ +val DamageSource.mcDamageSource: net.minecraft.world.damagesource.DamageSource + get() = (this as CraftDamageSource).handle \ No newline at end of file From e520331afa815a14ddc35662cf3d439d70590555 Mon Sep 17 00:00:00 2001 From: Paul Kindler Date: Tue, 21 Jan 2025 22:44:20 +0100 Subject: [PATCH 12/27] update usages of DamageSource conversion --- .../paper/events/internal/EntityEvents.kt | 18 +++---------- .../paper/events/internal/PlayerEvents.kt | 25 ++++--------------- 2 files changed, 9 insertions(+), 34 deletions(-) diff --git a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/EntityEvents.kt b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/EntityEvents.kt index 0952591a..9d283c2c 100644 --- a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/EntityEvents.kt +++ b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/EntityEvents.kt @@ -9,6 +9,7 @@ import net.minecraft.world.entity.LivingEntity import net.minecraft.world.phys.Vec3 import net.silkmc.silk.core.event.EntityEvents import net.silkmc.silk.core.event.EventScopeProperty +import net.silkmc.silk.paper.conversions.mcDamageSource import net.silkmc.silk.paper.conversions.mcEntity import net.silkmc.silk.paper.events.listenSilk import org.bukkit.craftbukkit.damage.CraftDamageSource @@ -19,7 +20,7 @@ fun EntityEvents.setupPaper() { listenSilk { paperEvent -> val mcEntity = paperEvent.entity.mcEntity @Suppress("UnstableApiUsage") - val mcDamageSource = (paperEvent.damageSource as CraftDamageSource).handle + val mcDamageSource = paperEvent.damageSource.mcDamageSource val checkEvent = EntityEvents.EntityCheckInvulnerabilityEvent( entity = mcEntity, @@ -42,19 +43,8 @@ fun EntityEvents.setupPaper() { val pos = it.entity.location val event = EntityEvents.EntityDeathEvent( it.entity.mcEntity as LivingEntity, - DamageSource( - Holder.direct( - DamageType( - it.damageSource.damageType.key.key, - DamageScaling.WHEN_CAUSED_BY_LIVING_NON_PLAYER, //TODO: Use DamageTypeRegistryEntry in 1.21.4 - it.damageSource.foodExhaustion, - DamageEffects.valueOf(it.damageSource.damageType.damageEffect.toString()) - ) - ), - it.entity.mcEntity, - it.entity.mcEntity, - Vec3(pos.x, pos.y, pos.z), - ) + @Suppress("UnstableApiUsage") + it.damageSource.mcDamageSource ) onDeath.invoke(event) } diff --git a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt index 0e0d0ca6..aaf58637 100644 --- a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt +++ b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt @@ -2,15 +2,9 @@ package net.silkmc.silk.paper.events.internal import io.papermc.paper.adventure.AdventureComponent import net.kyori.adventure.text.Component -import net.minecraft.core.Holder -import net.minecraft.world.damagesource.DamageEffects -import net.minecraft.world.damagesource.DamageScaling -import net.minecraft.world.damagesource.DamageSource -import net.minecraft.world.damagesource.DamageType -import net.minecraft.world.phys.Vec3 import net.silkmc.silk.core.event.EventScopeProperty import net.silkmc.silk.core.event.PlayerEvents -import net.silkmc.silk.paper.conversions.mcEntity +import net.silkmc.silk.paper.conversions.mcDamageSource import net.silkmc.silk.paper.conversions.mcPlayer import net.silkmc.silk.paper.events.listenSilk import org.bukkit.event.entity.PlayerDeathEvent @@ -32,19 +26,10 @@ fun PlayerEvents.setupPaper() { listenSilk { val pos = it.player.location val event = PlayerEvents.PlayerDeathEvent( - it.player.mcPlayer, DamageSource( - Holder.direct( - DamageType( - it.damageSource.damageType.key.key, - DamageScaling.WHEN_CAUSED_BY_LIVING_NON_PLAYER, //TODO: Use DamageTypeRegistryEntry in 1.21.4 - it.damageSource.foodExhaustion, - DamageEffects.valueOf(it.damageSource.damageType.damageEffect.toString()) - ) - ), - it.entity.mcEntity, - it.entity.mcEntity, - Vec3(pos.x, pos.y, pos.z), - ), EventScopeProperty(AdventureComponent(it.deathMessage())) + it.player.mcPlayer, + @Suppress("UnstableApiUsage") + it.damageSource.mcDamageSource, + EventScopeProperty(AdventureComponent(it.deathMessage())) ) onDeath.invoke(event) it.deathMessage(Component.text(event.deathMessage.get().string)) From 980c6bb87643fc42083137097c9e4803ac7787b4 Mon Sep 17 00:00:00 2001 From: Paul Kindler Date: Fri, 24 Jan 2025 20:34:13 +0100 Subject: [PATCH 13/27] add mutable joinMessage to PostLoginEvent --- .../core/mixin/server/MixinPlayerList.java | 45 +++++++++++-------- .../silkmc/silk/core/event/PlayerEvents.kt | 8 +++- .../paper/events/internal/PlayerEvents.kt | 13 +++++- 3 files changed, 45 insertions(+), 21 deletions(-) diff --git a/silk-core/src/main/java/net/silkmc/silk/core/mixin/server/MixinPlayerList.java b/silk-core/src/main/java/net/silkmc/silk/core/mixin/server/MixinPlayerList.java index b6619b50..abf295f5 100644 --- a/silk-core/src/main/java/net/silkmc/silk/core/mixin/server/MixinPlayerList.java +++ b/silk-core/src/main/java/net/silkmc/silk/core/mixin/server/MixinPlayerList.java @@ -1,9 +1,13 @@ package net.silkmc.silk.core.mixin.server; +import com.llamalad7.mixinextras.sugar.Local; +import com.llamalad7.mixinextras.sugar.ref.LocalRef; import net.minecraft.network.Connection; +import net.minecraft.network.chat.MutableComponent; import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.network.CommonListenerCookie; import net.minecraft.server.players.PlayerList; +import net.silkmc.silk.core.event.EventScopeProperty; import net.silkmc.silk.core.event.PlayerEvents; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -13,23 +17,28 @@ @Mixin(PlayerList.class) public class MixinPlayerList { - @Inject( - method = "placeNewPlayer", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/server/network/ServerGamePacketListenerImpl;(Lnet/minecraft/server/MinecraftServer;Lnet/minecraft/network/Connection;Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/server/network/CommonListenerCookie;)V", - shift = At.Shift.BEFORE - ) - ) - private void onPreLogin(Connection connection, ServerPlayer player, CommonListenerCookie commonListenerCookie, CallbackInfo ci) { - PlayerEvents.INSTANCE.getPreLogin().invoke(new PlayerEvents.PlayerEvent<>(player)); - } + @Inject( + method = "placeNewPlayer", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/network/ServerGamePacketListenerImpl;(Lnet/minecraft/server/MinecraftServer;Lnet/minecraft/network/Connection;Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/server/network/CommonListenerCookie;)V", + shift = At.Shift.BEFORE + ) + ) + private void onPreLogin(Connection connection, ServerPlayer player, CommonListenerCookie commonListenerCookie, CallbackInfo ci) { + PlayerEvents.INSTANCE.getPreLogin().invoke(new PlayerEvents.PlayerEvent<>(player)); + } - @Inject( - method = "placeNewPlayer", - at = @At("TAIL") - ) - private void onPostLogin(Connection connection, ServerPlayer player, CommonListenerCookie commonListenerCookie, CallbackInfo ci) { - PlayerEvents.INSTANCE.getPostLogin().invoke(new PlayerEvents.PlayerEvent<>(player)); - } + @Inject( + method = "placeNewPlayer", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/players/PlayerList;broadcastSystemMessage(Lnet/minecraft/network/chat/Component;Z)V", + shift = At.Shift.BEFORE) + ) + private void onPostLogin(Connection connection, ServerPlayer player, CommonListenerCookie commonListenerCookie, CallbackInfo ci, @Local LocalRef mutableComponent) { + var event = new PlayerEvents.PostLoginEvent(player, new EventScopeProperty<>(mutableComponent.get())); + PlayerEvents.INSTANCE.getPostLogin().invoke(event); + mutableComponent.set(event.getJoinMessage().get().copy()); + } } diff --git a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt index f256089a..fd7fd1b1 100644 --- a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt +++ b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt @@ -2,6 +2,7 @@ package net.silkmc.silk.core.event import com.mojang.authlib.GameProfile import net.minecraft.network.chat.Component +import net.minecraft.network.chat.MutableComponent import net.minecraft.server.level.ServerPlayer import net.minecraft.world.damagesource.DamageSource import net.minecraft.world.entity.player.Player @@ -17,10 +18,15 @@ object PlayerEvents { */ val preLogin = Event.syncAsync>() + open class PostLoginEvent( + player: ServerPlayer, + val joinMessage: EventScopeProperty + ) : PlayerEvent(player) + /** * Called after a player has received all login information from the server. */ - val postLogin = Event.syncAsync>() + val postLogin = Event.syncAsync() open class PlayerQuitEvent( player: ServerPlayer, diff --git a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt index aaf58637..f552dfa1 100644 --- a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt +++ b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt @@ -1,7 +1,10 @@ package net.silkmc.silk.paper.events.internal import io.papermc.paper.adventure.AdventureComponent +import io.papermc.paper.adventure.PaperAdventure import net.kyori.adventure.text.Component +import net.kyori.adventure.text.TextComponent +import net.minecraft.network.chat.MutableComponent import net.silkmc.silk.core.event.EventScopeProperty import net.silkmc.silk.core.event.PlayerEvents import net.silkmc.silk.paper.conversions.mcDamageSource @@ -17,7 +20,13 @@ fun PlayerEvents.setupPaper() { preLogin.invoke(PlayerEvents.PlayerEvent(it.player.mcPlayer)) } listenSilk { - postLogin.invoke(PlayerEvents.PlayerEvent(it.player.mcPlayer)) + val event = PlayerEvents.PostLoginEvent( + it.player.mcPlayer, EventScopeProperty( + AdventureComponent(it.joinMessage()).deepConverted() + ) + ) + postLogin.invoke(event) + it.joinMessage(PaperAdventure.asAdventure(event.joinMessage.get())) } listenSilk { preQuit.invoke(PlayerEvents.PlayerQuitEvent(it.player.mcPlayer, AdventureComponent(it.quitMessage()))) @@ -32,6 +41,6 @@ fun PlayerEvents.setupPaper() { EventScopeProperty(AdventureComponent(it.deathMessage())) ) onDeath.invoke(event) - it.deathMessage(Component.text(event.deathMessage.get().string)) + it.deathMessage(PaperAdventure.asAdventure(event.deathMessage.get())) } } From 2d9cadeae4f9c9891bf7b86d291fb5951116b4a5 Mon Sep 17 00:00:00 2001 From: Paul Kindler Date: Tue, 28 Jan 2025 23:09:23 +0100 Subject: [PATCH 14/27] remove unused PlayerEvents imports --- .../net/silkmc/silk/paper/events/internal/PlayerEvents.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt index f552dfa1..28f40925 100644 --- a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt +++ b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt @@ -2,9 +2,6 @@ package net.silkmc.silk.paper.events.internal import io.papermc.paper.adventure.AdventureComponent import io.papermc.paper.adventure.PaperAdventure -import net.kyori.adventure.text.Component -import net.kyori.adventure.text.TextComponent -import net.minecraft.network.chat.MutableComponent import net.silkmc.silk.core.event.EventScopeProperty import net.silkmc.silk.core.event.PlayerEvents import net.silkmc.silk.paper.conversions.mcDamageSource From 45f7a7d21616f69dff0c86f1b9b40cbb215095fe Mon Sep 17 00:00:00 2001 From: Paul K Date: Tue, 10 Jun 2025 01:20:15 +0200 Subject: [PATCH 15/27] add chat event, remove unsued pos --- .../core/mixin/server/MixinPlayerList.java | 24 +++++++++++++++++++ .../silkmc/silk/core/event/PlayerEvents.kt | 19 ++++++++++++++- .../paper/events/internal/PlayerEvents.kt | 1 - 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/silk-core/src/main/java/net/silkmc/silk/core/mixin/server/MixinPlayerList.java b/silk-core/src/main/java/net/silkmc/silk/core/mixin/server/MixinPlayerList.java index abf295f5..8888501c 100644 --- a/silk-core/src/main/java/net/silkmc/silk/core/mixin/server/MixinPlayerList.java +++ b/silk-core/src/main/java/net/silkmc/silk/core/mixin/server/MixinPlayerList.java @@ -3,13 +3,18 @@ import com.llamalad7.mixinextras.sugar.Local; import com.llamalad7.mixinextras.sugar.ref.LocalRef; import net.minecraft.network.Connection; +import net.minecraft.network.chat.ChatType; import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.chat.PlayerChatMessage; +import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.network.CommonListenerCookie; import net.minecraft.server.players.PlayerList; import net.silkmc.silk.core.event.EventScopeProperty; import net.silkmc.silk.core.event.PlayerEvents; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -17,6 +22,10 @@ @Mixin(PlayerList.class) public class MixinPlayerList { + @Shadow + @Final + private MinecraftServer server; + @Inject( method = "placeNewPlayer", at = @At( @@ -41,4 +50,19 @@ private void onPostLogin(Connection connection, ServerPlayer player, CommonListe PlayerEvents.INSTANCE.getPostLogin().invoke(event); mutableComponent.set(event.getJoinMessage().get().copy()); } + + @Inject( + method = "broadcastChatMessage(Lnet/minecraft/network/chat/PlayerChatMessage;Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/network/chat/ChatType$Bound;)V", + at = @At( + "HEAD" + ), + cancellable = true + ) + private void broadcastChatMessage(PlayerChatMessage playerChatMessage, ServerPlayer serverPlayer, ChatType.Bound bound, CallbackInfo ci) { + var event = new PlayerEvents.PlayerChatEvent(serverPlayer, playerChatMessage, bound); + PlayerEvents.INSTANCE.getOnChat().invoke(event); + if (event.isCancelled().get()) { + ci.cancel(); + } + } } diff --git a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt index fd7fd1b1..f67da5c7 100644 --- a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt +++ b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt @@ -1,12 +1,16 @@ package net.silkmc.silk.core.event import com.mojang.authlib.GameProfile +import net.minecraft.network.chat.ChatType import net.minecraft.network.chat.Component -import net.minecraft.network.chat.MutableComponent +import net.minecraft.network.chat.PlayerChatMessage import net.minecraft.server.level.ServerPlayer import net.minecraft.world.damagesource.DamageSource import net.minecraft.world.entity.player.Player import net.silkmc.silk.core.annotations.ExperimentalSilkApi +import net.silkmc.silk.core.event.PlayerEvents.preQuit +import net.silkmc.silk.core.event.PlayerEvents.quitDuringConfiguration +import net.silkmc.silk.core.event.PlayerEvents.quitDuringLogin @ExperimentalSilkApi object PlayerEvents { @@ -79,5 +83,18 @@ object PlayerEvents { */ val onDeath = Event.syncAsync() + /** + * Called before a message from a player is broadcasted. + */ + open class PlayerChatEvent( + player: ServerPlayer, + val message: PlayerChatMessage, + val bound: ChatType.Bound, + ) : PlayerEvent(player), Cancellable { + + override val isCancelled: EventScopeProperty = EventScopeProperty(false) + } + + val onChat = Event.syncAsync() } diff --git a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt index 28f40925..ebcb7b40 100644 --- a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt +++ b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt @@ -30,7 +30,6 @@ fun PlayerEvents.setupPaper() { } listenSilk { - val pos = it.player.location val event = PlayerEvents.PlayerDeathEvent( it.player.mcPlayer, @Suppress("UnstableApiUsage") From cf360b896a66b60b0d0f89cb1bcc54f273fe6424 Mon Sep 17 00:00:00 2001 From: Paul K Date: Fri, 13 Jun 2025 01:46:39 +0200 Subject: [PATCH 16/27] add paper implementation for chat event --- .../paper/events/internal/PlayerEvents.kt | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt index ebcb7b40..e2d35285 100644 --- a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt +++ b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt @@ -2,9 +2,14 @@ package net.silkmc.silk.paper.events.internal import io.papermc.paper.adventure.AdventureComponent import io.papermc.paper.adventure.PaperAdventure +import io.papermc.paper.event.player.AsyncChatEvent +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer +import net.minecraft.network.chat.ChatType +import net.minecraft.network.chat.PlayerChatMessage import net.silkmc.silk.core.event.EventScopeProperty import net.silkmc.silk.core.event.PlayerEvents import net.silkmc.silk.paper.conversions.mcDamageSource +import net.silkmc.silk.paper.conversions.mcEntity import net.silkmc.silk.paper.conversions.mcPlayer import net.silkmc.silk.paper.events.listenSilk import org.bukkit.event.entity.PlayerDeathEvent @@ -39,4 +44,21 @@ fun PlayerEvents.setupPaper() { onDeath.invoke(event) it.deathMessage(PaperAdventure.asAdventure(event.deathMessage.get())) } + + listenSilk { + val message: PlayerChatMessage = PlayerChatMessage.unsigned( + it.player.uniqueId, + PlainTextComponentSerializer.plainText().serialize(it.message()) + ) + val bound: ChatType.Bound = ChatType.bind(ChatType.CHAT, it.player.mcEntity) + val event = PlayerEvents.PlayerChatEvent( + it.player.mcPlayer, + message, + bound + ) + + PlayerEvents.onChat.invoke(event) + it.isCancelled = event.isCancelled.get() + it.message(PaperAdventure.asAdventure(event.message.decoratedContent())) + } } From a85b90a3281cb4587ec9b4407dbae9044fd6a54f Mon Sep 17 00:00:00 2001 From: Paul K Date: Fri, 13 Jun 2025 01:54:46 +0200 Subject: [PATCH 17/27] refine chat event (paper) --- .../paper/events/internal/PlayerEvents.kt | 44 ++++++++++++++----- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt index e2d35285..ac1068e8 100644 --- a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt +++ b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt @@ -4,8 +4,7 @@ import io.papermc.paper.adventure.AdventureComponent import io.papermc.paper.adventure.PaperAdventure import io.papermc.paper.event.player.AsyncChatEvent import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer -import net.minecraft.network.chat.ChatType -import net.minecraft.network.chat.PlayerChatMessage +import net.minecraft.network.chat.* import net.silkmc.silk.core.event.EventScopeProperty import net.silkmc.silk.core.event.PlayerEvents import net.silkmc.silk.paper.conversions.mcDamageSource @@ -45,20 +44,41 @@ fun PlayerEvents.setupPaper() { it.deathMessage(PaperAdventure.asAdventure(event.deathMessage.get())) } - listenSilk { - val message: PlayerChatMessage = PlayerChatMessage.unsigned( - it.player.uniqueId, - PlainTextComponentSerializer.plainText().serialize(it.message()) + listenSilk { event -> + val message = event.player.mcPlayer.chatSession?.let { session -> + val link = SignedMessageLink.root(event.player.uniqueId, session.sessionId) + val signature = MessageSignature( + event.signedMessage().signature()?.bytes() ?: byteArrayOf() + ) + val body = SignedMessageBody( + event.signedMessage().message(), + event.signedMessage().timestamp(), + event.signedMessage().salt(), + LastSeenMessages.EMPTY + ) + val unsigned: Component = AdventureComponent(event.signedMessage().unsignedContent()) + val filter: FilterMask = FilterMask.PASS_THROUGH + PlayerChatMessage( + link, + signature, + body, + unsigned, + filter + ) + } ?: PlayerChatMessage.unsigned( + event.player.uniqueId, + PlainTextComponentSerializer.plainText().serialize(event.message()) ) - val bound: ChatType.Bound = ChatType.bind(ChatType.CHAT, it.player.mcEntity) - val event = PlayerEvents.PlayerChatEvent( - it.player.mcPlayer, + + val bound: ChatType.Bound = ChatType.bind(ChatType.CHAT, event.player.mcEntity) + val chatEvent = PlayerEvents.PlayerChatEvent( + event.player.mcPlayer, message, bound ) - PlayerEvents.onChat.invoke(event) - it.isCancelled = event.isCancelled.get() - it.message(PaperAdventure.asAdventure(event.message.decoratedContent())) + PlayerEvents.onChat.invoke(chatEvent) + event.isCancelled = chatEvent.isCancelled.get() + event.message(PaperAdventure.asAdventure(chatEvent.message.decoratedContent())) } } From ea1c662181922c1b960603a5f78142ffa7b9a1d9 Mon Sep 17 00:00:00 2001 From: Paul K Date: Fri, 13 Jun 2025 01:56:36 +0200 Subject: [PATCH 18/27] add nullable message signature to chat event --- .../net/silkmc/silk/paper/events/internal/PlayerEvents.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt index ac1068e8..654fde66 100644 --- a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt +++ b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt @@ -47,9 +47,9 @@ fun PlayerEvents.setupPaper() { listenSilk { event -> val message = event.player.mcPlayer.chatSession?.let { session -> val link = SignedMessageLink.root(event.player.uniqueId, session.sessionId) - val signature = MessageSignature( - event.signedMessage().signature()?.bytes() ?: byteArrayOf() - ) + val signature = event.signedMessage().signature()?.let { signature -> + MessageSignature(signature.bytes()) + } val body = SignedMessageBody( event.signedMessage().message(), event.signedMessage().timestamp(), From c1a6a891ee3d67d094d66bd1acad011fcfc8c10c Mon Sep 17 00:00:00 2001 From: Paul K Date: Fri, 13 Jun 2025 01:59:04 +0200 Subject: [PATCH 19/27] removed unused pos from EntityDeathEvent, corrected to EntityDeathEvent instead of PlayerDeathEvent --- .../silk/paper/events/internal/EntityEvents.kt | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/EntityEvents.kt b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/EntityEvents.kt index 9d283c2c..28e76611 100644 --- a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/EntityEvents.kt +++ b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/EntityEvents.kt @@ -1,20 +1,13 @@ package net.silkmc.silk.paper.events.internal -import net.minecraft.core.Holder -import net.minecraft.world.damagesource.DamageEffects -import net.minecraft.world.damagesource.DamageScaling -import net.minecraft.world.damagesource.DamageSource -import net.minecraft.world.damagesource.DamageType import net.minecraft.world.entity.LivingEntity -import net.minecraft.world.phys.Vec3 import net.silkmc.silk.core.event.EntityEvents import net.silkmc.silk.core.event.EventScopeProperty import net.silkmc.silk.paper.conversions.mcDamageSource import net.silkmc.silk.paper.conversions.mcEntity import net.silkmc.silk.paper.events.listenSilk -import org.bukkit.craftbukkit.damage.CraftDamageSource import org.bukkit.event.entity.EntityDamageEvent -import org.bukkit.event.entity.PlayerDeathEvent +import org.bukkit.event.entity.EntityDeathEvent fun EntityEvents.setupPaper() { listenSilk { paperEvent -> @@ -39,8 +32,7 @@ fun EntityEvents.setupPaper() { } } - listenSilk { - val pos = it.entity.location + listenSilk { val event = EntityEvents.EntityDeathEvent( it.entity.mcEntity as LivingEntity, @Suppress("UnstableApiUsage") From 90afef7ce2ff80d330cc583bc7cbfef14953343a Mon Sep 17 00:00:00 2001 From: Paul K Date: Sun, 22 Jun 2025 23:59:04 +0200 Subject: [PATCH 20/27] add modifiable messages to PlayerChatEvent --- .../core/mixin/server/MixinPlayerList.java | 42 +++++++++++++++---- .../silkmc/silk/core/event/PlayerEvents.kt | 3 +- .../paper/events/internal/PlayerEvents.kt | 3 +- .../silk/test/events/PlayerEventTest.kt | 4 ++ 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/silk-core/src/main/java/net/silkmc/silk/core/mixin/server/MixinPlayerList.java b/silk-core/src/main/java/net/silkmc/silk/core/mixin/server/MixinPlayerList.java index 8888501c..9c6c955a 100644 --- a/silk-core/src/main/java/net/silkmc/silk/core/mixin/server/MixinPlayerList.java +++ b/silk-core/src/main/java/net/silkmc/silk/core/mixin/server/MixinPlayerList.java @@ -3,9 +3,7 @@ import com.llamalad7.mixinextras.sugar.Local; import com.llamalad7.mixinextras.sugar.ref.LocalRef; import net.minecraft.network.Connection; -import net.minecraft.network.chat.ChatType; -import net.minecraft.network.chat.MutableComponent; -import net.minecraft.network.chat.PlayerChatMessage; +import net.minecraft.network.chat.*; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.network.CommonListenerCookie; @@ -19,6 +17,9 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import java.util.List; +import java.util.function.Predicate; + @Mixin(PlayerList.class) public class MixinPlayerList { @@ -26,6 +27,10 @@ public class MixinPlayerList { @Final private MinecraftServer server; + @Shadow + @Final + public List players; + @Inject( method = "placeNewPlayer", at = @At( @@ -43,7 +48,8 @@ private void onPreLogin(Connection connection, ServerPlayer player, CommonListen at = @At( value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastSystemMessage(Lnet/minecraft/network/chat/Component;Z)V", - shift = At.Shift.BEFORE) + shift = At.Shift.BEFORE + ) ) private void onPostLogin(Connection connection, ServerPlayer player, CommonListenerCookie commonListenerCookie, CallbackInfo ci, @Local LocalRef mutableComponent) { var event = new PlayerEvents.PostLoginEvent(player, new EventScopeProperty<>(mutableComponent.get())); @@ -52,17 +58,37 @@ private void onPostLogin(Connection connection, ServerPlayer player, CommonListe } @Inject( - method = "broadcastChatMessage(Lnet/minecraft/network/chat/PlayerChatMessage;Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/network/chat/ChatType$Bound;)V", + method = "broadcastChatMessage(Lnet/minecraft/network/chat/PlayerChatMessage;Ljava/util/function/Predicate;Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/network/chat/ChatType$Bound;)V", at = @At( - "HEAD" + value = "INVOKE", + target = "Ljava/util/List;iterator()Ljava/util/Iterator;" ), cancellable = true ) - private void broadcastChatMessage(PlayerChatMessage playerChatMessage, ServerPlayer serverPlayer, ChatType.Bound bound, CallbackInfo ci) { - var event = new PlayerEvents.PlayerChatEvent(serverPlayer, playerChatMessage, bound); + private void broadcastChatMessage(PlayerChatMessage playerChatMessage, Predicate predicate, ServerPlayer serverPlayer, ChatType.Bound bound, CallbackInfo ci, @Local LocalRef outgoingChatMessage) { + var event = new PlayerEvents.PlayerChatEvent(serverPlayer, playerChatMessage, new EventScopeProperty<>(outgoingChatMessage.get().content()), bound); PlayerEvents.INSTANCE.getOnChat().invoke(event); if (event.isCancelled().get()) { ci.cancel(); } + + var message = new PlayerChatMessage( + playerChatMessage.link(), + playerChatMessage.signature(), + new SignedMessageBody( + event.getMessage().get().getString(), + playerChatMessage.signedBody().timeStamp(), + playerChatMessage.salt(), + LastSeenMessages.EMPTY + ), + event.getChatMessage().unsignedContent(), + playerChatMessage.filterMask() + ); + + serverPlayer.sendSystemMessage(Component.literal("| ---- |")); + serverPlayer.sendSystemMessage(event.getMessage().get()); + serverPlayer.sendSystemMessage(message.decoratedContent()); + serverPlayer.sendSystemMessage(Component.literal("| ---- |")); + outgoingChatMessage.set(OutgoingChatMessage.create(message)); } } diff --git a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt index f67da5c7..da56ee86 100644 --- a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt +++ b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt @@ -88,7 +88,8 @@ object PlayerEvents { */ open class PlayerChatEvent( player: ServerPlayer, - val message: PlayerChatMessage, + val chatMessage: PlayerChatMessage, + var message: EventScopeProperty, val bound: ChatType.Bound, ) : PlayerEvent(player), Cancellable { diff --git a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt index 654fde66..a62350d6 100644 --- a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt +++ b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt @@ -74,11 +74,12 @@ fun PlayerEvents.setupPaper() { val chatEvent = PlayerEvents.PlayerChatEvent( event.player.mcPlayer, message, + EventScopeProperty(message.decoratedContent()), bound ) PlayerEvents.onChat.invoke(chatEvent) event.isCancelled = chatEvent.isCancelled.get() - event.message(PaperAdventure.asAdventure(chatEvent.message.decoratedContent())) + event.message(PaperAdventure.asAdventure(chatEvent.message.get())) } } diff --git a/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/PlayerEventTest.kt b/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/PlayerEventTest.kt index 69125cb1..76edf8d4 100644 --- a/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/PlayerEventTest.kt +++ b/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/PlayerEventTest.kt @@ -11,5 +11,9 @@ object PlayerEventTest { Events.Player.onDeath.listen { logInfo("received Player.onDeath event") } + + Events.Player.onChat.listen { + logInfo("received Player.onChat event") + } } } \ No newline at end of file From 9c38a748c18139731d23109c7cc66d3b7a0ab47f Mon Sep 17 00:00:00 2001 From: Paul K Date: Mon, 23 Jun 2025 00:00:43 +0200 Subject: [PATCH 21/27] removed debug messages --- .../net/silkmc/silk/core/mixin/server/MixinPlayerList.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/silk-core/src/main/java/net/silkmc/silk/core/mixin/server/MixinPlayerList.java b/silk-core/src/main/java/net/silkmc/silk/core/mixin/server/MixinPlayerList.java index 9c6c955a..8e453fb9 100644 --- a/silk-core/src/main/java/net/silkmc/silk/core/mixin/server/MixinPlayerList.java +++ b/silk-core/src/main/java/net/silkmc/silk/core/mixin/server/MixinPlayerList.java @@ -85,10 +85,6 @@ private void broadcastChatMessage(PlayerChatMessage playerChatMessage, Predicate playerChatMessage.filterMask() ); - serverPlayer.sendSystemMessage(Component.literal("| ---- |")); - serverPlayer.sendSystemMessage(event.getMessage().get()); - serverPlayer.sendSystemMessage(message.decoratedContent()); - serverPlayer.sendSystemMessage(Component.literal("| ---- |")); outgoingChatMessage.set(OutgoingChatMessage.create(message)); } } From 5cb462857d6f652234656d1ef0c61184d0851b00 Mon Sep 17 00:00:00 2001 From: Paul K Date: Mon, 23 Jun 2025 00:07:33 +0200 Subject: [PATCH 22/27] add events to test events --- .../net/silkmc/silk/test/events/PlayerEventTest.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/PlayerEventTest.kt b/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/PlayerEventTest.kt index 76edf8d4..87ca7016 100644 --- a/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/PlayerEventTest.kt +++ b/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/PlayerEventTest.kt @@ -15,5 +15,17 @@ object PlayerEventTest { Events.Player.onChat.listen { logInfo("received Player.onChat event") } + + Events.Player.preLogin.listen { + logInfo("received Player.preLogin event") + } + + Events.Player.preQuit.listen { + logInfo("received Player.preQuit event") + } + + Events.Player.postLogin.listen { + logInfo("received Player.postLogin event") + } } } \ No newline at end of file From 8fa8073036cac9723ef23d647c8df7de6dd0955c Mon Sep 17 00:00:00 2001 From: Paul K Date: Mon, 23 Jun 2025 13:24:33 +0200 Subject: [PATCH 23/27] removed shadowed variables added by accident --- .../silk/core/mixin/server/MixinPlayerList.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/silk-core/src/main/java/net/silkmc/silk/core/mixin/server/MixinPlayerList.java b/silk-core/src/main/java/net/silkmc/silk/core/mixin/server/MixinPlayerList.java index 8e453fb9..98bef830 100644 --- a/silk-core/src/main/java/net/silkmc/silk/core/mixin/server/MixinPlayerList.java +++ b/silk-core/src/main/java/net/silkmc/silk/core/mixin/server/MixinPlayerList.java @@ -4,33 +4,21 @@ import com.llamalad7.mixinextras.sugar.ref.LocalRef; import net.minecraft.network.Connection; import net.minecraft.network.chat.*; -import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.network.CommonListenerCookie; import net.minecraft.server.players.PlayerList; import net.silkmc.silk.core.event.EventScopeProperty; import net.silkmc.silk.core.event.PlayerEvents; -import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.List; import java.util.function.Predicate; @Mixin(PlayerList.class) public class MixinPlayerList { - @Shadow - @Final - private MinecraftServer server; - - @Shadow - @Final - public List players; - @Inject( method = "placeNewPlayer", at = @At( From b6371fb5f790254a62459f7bd6f01bf7d8cb796b Mon Sep 17 00:00:00 2001 From: Paul K Date: Mon, 23 Jun 2025 20:09:29 +0200 Subject: [PATCH 24/27] add EntitySpawnEvent --- .../core/mixin/level/MixinServerLevel.java | 35 +++++++++++++++++++ .../silkmc/silk/core/event/EntityEvents.kt | 10 ++++++ .../src/main/resources/silk-core.mixins.json | 1 + .../paper/events/internal/EntityEvents.kt | 11 ++++++ .../silk/test/events/EntityEventTest.kt | 4 +++ 5 files changed, 61 insertions(+) create mode 100644 silk-core/src/main/java/net/silkmc/silk/core/mixin/level/MixinServerLevel.java diff --git a/silk-core/src/main/java/net/silkmc/silk/core/mixin/level/MixinServerLevel.java b/silk-core/src/main/java/net/silkmc/silk/core/mixin/level/MixinServerLevel.java new file mode 100644 index 00000000..4a68df11 --- /dev/null +++ b/silk-core/src/main/java/net/silkmc/silk/core/mixin/level/MixinServerLevel.java @@ -0,0 +1,35 @@ +package net.silkmc.silk.core.mixin.level; + +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.silkmc.silk.core.event.EntityEvents; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(ServerLevel.class) +public class MixinServerLevel { + + @Inject( + method = "addEntity", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;addNewEntity(Lnet/minecraft/world/level/entity/EntityAccess;)Z", + shift = At.Shift.BEFORE + ), + cancellable = true + ) + private void addEntity(Entity entity, CallbackInfoReturnable cir) { + var event = new EntityEvents.EntitySpawnEvent( + entity + ); + + EntityEvents.INSTANCE.getOnSpawn().invoke(event); + + if (event.isCancelled().get()) { + cir.cancel(); + } + } + +} diff --git a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/EntityEvents.kt b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/EntityEvents.kt index 9e06f82b..0c943391 100644 --- a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/EntityEvents.kt +++ b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/EntityEvents.kt @@ -4,6 +4,7 @@ import net.minecraft.world.damagesource.DamageSource import net.minecraft.world.entity.Entity import net.minecraft.world.entity.LivingEntity import net.silkmc.silk.core.annotations.ExperimentalSilkApi +import net.silkmc.silk.core.event.EntityEvents.checkInvulnerability @ExperimentalSilkApi object EntityEvents { @@ -52,4 +53,13 @@ object EntityEvents { * Called when a [LivingEntity] dies. */ val onDeath = Event.syncAsync() + + open class EntitySpawnEvent( + entity: Entity, + ) : EntityEvent(entity), Cancellable { + + override val isCancelled: EventScopeProperty = EventScopeProperty(false) + } + + val onSpawn = Event.syncAsync() } diff --git a/silk-core/src/main/resources/silk-core.mixins.json b/silk-core/src/main/resources/silk-core.mixins.json index 460d3d30..e0dfee3d 100644 --- a/silk-core/src/main/resources/silk-core.mixins.json +++ b/silk-core/src/main/resources/silk-core.mixins.json @@ -6,6 +6,7 @@ "block.AbstractBlockAccessor", "entity.MixinEntity", "entity.MixinLivingEntity", + "level.MixinServerLevel", "player.MixinServerPlayer", "server.MixinMinecraftServer", "server.MixinPlayerList", diff --git a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/EntityEvents.kt b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/EntityEvents.kt index 28e76611..222c797c 100644 --- a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/EntityEvents.kt +++ b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/EntityEvents.kt @@ -8,6 +8,7 @@ import net.silkmc.silk.paper.conversions.mcEntity import net.silkmc.silk.paper.events.listenSilk import org.bukkit.event.entity.EntityDamageEvent import org.bukkit.event.entity.EntityDeathEvent +import org.bukkit.event.entity.EntitySpawnEvent fun EntityEvents.setupPaper() { listenSilk { paperEvent -> @@ -40,4 +41,14 @@ fun EntityEvents.setupPaper() { ) onDeath.invoke(event) } + + listenSilk { + val event = EntityEvents.EntitySpawnEvent( + it.entity.mcEntity + ) + + onSpawn.invoke(event) + + it.isCancelled = event.isCancelled.get() + } } diff --git a/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/EntityEventTest.kt b/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/EntityEventTest.kt index 0c9d1b14..f0fc980a 100644 --- a/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/EntityEventTest.kt +++ b/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/EntityEventTest.kt @@ -11,5 +11,9 @@ object EntityEventTest { Events.Entity.onDeath.listen { logInfo("received Entity.onDeath event") } + + Events.Entity.onSpawn.listen { + logInfo("received Entity.onSpawn event") + } } } \ No newline at end of file From 615eeedd91512d60bee1336ada7550663bbd5ae8 Mon Sep 17 00:00:00 2001 From: Paul K Date: Tue, 24 Jun 2025 22:43:06 +0200 Subject: [PATCH 25/27] add native block conversion --- .../silkmc/silk/paper/conversions/NativeMcConversions.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/conversions/NativeMcConversions.kt b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/conversions/NativeMcConversions.kt index 8dc8c7a1..b078b494 100644 --- a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/conversions/NativeMcConversions.kt +++ b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/conversions/NativeMcConversions.kt @@ -5,7 +5,9 @@ import net.minecraft.server.dedicated.DedicatedServer import net.minecraft.server.level.ServerEntity import net.minecraft.server.level.ServerPlayer import org.bukkit.Server +import org.bukkit.block.Block import org.bukkit.craftbukkit.CraftServer +import org.bukkit.craftbukkit.block.CraftBlock import org.bukkit.craftbukkit.damage.CraftDamageSource import org.bukkit.craftbukkit.entity.CraftEntity import org.bukkit.craftbukkit.entity.CraftPlayer @@ -37,4 +39,7 @@ val Entity.mcEntity: net.minecraft.world.entity.Entity * Converts a Paper [DamageSource] to a native [net.minecraft.world.damagesource.DamageSource]. */ val DamageSource.mcDamageSource: net.minecraft.world.damagesource.DamageSource - get() = (this as CraftDamageSource).handle \ No newline at end of file + get() = (this as CraftDamageSource).handle + +val Block.mcBlock: net.minecraft.world.level.block.Block? + get() = (this as CraftBlock).handle.getBlockIfLoaded(this.position) From 7ec20b8491804777bf6a3aee794020f8d40b675c Mon Sep 17 00:00:00 2001 From: Paul K Date: Tue, 24 Jun 2025 22:44:56 +0200 Subject: [PATCH 26/27] add documentation for conversion --- .../net/silkmc/silk/paper/conversions/NativeMcConversions.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/conversions/NativeMcConversions.kt b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/conversions/NativeMcConversions.kt index b078b494..2f367ee9 100644 --- a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/conversions/NativeMcConversions.kt +++ b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/conversions/NativeMcConversions.kt @@ -41,5 +41,8 @@ val Entity.mcEntity: net.minecraft.world.entity.Entity val DamageSource.mcDamageSource: net.minecraft.world.damagesource.DamageSource get() = (this as CraftDamageSource).handle +/** + * Converts a Paper [Block] to a native [net.minecraft.world.level.block.Block]. + */ val Block.mcBlock: net.minecraft.world.level.block.Block? get() = (this as CraftBlock).handle.getBlockIfLoaded(this.position) From 18b2346593b4c7765aea597a10d4d410532266f9 Mon Sep 17 00:00:00 2001 From: Paul K Date: Sun, 29 Jun 2025 00:41:54 +0200 Subject: [PATCH 27/27] add PlayerInteractEvent, still misses entity on fabric side --- .../silk/core/mixin/level/MixinBlockItem.java | 37 +++++++++++++++++++ .../silkmc/silk/core/event/PlayerEvents.kt | 15 ++++++++ .../src/main/resources/silk-core.mixins.json | 1 + .../paper/events/internal/PlayerEvents.kt | 31 ++++++++++++++-- 4 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 silk-core/src/main/java/net/silkmc/silk/core/mixin/level/MixinBlockItem.java diff --git a/silk-core/src/main/java/net/silkmc/silk/core/mixin/level/MixinBlockItem.java b/silk-core/src/main/java/net/silkmc/silk/core/mixin/level/MixinBlockItem.java new file mode 100644 index 00000000..59a17dbf --- /dev/null +++ b/silk-core/src/main/java/net/silkmc/silk/core/mixin/level/MixinBlockItem.java @@ -0,0 +1,37 @@ +package net.silkmc.silk.core.mixin.level; + +import net.minecraft.world.InteractionResult; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.context.UseOnContext; +import net.silkmc.silk.core.event.PlayerEvents; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(BlockItem.class) +public class MixinBlockItem { + + @Inject( + method = "useOn", + at = @At("HEAD"), + cancellable = true) + private void useOn(UseOnContext useOnContext, CallbackInfoReturnable cir) { + var player = useOnContext.getPlayer(); + + if (player == null) return; + + var event = new PlayerEvents.PlayerInteractEvent( + useOnContext.getPlayer(), + useOnContext.getHand(), + useOnContext.getLevel().getBlockState(useOnContext.getClickedPos()).getBlock(), + null + ); + + PlayerEvents.INSTANCE.getOnInteract().invoke(event); + + if (event.isCancelled().get()) { + cir.cancel(); + } + } +} diff --git a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt index da56ee86..632de8d1 100644 --- a/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt +++ b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt @@ -5,8 +5,11 @@ import net.minecraft.network.chat.ChatType import net.minecraft.network.chat.Component import net.minecraft.network.chat.PlayerChatMessage import net.minecraft.server.level.ServerPlayer +import net.minecraft.world.InteractionHand import net.minecraft.world.damagesource.DamageSource +import net.minecraft.world.entity.Entity import net.minecraft.world.entity.player.Player +import net.minecraft.world.level.block.Block import net.silkmc.silk.core.annotations.ExperimentalSilkApi import net.silkmc.silk.core.event.PlayerEvents.preQuit import net.silkmc.silk.core.event.PlayerEvents.quitDuringConfiguration @@ -98,4 +101,16 @@ object PlayerEvents { val onChat = Event.syncAsync() + open class PlayerInteractEvent( + player: Player, + val hand: InteractionHand, + val block: Block?, + val entity: Entity?, + ) : PlayerEvent(player), Cancellable { + + override val isCancelled: EventScopeProperty = EventScopeProperty(false) + } + + val onInteract = Event.syncAsync() + } diff --git a/silk-core/src/main/resources/silk-core.mixins.json b/silk-core/src/main/resources/silk-core.mixins.json index e0dfee3d..07bfdf71 100644 --- a/silk-core/src/main/resources/silk-core.mixins.json +++ b/silk-core/src/main/resources/silk-core.mixins.json @@ -6,6 +6,7 @@ "block.AbstractBlockAccessor", "entity.MixinEntity", "entity.MixinLivingEntity", + "level.MixinBlockItem", "level.MixinServerLevel", "player.MixinServerPlayer", "server.MixinMinecraftServer", diff --git a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt index a62350d6..90390884 100644 --- a/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt +++ b/silk-paper/src/main/kotlin/net/silkmc/silk/paper/events/internal/PlayerEvents.kt @@ -5,16 +5,17 @@ import io.papermc.paper.adventure.PaperAdventure import io.papermc.paper.event.player.AsyncChatEvent import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer import net.minecraft.network.chat.* +import net.minecraft.world.InteractionHand import net.silkmc.silk.core.event.EventScopeProperty import net.silkmc.silk.core.event.PlayerEvents +import net.silkmc.silk.paper.conversions.mcBlock import net.silkmc.silk.paper.conversions.mcDamageSource import net.silkmc.silk.paper.conversions.mcEntity import net.silkmc.silk.paper.conversions.mcPlayer import net.silkmc.silk.paper.events.listenSilk import org.bukkit.event.entity.PlayerDeathEvent -import org.bukkit.event.player.PlayerJoinEvent -import org.bukkit.event.player.PlayerLoginEvent -import org.bukkit.event.player.PlayerQuitEvent +import org.bukkit.event.player.* +import org.bukkit.inventory.EquipmentSlot fun PlayerEvents.setupPaper() { listenSilk { @@ -82,4 +83,28 @@ fun PlayerEvents.setupPaper() { event.isCancelled = chatEvent.isCancelled.get() event.message(PaperAdventure.asAdventure(chatEvent.message.get())) } + + listenSilk { event -> + val interactEvent = PlayerEvents.PlayerInteractEvent( + event.player.mcPlayer, + if (event.hand == EquipmentSlot.HAND) InteractionHand.MAIN_HAND else InteractionHand.OFF_HAND, + event.clickedBlock?.mcBlock, + null, + ) + + PlayerEvents.onInteract.invoke(interactEvent) + event.isCancelled = interactEvent.isCancelled.get() + } + + listenSilk { event -> + val interactEvent = PlayerEvents.PlayerInteractEvent( + event.player.mcPlayer, + if (event.hand == EquipmentSlot.HAND) InteractionHand.MAIN_HAND else InteractionHand.OFF_HAND, + null, + event.rightClicked.mcEntity + ) + + PlayerEvents.onInteract.invoke(interactEvent) + event.isCancelled = interactEvent.isCancelled.get() + } }