From 3012c496f6ffe87aaf25d1deac57b73eb2c0737f Mon Sep 17 00:00:00 2001 From: Tides Date: Sat, 29 Apr 2023 03:11:21 -0400 Subject: [PATCH 1/8] Organize container events --- Obsidian.API/Events/CloseContainerEventArgs.cs | 9 +++++++++ Obsidian.API/Events/ContainerClickEventArgs.cs | 12 +++++------- Obsidian.API/Events/ContainerEventArgs.cs | 12 ++++++++++++ 3 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 Obsidian.API/Events/CloseContainerEventArgs.cs create mode 100644 Obsidian.API/Events/ContainerEventArgs.cs diff --git a/Obsidian.API/Events/CloseContainerEventArgs.cs b/Obsidian.API/Events/CloseContainerEventArgs.cs new file mode 100644 index 000000000..7058ec8e1 --- /dev/null +++ b/Obsidian.API/Events/CloseContainerEventArgs.cs @@ -0,0 +1,9 @@ +namespace Obsidian.API.Events; +public sealed class CloseContainerEventArgs : ContainerEventArgs, ICancellable +{ + public bool Cancel { get; set; } + + internal CloseContainerEventArgs(IPlayer player) : base(player) + { + } +} diff --git a/Obsidian.API/Events/ContainerClickEventArgs.cs b/Obsidian.API/Events/ContainerClickEventArgs.cs index 284eec1e1..c50830e43 100644 --- a/Obsidian.API/Events/ContainerClickEventArgs.cs +++ b/Obsidian.API/Events/ContainerClickEventArgs.cs @@ -1,12 +1,9 @@ -namespace Obsidian.API.Events; +using System.Diagnostics.CodeAnalysis; -public class ContainerClickEventArgs : PlayerEventArgs, ICancellable -{ - /// - /// Gets the clicked container - /// - public BaseContainer Container { get; } +namespace Obsidian.API.Events; +public sealed class ContainerClickEventArgs : ContainerEventArgs, ICancellable +{ /// /// Gets the current item that was clicked /// @@ -19,6 +16,7 @@ public class ContainerClickEventArgs : PlayerEventArgs, ICancellable public bool Cancel { get; set; } + [SetsRequiredMembers] internal ContainerClickEventArgs(IPlayer player, BaseContainer container, ItemStack item) : base(player) { this.Container = container; diff --git a/Obsidian.API/Events/ContainerEventArgs.cs b/Obsidian.API/Events/ContainerEventArgs.cs new file mode 100644 index 000000000..c39e4a65c --- /dev/null +++ b/Obsidian.API/Events/ContainerEventArgs.cs @@ -0,0 +1,12 @@ +using System.Diagnostics.CodeAnalysis; + +namespace Obsidian.API.Events; + +public class ContainerEventArgs : PlayerEventArgs +{ + public required BaseContainer Container { get; init; } + + protected ContainerEventArgs(IPlayer player) : base(player) + { + } +} From eeca699c1fb4ca7c16d94ebbe270ecaa659ed358 Mon Sep 17 00:00:00 2001 From: Tides Date: Sat, 29 Apr 2023 03:12:53 -0400 Subject: [PATCH 2/8] Better name :) --- Obsidian.API/Events/CloseContainerEventArgs.cs | 9 --------- Obsidian.API/Events/ContainerCloseEventArgs.cs | 9 +++++++++ 2 files changed, 9 insertions(+), 9 deletions(-) delete mode 100644 Obsidian.API/Events/CloseContainerEventArgs.cs create mode 100644 Obsidian.API/Events/ContainerCloseEventArgs.cs diff --git a/Obsidian.API/Events/CloseContainerEventArgs.cs b/Obsidian.API/Events/CloseContainerEventArgs.cs deleted file mode 100644 index 7058ec8e1..000000000 --- a/Obsidian.API/Events/CloseContainerEventArgs.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Obsidian.API.Events; -public sealed class CloseContainerEventArgs : ContainerEventArgs, ICancellable -{ - public bool Cancel { get; set; } - - internal CloseContainerEventArgs(IPlayer player) : base(player) - { - } -} diff --git a/Obsidian.API/Events/ContainerCloseEventArgs.cs b/Obsidian.API/Events/ContainerCloseEventArgs.cs new file mode 100644 index 000000000..fa19674b8 --- /dev/null +++ b/Obsidian.API/Events/ContainerCloseEventArgs.cs @@ -0,0 +1,9 @@ +namespace Obsidian.API.Events; +public sealed class ContainerCloseEventArgs : ContainerEventArgs, ICancellable +{ + public bool Cancel { get; set; } + + internal ContainerCloseEventArgs(IPlayer player) : base(player) + { + } +} From 0f68c6d3a8e2b04a51224c814b6059a2d2814815 Mon Sep 17 00:00:00 2001 From: Tides Date: Sat, 29 Apr 2023 03:14:03 -0400 Subject: [PATCH 3/8] Look --- Obsidian.API/Events/ContainerCloseEventArgs.cs | 9 --------- Obsidian.API/Events/ContainerClosedEventArgs.cs | 9 +++++++++ 2 files changed, 9 insertions(+), 9 deletions(-) delete mode 100644 Obsidian.API/Events/ContainerCloseEventArgs.cs create mode 100644 Obsidian.API/Events/ContainerClosedEventArgs.cs diff --git a/Obsidian.API/Events/ContainerCloseEventArgs.cs b/Obsidian.API/Events/ContainerCloseEventArgs.cs deleted file mode 100644 index fa19674b8..000000000 --- a/Obsidian.API/Events/ContainerCloseEventArgs.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Obsidian.API.Events; -public sealed class ContainerCloseEventArgs : ContainerEventArgs, ICancellable -{ - public bool Cancel { get; set; } - - internal ContainerCloseEventArgs(IPlayer player) : base(player) - { - } -} diff --git a/Obsidian.API/Events/ContainerClosedEventArgs.cs b/Obsidian.API/Events/ContainerClosedEventArgs.cs new file mode 100644 index 000000000..6cbf2d773 --- /dev/null +++ b/Obsidian.API/Events/ContainerClosedEventArgs.cs @@ -0,0 +1,9 @@ +namespace Obsidian.API.Events; +public sealed class ContainerClosedEventArgs : ContainerEventArgs, ICancellable +{ + public bool Cancel { get; set; } + + internal ContainerClosedEventArgs(IPlayer player) : base(player) + { + } +} From 0a3e4700138692be4cd6022718cae06f7923e185 Mon Sep 17 00:00:00 2001 From: Tides Date: Sat, 29 Apr 2023 03:32:08 -0400 Subject: [PATCH 4/8] Moved close container logic --- Obsidian/Entities/Player.cs | 2 +- Obsidian/Events/MinecraftEventHandler.cs | 8 ++ .../Net/Packets/Play/CloseContainerPacket.cs | 40 +--------- Obsidian/Server.Events.cs | 75 +++++++++++++++++++ Obsidian/Server.cs | 1 + 5 files changed, 88 insertions(+), 38 deletions(-) diff --git a/Obsidian/Entities/Player.cs b/Obsidian/Entities/Player.cs index ca3f268fd..32f6f1cb1 100644 --- a/Obsidian/Entities/Player.cs +++ b/Obsidian/Entities/Player.cs @@ -40,7 +40,7 @@ public sealed partial class Player : Living, IPlayer public Container Inventory { get; } public Container EnderInventory { get; } - public BaseContainer OpenedContainer { get; set; } + public BaseContainer? OpenedContainer { get; set; } public List SkinProperties { get; set; } = new(); diff --git a/Obsidian/Events/MinecraftEventHandler.cs b/Obsidian/Events/MinecraftEventHandler.cs index d7a230902..9ee92cf3c 100644 --- a/Obsidian/Events/MinecraftEventHandler.cs +++ b/Obsidian/Events/MinecraftEventHandler.cs @@ -19,6 +19,7 @@ public class MinecraftEventHandler public AsyncEvent EntityInteract; public AsyncEvent PlayerAttackEntity; public AsyncEvent PlayerInteract; + public AsyncEvent ContainerClosed; public AsyncEvent ServerTick; public MinecraftEventHandler() @@ -40,6 +41,7 @@ public MinecraftEventHandler() EntityInteract = new("EntityInteract", HandleException); PlayerAttackEntity = new("PlayerAttackEntity", HandleException); PlayerInteract = new("PlayerInteract", HandleException); + ContainerClosed = new("ContainerClosed", HandleException); } private void HandleException(AsyncEvent e, Exception exception) @@ -50,6 +52,12 @@ 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); diff --git a/Obsidian/Net/Packets/Play/CloseContainerPacket.cs b/Obsidian/Net/Packets/Play/CloseContainerPacket.cs index 0f225e9b9..310512189 100644 --- a/Obsidian/Net/Packets/Play/CloseContainerPacket.cs +++ b/Obsidian/Net/Packets/Play/CloseContainerPacket.cs @@ -1,6 +1,5 @@ -using Obsidian.API.Builders; +using Obsidian.API.Events; using Obsidian.Entities; -using Obsidian.Net.Packets.Play.Clientbound; using Obsidian.Serialization.Attributes; namespace Obsidian.Net.Packets.Play; @@ -14,43 +13,10 @@ public partial class CloseContainerPacket : IClientboundPacket, IServerboundPack public async ValueTask HandleAsync(Server server, Player player) { - if (WindowId == 0 || (player.OpenedContainer is not IBlockEntity tileEntity)) + if (WindowId == 0) return; - var position = tileEntity.BlockPosition; - - var block = await player.World.GetBlockAsync(position); - - if (block == null) - return; - - if (block.Is(Material.Chest)) - { - await player.client.QueuePacketAsync(new BlockActionPacket - { - Position = position, - ActionId = 1, - ActionParam = 0, - BlockType = block.BaseId - }); - - await player.SendSoundAsync(SoundEffectBuilder.Create(SoundId.BlockChestClose) - .WithSoundPosition(position.SoundPosition) - .Build()); - } - else if (block.Is(Material.EnderChest)) - { - await player.client.QueuePacketAsync(new BlockActionPacket - { - Position = position, - ActionId = 1, - ActionParam = 0, - BlockType = block.BaseId - }); - await player.SendSoundAsync(SoundEffectBuilder.Create(SoundId.BlockEnderChestClose) - .WithSoundPosition(position.SoundPosition) - .Build()); - } + await server.Events.InvokeContainerClosedAsync(new ContainerClosedEventArgs(player) { Container = player.OpenedContainer }); player.OpenedContainer = null; } diff --git a/Obsidian/Server.Events.cs b/Obsidian/Server.Events.cs index 881e9d5ff..91f3d90a2 100644 --- a/Obsidian/Server.Events.cs +++ b/Obsidian/Server.Events.cs @@ -20,6 +20,81 @@ private async Task PlayerAttack(PlayerAttackEntityEventArgs e) } } + private async Task OnContainerClosed(ContainerClosedEventArgs e) + { + if (e.Cancel || e.Container is not IBlockEntity blockEntity) + return; + + var position = blockEntity.BlockPosition; + var block = await e.Player.WorldLocation.GetBlockAsync(position); + + if (block is null) + return; + + var player = (e.Player as Player)!; + + switch (block.Material) + { + case Material.Chest: + { + await player.client.QueuePacketAsync(new BlockActionPacket + { + Position = position, + ActionId = 1, + ActionParam = 0, + BlockType = block.BaseId + }); + + await player.SendSoundAsync(SoundEffectBuilder.Create(SoundId.BlockChestClose) + .WithSoundPosition(position.SoundPosition) + .Build()); + + break; + } + case Material.EnderChest: + { + await player.client.QueuePacketAsync(new BlockActionPacket + { + Position = position, + ActionId = 1, + ActionParam = 0, + BlockType = block.BaseId + }); + + await player.SendSoundAsync(SoundEffectBuilder.Create(SoundId.BlockEnderChestClose) + .WithSoundPosition(position.SoundPosition) + .Build()); + break; + } + case Material.Barrel: + { + await player.SendSoundAsync(SoundEffectBuilder.Create(SoundId.BlockBarrelClose) + .WithSoundPosition(position.SoundPosition) + .Build()); + + break; + } + case Material.ShulkerBox: + { + await player.client.QueuePacketAsync(new BlockActionPacket + { + Position = position, + ActionId = 1, + ActionParam = 0, + BlockType = block.BaseId + }); + + await player.SendSoundAsync(SoundEffectBuilder.Create(SoundId.BlockShulkerBoxClose) + .WithSoundPosition(position.SoundPosition) + .Build()); + + break; + } + } + + player.OpenedContainer = null; + } + private async Task OnPlayerInteract(PlayerInteractEventArgs e) { var item = e.Item; diff --git a/Obsidian/Server.cs b/Obsidian/Server.cs index feaa3c645..1416aa1e3 100644 --- a/Obsidian/Server.cs +++ b/Obsidian/Server.cs @@ -136,6 +136,7 @@ public static string VERSION Events.PlayerJoin += OnPlayerJoin; Events.PlayerAttackEntity += PlayerAttack; Events.PlayerInteract += OnPlayerInteract; + Events.ContainerClosed += OnContainerClosed; PersistentDataPath = Path.Combine(ServerFolderPath, "persistentdata"); From 29980a404c78b69b12c222f593686626e86f5294 Mon Sep 17 00:00:00 2001 From: Tides Date: Sat, 29 Apr 2023 03:37:25 -0400 Subject: [PATCH 5/8] Update Server.Events.cs --- Obsidian/Server.Events.cs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/Obsidian/Server.Events.cs b/Obsidian/Server.Events.cs index 91f3d90a2..84f51f133 100644 --- a/Obsidian/Server.Events.cs +++ b/Obsidian/Server.Events.cs @@ -22,7 +22,19 @@ private async Task PlayerAttack(PlayerAttackEntityEventArgs e) private async Task OnContainerClosed(ContainerClosedEventArgs e) { - if (e.Cancel || e.Container is not IBlockEntity blockEntity) + var player = (e.Player as Player)!; + + if (e.Cancel) + { + //Resend open container again. + await player.OpenInventoryAsync(e.Container); + return; + } + + //Player successfully exited container + player.OpenedContainer = null; + + if (e.Container is not IBlockEntity blockEntity) return; var position = blockEntity.BlockPosition; @@ -31,8 +43,6 @@ private async Task OnContainerClosed(ContainerClosedEventArgs e) if (block is null) return; - var player = (e.Player as Player)!; - switch (block.Material) { case Material.Chest: @@ -66,7 +76,7 @@ await player.SendSoundAsync(SoundEffectBuilder.Create(SoundId.BlockEnderChestClo .Build()); break; } - case Material.Barrel: + case Material.Barrel://Barrels don't have a block action { await player.SendSoundAsync(SoundEffectBuilder.Create(SoundId.BlockBarrelClose) .WithSoundPosition(position.SoundPosition) @@ -91,8 +101,6 @@ await player.SendSoundAsync(SoundEffectBuilder.Create(SoundId.BlockShulkerBoxClo break; } } - - player.OpenedContainer = null; } private async Task OnPlayerInteract(PlayerInteractEventArgs e) From 507a75d961f90ffffbc80a4357282a2ee129a777 Mon Sep 17 00:00:00 2001 From: Tides Date: Sat, 29 Apr 2023 03:40:11 -0400 Subject: [PATCH 6/8] Update CloseContainerPacket.cs --- Obsidian/Net/Packets/Play/CloseContainerPacket.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Obsidian/Net/Packets/Play/CloseContainerPacket.cs b/Obsidian/Net/Packets/Play/CloseContainerPacket.cs index 310512189..6c7637792 100644 --- a/Obsidian/Net/Packets/Play/CloseContainerPacket.cs +++ b/Obsidian/Net/Packets/Play/CloseContainerPacket.cs @@ -16,8 +16,6 @@ public async ValueTask HandleAsync(Server server, Player player) if (WindowId == 0) return; - await server.Events.InvokeContainerClosedAsync(new ContainerClosedEventArgs(player) { Container = player.OpenedContainer }); - - player.OpenedContainer = null; + await server.Events.InvokeContainerClosedAsync(new ContainerClosedEventArgs(player) { Container = player.OpenedContainer! }); } } From 406ac75a49df2bced5b4faf5fdf1bbdf40b6701a Mon Sep 17 00:00:00 2001 From: Tides Date: Sat, 29 Apr 2023 03:41:51 -0400 Subject: [PATCH 7/8] Don't re-open container on event cancel --- Obsidian/Server.Events.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Obsidian/Server.Events.cs b/Obsidian/Server.Events.cs index 84f51f133..192d3029f 100644 --- a/Obsidian/Server.Events.cs +++ b/Obsidian/Server.Events.cs @@ -22,14 +22,10 @@ private async Task PlayerAttack(PlayerAttackEntityEventArgs e) private async Task OnContainerClosed(ContainerClosedEventArgs e) { - var player = (e.Player as Player)!; - if (e.Cancel) - { - //Resend open container again. - await player.OpenInventoryAsync(e.Container); return; - } + + var player = (e.Player as Player)!; //Player successfully exited container player.OpenedContainer = null; From 7f786cb38602ff5fec040f5463d9d19964d6d248 Mon Sep 17 00:00:00 2001 From: Tides Date: Wed, 10 May 2023 23:20:36 -0400 Subject: [PATCH 8/8] Fix broken stuff --- Obsidian.API/Events/ContainerClosedEventArgs.cs | 4 +++- Obsidian.API/Events/ICancellable.cs | 2 +- Obsidian/Server.Events.cs | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Obsidian.API/Events/ContainerClosedEventArgs.cs b/Obsidian.API/Events/ContainerClosedEventArgs.cs index 6cbf2d773..464018723 100644 --- a/Obsidian.API/Events/ContainerClosedEventArgs.cs +++ b/Obsidian.API/Events/ContainerClosedEventArgs.cs @@ -1,9 +1,11 @@ namespace Obsidian.API.Events; public sealed class ContainerClosedEventArgs : ContainerEventArgs, ICancellable { - public bool Cancel { get; set; } + public bool IsCancelled { get; private set; } internal ContainerClosedEventArgs(IPlayer player) : base(player) { } + + public void Cancel() => this.IsCancelled = true; } diff --git a/Obsidian.API/Events/ICancellable.cs b/Obsidian.API/Events/ICancellable.cs index 9592e6776..b96539b6f 100644 --- a/Obsidian.API/Events/ICancellable.cs +++ b/Obsidian.API/Events/ICancellable.cs @@ -13,6 +13,6 @@ public interface ICancellable /// /// Sets a flag which prevents default (vanilla) behavior from executing. /// - /// This flag only affects vanilla behavior. If you wish to prevent other handlers from running, see . + /// This flag only affects vanilla behavior. If you wish to prevent other handlers from running, see . public void Cancel(); } diff --git a/Obsidian/Server.Events.cs b/Obsidian/Server.Events.cs index 609a314ed..ec81d99da 100644 --- a/Obsidian/Server.Events.cs +++ b/Obsidian/Server.Events.cs @@ -22,7 +22,7 @@ private async Task PlayerAttack(PlayerAttackEntityEventArgs e) private async Task OnContainerClosed(ContainerClosedEventArgs e) { - if (e.Cancel) + if (e.IsCancelled) return; var player = (e.Player as Player)!;