Skip to content

Commit

Permalink
Refactor server events (#360)
Browse files Browse the repository at this point in the history
  • Loading branch information
Seb-stian committed May 30, 2023
1 parent f7bf0c6 commit f5160ee
Show file tree
Hide file tree
Showing 15 changed files with 44 additions and 153 deletions.
10 changes: 5 additions & 5 deletions Obsidian/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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);
Expand All @@ -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));
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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));
Expand Down
6 changes: 3 additions & 3 deletions Obsidian/Entities/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -779,7 +779,7 @@ public async Task<bool> 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;
}
Expand All @@ -801,7 +801,7 @@ public async Task<bool> 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;
}
Expand Down
6 changes: 3 additions & 3 deletions Obsidian/Events/AsyncEvent.T.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
using System.Runtime.CompilerServices;
using System.Threading;

#nullable enable

namespace Obsidian.Events;

public sealed class AsyncEvent<T> : IEventRegistry
Expand Down Expand Up @@ -68,7 +66,7 @@ public async Task UnregisterAsync(Hook<T> handler)
semaphore.Release();
}

public async ValueTask InvokeAsync(T args)
public async ValueTask<T> 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
Expand All @@ -89,6 +87,8 @@ public async ValueTask InvokeAsync(T args)
}
}
semaphore.Release();

return args;
}

public bool TryRegisterEvent(MethodInfo method, object? instance, out Delegate? @delegate)
Expand Down
2 changes: 0 additions & 2 deletions Obsidian/Events/AsyncEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
using System.Runtime.InteropServices;
using System.Threading;

#nullable enable

namespace Obsidian.Events;

public sealed class AsyncEvent : IEventRegistry
Expand Down
4 changes: 2 additions & 2 deletions Obsidian/Events/EventArgs/BasePacketEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class BasePacketEventArgs : AsyncEventArgs

internal BasePacketEventArgs(Client client, IPacket packet)
{
this.Client = client;
this.Packet = packet;
Client = client;
Packet = packet;
}
}
4 changes: 3 additions & 1 deletion Obsidian/Events/EventArgs/QueuePacketEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ public class QueuePacketEventArgs : BasePacketEventArgs, ICancellable
/// <inheritdoc />
public bool IsCancelled { get; private set; }

internal QueuePacketEventArgs(Client client, IPacket packet) : base(client, packet) { }
internal QueuePacketEventArgs(Client client, IPacket packet) : base(client, packet)
{
}

/// <inheritdoc />
public void Cancel()
Expand Down
3 changes: 0 additions & 3 deletions Obsidian/Events/IEventRegistry.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
using System.Reflection;

#nullable enable

namespace Obsidian.Events;

public interface IEventRegistry
{
public string? Name { get; }

public bool TryRegisterEvent(MethodInfo method, object? instance, out Delegate? @delegate);

public bool UnregisterEvent(Delegate @delegate);
}
142 changes: 18 additions & 124 deletions Obsidian/Events/MinecraftEventHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,134 +5,28 @@ namespace Obsidian.Events;

