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/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/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/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/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..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 @@ -1,35 +1,78 @@ 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.*; 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; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import java.util.function.Predicate; + @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( + 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()); + } - @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 = "broadcastChatMessage(Lnet/minecraft/network/chat/PlayerChatMessage;Ljava/util/function/Predicate;Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/network/chat/ChatType$Bound;)V", + at = @At( + value = "INVOKE", + target = "Ljava/util/List;iterator()Ljava/util/Iterator;" + ), + cancellable = true + ) + 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() + ); + + outgoingChatMessage.set(OutgoingChatMessage.create(message)); + } } 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..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 { @@ -42,4 +43,23 @@ object EntityEvents { * event, since Minecraft performs its checks more than one time */ val checkInvulnerability = Event.onlySync() + + open class EntityDeathEvent( + entity: LivingEntity, + val damageSource: DamageSource, + ) : EntityEvent(entity) + + /** + * 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/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt b/silk-core/src/main/kotlin/net/silkmc/silk/core/event/PlayerEvents.kt index 41941a09..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 @@ -1,10 +1,19 @@ 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.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 +import net.silkmc.silk.core.event.PlayerEvents.quitDuringLogin @ExperimentalSilkApi object PlayerEvents { @@ -16,10 +25,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, @@ -60,4 +74,43 @@ object PlayerEvents { * @see preQuit */ val quitDuringConfiguration = Event.syncAsync() + + open class PlayerDeathEvent( + player: ServerPlayer, + val source: DamageSource, + var deathMessage: EventScopeProperty, + ) : PlayerEvent(player) + + /** + * Called when a [ServerPlayer] dies. + */ + val onDeath = Event.syncAsync() + + /** + * Called before a message from a player is broadcasted. + */ + open class PlayerChatEvent( + player: ServerPlayer, + val chatMessage: PlayerChatMessage, + var message: EventScopeProperty, + val bound: ChatType.Bound, + ) : PlayerEvent(player), Cancellable { + + override val isCancelled: EventScopeProperty = EventScopeProperty(false) + } + + 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 ec54db7e..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,9 @@ "block.AbstractBlockAccessor", "entity.MixinEntity", "entity.MixinLivingEntity", + "level.MixinBlockItem", + "level.MixinServerLevel", + "player.MixinServerPlayer", "server.MixinMinecraftServer", "server.MixinPlayerList", "server.MixinServerConfigurationPacketListenerImpl", 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..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 @@ -5,9 +5,13 @@ 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 +import org.bukkit.damage.DamageSource import org.bukkit.entity.Entity import org.bukkit.entity.Player @@ -29,3 +33,16 @@ 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 + +/** + * 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) 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..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 @@ -3,16 +3,18 @@ package net.silkmc.silk.paper.events.internal import net.minecraft.world.entity.LivingEntity 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.EntityDeathEvent +import org.bukkit.event.entity.EntitySpawnEvent 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, @@ -30,4 +32,23 @@ fun EntityEvents.setupPaper() { source = mcDamageSource)) } } + + listenSilk { + val event = EntityEvents.EntityDeathEvent( + it.entity.mcEntity as LivingEntity, + @Suppress("UnstableApiUsage") + it.damageSource.mcDamageSource + ) + onDeath.invoke(event) + } + + listenSilk { + val event = EntityEvents.EntitySpawnEvent( + it.entity.mcEntity + ) + + onSpawn.invoke(event) + + it.isCancelled = event.isCancelled.get() + } } 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..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 @@ -1,21 +1,110 @@ 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.* +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.player.PlayerJoinEvent -import org.bukkit.event.player.PlayerLoginEvent -import org.bukkit.event.player.PlayerQuitEvent +import org.bukkit.event.entity.PlayerDeathEvent +import org.bukkit.event.player.* +import org.bukkit.inventory.EquipmentSlot fun PlayerEvents.setupPaper() { listenSilk { 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()))) } + + listenSilk { + val event = PlayerEvents.PlayerDeathEvent( + it.player.mcPlayer, + @Suppress("UnstableApiUsage") + it.damageSource.mcDamageSource, + EventScopeProperty(AdventureComponent(it.deathMessage())) + ) + onDeath.invoke(event) + it.deathMessage(PaperAdventure.asAdventure(event.deathMessage.get())) + } + + listenSilk { event -> + val message = event.player.mcPlayer.chatSession?.let { session -> + val link = SignedMessageLink.root(event.player.uniqueId, session.sessionId) + val signature = event.signedMessage().signature()?.let { signature -> + MessageSignature(signature.bytes()) + } + 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, event.player.mcEntity) + 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.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() + } } 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..f0fc980a --- /dev/null +++ b/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/EntityEventTest.kt @@ -0,0 +1,19 @@ +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") + } + + Events.Entity.onSpawn.listen { + logInfo("received Entity.onSpawn 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..87ca7016 --- /dev/null +++ b/silk-testmod/src/main/kotlin/net/silkmc/silk/test/events/PlayerEventTest.kt @@ -0,0 +1,31 @@ +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") + } + + 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 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 {