From e3bfe1faa1a851c3b024051524040ab9f4e343bb Mon Sep 17 00:00:00 2001 From: Spi3lot Date: Sun, 29 Mar 2026 22:46:24 +0200 Subject: [PATCH 1/9] Update dotnet.yml --- .github/workflows/dotnet.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 98d1240..4772bc9 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -5,9 +5,9 @@ name: .NET on: push: - branches: [ "*" ] + branches: [ "main" ] pull_request: - branches: [ "*" ] + branches: [ "main" ] jobs: build: From 9d6b85b92c12fd9f2b19f1b7f5feee557f051a54 Mon Sep 17 00:00:00 2001 From: Spi3lot Date: Sun, 29 Mar 2026 22:46:55 +0200 Subject: [PATCH 2/9] Add TODO --- .../Protocol/Packets/Login/Serverbound/HelloPacket.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Sharpmine.Server/Protocol/Packets/Login/Serverbound/HelloPacket.cs b/Sharpmine.Server/Protocol/Packets/Login/Serverbound/HelloPacket.cs index e99ad7e..f0874c5 100644 --- a/Sharpmine.Server/Protocol/Packets/Login/Serverbound/HelloPacket.cs +++ b/Sharpmine.Server/Protocol/Packets/Login/Serverbound/HelloPacket.cs @@ -29,6 +29,7 @@ public Task ProcessAsync( BinaryWriter writer, CancellationToken cancellationToken) { + // TODO var profile = new GameProfile( Uuid, Name, From 6a088b417873fca57e698bb05b903e556ea48fd8 Mon Sep 17 00:00:00 2001 From: Spi3lot Date: Sun, 29 Mar 2026 22:47:33 +0200 Subject: [PATCH 3/9] - Add both clientbound and serverbound KeepAlivePackets - Implement clientbound KeepAlivepacket --- .../Clientbound/KeepAlivePacket.cs | 15 +++++++++++ .../Serverbound/KeepAlivePacket.cs | 26 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 Sharpmine.Server/Protocol/Packets/Configuration/Clientbound/KeepAlivePacket.cs create mode 100644 Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/KeepAlivePacket.cs diff --git a/Sharpmine.Server/Protocol/Packets/Configuration/Clientbound/KeepAlivePacket.cs b/Sharpmine.Server/Protocol/Packets/Configuration/Clientbound/KeepAlivePacket.cs new file mode 100644 index 0000000..abd13b0 --- /dev/null +++ b/Sharpmine.Server/Protocol/Packets/Configuration/Clientbound/KeepAlivePacket.cs @@ -0,0 +1,15 @@ +namespace Sharpmine.Server.Protocol.Packets.Configuration.Clientbound; + +public partial record KeepAlivePacket(long KeepAliveId) +{ + + public Task SerializeContentAsync( + Stream stream, + BinaryWriter writer, + CancellationToken cancellationToken) + { + writer.Write(KeepAliveId); + return Task.CompletedTask; + } + +} diff --git a/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/KeepAlivePacket.cs b/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/KeepAlivePacket.cs new file mode 100644 index 0000000..9204afa --- /dev/null +++ b/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/KeepAlivePacket.cs @@ -0,0 +1,26 @@ +namespace Sharpmine.Server.Protocol.Packets.Configuration.Serverbound; + +public partial record KeepAlivePacket +{ + + public long KeepAliveId { get; set; } + + public Task DeserializeContentAsync( + NetworkStream stream, + BinaryReader reader, + CancellationToken cancellationToken) + { + KeepAliveId = reader.ReadInt64(); + return Task.CompletedTask; + } + + public Task ProcessAsync(ClientHandler handler, + NetworkStream stream, + BinaryReader reader, + BinaryWriter writer, + CancellationToken cancellationToken) + { + throw new NotImplementedException("Check whether the client responded with the same packet"); + } + +} From 2d1a5656d83d8cdbf004b5b555d0c0aef73ba76e Mon Sep 17 00:00:00 2001 From: Spi3lot Date: Sun, 29 Mar 2026 22:49:57 +0200 Subject: [PATCH 4/9] - Add Status property to ServerService - Pass ServerService to ClientHandler - Make use of the above points in StatusRequestPacket - Refactor ServerStatus --- Sharpmine.Server/Protocol/ClientHandler.cs | 3 ++ .../Protocol/ClientHandlerFactory.cs | 4 +- .../Protocol/Packets/Status/ServerStatus.cs | 39 +++++++++---------- .../Status/Serverbound/StatusRequestPacket.cs | 11 ++---- Sharpmine.Server/ServerService.cs | 9 ++++- 5 files changed, 36 insertions(+), 30 deletions(-) diff --git a/Sharpmine.Server/Protocol/ClientHandler.cs b/Sharpmine.Server/Protocol/ClientHandler.cs index 5fbf97c..091b389 100644 --- a/Sharpmine.Server/Protocol/ClientHandler.cs +++ b/Sharpmine.Server/Protocol/ClientHandler.cs @@ -8,6 +8,7 @@ namespace Sharpmine.Server.Protocol; public sealed partial class ClientHandler( TcpClient client, + ServerService server, ILogger logger) : IAsyncDisposable { @@ -23,6 +24,8 @@ public sealed partial class ClientHandler( public TcpClient Client { get; } = client; + public ServerService Server { get; } = server; + public PacketTransceiver PacketTransceiver { get; internal set; } = null!; public ProtocolState ProtocolState { get; private set; } = ProtocolState.Handshake; diff --git a/Sharpmine.Server/Protocol/ClientHandlerFactory.cs b/Sharpmine.Server/Protocol/ClientHandlerFactory.cs index 6b03fa1..f8e5c54 100644 --- a/Sharpmine.Server/Protocol/ClientHandlerFactory.cs +++ b/Sharpmine.Server/Protocol/ClientHandlerFactory.cs @@ -7,12 +7,12 @@ namespace Sharpmine.Server.Protocol; public class ClientHandlerFactory(ILoggerFactory loggerFactory) { - public ClientHandler Create(TcpClient client) + public ClientHandler Create(TcpClient client, ServerService server) { var clientHandlerLogger = loggerFactory.CreateLogger(); var packetLogger = loggerFactory.CreateLogger(); var packetTransceiver = new PacketTransceiver(packetLogger); - var handler = new ClientHandler(client, clientHandlerLogger); + var handler = new ClientHandler(client, server, clientHandlerLogger); packetTransceiver.Handler = handler; handler.PacketTransceiver = packetTransceiver; return handler; diff --git a/Sharpmine.Server/Protocol/Packets/Status/ServerStatus.cs b/Sharpmine.Server/Protocol/Packets/Status/ServerStatus.cs index 0452b78..8c024d9 100644 --- a/Sharpmine.Server/Protocol/Packets/Status/ServerStatus.cs +++ b/Sharpmine.Server/Protocol/Packets/Status/ServerStatus.cs @@ -1,29 +1,28 @@ -namespace Sharpmine.Server.Protocol.Packets.Status; +using System.Text; -public record ServerStatus -{ - - public required StatusVersion Version { get; init; } - - public StatusPlayers? Players { get; init; } - - public StatusDescription? Description { get; init; } - - public string? Favicon { get; init; } - - public bool EnforcesSecureChat { get; init; } +namespace Sharpmine.Server.Protocol.Packets.Status; - public record StatusVersion(string Name, int Protocol); +public record ServerStatus( + StatusVersion Version, + StatusPlayers? Players = null, + StatusDescription? Description = null, + string? Favicon = null, + bool EnforcesSecureChat = false) +{ - public record StatusPlayers(int Max, int Online) + public override string ToString() { + var builder = new StringBuilder(); + (this with { Favicon = null }).PrintMembers(builder); + return builder.ToString(); + } - public List Sample { get; init; } = []; +} - public record Player(string Name, Guid Id); +public record StatusVersion(string Name, int? Protocol = null); - } +public record StatusPlayers(int Max, int Online, List? Sample = null); - public record StatusDescription(string Text); +public record StatusPlayer(string Name, Guid Id); -} +public record StatusDescription(string Text); diff --git a/Sharpmine.Server/Protocol/Packets/Status/Serverbound/StatusRequestPacket.cs b/Sharpmine.Server/Protocol/Packets/Status/Serverbound/StatusRequestPacket.cs index 27d5853..f928667 100644 --- a/Sharpmine.Server/Protocol/Packets/Status/Serverbound/StatusRequestPacket.cs +++ b/Sharpmine.Server/Protocol/Packets/Status/Serverbound/StatusRequestPacket.cs @@ -17,19 +17,16 @@ public Task ProcessAsync( BinaryWriter writer, CancellationToken cancellationToken) { - var status = new ServerStatus + var status = handler.Server.Status with { - Version = new ServerStatus.StatusVersion("1.21.10", 773), - Players = new ServerStatus.StatusPlayers(1337, 2) + Players = new StatusPlayers(1337, 2) { Sample = [ - new ServerStatus.StatusPlayers.Player("Deswegen", Guid.Parse("7e5abf92-0bf6-4b21-8c12-ad9a32720f3b")), - new ServerStatus.StatusPlayers.Player("Yes_Mc", Guid.Parse("ae2f02a6-001e-46b6-a659-5e016cf6e8e5")) + new StatusPlayer("Deswegen", Guid.Parse("7e5abf92-0bf6-4b21-8c12-ad9a32720f3b")), + new StatusPlayer("Yes_Mc", Guid.Parse("ae2f02a6-001e-46b6-a659-5e016cf6e8e5")) ], }, - Description = new ServerStatus.StatusDescription("Heya"), - Favicon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAApgAAAKYB3X3/OAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAANCSURBVEiJtZZPbBtFFMZ/M7ubXdtdb1xSFyeilBapySVU8h8OoFaooFSqiihIVIpQBKci6KEg9Q6H9kovIHoCIVQJJCKE1ENFjnAgcaSGC6rEnxBwA04Tx43t2FnvDAfjkNibxgHxnWb2e/u992bee7tCa00YFsffekFY+nUzFtjW0LrvjRXrCDIAaPLlW0nHL0SsZtVoaF98mLrx3pdhOqLtYPHChahZcYYO7KvPFxvRl5XPp1sN3adWiD1ZAqD6XYK1b/dvE5IWryTt2udLFedwc1+9kLp+vbbpoDh+6TklxBeAi9TL0taeWpdmZzQDry0AcO+jQ12RyohqqoYoo8RDwJrU+qXkjWtfi8Xxt58BdQuwQs9qC/afLwCw8tnQbqYAPsgxE1S6F3EAIXux2oQFKm0ihMsOF71dHYx+f3NND68ghCu1YIoePPQN1pGRABkJ6Bus96CutRZMydTl+TvuiRW1m3n0eDl0vRPcEysqdXn+jsQPsrHMquGeXEaY4Yk4wxWcY5V/9scqOMOVUFthatyTy8QyqwZ+kDURKoMWxNKr2EeqVKcTNOajqKoBgOE28U4tdQl5p5bwCw7BWquaZSzAPlwjlithJtp3pTImSqQRrb2Z8PHGigD4RZuNX6JYj6wj7O4TFLbCO/Mn/m8R+h6rYSUb3ekokRY6f/YukArN979jcW+V/S8g0eT/N3VN3kTqWbQ428m9/8k0P/1aIhF36PccEl6EhOcAUCrXKZXXWS3XKd2vc/TRBG9O5ELC17MmWubD2nKhUKZa26Ba2+D3P+4/MNCFwg59oWVeYhkzgN/JDR8deKBoD7Y+ljEjGZ0sosXVTvbc6RHirr2reNy1OXd6pJsQ+gqjk8VWFYmHrwBzW/n+uMPFiRwHB2I7ih8ciHFxIkd/3Omk5tCDV1t+2nNu5sxxpDFNx+huNhVT3/zMDz8usXC3ddaHBj1GHj/As08fwTS7Kt1HBTmyN29vdwAw+/wbwLVOJ3uAD1wi/dUH7Qei66PfyuRj4Ik9is+hglfbkbfR3cnZm7chlUWLdwmprtCohX4HUtlOcQjLYCu+fzGJH2QRKvP3UNz8bWk1qMxjGTOMThZ3kvgLI5AzFfo379UAAAAASUVORK5CYII=", }; var response = new StatusResponsePacket(status); diff --git a/Sharpmine.Server/ServerService.cs b/Sharpmine.Server/ServerService.cs index 1d36a77..0ffec9a 100644 --- a/Sharpmine.Server/ServerService.cs +++ b/Sharpmine.Server/ServerService.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging; using Sharpmine.Server.Protocol; +using Sharpmine.Server.Protocol.Packets.Status; namespace Sharpmine.Server; @@ -21,6 +22,12 @@ public partial class ServerService( public ConcurrentDictionary ActiveClientHandlers { get; } = []; + // TODO: Read from server properties + public ServerStatus Status { get; } = new( + Version: new StatusVersion("1.21.10", 773), + Description: new StatusDescription("Heya"), + Favicon: "data:image/png;base64,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"); + protected override async Task ExecuteAsync(CancellationToken stoppingToken) { using var lobby = new SemaphoreSlim(2, 2); // TODO: Use MaxPlayerCount from properties @@ -63,7 +70,7 @@ private void HandleTcpClientAsync(TcpClient client, SemaphoreSlim lobby, Cancell { try { - var handler = clientHandlerFactory.Create(client); + var handler = clientHandlerFactory.Create(client, this); SetupHandler(handler); await handler.HandleAsync(stoppingToken); } From d1a65c42cdb35e061cc7e83892c9ed6bcd326e98 Mon Sep 17 00:00:00 2001 From: Spi3lot Date: Sun, 29 Mar 2026 22:51:43 +0200 Subject: [PATCH 5/9] - Implement ClientInformationPacket(s) - Add Information property to ClientHandler - Make source gen add 'new' keyword to State and Id of IPacket for packet inheritance to work without warnings --- Sharpmine.Gen/PacketGenerator.cs | 9 ++++++--- Sharpmine.Server/Protocol/ClientHandler.cs | 3 +++ .../Configuration/Serverbound/ClientInformationPacket.cs | 3 ++- .../Packets/Play/Serverbound/ClientInformationPacket.cs | 3 +++ 4 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 Sharpmine.Server/Protocol/Packets/Play/Serverbound/ClientInformationPacket.cs diff --git a/Sharpmine.Gen/PacketGenerator.cs b/Sharpmine.Gen/PacketGenerator.cs index 2ed21ba..243435a 100644 --- a/Sharpmine.Gen/PacketGenerator.cs +++ b/Sharpmine.Gen/PacketGenerator.cs @@ -96,8 +96,8 @@ namespace {{BaseNamespace}}.{{stateName}}.{{directionName}}; public partial record {{className}} : {{interfaceName}} { - public ProtocolState State => ProtocolState.{{stateName}}; - public int Id => 0x{{id:X2}}; + public new ProtocolState State => ProtocolState.{{stateName}}; + public new int Id => 0x{{id:X2}}; } """; @@ -118,7 +118,10 @@ namespace {{BaseNamespace}}; public static class ServerboundPacketRegistry { - public static bool TryCreatePacket(ProtocolState state, int id, [NotNullWhen(true)] out IServerboundPacket? packet) + public static bool TryCreatePacket( + ProtocolState state, + int id, + [NotNullWhen(true)] out IServerboundPacket? packet) { packet = (state, id) switch { diff --git a/Sharpmine.Server/Protocol/ClientHandler.cs b/Sharpmine.Server/Protocol/ClientHandler.cs index 091b389..79a1bf0 100644 --- a/Sharpmine.Server/Protocol/ClientHandler.cs +++ b/Sharpmine.Server/Protocol/ClientHandler.cs @@ -3,6 +3,7 @@ using Serilog.Context; using Sharpmine.Server.Protocol.Packets; +using Sharpmine.Server.Protocol.Packets.Configuration.Serverbound; namespace Sharpmine.Server.Protocol; @@ -28,6 +29,8 @@ public sealed partial class ClientHandler( public PacketTransceiver PacketTransceiver { get; internal set; } = null!; + public ClientInformationPacket? Information { get; set; } + public ProtocolState ProtocolState { get; private set; } = ProtocolState.Handshake; public void SwitchProtocolState(ProtocolState newState) diff --git a/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/ClientInformationPacket.cs b/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/ClientInformationPacket.cs index 7a676e4..8231cf4 100644 --- a/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/ClientInformationPacket.cs +++ b/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/ClientInformationPacket.cs @@ -45,7 +45,8 @@ public Task ProcessAsync( BinaryWriter writer, CancellationToken cancellationToken) { - throw new NotImplementedException(); + handler.Information = this; + return Task.CompletedTask; } } diff --git a/Sharpmine.Server/Protocol/Packets/Play/Serverbound/ClientInformationPacket.cs b/Sharpmine.Server/Protocol/Packets/Play/Serverbound/ClientInformationPacket.cs new file mode 100644 index 0000000..e62c97a --- /dev/null +++ b/Sharpmine.Server/Protocol/Packets/Play/Serverbound/ClientInformationPacket.cs @@ -0,0 +1,3 @@ +namespace Sharpmine.Server.Protocol.Packets.Play.Serverbound; + +public partial record ClientInformationPacket : Configuration.Serverbound.ClientInformationPacket; From 3e80d103c1260a06b7de94acbe96d5f09ba2fc54 Mon Sep 17 00:00:00 2001 From: Spi3lot Date: Sun, 29 Mar 2026 23:28:40 +0200 Subject: [PATCH 6/9] Document Aspire orchestration in README Added notes about Sharpmine.AppHost and Sharpmine.ServiceDefaults for future use. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 913f3c1..54d1ddf 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ The project aims to provide a high-performance, efficient server engine. Instead * **Sharpmine.Server**: Core logic and GUI. * **Sharpmine.Gen**: The incremental source generator for the protocol. * **Sharpmine.Tests**: Unit tests. +* **Sharpmine.AppHost** and **Sharpmine.ServiceDefaults**: Aspire orchestration. Not yet made proper use of, but maybe in the future. ## Contribute From 8b3e2f8e95d31d3fae09626ba6f946354e619221 Mon Sep 17 00:00:00 2001 From: Spi3lot Date: Mon, 13 Apr 2026 21:28:33 +0200 Subject: [PATCH 7/9] #11 make inter-state non-distinct packets inherit from an abstract equally named record class --- Sharpmine.Server/Protocol/ClientHandler.cs | 2 +- .../Abstract/Clientbound/KeepAlivePacket.cs | 21 ++++ .../Clientbound/PongResponsePacket.cs | 21 ++++ .../Serverbound/ClientInformationPacket.cs | 107 ++++++++++++++++++ .../Serverbound/CustomPayloadPacket.cs | 30 +++++ .../Abstract/Serverbound/KeepAlivePacket.cs | 30 +++++ .../Abstract/Serverbound/PingRequestPacket.cs | 37 ++++++ .../Clientbound/KeepAlivePacket.cs | 14 +-- .../Serverbound/ClientInformationPacket.cs | 102 +---------------- .../Serverbound/CustomPayloadPacket.cs | 25 +--- .../Serverbound/KeepAlivePacket.cs | 25 +--- .../Play/Clientbound/KeepAlivePacket.cs | 3 + .../Play/Clientbound/PongResponsePacket.cs | 3 + .../Serverbound/ClientInformationPacket.cs | 2 +- .../Play/Serverbound/KeepAlivePacket.cs | 3 + .../Play/Serverbound/PingRequestPacket.cs | 13 +++ .../Status/Clientbound/PongResponsePacket.cs | 14 +-- .../Status/Serverbound/PingRequestPacket.cs | 27 +---- 18 files changed, 279 insertions(+), 200 deletions(-) create mode 100644 Sharpmine.Server/Protocol/Packets/Abstract/Clientbound/KeepAlivePacket.cs create mode 100644 Sharpmine.Server/Protocol/Packets/Abstract/Clientbound/PongResponsePacket.cs create mode 100644 Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/ClientInformationPacket.cs create mode 100644 Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/CustomPayloadPacket.cs create mode 100644 Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/KeepAlivePacket.cs create mode 100644 Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/PingRequestPacket.cs create mode 100644 Sharpmine.Server/Protocol/Packets/Play/Clientbound/KeepAlivePacket.cs create mode 100644 Sharpmine.Server/Protocol/Packets/Play/Clientbound/PongResponsePacket.cs create mode 100644 Sharpmine.Server/Protocol/Packets/Play/Serverbound/KeepAlivePacket.cs create mode 100644 Sharpmine.Server/Protocol/Packets/Play/Serverbound/PingRequestPacket.cs diff --git a/Sharpmine.Server/Protocol/ClientHandler.cs b/Sharpmine.Server/Protocol/ClientHandler.cs index 79a1bf0..4c7aa64 100644 --- a/Sharpmine.Server/Protocol/ClientHandler.cs +++ b/Sharpmine.Server/Protocol/ClientHandler.cs @@ -3,7 +3,7 @@ using Serilog.Context; using Sharpmine.Server.Protocol.Packets; -using Sharpmine.Server.Protocol.Packets.Configuration.Serverbound; +using Sharpmine.Server.Protocol.Packets.Abstract.Serverbound; namespace Sharpmine.Server.Protocol; diff --git a/Sharpmine.Server/Protocol/Packets/Abstract/Clientbound/KeepAlivePacket.cs b/Sharpmine.Server/Protocol/Packets/Abstract/Clientbound/KeepAlivePacket.cs new file mode 100644 index 0000000..c324b62 --- /dev/null +++ b/Sharpmine.Server/Protocol/Packets/Abstract/Clientbound/KeepAlivePacket.cs @@ -0,0 +1,21 @@ +namespace Sharpmine.Server.Protocol.Packets.Abstract.Clientbound; + +public abstract record KeepAlivePacket : IClientboundPacket +{ + + public abstract ProtocolState State { get; } + + public abstract int Id { get; } + + public long KeepAliveId { get; init; } + + public Task SerializeContentAsync( + Stream stream, + BinaryWriter writer, + CancellationToken cancellationToken) + { + writer.Write(KeepAliveId); + return Task.CompletedTask; + } + +} diff --git a/Sharpmine.Server/Protocol/Packets/Abstract/Clientbound/PongResponsePacket.cs b/Sharpmine.Server/Protocol/Packets/Abstract/Clientbound/PongResponsePacket.cs new file mode 100644 index 0000000..25c1baa --- /dev/null +++ b/Sharpmine.Server/Protocol/Packets/Abstract/Clientbound/PongResponsePacket.cs @@ -0,0 +1,21 @@ +namespace Sharpmine.Server.Protocol.Packets.Abstract.Clientbound; + +public abstract record PongResponsePacket : IClientboundPacket +{ + + public abstract ProtocolState State { get; } + + public abstract int Id { get; } + + public long Timestamp { get; init; } + + public Task SerializeContentAsync( + Stream stream, + BinaryWriter writer, + CancellationToken cancellationToken) + { + writer.Write(Timestamp); + return Task.CompletedTask; + } + +} diff --git a/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/ClientInformationPacket.cs b/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/ClientInformationPacket.cs new file mode 100644 index 0000000..7f2b112 --- /dev/null +++ b/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/ClientInformationPacket.cs @@ -0,0 +1,107 @@ +namespace Sharpmine.Server.Protocol.Packets.Abstract.Serverbound; + +public abstract record ClientInformationPacket : IServerboundPacket +{ + + public abstract ProtocolState State { get; } + + public abstract int Id { get; } + + public string Locale { get; set; } = null!; + + public sbyte ViewDistance { get; set; } + + public ChatMode ChatMode { get; set; } + + public bool ChatColors { get; set; } + + public SkinParts DisplayedSkinParts { get; set; } + + public Hand MainHand { get; set; } + + public bool EnableTextFiltering { get; set; } + + public bool AllowServerListings { get; set; } + + public ParticleStatus ParticleStatus { get; set; } + + public Task DeserializeContentAsync( + NetworkStream stream, + BinaryReader reader, + CancellationToken cancellationToken) + { + Locale = reader.ReadString(); + ViewDistance = reader.ReadSByte(); + ChatMode = (ChatMode) reader.Read7BitEncodedInt(); + ChatColors = reader.ReadBoolean(); + DisplayedSkinParts = (SkinParts) reader.ReadByte(); + MainHand = (Hand) reader.Read7BitEncodedInt(); + EnableTextFiltering = reader.ReadBoolean(); + AllowServerListings = reader.ReadBoolean(); + ParticleStatus = (ParticleStatus) reader.Read7BitEncodedInt(); + return Task.CompletedTask; + } + + public Task ProcessAsync( + ClientHandler handler, + NetworkStream stream, + BinaryReader reader, + BinaryWriter writer, + CancellationToken cancellationToken) + { + handler.Information = this; + return Task.CompletedTask; + } + +} + +public enum ChatMode +{ + + Enabled = 0, + + CommandsOnly = 1, + + Hidden = 2, + +} + +[Flags] +public enum SkinParts : byte +{ + + Cape = 0x01, + + Jacket = 0x02, + + LeftSleeve = 0x04, + + RightSleeve = 0x08, + + LeftPantsLeg = 0x10, + + RightPantsLeg = 0x20, + + Hat = 0x40, + +} + +public enum Hand +{ + + Left = 0, + + Right = 1, + +} + +public enum ParticleStatus +{ + + All = 0, + + Decreased = 1, + + Minimal = 2, + +} diff --git a/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/CustomPayloadPacket.cs b/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/CustomPayloadPacket.cs new file mode 100644 index 0000000..1d9d534 --- /dev/null +++ b/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/CustomPayloadPacket.cs @@ -0,0 +1,30 @@ +namespace Sharpmine.Server.Protocol.Packets.Abstract.Serverbound; + +public abstract record CustomPayloadPacket : IServerboundPacket +{ + + public abstract ProtocolState State { get; } + + public abstract int Id { get; } + + public string Channel { get; set; } = null!; + + // TODO: Data + + public Task DeserializeContentAsync( + NetworkStream stream, + BinaryReader reader, + CancellationToken cancellationToken) + { + Channel = reader.ReadString(); + return Task.CompletedTask; + } + + public Task ProcessAsync( + ClientHandler handler, + NetworkStream stream, + BinaryReader reader, + BinaryWriter writer, + CancellationToken cancellationToken) => Task.CompletedTask; + +} diff --git a/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/KeepAlivePacket.cs b/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/KeepAlivePacket.cs new file mode 100644 index 0000000..14184c6 --- /dev/null +++ b/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/KeepAlivePacket.cs @@ -0,0 +1,30 @@ +namespace Sharpmine.Server.Protocol.Packets.Abstract.Serverbound; + +public abstract record KeepAlivePacket : IServerboundPacket +{ + + public abstract ProtocolState State { get; } + + public abstract int Id { get; } + + public long KeepAliveId { get; set; } + + public Task DeserializeContentAsync( + NetworkStream stream, + BinaryReader reader, + CancellationToken cancellationToken) + { + KeepAliveId = reader.ReadInt64(); + return Task.CompletedTask; + } + + public Task ProcessAsync(ClientHandler handler, + NetworkStream stream, + BinaryReader reader, + BinaryWriter writer, + CancellationToken cancellationToken) + { + throw new NotImplementedException("Check whether the client responded with the same packet"); + } + +} diff --git a/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/PingRequestPacket.cs b/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/PingRequestPacket.cs new file mode 100644 index 0000000..b075372 --- /dev/null +++ b/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/PingRequestPacket.cs @@ -0,0 +1,37 @@ +using Sharpmine.Server.Protocol.Packets.Abstract.Clientbound; + +namespace Sharpmine.Server.Protocol.Packets.Abstract.Serverbound; + +public abstract record PingRequestPacket : IServerboundPacket +{ + + public abstract ProtocolState State { get; } + + public abstract int Id { get; } + + public long Timestamp { get; set; } + + public Task DeserializeContentAsync( + NetworkStream stream, + BinaryReader reader, + CancellationToken cancellationToken) + { + // TODO: Maybe catch exceptions and return Task.FromException + Timestamp = reader.Read7BitEncodedInt64(); + return Task.CompletedTask; + } + + public async Task ProcessAsync( + ClientHandler handler, + NetworkStream stream, + BinaryReader reader, + BinaryWriter writer, + CancellationToken cancellationToken) + { + await handler.PacketTransceiver.TransmitAsync(CreatePongResponsePacket(), stream, writer, cancellationToken); + await handler.DisposeAsync(); + } + + protected abstract PongResponsePacket CreatePongResponsePacket(); + +} diff --git a/Sharpmine.Server/Protocol/Packets/Configuration/Clientbound/KeepAlivePacket.cs b/Sharpmine.Server/Protocol/Packets/Configuration/Clientbound/KeepAlivePacket.cs index abd13b0..c8ea55f 100644 --- a/Sharpmine.Server/Protocol/Packets/Configuration/Clientbound/KeepAlivePacket.cs +++ b/Sharpmine.Server/Protocol/Packets/Configuration/Clientbound/KeepAlivePacket.cs @@ -1,15 +1,3 @@ namespace Sharpmine.Server.Protocol.Packets.Configuration.Clientbound; -public partial record KeepAlivePacket(long KeepAliveId) -{ - - public Task SerializeContentAsync( - Stream stream, - BinaryWriter writer, - CancellationToken cancellationToken) - { - writer.Write(KeepAliveId); - return Task.CompletedTask; - } - -} +public partial record KeepAlivePacket : Abstract.Clientbound.KeepAlivePacket; diff --git a/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/ClientInformationPacket.cs b/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/ClientInformationPacket.cs index 8231cf4..464e58c 100644 --- a/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/ClientInformationPacket.cs +++ b/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/ClientInformationPacket.cs @@ -1,103 +1,3 @@ namespace Sharpmine.Server.Protocol.Packets.Configuration.Serverbound; -public partial record ClientInformationPacket -{ - - public string Locale { get; set; } = null!; - - public sbyte ViewDistance { get; set; } - - public ChatMode ChatMode { get; set; } - - public bool ChatColors { get; set; } - - public SkinParts DisplayedSkinParts { get; set; } - - public Hand MainHand { get; set; } - - public bool EnableTextFiltering { get; set; } - - public bool AllowServerListings { get; set; } - - public ParticleStatus ParticleStatus { get; set; } - - public Task DeserializeContentAsync( - NetworkStream stream, - BinaryReader reader, - CancellationToken cancellationToken) - { - Locale = reader.ReadString(); - ViewDistance = reader.ReadSByte(); - ChatMode = (ChatMode) reader.Read7BitEncodedInt(); - ChatColors = reader.ReadBoolean(); - DisplayedSkinParts = (SkinParts) reader.ReadByte(); - MainHand = (Hand) reader.Read7BitEncodedInt(); - EnableTextFiltering = reader.ReadBoolean(); - AllowServerListings = reader.ReadBoolean(); - ParticleStatus = (ParticleStatus) reader.Read7BitEncodedInt(); - return Task.CompletedTask; - } - - public Task ProcessAsync( - ClientHandler handler, - NetworkStream stream, - BinaryReader reader, - BinaryWriter writer, - CancellationToken cancellationToken) - { - handler.Information = this; - return Task.CompletedTask; - } - -} - -public enum ChatMode -{ - - Enabled = 0, - - CommandsOnly = 1, - - Hidden = 2, - -} - -[Flags] -public enum SkinParts : byte -{ - - Cape = 0x01, - - Jacket = 0x02, - - LeftSleeve = 0x04, - - RightSleeve = 0x08, - - LeftPantsLeg = 0x10, - - RightPantsLeg = 0x20, - - Hat = 0x40, - -} - -public enum Hand -{ - - Left = 0, - - Right = 1, - -} - -public enum ParticleStatus -{ - - All = 0, - - Decreased = 1, - - Minimal = 2, - -} +public partial record ClientInformationPacket : Abstract.Serverbound.ClientInformationPacket; diff --git a/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/CustomPayloadPacket.cs b/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/CustomPayloadPacket.cs index e48d468..7301fe6 100644 --- a/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/CustomPayloadPacket.cs +++ b/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/CustomPayloadPacket.cs @@ -1,26 +1,3 @@ namespace Sharpmine.Server.Protocol.Packets.Configuration.Serverbound; -public partial record CustomPayloadPacket -{ - - public string Channel { get; set; } = null!; - - // TODO: Data - - public Task DeserializeContentAsync( - NetworkStream stream, - BinaryReader reader, - CancellationToken cancellationToken) - { - Channel = reader.ReadString(); - return Task.CompletedTask; - } - - public Task ProcessAsync( - ClientHandler handler, - NetworkStream stream, - BinaryReader reader, - BinaryWriter writer, - CancellationToken cancellationToken) => Task.CompletedTask; - -} +public partial record CustomPayloadPacket : Abstract.Serverbound.CustomPayloadPacket; diff --git a/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/KeepAlivePacket.cs b/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/KeepAlivePacket.cs index 9204afa..5df00c9 100644 --- a/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/KeepAlivePacket.cs +++ b/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/KeepAlivePacket.cs @@ -1,26 +1,3 @@ namespace Sharpmine.Server.Protocol.Packets.Configuration.Serverbound; -public partial record KeepAlivePacket -{ - - public long KeepAliveId { get; set; } - - public Task DeserializeContentAsync( - NetworkStream stream, - BinaryReader reader, - CancellationToken cancellationToken) - { - KeepAliveId = reader.ReadInt64(); - return Task.CompletedTask; - } - - public Task ProcessAsync(ClientHandler handler, - NetworkStream stream, - BinaryReader reader, - BinaryWriter writer, - CancellationToken cancellationToken) - { - throw new NotImplementedException("Check whether the client responded with the same packet"); - } - -} +public partial record KeepAlivePacket : Abstract.Serverbound.KeepAlivePacket; diff --git a/Sharpmine.Server/Protocol/Packets/Play/Clientbound/KeepAlivePacket.cs b/Sharpmine.Server/Protocol/Packets/Play/Clientbound/KeepAlivePacket.cs new file mode 100644 index 0000000..8c73a42 --- /dev/null +++ b/Sharpmine.Server/Protocol/Packets/Play/Clientbound/KeepAlivePacket.cs @@ -0,0 +1,3 @@ +namespace Sharpmine.Server.Protocol.Packets.Play.Clientbound; + +public partial record KeepAlivePacket : Abstract.Clientbound.KeepAlivePacket; diff --git a/Sharpmine.Server/Protocol/Packets/Play/Clientbound/PongResponsePacket.cs b/Sharpmine.Server/Protocol/Packets/Play/Clientbound/PongResponsePacket.cs new file mode 100644 index 0000000..50d98e9 --- /dev/null +++ b/Sharpmine.Server/Protocol/Packets/Play/Clientbound/PongResponsePacket.cs @@ -0,0 +1,3 @@ +namespace Sharpmine.Server.Protocol.Packets.Play.Clientbound; + +public partial record PongResponsePacket : Abstract.Clientbound.PongResponsePacket; diff --git a/Sharpmine.Server/Protocol/Packets/Play/Serverbound/ClientInformationPacket.cs b/Sharpmine.Server/Protocol/Packets/Play/Serverbound/ClientInformationPacket.cs index e62c97a..a47af15 100644 --- a/Sharpmine.Server/Protocol/Packets/Play/Serverbound/ClientInformationPacket.cs +++ b/Sharpmine.Server/Protocol/Packets/Play/Serverbound/ClientInformationPacket.cs @@ -1,3 +1,3 @@ namespace Sharpmine.Server.Protocol.Packets.Play.Serverbound; -public partial record ClientInformationPacket : Configuration.Serverbound.ClientInformationPacket; +public partial record ClientInformationPacket : Abstract.Serverbound.ClientInformationPacket; diff --git a/Sharpmine.Server/Protocol/Packets/Play/Serverbound/KeepAlivePacket.cs b/Sharpmine.Server/Protocol/Packets/Play/Serverbound/KeepAlivePacket.cs new file mode 100644 index 0000000..224a644 --- /dev/null +++ b/Sharpmine.Server/Protocol/Packets/Play/Serverbound/KeepAlivePacket.cs @@ -0,0 +1,3 @@ +namespace Sharpmine.Server.Protocol.Packets.Play.Serverbound; + +public partial record KeepAlivePacket : Abstract.Serverbound.KeepAlivePacket; diff --git a/Sharpmine.Server/Protocol/Packets/Play/Serverbound/PingRequestPacket.cs b/Sharpmine.Server/Protocol/Packets/Play/Serverbound/PingRequestPacket.cs new file mode 100644 index 0000000..7dc6d9f --- /dev/null +++ b/Sharpmine.Server/Protocol/Packets/Play/Serverbound/PingRequestPacket.cs @@ -0,0 +1,13 @@ +using Sharpmine.Server.Protocol.Packets.Abstract.Clientbound; + +namespace Sharpmine.Server.Protocol.Packets.Play.Serverbound; + +public partial record PingRequestPacket : Abstract.Serverbound.PingRequestPacket +{ + + protected override PongResponsePacket CreatePongResponsePacket() + { + return new Clientbound.PongResponsePacket { Timestamp = Timestamp }; + } + +} diff --git a/Sharpmine.Server/Protocol/Packets/Status/Clientbound/PongResponsePacket.cs b/Sharpmine.Server/Protocol/Packets/Status/Clientbound/PongResponsePacket.cs index c04bed6..1bb8860 100644 --- a/Sharpmine.Server/Protocol/Packets/Status/Clientbound/PongResponsePacket.cs +++ b/Sharpmine.Server/Protocol/Packets/Status/Clientbound/PongResponsePacket.cs @@ -1,15 +1,3 @@ namespace Sharpmine.Server.Protocol.Packets.Status.Clientbound; -public partial record PongResponsePacket(long Timestamp) -{ - - public Task SerializeContentAsync( - Stream stream, - BinaryWriter writer, - CancellationToken cancellationToken) - { - writer.Write(Timestamp); - return Task.CompletedTask; - } - -} \ No newline at end of file +public partial record PongResponsePacket : Abstract.Clientbound.PongResponsePacket; diff --git a/Sharpmine.Server/Protocol/Packets/Status/Serverbound/PingRequestPacket.cs b/Sharpmine.Server/Protocol/Packets/Status/Serverbound/PingRequestPacket.cs index 586bf38..f6563e2 100644 --- a/Sharpmine.Server/Protocol/Packets/Status/Serverbound/PingRequestPacket.cs +++ b/Sharpmine.Server/Protocol/Packets/Status/Serverbound/PingRequestPacket.cs @@ -1,32 +1,13 @@ -using Sharpmine.Server.Protocol.Packets.Status.Clientbound; +using Sharpmine.Server.Protocol.Packets.Abstract.Clientbound; namespace Sharpmine.Server.Protocol.Packets.Status.Serverbound; -public partial record PingRequestPacket +public partial record PingRequestPacket : Abstract.Serverbound.PingRequestPacket { - public long Timestamp { get; set; } - - public Task DeserializeContentAsync( - NetworkStream stream, - BinaryReader reader, - CancellationToken cancellationToken) - { - // TODO: Maybe catch exceptions and return Task.FromException - Timestamp = reader.Read7BitEncodedInt64(); - return Task.CompletedTask; - } - - public async Task ProcessAsync( - ClientHandler handler, - NetworkStream stream, - BinaryReader reader, - BinaryWriter writer, - CancellationToken cancellationToken) + protected override PongResponsePacket CreatePongResponsePacket() { - var response = new PongResponsePacket(Timestamp); - await handler.PacketTransceiver.TransmitAsync(response, stream, writer, cancellationToken); - await handler.DisposeAsync(); + return new Clientbound.PongResponsePacket { Timestamp = Timestamp }; } } From 98750129c26ad531f91811bb26a7aee4ab4a2abe Mon Sep 17 00:00:00 2001 From: Spi3lot Date: Mon, 13 Apr 2026 23:31:38 +0200 Subject: [PATCH 8/9] #12 - Rename DeserializeContentAsync to DeserializeAsync - Make DeserializeAsync static and abstract - Adapt PacketGenerator accordingly - Adapt PacketTransceiver accordingly --- Sharpmine.Gen/PacketGenerator.cs | 12 ++++++---- .../Protocol/Packets/IServerboundPacket.cs | 4 ++-- .../Protocol/Packets/PacketTransceiver.cs | 24 ++++++++++--------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/Sharpmine.Gen/PacketGenerator.cs b/Sharpmine.Gen/PacketGenerator.cs index 243435a..ab4812b 100644 --- a/Sharpmine.Gen/PacketGenerator.cs +++ b/Sharpmine.Gen/PacketGenerator.cs @@ -74,7 +74,7 @@ private static void GenerateProtocolDirection( string packetName = packet.Name.Substring("minecraft:".Length); string packetClassName = ToPascalCase(packetName) + "Packet"; GeneratePacketPartial(context, packetClassName, interfaceName, stateName, directionName, packet.Id); - sb?.AppendLine($" (ProtocolState.{stateName}, 0x{packet.Id:X2}) => new {stateName}.{directionName}.{packetClassName}(),"); + sb?.AppendLine($" (ProtocolState.{stateName}, 0x{packet.Id:X2}) => {stateName}.{directionName}.{packetClassName}.DeserializeAsync(stream, reader, cancellationToken),"); } } @@ -118,12 +118,14 @@ namespace {{BaseNamespace}}; public static class ServerboundPacketRegistry { - public static bool TryCreatePacket( + public static Task TryDeserializePacket( ProtocolState state, int id, - [NotNullWhen(true)] out IServerboundPacket? packet) + NetworkStream stream, + BinaryReader reader, + CancellationToken cancellationToken) { - packet = (state, id) switch + return (state, id) switch { """); } @@ -131,7 +133,7 @@ public static bool TryCreatePacket( private static void EndRegistry(StringBuilder sb) { sb.Append(""" - _ => null + _ => Task.FromResult(null) }; return packet is not null; diff --git a/Sharpmine.Server/Protocol/Packets/IServerboundPacket.cs b/Sharpmine.Server/Protocol/Packets/IServerboundPacket.cs index 0d32a77..f36ce84 100644 --- a/Sharpmine.Server/Protocol/Packets/IServerboundPacket.cs +++ b/Sharpmine.Server/Protocol/Packets/IServerboundPacket.cs @@ -4,10 +4,10 @@ public interface IServerboundPacket : IPacket { // TODO: Consider ValueTask - Task DeserializeContentAsync( + static abstract Task DeserializeAsync( NetworkStream stream, BinaryReader reader, - CancellationToken cancellationToken) => throw new NotImplementedException(); + CancellationToken cancellationToken); // TODO: Consider ValueTask Task ProcessAsync( diff --git a/Sharpmine.Server/Protocol/Packets/PacketTransceiver.cs b/Sharpmine.Server/Protocol/Packets/PacketTransceiver.cs index 87832e6..a4f2f69 100644 --- a/Sharpmine.Server/Protocol/Packets/PacketTransceiver.cs +++ b/Sharpmine.Server/Protocol/Packets/PacketTransceiver.cs @@ -64,22 +64,24 @@ public async Task TransmitAsync( } int packetId = reader.Read7BitEncodedInt(); - - if (!ServerboundPacketRegistry.TryCreatePacket(state, packetId, out var packet)) - { - LogReceivedUnknownPacket(state, packetId, length); - return null; - } + IServerboundPacket? packet; try { - await packet.DeserializeContentAsync(stream, reader, cancellationToken); + packet = await ServerboundPacketRegistry.TryDeserializePacket(state, packetId, stream, reader, cancellationToken); + + if (packet is null) + { + LogReceivedUnknownPacket(state, packetId, length); + return null; + } + LogReceivedPacket(packet, state, packetId, length); return packet; } - catch (NotImplementedException) + catch (NotImplementedException ex) { - LogDeserializeNotImplemented(packet); + LogDeserializeNotImplemented(ex); return null; } } @@ -102,8 +104,8 @@ private static bool IsLegacyPing(ProtocolState state, int length) [LoggerMessage(LogLevel.Error, "{Packet} has no implementation for serialization")] partial void LogSerializeNotImplemented(IClientboundPacket packet); - [LoggerMessage(LogLevel.Error, "{Packet} has no implementation for deserialization")] - partial void LogDeserializeNotImplemented(IServerboundPacket packet); + [LoggerMessage(LogLevel.Error, "Received packet has no implementation for deserialization")] + partial void LogDeserializeNotImplemented(NotImplementedException exception); [LoggerMessage(LogLevel.Error, "Received {State}:0x{Id:X2} with {Length} bytes: UNKNOWN PACKET")] partial void LogReceivedUnknownPacket(ProtocolState state, int id, int length); From ef67fce8770f7bef997523d36de928e4e67e0682 Mon Sep 17 00:00:00 2001 From: Spi3lot Date: Mon, 13 Apr 2026 23:33:13 +0200 Subject: [PATCH 9/9] #12 Apply name and staticity change to all occurrences of Deserialize[Content]Async --- .../Packets/Abstract/Serverbound/ClientInformationPacket.cs | 2 +- .../Packets/Abstract/Serverbound/CustomPayloadPacket.cs | 2 +- .../Protocol/Packets/Abstract/Serverbound/KeepAlivePacket.cs | 2 +- .../Protocol/Packets/Abstract/Serverbound/PingRequestPacket.cs | 2 +- .../Configuration/Serverbound/FinishConfigurationPacket.cs | 2 +- .../Protocol/Packets/Handshake/Serverbound/IntentionPacket.cs | 2 +- .../Protocol/Packets/Login/Serverbound/HelloPacket.cs | 2 +- .../Packets/Login/Serverbound/LoginAcknowledgedPacket.cs | 2 +- .../Packets/Play/Serverbound/AcceptTeleportationPacket.cs | 2 +- .../Protocol/Packets/Status/Serverbound/StatusRequestPacket.cs | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/ClientInformationPacket.cs b/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/ClientInformationPacket.cs index 7f2b112..1e48d54 100644 --- a/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/ClientInformationPacket.cs +++ b/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/ClientInformationPacket.cs @@ -25,7 +25,7 @@ public abstract record ClientInformationPacket : IServerboundPacket public ParticleStatus ParticleStatus { get; set; } - public Task DeserializeContentAsync( + public static Task DeserializeAsync( NetworkStream stream, BinaryReader reader, CancellationToken cancellationToken) diff --git a/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/CustomPayloadPacket.cs b/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/CustomPayloadPacket.cs index 1d9d534..a1d300b 100644 --- a/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/CustomPayloadPacket.cs +++ b/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/CustomPayloadPacket.cs @@ -11,7 +11,7 @@ public abstract record CustomPayloadPacket : IServerboundPacket // TODO: Data - public Task DeserializeContentAsync( + public static Task DeserializeAsync( NetworkStream stream, BinaryReader reader, CancellationToken cancellationToken) diff --git a/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/KeepAlivePacket.cs b/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/KeepAlivePacket.cs index 14184c6..75c6047 100644 --- a/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/KeepAlivePacket.cs +++ b/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/KeepAlivePacket.cs @@ -9,7 +9,7 @@ public abstract record KeepAlivePacket : IServerboundPacket public long KeepAliveId { get; set; } - public Task DeserializeContentAsync( + public static Task DeserializeAsync( NetworkStream stream, BinaryReader reader, CancellationToken cancellationToken) diff --git a/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/PingRequestPacket.cs b/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/PingRequestPacket.cs index b075372..3027016 100644 --- a/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/PingRequestPacket.cs +++ b/Sharpmine.Server/Protocol/Packets/Abstract/Serverbound/PingRequestPacket.cs @@ -11,7 +11,7 @@ public abstract record PingRequestPacket : IServerboundPacket public long Timestamp { get; set; } - public Task DeserializeContentAsync( + public static Task DeserializeAsync( NetworkStream stream, BinaryReader reader, CancellationToken cancellationToken) diff --git a/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/FinishConfigurationPacket.cs b/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/FinishConfigurationPacket.cs index d2a296b..46a2807 100644 --- a/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/FinishConfigurationPacket.cs +++ b/Sharpmine.Server/Protocol/Packets/Configuration/Serverbound/FinishConfigurationPacket.cs @@ -3,7 +3,7 @@ public partial record FinishConfigurationPacket { - public Task DeserializeContentAsync( + public static Task DeserializeAsync( NetworkStream stream, BinaryReader reader, CancellationToken cancellationToken) => Task.CompletedTask; diff --git a/Sharpmine.Server/Protocol/Packets/Handshake/Serverbound/IntentionPacket.cs b/Sharpmine.Server/Protocol/Packets/Handshake/Serverbound/IntentionPacket.cs index dccba8b..ac46dc8 100644 --- a/Sharpmine.Server/Protocol/Packets/Handshake/Serverbound/IntentionPacket.cs +++ b/Sharpmine.Server/Protocol/Packets/Handshake/Serverbound/IntentionPacket.cs @@ -11,7 +11,7 @@ public partial record IntentionPacket public Intent Intent { get; set; } - public Task DeserializeContentAsync( + public static Task DeserializeAsync( NetworkStream stream, BinaryReader reader, CancellationToken cancellationToken) diff --git a/Sharpmine.Server/Protocol/Packets/Login/Serverbound/HelloPacket.cs b/Sharpmine.Server/Protocol/Packets/Login/Serverbound/HelloPacket.cs index f0874c5..692790e 100644 --- a/Sharpmine.Server/Protocol/Packets/Login/Serverbound/HelloPacket.cs +++ b/Sharpmine.Server/Protocol/Packets/Login/Serverbound/HelloPacket.cs @@ -12,7 +12,7 @@ public partial record HelloPacket public Guid Uuid { get; set; } - public Task DeserializeContentAsync( + public static Task DeserializeAsync( NetworkStream stream, BinaryReader reader, CancellationToken cancellationToken) diff --git a/Sharpmine.Server/Protocol/Packets/Login/Serverbound/LoginAcknowledgedPacket.cs b/Sharpmine.Server/Protocol/Packets/Login/Serverbound/LoginAcknowledgedPacket.cs index a0e1f56..223333c 100644 --- a/Sharpmine.Server/Protocol/Packets/Login/Serverbound/LoginAcknowledgedPacket.cs +++ b/Sharpmine.Server/Protocol/Packets/Login/Serverbound/LoginAcknowledgedPacket.cs @@ -3,7 +3,7 @@ public partial record LoginAcknowledgedPacket { - public Task DeserializeContentAsync( + public static Task DeserializeAsync( NetworkStream stream, BinaryReader reader, CancellationToken cancellationToken) => Task.CompletedTask; diff --git a/Sharpmine.Server/Protocol/Packets/Play/Serverbound/AcceptTeleportationPacket.cs b/Sharpmine.Server/Protocol/Packets/Play/Serverbound/AcceptTeleportationPacket.cs index 9d601f7..0455fa1 100644 --- a/Sharpmine.Server/Protocol/Packets/Play/Serverbound/AcceptTeleportationPacket.cs +++ b/Sharpmine.Server/Protocol/Packets/Play/Serverbound/AcceptTeleportationPacket.cs @@ -5,7 +5,7 @@ public partial record AcceptTeleportationPacket public int TeleportId { get; set; } - public Task DeserializeContentAsync( + public static Task DeserializeAsync( NetworkStream stream, BinaryReader reader, CancellationToken cancellationToken) diff --git a/Sharpmine.Server/Protocol/Packets/Status/Serverbound/StatusRequestPacket.cs b/Sharpmine.Server/Protocol/Packets/Status/Serverbound/StatusRequestPacket.cs index f928667..dfce10c 100644 --- a/Sharpmine.Server/Protocol/Packets/Status/Serverbound/StatusRequestPacket.cs +++ b/Sharpmine.Server/Protocol/Packets/Status/Serverbound/StatusRequestPacket.cs @@ -5,7 +5,7 @@ namespace Sharpmine.Server.Protocol.Packets.Status.Serverbound; public partial record StatusRequestPacket { - public Task DeserializeContentAsync( + public static Task DeserializeAsync( NetworkStream stream, BinaryReader reader, CancellationToken cancellationToken) => Task.CompletedTask;