diff --git a/Obsidian/Client.cs b/Obsidian/Client.cs index 5dbdc808a..07532df28 100644 --- a/Obsidian/Client.cs +++ b/Obsidian/Client.cs @@ -302,7 +302,7 @@ public async Task StartConnectionAsync() case ClientState.Play: Debug.Assert(Player is not null); var packetReceivedEventArgs = new PacketReceivedEventArgs(Player, id, data); - await Server.Events.InvokePacketReceivedAsync(packetReceivedEventArgs); + await Server.Events.PacketReceived.InvokeAsync(packetReceivedEventArgs); if (!packetReceivedEventArgs.IsCancelled) { @@ -320,7 +320,7 @@ public async Task StartConnectionAsync() if (State == ClientState.Play) { Debug.Assert(Player is not null); - await Server.Events.InvokePlayerLeaveAsync(new PlayerLeaveEventArgs(Player, DateTimeOffset.Now)); + await Server.Events.PlayerLeave.InvokeAsync(new PlayerLeaveEventArgs(Player, DateTimeOffset.Now)); } Disconnected?.Invoke(this); @@ -331,7 +331,7 @@ private async Task HandleServerStatusRequestAsync() { var status = new ServerStatus(Server); - _ = await Server.Events.InvokeServerStatusRequest(new ServerStatusRequestEventArgs(Server, status)); + _ = await Server.Events.ServerStatusRequest.InvokeAsync(new ServerStatusRequestEventArgs(Server, status)); SendPacket(new RequestResponse(status)); } @@ -532,7 +532,7 @@ await QueuePacketAsync(new UpdateRecipeBookPacket await SendPlayerInfoAsync(); await Player.UpdateChunksAsync(distance: 7); await SendInfoAsync(); - await Server.Events.InvokePlayerJoinAsync(new PlayerJoinEventArgs(Player, DateTimeOffset.Now)); + await Server.Events.PlayerJoin.InvokeAsync(new PlayerJoinEventArgs(Player, DateTimeOffset.Now)); } #region Packet sending @@ -725,7 +725,7 @@ internal void SendPacket(IClientboundPacket packet) internal async Task QueuePacketAsync(IClientboundPacket packet) { - var args = await Server.Events.InvokeQueuePacketAsync(new QueuePacketEventArgs(this, packet)); + var args = await Server.Events.QueuePacket.InvokeAsync(new QueuePacketEventArgs(this, packet)); if (args.IsCancelled) { Logger.LogDebug("Packet {PacketId} was sent to the queue, however an event handler registered in {Name} has cancelled it.", args.Packet.Id, nameof(Server.Events)); diff --git a/Obsidian/Entities/Player.cs b/Obsidian/Entities/Player.cs index 2b672ed2a..39532b478 100644 --- a/Obsidian/Entities/Player.cs +++ b/Obsidian/Entities/Player.cs @@ -211,7 +211,7 @@ public async override Task TeleportAsync(VectorF pos) var tid = Globals.Random.Next(0, 999); - await client.Server.Events.InvokePlayerTeleportedAsync( + await client.Server.Events.PlayerTeleported.InvokeAsync( new PlayerTeleportEventArgs ( this, @@ -779,7 +779,7 @@ public async Task GrantPermissionAsync(string permissionNode) await this.SavePermsAsync(); if (result) - await this.client.Server.Events.InvokePermissionGrantedAsync(new PermissionGrantedEventArgs(this, permissionNode)); + await this.client.Server.Events.PermissionGranted.InvokeAsync(new PermissionGrantedEventArgs(this, permissionNode)); return result; } @@ -801,7 +801,7 @@ public async Task RevokePermissionAsync(string permissionNode) parent.Children.Remove(childToRemove); await this.SavePermsAsync(); - await this.client.Server.Events.InvokePermissionRevokedAsync(new PermissionRevokedEventArgs(this, permissionNode)); + await this.client.Server.Events.PermissionRevoked.InvokeAsync(new PermissionRevokedEventArgs(this, permissionNode)); return true; } diff --git a/Obsidian/Events/AsyncEvent.T.cs b/Obsidian/Events/AsyncEvent.T.cs index 600854b3f..4c8e41fd9 100644 --- a/Obsidian/Events/AsyncEvent.T.cs +++ b/Obsidian/Events/AsyncEvent.T.cs @@ -2,8 +2,6 @@ using System.Runtime.CompilerServices; using System.Threading; -#nullable enable - namespace Obsidian.Events; public sealed class AsyncEvent : IEventRegistry @@ -68,7 +66,7 @@ public async Task UnregisterAsync(Hook handler) semaphore.Release(); } - public async ValueTask InvokeAsync(T args) + public async ValueTask InvokeAsync(T args) { // This might block hook registration, but that is not expected to happen so often, // unlike invoking events. That's why it's better to just lock the collection instead @@ -89,6 +87,8 @@ public async ValueTask InvokeAsync(T args) } } semaphore.Release(); + + return args; } public bool TryRegisterEvent(MethodInfo method, object? instance, out Delegate? @delegate) diff --git a/Obsidian/Events/AsyncEvent.cs b/Obsidian/Events/AsyncEvent.cs index 2307de82d..8ad5260d8 100644 --- a/Obsidian/Events/AsyncEvent.cs +++ b/Obsidian/Events/AsyncEvent.cs @@ -3,8 +3,6 @@ using System.Runtime.InteropServices; using System.Threading; -#nullable enable - namespace Obsidian.Events; public sealed class AsyncEvent : IEventRegistry diff --git a/Obsidian/Events/EventArgs/BasePacketEventArgs.cs b/Obsidian/Events/EventArgs/BasePacketEventArgs.cs index e23d1024f..dc16db6f2 100644 --- a/Obsidian/Events/EventArgs/BasePacketEventArgs.cs +++ b/Obsidian/Events/EventArgs/BasePacketEventArgs.cs @@ -17,7 +17,7 @@ public class BasePacketEventArgs : AsyncEventArgs internal BasePacketEventArgs(Client client, IPacket packet) { - this.Client = client; - this.Packet = packet; + Client = client; + Packet = packet; } } diff --git a/Obsidian/Events/EventArgs/QueuePacketEventArgs.cs b/Obsidian/Events/EventArgs/QueuePacketEventArgs.cs index c56d0738c..8a3f6d910 100644 --- a/Obsidian/Events/EventArgs/QueuePacketEventArgs.cs +++ b/Obsidian/Events/EventArgs/QueuePacketEventArgs.cs @@ -8,7 +8,9 @@ public class QueuePacketEventArgs : BasePacketEventArgs, ICancellable /// public bool IsCancelled { get; private set; } - internal QueuePacketEventArgs(Client client, IPacket packet) : base(client, packet) { } + internal QueuePacketEventArgs(Client client, IPacket packet) : base(client, packet) + { + } /// public void Cancel() diff --git a/Obsidian/Events/IEventRegistry.cs b/Obsidian/Events/IEventRegistry.cs index 2d739156b..929ce42dc 100644 --- a/Obsidian/Events/IEventRegistry.cs +++ b/Obsidian/Events/IEventRegistry.cs @@ -1,7 +1,5 @@ using System.Reflection; -#nullable enable - namespace Obsidian.Events; public interface IEventRegistry @@ -9,6 +7,5 @@ public interface IEventRegistry public string? Name { get; } public bool TryRegisterEvent(MethodInfo method, object? instance, out Delegate? @delegate); - public bool UnregisterEvent(Delegate @delegate); } diff --git a/Obsidian/Events/MinecraftEventHandler.cs b/Obsidian/Events/MinecraftEventHandler.cs index 9ee92cf3c..1b4526da3 100644 --- a/Obsidian/Events/MinecraftEventHandler.cs +++ b/Obsidian/Events/MinecraftEventHandler.cs @@ -5,134 +5,28 @@ namespace Obsidian.Events; public class MinecraftEventHandler { - public AsyncEvent PacketReceived; - public AsyncEvent QueuePacket; - public AsyncEvent PlayerJoin; - public AsyncEvent PlayerLeave; - public AsyncEvent PlayerTeleported; - public AsyncEvent PermissionGranted; - public AsyncEvent PermissionRevoked; - public AsyncEvent ClickEvent; - public AsyncEvent BlockBreak; - public AsyncEvent IncomingChatMessage; - public AsyncEvent ServerStatusRequest; - public AsyncEvent EntityInteract; - public AsyncEvent PlayerAttackEntity; - public AsyncEvent PlayerInteract; - public AsyncEvent ContainerClosed; - public AsyncEvent ServerTick; + public AsyncEvent PacketReceived = new(nameof(PacketReceived), HandleException); + public AsyncEvent QueuePacket = new(nameof(QueuePacket), HandleException); + public AsyncEvent PlayerJoin = new(nameof(PlayerJoin), HandleException); + public AsyncEvent PlayerLeave = new(nameof(PlayerLeave), HandleException); + public AsyncEvent PlayerTeleported = new(nameof(PlayerTeleported), HandleException); + public AsyncEvent PermissionGranted = new(nameof(PermissionGranted), HandleException); + public AsyncEvent PermissionRevoked = new(nameof(PermissionRevoked), HandleException); + public AsyncEvent ContainerClick = new(nameof(ContainerClick), HandleException); + public AsyncEvent BlockBreak = new(nameof(BlockBreak), HandleException); + public AsyncEvent IncomingChatMessage = new(nameof(IncomingChatMessage), HandleException); + public AsyncEvent ServerStatusRequest = new(nameof(ServerStatusRequest), HandleException); + public AsyncEvent EntityInteract = new(nameof(EntityInteract), HandleException); + public AsyncEvent PlayerAttackEntity = new(nameof(PlayerAttackEntity), HandleException); + public AsyncEvent PlayerInteract = new(nameof(PlayerInteract), HandleException); + public AsyncEvent ContainerClosed = new(nameof(ContainerClosed), HandleException); + public AsyncEvent ServerTick = new(nameof(ServerTick), HandleException); - public MinecraftEventHandler() + private static void HandleException(AsyncEvent e, Exception exception) { - // Events that don't need additional arguments - PacketReceived = new("PacketReceived", HandleException); - QueuePacket = new("QueuePacket", HandleException); - - PlayerJoin = new("PlayerJoin", HandleException); - PlayerLeave = new("PlayerLeave", HandleException); - ServerTick = new("ServerTick", HandleException); - PermissionGranted = new("PermissionGranted", HandleException); - PermissionRevoked = new("PermissionRevoked", HandleException); - ClickEvent = new("ContainerClick", HandleException); - BlockBreak = new("BlockBreak", HandleException); - IncomingChatMessage = new("IncomingChatMessage", HandleException); - PlayerTeleported = new("PlayerTeleported", HandleException); - ServerStatusRequest = new("ServerStatusRequest", HandleException); - EntityInteract = new("EntityInteract", HandleException); - PlayerAttackEntity = new("PlayerAttackEntity", HandleException); - PlayerInteract = new("PlayerInteract", HandleException); - ContainerClosed = new("ContainerClosed", HandleException); - } - - private void HandleException(AsyncEvent e, Exception exception) - { - } - - private void HandleException(AsyncEvent e, Exception exception) - { - } - - internal async ValueTask InvokeContainerClosedAsync(ContainerClosedEventArgs eventArgs) - { - await ContainerClosed.InvokeAsync(eventArgs); - return eventArgs; - } - - internal async ValueTask InvokeQueuePacketAsync(QueuePacketEventArgs eventArgs) - { - await QueuePacket.InvokeAsync(eventArgs); - return eventArgs; - } - - internal async ValueTask InvokeContainerClickAsync(ContainerClickEventArgs eventArgs) - { - await ClickEvent.InvokeAsync(eventArgs); - return eventArgs; - } - - internal async ValueTask InvokeBlockBreakAsync(BlockBreakEventArgs eventArgs) - { - await BlockBreak.InvokeAsync(eventArgs); - return eventArgs; - } - - internal async ValueTask InvokePlayerInteractAsync(PlayerInteractEventArgs eventArgs) - { - await PlayerInteract.InvokeAsync(eventArgs); - return eventArgs; } - internal async ValueTask InvokeIncomingChatMessageAsync(IncomingChatMessageEventArgs eventArgs) - { - await IncomingChatMessage.InvokeAsync(eventArgs); - return eventArgs; - } - - internal async ValueTask InvokePlayerTeleportedAsync(PlayerTeleportEventArgs eventArgs) - { - await PlayerTeleported.InvokeAsync(eventArgs); - return eventArgs; - } - - internal async ValueTask InvokePermissionGrantedAsync(PermissionGrantedEventArgs eventArgs) - { - await PermissionGranted.InvokeAsync(eventArgs); - return eventArgs; - } - - internal async ValueTask InvokePermissionRevokedAsync(PermissionRevokedEventArgs eventArgs) - { - await PermissionRevoked.InvokeAsync(eventArgs); - return eventArgs; - } - - internal async ValueTask InvokeEntityInteractAsync(EntityInteractEventArgs eventArgs) - { - await EntityInteract.InvokeAsync(eventArgs); - return eventArgs; - } - - internal async ValueTask InvokePlayerAttackEntityAsync(PlayerAttackEntityEventArgs eventArgs) - { - await PlayerAttackEntity.InvokeAsync(eventArgs); - return eventArgs; - } - - internal ValueTask InvokePacketReceivedAsync(PacketReceivedEventArgs eventArgs) => - PacketReceived.InvokeAsync(eventArgs); - - internal ValueTask InvokePlayerJoinAsync(PlayerJoinEventArgs eventArgs) => - PlayerJoin.InvokeAsync(eventArgs); - - internal ValueTask InvokePlayerLeaveAsync(PlayerLeaveEventArgs eventArgs) => - PlayerLeave.InvokeAsync(eventArgs); - - internal ValueTask InvokeServerTickAsync() => - ServerTick.InvokeAsync(); - - internal async ValueTask InvokeServerStatusRequest(ServerStatusRequestEventArgs eventArgs) + private static void HandleException(AsyncEvent e, Exception exception) { - await ServerStatusRequest.InvokeAsync(eventArgs); - return eventArgs; } } diff --git a/Obsidian/Net/Packets/Play/CloseContainerPacket.cs b/Obsidian/Net/Packets/Play/CloseContainerPacket.cs index 6c7637792..239717daf 100644 --- a/Obsidian/Net/Packets/Play/CloseContainerPacket.cs +++ b/Obsidian/Net/Packets/Play/CloseContainerPacket.cs @@ -16,6 +16,6 @@ public async ValueTask HandleAsync(Server server, Player player) if (WindowId == 0) return; - await server.Events.InvokeContainerClosedAsync(new ContainerClosedEventArgs(player) { Container = player.OpenedContainer! }); + await server.Events.ContainerClosed.InvokeAsync(new ContainerClosedEventArgs(player) { Container = player.OpenedContainer! }); } } diff --git a/Obsidian/Net/Packets/Play/Serverbound/ClickContainerPacket.cs b/Obsidian/Net/Packets/Play/Serverbound/ClickContainerPacket.cs index c5de3c347..0faa537c1 100644 --- a/Obsidian/Net/Packets/Play/Serverbound/ClickContainerPacket.cs +++ b/Obsidian/Net/Packets/Play/Serverbound/ClickContainerPacket.cs @@ -271,7 +271,7 @@ private async Task HandleMouseClick(BaseContainer container, Server server, Play { if (!CarriedItem.IsAir) { - var @event = await server.Events.InvokeContainerClickAsync(new ContainerClickEventArgs(player, container, CarriedItem) + var @event = await server.Events.ContainerClick.InvokeAsync(new ContainerClickEventArgs(player, container, CarriedItem) { Slot = slot }); diff --git a/Obsidian/Net/Packets/Play/Serverbound/InteractPacket.cs b/Obsidian/Net/Packets/Play/Serverbound/InteractPacket.cs index cc768f0ed..7bc8eeb03 100644 --- a/Obsidian/Net/Packets/Play/Serverbound/InteractPacket.cs +++ b/Obsidian/Net/Packets/Play/Serverbound/InteractPacket.cs @@ -30,15 +30,15 @@ public async ValueTask HandleAsync(Server server, Player player) switch (Type) { case InteractionType.Interact: - await server.Events.InvokeEntityInteractAsync(new EntityInteractEventArgs(player, entity, server, Sneaking)); + await server.Events.EntityInteract.InvokeAsync(new EntityInteractEventArgs(player, entity, server, Sneaking)); break; case InteractionType.Attack: - await server.Events.InvokePlayerAttackEntityAsync(new PlayerAttackEntityEventArgs(player, entity, server, Sneaking)); + await server.Events.PlayerAttackEntity.InvokeAsync(new PlayerAttackEntityEventArgs(player, entity, server, Sneaking)); break; case InteractionType.InteractAt: - await server.Events.InvokeEntityInteractAsync(new EntityInteractEventArgs(player, entity, server, Hand, Target, Sneaking)); + await server.Events.EntityInteract.InvokeAsync(new EntityInteractEventArgs(player, entity, server, Hand, Target, Sneaking)); break; } } diff --git a/Obsidian/Net/Packets/Play/Serverbound/PlayerActionPacket.cs b/Obsidian/Net/Packets/Play/Serverbound/PlayerActionPacket.cs index c46a11e5c..fd8c9b083 100644 --- a/Obsidian/Net/Packets/Play/Serverbound/PlayerActionPacket.cs +++ b/Obsidian/Net/Packets/Play/Serverbound/PlayerActionPacket.cs @@ -36,7 +36,7 @@ public async ValueTask HandleAsync(Server server, Player player) SequenceID = Sequence }); - var blockBreakEvent = await server.Events.InvokeBlockBreakAsync(new BlockBreakEventArgs(server, player, block, Position)); + var blockBreakEvent = await server.Events.BlockBreak.InvokeAsync(new BlockBreakEventArgs(server, player, block, Position)); if (blockBreakEvent.Handled) return; } diff --git a/Obsidian/Net/Packets/Play/Serverbound/UseItemOnPacket.cs b/Obsidian/Net/Packets/Play/Serverbound/UseItemOnPacket.cs index 8239aa3ed..f5df34554 100644 --- a/Obsidian/Net/Packets/Play/Serverbound/UseItemOnPacket.cs +++ b/Obsidian/Net/Packets/Play/Serverbound/UseItemOnPacket.cs @@ -41,7 +41,7 @@ public async ValueTask HandleAsync(Server server, Player player) if (TagsRegistry.Blocks.PlayersCanInteract.Entries.Contains(interactedBlock.RegistryId) && !player.Sneaking) { - await server.Events.InvokePlayerInteractAsync(new PlayerInteractEventArgs(player) + await server.Events.PlayerInteract.InvokeAsync(new PlayerInteractEventArgs(player) { Item = currentItem, Block = interactedBlock, diff --git a/Obsidian/Net/Packets/Play/Serverbound/UseItemPacket.cs b/Obsidian/Net/Packets/Play/Serverbound/UseItemPacket.cs index f15be77bf..d8b7c79c3 100644 --- a/Obsidian/Net/Packets/Play/Serverbound/UseItemPacket.cs +++ b/Obsidian/Net/Packets/Play/Serverbound/UseItemPacket.cs @@ -16,7 +16,7 @@ public partial class UseItemPacket : IServerboundPacket public async ValueTask HandleAsync(Server server, Player player) { - await server.Events.InvokePlayerInteractAsync(new PlayerInteractEventArgs(player) + await server.Events.PlayerInteract.InvokeAsync(new PlayerInteractEventArgs(player) { Item = this.Hand == Hand.MainHand ? player.GetHeldItem() : player.GetOffHandItem(), Hand = this.Hand, diff --git a/Obsidian/Server.cs b/Obsidian/Server.cs index beca7328c..fc25445aa 100644 --- a/Obsidian/Server.cs +++ b/Obsidian/Server.cs @@ -443,7 +443,7 @@ internal async Task HandleIncomingMessageAsync(ChatMessagePacket packet, Client var format = "<{0}> {1}"; var message = packet.Message; - var chat = await Events.InvokeIncomingChatMessageAsync(new IncomingChatMessageEventArgs(source.Player, message, format)); + var chat = await Events.IncomingChatMessage.InvokeAsync(new IncomingChatMessageEventArgs(source.Player, message, format)); if (chat.IsCancelled) return; @@ -658,7 +658,7 @@ private async Task LoopAsync() { while (await timer.WaitForNextTickAsync()) { - await Events.InvokeServerTickAsync(); + await Events.ServerTick.InvokeAsync(); keepAliveTicks++; if (keepAliveTicks > (Config.KeepAliveInterval / 50)) // to clarify: one tick is 50 milliseconds. 50 * 200 = 10000 millis means 10 seconds