public class MinecraftEventHandler
{
public AsyncEvent<PacketReceivedEventArgs> PacketReceived;
public AsyncEvent<QueuePacketEventArgs> QueuePacket;
public AsyncEvent<PlayerJoinEventArgs> PlayerJoin;
public AsyncEvent<PlayerLeaveEventArgs> PlayerLeave;
public AsyncEvent<PlayerTeleportEventArgs> PlayerTeleported;
public AsyncEvent<PermissionGrantedEventArgs> PermissionGranted;
public AsyncEvent<PermissionRevokedEventArgs> PermissionRevoked;
public AsyncEvent<ContainerClickEventArgs> ClickEvent;
public AsyncEvent<BlockBreakEventArgs> BlockBreak;
public AsyncEvent<IncomingChatMessageEventArgs> IncomingChatMessage;
public AsyncEvent<ServerStatusRequestEventArgs> ServerStatusRequest;
public AsyncEvent<EntityInteractEventArgs> EntityInteract;
public AsyncEvent<PlayerAttackEntityEventArgs> PlayerAttackEntity;
public AsyncEvent<PlayerInteractEventArgs> PlayerInteract;
public AsyncEvent<ContainerClosedEventArgs> ContainerClosed;
public AsyncEvent ServerTick;
public AsyncEvent<PacketReceivedEventArgs> PacketReceived = new(nameof(PacketReceived), HandleException);
public AsyncEvent<QueuePacketEventArgs> QueuePacket = new(nameof(QueuePacket), HandleException);
public AsyncEvent<PlayerJoinEventArgs> PlayerJoin = new(nameof(PlayerJoin), HandleException);
public AsyncEvent<PlayerLeaveEventArgs> PlayerLeave = new(nameof(PlayerLeave), HandleException);
public AsyncEvent<PlayerTeleportEventArgs> PlayerTeleported = new(nameof(PlayerTeleported), HandleException);
public AsyncEvent<PermissionGrantedEventArgs> PermissionGranted = new(nameof(PermissionGranted), HandleException);
public AsyncEvent<PermissionRevokedEventArgs> PermissionRevoked = new(nameof(PermissionRevoked), HandleException);
public AsyncEvent<ContainerClickEventArgs> ContainerClick = new(nameof(ContainerClick), HandleException);
public AsyncEvent<BlockBreakEventArgs> BlockBreak = new(nameof(BlockBreak), HandleException);
public AsyncEvent<IncomingChatMessageEventArgs> IncomingChatMessage = new(nameof(IncomingChatMessage), HandleException);
public AsyncEvent<ServerStatusRequestEventArgs> ServerStatusRequest = new(nameof(ServerStatusRequest), HandleException);
public AsyncEvent<EntityInteractEventArgs> EntityInteract = new(nameof(EntityInteract), HandleException);
public AsyncEvent<PlayerAttackEntityEventArgs> PlayerAttackEntity = new(nameof(PlayerAttackEntity), HandleException);
public AsyncEvent<PlayerInteractEventArgs> PlayerInteract = new(nameof(PlayerInteract), HandleException);
public AsyncEvent<ContainerClosedEventArgs> 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<T>(AsyncEvent<T> e, Exception exception)
{
}

internal async ValueTask<ContainerClosedEventArgs> InvokeContainerClosedAsync(ContainerClosedEventArgs eventArgs)
{
await ContainerClosed.InvokeAsync(eventArgs);
return eventArgs;
}

internal async ValueTask<QueuePacketEventArgs> InvokeQueuePacketAsync(QueuePacketEventArgs eventArgs)
{
await QueuePacket.InvokeAsync(eventArgs);
return eventArgs;
}

internal async ValueTask<ContainerClickEventArgs> InvokeContainerClickAsync(ContainerClickEventArgs eventArgs)
{
await ClickEvent.InvokeAsync(eventArgs);
return eventArgs;
}

internal async ValueTask<BlockBreakEventArgs> InvokeBlockBreakAsync(BlockBreakEventArgs eventArgs)
{
await BlockBreak.InvokeAsync(eventArgs);
return eventArgs;
}

internal async ValueTask<PlayerInteractEventArgs> InvokePlayerInteractAsync(PlayerInteractEventArgs eventArgs)
{
await PlayerInteract.InvokeAsync(eventArgs);
return eventArgs;
}

internal async ValueTask<IncomingChatMessageEventArgs> InvokeIncomingChatMessageAsync(IncomingChatMessageEventArgs eventArgs)
{
await IncomingChatMessage.InvokeAsync(eventArgs);
return eventArgs;
}

internal async ValueTask<PlayerTeleportEventArgs> InvokePlayerTeleportedAsync(PlayerTeleportEventArgs eventArgs)
{
await PlayerTeleported.InvokeAsync(eventArgs);
return eventArgs;
}

internal async ValueTask<PermissionGrantedEventArgs> InvokePermissionGrantedAsync(PermissionGrantedEventArgs eventArgs)
{
await PermissionGranted.InvokeAsync(eventArgs);
return eventArgs;
}

internal async ValueTask<PermissionRevokedEventArgs> InvokePermissionRevokedAsync(PermissionRevokedEventArgs eventArgs)
{
await PermissionRevoked.InvokeAsync(eventArgs);
return eventArgs;
}

internal async ValueTask<EntityInteractEventArgs> InvokeEntityInteractAsync(EntityInteractEventArgs eventArgs)
{
await EntityInteract.InvokeAsync(eventArgs);
return eventArgs;
}

internal async ValueTask<PlayerAttackEntityEventArgs> 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<ServerStatusRequestEventArgs> InvokeServerStatusRequest(ServerStatusRequestEventArgs eventArgs)
private static void HandleException<T>(AsyncEvent<T> e, Exception exception)
{
await ServerStatusRequest.InvokeAsync(eventArgs);
return eventArgs;
}
}
2 changes: 1 addition & 1 deletion Obsidian/Net/Packets/Play/CloseContainerPacket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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! });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
});
Expand Down
6 changes: 3 additions & 3 deletions Obsidian/Net/Packets/Play/Serverbound/InteractPacket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion Obsidian/Net/Packets/Play/Serverbound/UseItemOnPacket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion Obsidian/Net/Packets/Play/Serverbound/UseItemPacket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions Obsidian/Server.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand Down

0 comments on commit f5160ee

Please sign in to comment.