From e9ea621b93fbb58d9edfca8375918791637bbd52 Mon Sep 17 00:00:00 2001 From: chai Date: Wed, 30 Dec 2020 20:59:04 +0800 Subject: +init --- Impostor-dev/src/Impostor.Api/Net/IClient.cs | 76 ++++++++++++ Impostor-dev/src/Impostor.Api/Net/IClientPlayer.cs | 43 +++++++ Impostor-dev/src/Impostor.Api/Net/IConnection.cs | 7 ++ .../src/Impostor.Api/Net/IHazelConnection.cs | 41 +++++++ .../src/Impostor.Api/Net/Inner/IGameNet.cs | 18 +++ .../src/Impostor.Api/Net/Inner/IInnerNetObject.cs | 9 ++ .../Components/IInnerCustomNetworkTransform.cs | 15 +++ .../Objects/Components/IInnerPlayerPhysics.cs | 6 + .../Net/Inner/Objects/IInnerGameData.cs | 6 + .../Net/Inner/Objects/IInnerLobbyBehaviour.cs | 6 + .../Net/Inner/Objects/IInnerMeetingHud.cs | 6 + .../Net/Inner/Objects/IInnerPlayerControl.cs | 116 +++++++++++++++++++ .../Net/Inner/Objects/IInnerPlayerInfo.cs | 53 +++++++++ .../Net/Inner/Objects/IInnerShipStatus.cs | 7 ++ .../Net/Inner/Objects/IInnerVoteBanSystem.cs | 7 ++ .../Impostor.Api/Net/Inner/Objects/ITaskInfo.cs | 14 +++ Impostor-dev/src/Impostor.Api/Net/LimboStates.cs | 13 +++ .../src/Impostor.Api/Net/Manager/IClientManager.cs | 9 ++ .../Net/Messages/C2S/Message00HostGameC2S.cs | 27 +++++ .../Net/Messages/C2S/Message01JoinGameC2S.cs | 20 ++++ .../Net/Messages/C2S/Message04RemovePlayerC2S.cs | 16 +++ .../Net/Messages/C2S/Message08EndGameC2S.cs | 18 +++ .../Net/Messages/C2S/Message10AlterGameC2S.cs | 20 ++++ .../Net/Messages/C2S/Message11KickPlayerC2S.cs | 16 +++ .../Net/Messages/C2S/Message16GetGameListC2S.cs | 18 +++ .../Impostor.Api/Net/Messages/IMessageReader.cs | 68 +++++++++++ .../Impostor.Api/Net/Messages/IMessageWriter.cs | 127 +++++++++++++++++++++ .../Net/Messages/IMessageWriterProvider.cs | 16 +++ .../src/Impostor.Api/Net/Messages/MessageFlags.cs | 22 ++++ .../src/Impostor.Api/Net/Messages/MessageType.cs | 32 ++++++ .../Net/Messages/S2C/Message00HostGameS2C.cs | 20 ++++ .../Net/Messages/S2C/Message01JoinGameS2C.cs | 50 ++++++++ .../Net/Messages/S2C/Message04RemovePlayerS2C.cs | 29 +++++ .../Net/Messages/S2C/Message07JoinedGameS2C.cs | 31 +++++ .../Net/Messages/S2C/Message10AlterGameS2C.cs | 26 +++++ .../Net/Messages/S2C/Message11KickPlayerS2C.cs | 24 ++++ .../Net/Messages/S2C/Message12WaitForHostS2C.cs | 23 ++++ .../Net/Messages/S2C/Message13RedirectS2C.cs | 25 ++++ .../Net/Messages/S2C/Message16GetGameListS2C.cs | 46 ++++++++ 39 files changed, 1126 insertions(+) create mode 100644 Impostor-dev/src/Impostor.Api/Net/IClient.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/IClientPlayer.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/IConnection.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/IHazelConnection.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Inner/IGameNet.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Inner/IInnerNetObject.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Inner/Objects/Components/IInnerCustomNetworkTransform.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Inner/Objects/Components/IInnerPlayerPhysics.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerGameData.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerLobbyBehaviour.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerMeetingHud.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerPlayerControl.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerPlayerInfo.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerShipStatus.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerVoteBanSystem.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Inner/Objects/ITaskInfo.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/LimboStates.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Manager/IClientManager.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message00HostGameC2S.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message01JoinGameC2S.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message04RemovePlayerC2S.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message08EndGameC2S.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message10AlterGameC2S.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message11KickPlayerC2S.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message16GetGameListC2S.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Messages/IMessageReader.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Messages/IMessageWriter.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Messages/IMessageWriterProvider.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Messages/MessageFlags.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Messages/MessageType.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message00HostGameS2C.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message01JoinGameS2C.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message04RemovePlayerS2C.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message07JoinedGameS2C.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message10AlterGameS2C.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message11KickPlayerS2C.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message12WaitForHostS2C.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message13RedirectS2C.cs create mode 100644 Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message16GetGameListS2C.cs (limited to 'Impostor-dev/src/Impostor.Api/Net') diff --git a/Impostor-dev/src/Impostor.Api/Net/IClient.cs b/Impostor-dev/src/Impostor.Api/Net/IClient.cs new file mode 100644 index 0000000..48efeda --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/IClient.cs @@ -0,0 +1,76 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Impostor.Api.Innersloth; +using Impostor.Api.Net.Messages; + +namespace Impostor.Api.Net +{ + /// + /// Represents a connected game client. + /// + public interface IClient + { + /// + /// Gets or sets the unique ID of the client. + /// + /// + /// This ID is generated when the client is registered in the client manager and should not be used + /// to store persisted data. + /// + int Id { get; set; } + + /// + /// Gets the name that was provided by the player in the client. + /// + /// + /// The name is provided by the player and should not be used to store persisted data. + /// + string Name { get; } + + /// + /// Gets the connection of the client. + /// + /// + /// Null when the client was not registered by the matchmaker. + /// + IHazelConnection? Connection { get; } + + /// + /// Gets a key/value collection that can be used to share data between messages. + /// + /// + /// + /// The stored data will not be saved. + /// After the connection has been closed all data will be lost. + /// + /// + /// Note that the values will not be disposed after the connection has been closed. + /// This has to be implemented by the plugin. + /// + /// + IDictionary Items { get; } + + /// + /// Gets or sets the current game data of the . + /// + IClientPlayer? Player { get; } + + ValueTask HandleMessageAsync(IMessageReader message, MessageType messageType); + + ValueTask HandleDisconnectAsync(string reason); + + /// + /// Disconnect the client with a . + /// + /// + /// The message to show to the player. + /// + /// + /// Only used when is set to . + /// + /// + /// A representing the asynchronous operation. + /// + ValueTask DisconnectAsync(DisconnectReason reason, string? message = null); + } +} diff --git a/Impostor-dev/src/Impostor.Api/Net/IClientPlayer.cs b/Impostor-dev/src/Impostor.Api/Net/IClientPlayer.cs new file mode 100644 index 0000000..6070210 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/IClientPlayer.cs @@ -0,0 +1,43 @@ +using System.Threading.Tasks; +using Impostor.Api.Games; +using Impostor.Api.Net.Inner; +using Impostor.Api.Net.Inner.Objects; + +namespace Impostor.Api.Net +{ + /// + /// Represents a player in . + /// + public interface IClientPlayer + { + /// + /// Gets the client that belongs to the player. + /// + IClient Client { get; } + + /// + /// Gets the game where the belongs to. + /// + IGame Game { get; } + + /// + /// Gets or sets the current limbo state of the player. + /// + LimboStates Limbo { get; set; } + + IInnerPlayerControl? Character { get; } + + public bool IsHost { get; } + + /// + /// Checks if the specified is owned by . + /// + /// The . + /// Returns true if owned by . + bool IsOwner(IInnerNetObject netObject); + + ValueTask KickAsync(); + + ValueTask BanAsync(); + } +} diff --git a/Impostor-dev/src/Impostor.Api/Net/IConnection.cs b/Impostor-dev/src/Impostor.Api/Net/IConnection.cs new file mode 100644 index 0000000..94f9b8b --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/IConnection.cs @@ -0,0 +1,7 @@ +namespace Impostor.Api.Net +{ + public interface IConnection + { + + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/IHazelConnection.cs b/Impostor-dev/src/Impostor.Api/Net/IHazelConnection.cs new file mode 100644 index 0000000..4e6c4b3 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/IHazelConnection.cs @@ -0,0 +1,41 @@ +using System.Net; +using System.Threading.Tasks; +using Impostor.Api.Net.Messages; + +namespace Impostor.Api.Net +{ + /// + /// Represents the connection of the client. + /// + public interface IHazelConnection + { + /// + /// Gets the IP endpoint of the client. + /// + IPEndPoint EndPoint { get; } + + /// + /// Gets a value indicating whether the client is connected to the server. + /// + bool IsConnected { get; } + + /// + /// Gets the client of the connection. + /// + IClient? Client { get; set; } + + /// + /// Sends a message writer to the connection. + /// + /// The message. + /// + ValueTask SendAsync(IMessageWriter writer); + + /// + /// Disconnects the client and invokes the disconnect handler. + /// + /// A reason. + /// + ValueTask DisconnectAsync(string? reason); + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Inner/IGameNet.cs b/Impostor-dev/src/Impostor.Api/Net/Inner/IGameNet.cs new file mode 100644 index 0000000..933a4de --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Inner/IGameNet.cs @@ -0,0 +1,18 @@ +using Impostor.Api.Net.Inner.Objects; + +namespace Impostor.Api.Net.Inner +{ + /// + /// Holds all data that is serialized over the network through GameData packets. + /// + public interface IGameNet + { + IInnerLobbyBehaviour LobbyBehaviour { get; } + + IInnerGameData GameData { get; } + + IInnerVoteBanSystem VoteBan { get; } + + IInnerShipStatus ShipStatus { get; } + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Inner/IInnerNetObject.cs b/Impostor-dev/src/Impostor.Api/Net/Inner/IInnerNetObject.cs new file mode 100644 index 0000000..c171377 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Inner/IInnerNetObject.cs @@ -0,0 +1,9 @@ +namespace Impostor.Api.Net.Inner +{ + public interface IInnerNetObject + { + public uint NetId { get; } + + public int OwnerId { get; } + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/Components/IInnerCustomNetworkTransform.cs b/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/Components/IInnerCustomNetworkTransform.cs new file mode 100644 index 0000000..6d867e7 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/Components/IInnerCustomNetworkTransform.cs @@ -0,0 +1,15 @@ +using System.Numerics; +using System.Threading.Tasks; + +namespace Impostor.Api.Net.Inner.Objects.Components +{ + public interface IInnerCustomNetworkTransform : IInnerNetObject + { + /// + /// Snaps the current to the given position . + /// + /// The target position. + /// Task that must be awaited. + ValueTask SnapToAsync(Vector2 position); + } +} diff --git a/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/Components/IInnerPlayerPhysics.cs b/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/Components/IInnerPlayerPhysics.cs new file mode 100644 index 0000000..9378c5b --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/Components/IInnerPlayerPhysics.cs @@ -0,0 +1,6 @@ +namespace Impostor.Api.Net.Inner.Objects.Components +{ + public interface IInnerPlayerPhysics : IInnerNetObject + { + } +} diff --git a/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerGameData.cs b/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerGameData.cs new file mode 100644 index 0000000..6e41020 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerGameData.cs @@ -0,0 +1,6 @@ +namespace Impostor.Api.Net.Inner.Objects +{ + public interface IInnerGameData : IInnerNetObject + { + } +} diff --git a/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerLobbyBehaviour.cs b/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerLobbyBehaviour.cs new file mode 100644 index 0000000..f05f4cf --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerLobbyBehaviour.cs @@ -0,0 +1,6 @@ +namespace Impostor.Api.Net.Inner.Objects +{ + public interface IInnerLobbyBehaviour : IInnerNetObject + { + } +} diff --git a/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerMeetingHud.cs b/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerMeetingHud.cs new file mode 100644 index 0000000..9c89d05 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerMeetingHud.cs @@ -0,0 +1,6 @@ +namespace Impostor.Api.Net.Inner.Objects +{ + public interface IInnerMeetingHud + { + } +} diff --git a/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerPlayerControl.cs b/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerPlayerControl.cs new file mode 100644 index 0000000..04558b9 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerPlayerControl.cs @@ -0,0 +1,116 @@ +using System.Threading.Tasks; +using Impostor.Api.Innersloth.Customization; +using Impostor.Api.Net.Inner.Objects.Components; + +namespace Impostor.Api.Net.Inner.Objects +{ + public interface IInnerPlayerControl : IInnerNetObject + { + /// + /// Gets the assigned by the client of the host of the game. + /// + byte PlayerId { get; } + + /// + /// Gets the of the . + /// Contains vent logic. + /// + IInnerPlayerPhysics Physics { get; } + + /// + /// Gets the of the . + /// Contains position data about the player. + /// + IInnerCustomNetworkTransform NetworkTransform { get; } + + /// + /// Gets the of the . + /// Contains metadata about the player. + /// + IInnerPlayerInfo PlayerInfo { get; } + + /// + /// Sets the name of the current . + /// Visible to all players. + /// + /// A name for the player. + /// Task that must be awaited. + ValueTask SetNameAsync(string name); + + /// + /// Sets the color of the current . + /// Visible to all players. + /// + /// A color for the player. + /// Task that must be awaited. + ValueTask SetColorAsync(byte colorId); + + /// A color for the player. + /// + ValueTask SetColorAsync(ColorType colorType); + + /// + /// Sets the hat of the current . + /// Visible to all players. + /// + /// An hat for the player. + /// Task that must be awaited. + ValueTask SetHatAsync(uint hatId); + + /// An hat for the player. + /// + ValueTask SetHatAsync(HatType hatType); + + /// + /// Sets the pet of the current . + /// Visible to all players. + /// + /// A pet for the player. + /// Task that must be awaited. + ValueTask SetPetAsync(uint petId); + + /// A pet for the player. + /// + ValueTask SetPetAsync(PetType petType); + + /// + /// Sets the skin of the current . + /// Visible to all players. + /// + /// A skin for the player. + /// Task that must be awaited. + ValueTask SetSkinAsync(uint skinId); + + /// A skin for the player. + /// + ValueTask SetSkinAsync(SkinType skinType); + + /// + /// Send a chat message as the current . + /// Visible to all players. + /// + /// The message to send. + /// Task that must be awaited. + ValueTask SendChatAsync(string text); + + /// + /// Send a chat message as the current . + /// Visible to only the current. + /// + /// The message to send. + /// + /// The player that should receive this chat message. + /// When left as null, will send message to self. + /// + /// Task that must be awaited. + ValueTask SendChatToPlayerAsync(string text, IInnerPlayerControl? player = null); + + /// + /// Sets the current to be murdered by an impostor . + /// Visible to all players. + /// + /// /// The Impostor who kill. + /// Task that must be awaited. + ValueTask SetMurderedByAsync(IClientPlayer impostor); + } +} diff --git a/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerPlayerInfo.cs b/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerPlayerInfo.cs new file mode 100644 index 0000000..6cb3302 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerPlayerInfo.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using Impostor.Api.Innersloth; + +namespace Impostor.Api.Net.Inner.Objects +{ + public interface IInnerPlayerInfo + { + /// + /// Gets the name of the player as decided by the host. + /// + string PlayerName { get; } + + /// + /// Gets the color of the player. + /// + byte ColorId { get; } + + /// + /// Gets the hat of the player. + /// + uint HatId { get; } + + /// + /// Gets the pet of the player. + /// + uint PetId { get; } + + /// + /// Gets the skin of the player. + /// + uint SkinId { get; } + + /// + /// Gets a value indicating whether the player is an impostor. + /// + bool IsImpostor { get; } + + /// + /// Gets a value indicating whether the player is a dead in the current game. + /// + bool IsDead { get; } + + /// + /// Gets the reason why the player is dead in the current game. + /// + DeathReason LastDeathReason { get; } + + IEnumerable Tasks { get; } + + DateTimeOffset LastMurder { get; } + } +} diff --git a/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerShipStatus.cs b/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerShipStatus.cs new file mode 100644 index 0000000..c0a05ae --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerShipStatus.cs @@ -0,0 +1,7 @@ +namespace Impostor.Api.Net.Inner.Objects +{ + public interface IInnerShipStatus : IInnerNetObject + { + + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerVoteBanSystem.cs b/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerVoteBanSystem.cs new file mode 100644 index 0000000..d0a816d --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/IInnerVoteBanSystem.cs @@ -0,0 +1,7 @@ +namespace Impostor.Api.Net.Inner.Objects +{ + public interface IInnerVoteBanSystem : IInnerNetObject + { + + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/ITaskInfo.cs b/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/ITaskInfo.cs new file mode 100644 index 0000000..2b6dd86 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Inner/Objects/ITaskInfo.cs @@ -0,0 +1,14 @@ +using Impostor.Api.Innersloth; +using Impostor.Api.Net.Messages; + +namespace Impostor.Api.Net.Inner.Objects +{ + public interface ITaskInfo + { + uint Id { get; } + + TaskTypes Type { get; } + + bool Complete { get; } + } +} diff --git a/Impostor-dev/src/Impostor.Api/Net/LimboStates.cs b/Impostor-dev/src/Impostor.Api/Net/LimboStates.cs new file mode 100644 index 0000000..44c493e --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/LimboStates.cs @@ -0,0 +1,13 @@ +using System; + +namespace Impostor.Api.Net +{ + [Flags] + public enum LimboStates + { + PreSpawn = 1, + NotLimbo = 2, + WaitingForHost = 4, + All = PreSpawn | NotLimbo | WaitingForHost, + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Manager/IClientManager.cs b/Impostor-dev/src/Impostor.Api/Net/Manager/IClientManager.cs new file mode 100644 index 0000000..92bf89f --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Manager/IClientManager.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Impostor.Api.Net.Manager +{ + public interface IClientManager + { + IEnumerable Clients { get; } + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message00HostGameC2S.cs b/Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message00HostGameC2S.cs new file mode 100644 index 0000000..4f5b39c --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message00HostGameC2S.cs @@ -0,0 +1,27 @@ +using System.IO; +using Impostor.Api.Innersloth; + +namespace Impostor.Api.Net.Messages.C2S +{ + public static class Message00HostGameC2S + { + public static void Serialize(IMessageWriter writer, GameOptionsData gameOptionsData) + { + writer.StartMessage(MessageFlags.HostGame); + + using (var memory = new MemoryStream()) + using (var writerBin = new BinaryWriter(memory)) + { + gameOptionsData.Serialize(writerBin, GameOptionsData.LatestVersion); + writer.WriteBytesAndSize(memory.ToArray()); + } + + writer.EndMessage(); + } + + public static GameOptionsData Deserialize(IMessageReader reader) + { + return GameOptionsData.DeserializeCreate(reader); + } + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message01JoinGameC2S.cs b/Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message01JoinGameC2S.cs new file mode 100644 index 0000000..f121b97 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message01JoinGameC2S.cs @@ -0,0 +1,20 @@ +using System; + +namespace Impostor.Api.Net.Messages.C2S +{ + public static class Message01JoinGameC2S + { + public static void Serialize(IMessageWriter writer) + { + throw new System.NotImplementedException(); + } + + public static void Deserialize(IMessageReader reader, out int gameCode, out byte unknown) + { + var slice = reader.ReadBytes(sizeof(Int32) + sizeof(byte)).Span; + + gameCode = slice.ReadInt32(); + unknown = slice.ReadByte(); + } + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message04RemovePlayerC2S.cs b/Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message04RemovePlayerC2S.cs new file mode 100644 index 0000000..99cdcfa --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message04RemovePlayerC2S.cs @@ -0,0 +1,16 @@ +namespace Impostor.Api.Net.Messages.C2S +{ + public class Message04RemovePlayerC2S + { + public static void Serialize(IMessageWriter writer) + { + throw new System.NotImplementedException(); + } + + public static void Deserialize(IMessageReader reader, out int playerId, out byte reason) + { + playerId = reader.ReadPackedInt32(); + reason = reader.ReadByte(); + } + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message08EndGameC2S.cs b/Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message08EndGameC2S.cs new file mode 100644 index 0000000..7ca5e3a --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message08EndGameC2S.cs @@ -0,0 +1,18 @@ +using Impostor.Api.Innersloth; + +namespace Impostor.Api.Net.Messages.C2S +{ + public class Message08EndGameC2S + { + public static void Serialize(IMessageWriter writer) + { + throw new System.NotImplementedException(); + } + + public static void Deserialize(IMessageReader reader, out GameOverReason gameOverReason) + { + gameOverReason = (GameOverReason)reader.ReadByte(); + reader.ReadBoolean(); // showAd + } + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message10AlterGameC2S.cs b/Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message10AlterGameC2S.cs new file mode 100644 index 0000000..330f3b5 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message10AlterGameC2S.cs @@ -0,0 +1,20 @@ +using Impostor.Api.Innersloth; + +namespace Impostor.Api.Net.Messages.C2S +{ + public class Message10AlterGameC2S + { + public static void Serialize(IMessageWriter writer) + { + throw new System.NotImplementedException(); + } + + public static void Deserialize(IMessageReader reader, out AlterGameTags gameTag, out bool isPublic) + { + var slice = reader.ReadBytes(sizeof(byte) + sizeof(byte)).Span; + + gameTag = (AlterGameTags)slice.ReadByte(); + isPublic = slice.ReadBoolean(); + } + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message11KickPlayerC2S.cs b/Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message11KickPlayerC2S.cs new file mode 100644 index 0000000..7c5b8b9 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message11KickPlayerC2S.cs @@ -0,0 +1,16 @@ +namespace Impostor.Api.Net.Messages.C2S +{ + public class Message11KickPlayerC2S + { + public static void Serialize(IMessageWriter writer) + { + throw new System.NotImplementedException(); + } + + public static void Deserialize(IMessageReader reader, out int playerId, out bool isBan) + { + playerId = reader.ReadPackedInt32(); + isBan = reader.ReadBoolean(); + } + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message16GetGameListC2S.cs b/Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message16GetGameListC2S.cs new file mode 100644 index 0000000..2b7e12a --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Messages/C2S/Message16GetGameListC2S.cs @@ -0,0 +1,18 @@ +using Impostor.Api.Innersloth; + +namespace Impostor.Api.Net.Messages.C2S +{ + public class Message16GetGameListC2S + { + public static void Serialize(IMessageWriter writer) + { + throw new System.NotImplementedException(); + } + + public static void Deserialize(IMessageReader reader, out GameOptionsData options) + { + reader.ReadPackedInt32(); // Hardcoded 0. + options = GameOptionsData.DeserializeCreate(reader); + } + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Messages/IMessageReader.cs b/Impostor-dev/src/Impostor.Api/Net/Messages/IMessageReader.cs new file mode 100644 index 0000000..87c06c4 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Messages/IMessageReader.cs @@ -0,0 +1,68 @@ +using System; + +namespace Impostor.Api.Net.Messages +{ + public interface IMessageReader : IDisposable + { + /// + /// Gets the tag of the message. + /// + byte Tag { get; } + + /// + /// Gets the buffer of the message. + /// + byte[] Buffer { get; } + + /// + /// Gets the offset of our current in the entire . + /// + int Offset { get; } + + /// + /// Gets the current position of the reader. + /// + int Position { get; } + + /// + /// Gets the length of the buffer. + /// + int Length { get; } + + IMessageReader ReadMessage(); + + bool ReadBoolean(); + + sbyte ReadSByte(); + + byte ReadByte(); + + ushort ReadUInt16(); + + short ReadInt16(); + + uint ReadUInt32(); + + int ReadInt32(); + + float ReadSingle(); + + string ReadString(); + + ReadOnlyMemory ReadBytesAndSize(); + + ReadOnlyMemory ReadBytes(int length); + + int ReadPackedInt32(); + + uint ReadPackedUInt32(); + + void CopyTo(IMessageWriter writer); + + void Seek(int position); + + void RemoveMessage(IMessageReader message); + + IMessageReader Copy(int offset = 0); + } +} diff --git a/Impostor-dev/src/Impostor.Api/Net/Messages/IMessageWriter.cs b/Impostor-dev/src/Impostor.Api/Net/Messages/IMessageWriter.cs new file mode 100644 index 0000000..4f6765b --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Messages/IMessageWriter.cs @@ -0,0 +1,127 @@ +using System; +using System.Net; +using Impostor.Api.Games; + +namespace Impostor.Api.Net.Messages +{ + /// + /// Base message writer. + /// + public interface IMessageWriter : IDisposable + { + public byte[] Buffer { get; } + + public int Length { get; set; } + + public int Position { get; set; } + + public MessageType SendOption { get; } + + /// + /// Writes a boolean to the message. + /// + /// Value to write. + void Write(bool value); + + /// + /// Writes a sbyte to the message. + /// + /// Value to write. + void Write(sbyte value); + + /// + /// Writes a byte to the message. + /// + /// Value to write. + void Write(byte value); + + /// + /// Writes a short to the message. + /// + /// Value to write. + void Write(short value); + + /// + /// Writes an ushort to the message. + /// + /// Value to write. + void Write(ushort value); + + /// + /// Writes an uint to the message. + /// + /// Value to write. + void Write(uint value); + + /// + /// Writes an int to the message. + /// + /// Value to write. + void Write(int value); + + /// + /// Writes a float to the message. + /// + /// Value to write. + void Write(float value); + + /// + /// Writes a string to the message. + /// + /// Value to write. + void Write(string value); + + /// + /// Writes a to the message. + /// + /// Value to write. + void Write(IPAddress value); + + /// + /// Writes an packed int to the message. + /// + /// Value to write. + void WritePacked(int value); + + /// + /// Writes an packed uint to the message. + /// + /// Value to write. + void WritePacked(uint value); + + /// + /// Writes raw bytes to the message. + /// + /// Bytes to write. + void Write(ReadOnlyMemory data); + + /// + /// Writes a game code to the message. + /// + /// Value to write. + void Write(GameCode value); + + void WriteBytesAndSize(byte[] bytes); + + void WriteBytesAndSize(byte[] bytes, int length); + + void WriteBytesAndSize(byte[] bytes, int offset, int length); + + /// + /// Starts a new message. + /// + /// Message flag header. + void StartMessage(byte typeFlag); + + /// + /// Mark the end of the message. + /// + void EndMessage(); + + /// + /// Clear the message writer. + /// + /// New type of the message. + void Clear(MessageType type); + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Messages/IMessageWriterProvider.cs b/Impostor-dev/src/Impostor.Api/Net/Messages/IMessageWriterProvider.cs new file mode 100644 index 0000000..f398939 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Messages/IMessageWriterProvider.cs @@ -0,0 +1,16 @@ +namespace Impostor.Api.Net.Messages +{ + public interface IMessageWriterProvider + { + /// + /// Retrieves a from the internal pool. + /// Make sure to call when you are done! + /// + /// + /// Whether to send the message as or . + /// Reliable packets will ensure delivery while unreliable packets may be lost. + /// + /// A from the pool. + IMessageWriter Get(MessageType sendOption = MessageType.Unreliable); + } +} diff --git a/Impostor-dev/src/Impostor.Api/Net/Messages/MessageFlags.cs b/Impostor-dev/src/Impostor.Api/Net/Messages/MessageFlags.cs new file mode 100644 index 0000000..aea0c60 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Messages/MessageFlags.cs @@ -0,0 +1,22 @@ +namespace Impostor.Api.Net.Messages +{ + public static class MessageFlags + { + public const byte HostGame = 0; + public const byte JoinGame = 1; + public const byte StartGame = 2; + public const byte RemoveGame = 3; + public const byte RemovePlayer = 4; + public const byte GameData = 5; + public const byte GameDataTo = 6; + public const byte JoinedGame = 7; + public const byte EndGame = 8; + public const byte AlterGame = 10; + public const byte KickPlayer = 11; + public const byte WaitForHost = 12; + public const byte Redirect = 13; + public const byte ReselectServer = 14; + public const byte GetGameList = 9; + public const byte GetGameListV2 = 16; + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Messages/MessageType.cs b/Impostor-dev/src/Impostor.Api/Net/Messages/MessageType.cs new file mode 100644 index 0000000..1604358 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Messages/MessageType.cs @@ -0,0 +1,32 @@ +using System; + +namespace Impostor.Api.Net.Messages +{ + /// + /// Specifies how a message should be sent between connections. + /// + [Flags] + public enum MessageType : byte + { + /// + /// Requests unreliable delivery with no fragmentation. + /// + /// + /// Sending data using unreliable delivery means that data is not guaranteed to arrive at it's destination nor is + /// it guaranteed to arrive only once. However, unreliable delivery can be faster than other methods and it + /// typically requires a smaller number of protocol bytes than other methods. There is also typically less + /// processing involved and less memory needed as packets are not stored once sent. + /// + Unreliable, + + /// + /// Requests data be sent reliably but with no fragmentation. + /// + /// + /// Sending data reliably means that data is guaranteed to arrive and to arrive only once. Reliable delivery + /// typically requires more processing, more memory (as packets need to be stored in case they need resending), + /// a larger number of protocol bytes and can be slower than unreliable delivery. + /// + Reliable, + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message00HostGameS2C.cs b/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message00HostGameS2C.cs new file mode 100644 index 0000000..8402d10 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message00HostGameS2C.cs @@ -0,0 +1,20 @@ +using System; +using Impostor.Api.Innersloth; + +namespace Impostor.Api.Net.Messages.S2C +{ + public static class Message00HostGameS2C + { + public static void Serialize(IMessageWriter writer, int gameCode) + { + writer.StartMessage(MessageFlags.HostGame); + writer.Write(gameCode); + writer.EndMessage(); + } + + public static GameOptionsData Deserialize(IMessageReader reader) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message01JoinGameS2C.cs b/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message01JoinGameS2C.cs new file mode 100644 index 0000000..c455201 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message01JoinGameS2C.cs @@ -0,0 +1,50 @@ +using System; +using Impostor.Api.Innersloth; + +namespace Impostor.Api.Net.Messages.S2C +{ + public class Message01JoinGameS2C + { + public static void SerializeJoin(IMessageWriter writer, bool clear, int gameCode, int playerId, int hostId) + { + if (clear) + { + writer.Clear(MessageType.Reliable); + } + + writer.StartMessage(MessageFlags.JoinGame); + writer.Write(gameCode); + writer.Write(playerId); + writer.Write(hostId); + writer.EndMessage(); + } + + public static void SerializeError(IMessageWriter writer, bool clear, DisconnectReason reason, string? message = null) + { + if (clear) + { + writer.Clear(MessageType.Reliable); + } + + writer.StartMessage(MessageFlags.JoinGame); + writer.Write((int)reason); + + if (reason == DisconnectReason.Custom) + { + if (message == null) + { + throw new ArgumentNullException(nameof(message)); + } + + writer.Write(message); + } + + writer.EndMessage(); + } + + public static void Deserialize(IMessageReader reader) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message04RemovePlayerS2C.cs b/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message04RemovePlayerS2C.cs new file mode 100644 index 0000000..77b447d --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message04RemovePlayerS2C.cs @@ -0,0 +1,29 @@ +using Impostor.Api.Innersloth; + +namespace Impostor.Api.Net.Messages.S2C +{ + public class Message04RemovePlayerS2C + { + public static void Serialize(IMessageWriter writer, bool clear, int gameCode, int playerId, int hostId, DisconnectReason reason) + { + // Only a subset of DisconnectReason shows an unique message. + // ExitGame, Banned and Kicked. + if (clear) + { + writer.Clear(MessageType.Reliable); + } + + writer.StartMessage(MessageFlags.RemovePlayer); + writer.Write(gameCode); + writer.Write(playerId); + writer.Write(hostId); + writer.Write((byte)reason); + writer.EndMessage(); + } + + public static void Deserialize(IMessageReader reader) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message07JoinedGameS2C.cs b/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message07JoinedGameS2C.cs new file mode 100644 index 0000000..da6eb40 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message07JoinedGameS2C.cs @@ -0,0 +1,31 @@ +namespace Impostor.Api.Net.Messages.S2C +{ + public static class Message07JoinedGameS2C + { + public static void Serialize(IMessageWriter writer, bool clear, int gameCode, int playerId, int hostId, int[] otherPlayerIds) + { + if (clear) + { + writer.Clear(MessageType.Reliable); + } + + writer.StartMessage(MessageFlags.JoinedGame); + writer.Write(gameCode); + writer.Write(playerId); + writer.Write(hostId); + writer.WritePacked(otherPlayerIds.Length); + + foreach (var id in otherPlayerIds) + { + writer.WritePacked(id); + } + + writer.EndMessage(); + } + + public static void Deserialize(IMessageReader reader) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message10AlterGameS2C.cs b/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message10AlterGameS2C.cs new file mode 100644 index 0000000..fa155df --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message10AlterGameS2C.cs @@ -0,0 +1,26 @@ +using Impostor.Api.Innersloth; + +namespace Impostor.Api.Net.Messages.S2C +{ + public static class Message10AlterGameS2C + { + public static void Serialize(IMessageWriter writer, bool clear, int gameCode, bool isPublic) + { + if (clear) + { + writer.Clear(MessageType.Reliable); + } + + writer.StartMessage(MessageFlags.AlterGame); + writer.Write(gameCode); + writer.Write((byte)AlterGameTags.ChangePrivacy); + writer.Write(isPublic); + writer.EndMessage(); + } + + public static void Deserialize(IMessageReader reader) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message11KickPlayerS2C.cs b/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message11KickPlayerS2C.cs new file mode 100644 index 0000000..1e2b6ef --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message11KickPlayerS2C.cs @@ -0,0 +1,24 @@ +namespace Impostor.Api.Net.Messages.S2C +{ + public class Message11KickPlayerS2C + { + public static void Serialize(IMessageWriter writer, bool clear, int gameCode, int playerId, bool isBan) + { + if (clear) + { + writer.Clear(MessageType.Reliable); + } + + writer.StartMessage(MessageFlags.KickPlayer); + writer.Write(gameCode); + writer.WritePacked(playerId); + writer.Write(isBan); + writer.EndMessage(); + } + + public static void Deserialize(IMessageReader reader) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message12WaitForHostS2C.cs b/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message12WaitForHostS2C.cs new file mode 100644 index 0000000..5964b1c --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message12WaitForHostS2C.cs @@ -0,0 +1,23 @@ +namespace Impostor.Api.Net.Messages.S2C +{ + public class Message12WaitForHostS2C + { + public static void Serialize(IMessageWriter writer, bool clear, int gameCode, int playerId) + { + if (clear) + { + writer.Clear(MessageType.Reliable); + } + + writer.StartMessage(MessageFlags.WaitForHost); + writer.Write(gameCode); + writer.Write(playerId); + writer.EndMessage(); + } + + public static void Deserialize(IMessageReader reader) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message13RedirectS2C.cs b/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message13RedirectS2C.cs new file mode 100644 index 0000000..4b93b0e --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message13RedirectS2C.cs @@ -0,0 +1,25 @@ +using System.Net; + +namespace Impostor.Api.Net.Messages.S2C +{ + public class Message13RedirectS2C + { + public static void Serialize(IMessageWriter writer, bool clear, IPEndPoint ipEndPoint) + { + if (clear) + { + writer.Clear(MessageType.Reliable); + } + + writer.StartMessage(MessageFlags.Redirect); + writer.Write(ipEndPoint.Address); + writer.Write((ushort)ipEndPoint.Port); + writer.EndMessage(); + } + + public static void Deserialize(IMessageReader reader) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message16GetGameListS2C.cs b/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message16GetGameListS2C.cs new file mode 100644 index 0000000..93386d7 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Net/Messages/S2C/Message16GetGameListS2C.cs @@ -0,0 +1,46 @@ +using System.Collections.Generic; +using Impostor.Api.Games; + +namespace Impostor.Api.Net.Messages.S2C +{ + public class Message16GetGameListS2C + { + public static void Serialize(IMessageWriter writer, int skeldGameCount, int miraHqGameCount, int polusGameCount, IEnumerable games) + { + writer.StartMessage(MessageFlags.GetGameListV2); + + // Count + writer.StartMessage(1); + writer.Write(skeldGameCount); // The Skeld + writer.Write(miraHqGameCount); // Mira HQ + writer.Write(polusGameCount); // Polus + writer.EndMessage(); + + // Listing + writer.StartMessage(0); + + foreach (var game in games) + { + writer.StartMessage(0); + writer.Write(game.PublicIp.Address); + writer.Write((ushort)game.PublicIp.Port); + writer.Write(game.Code); + writer.Write(game.Host.Client.Name); + writer.Write((byte)game.PlayerCount); + writer.WritePacked(1); // TODO: What does Age do? + writer.Write((byte)game.Options.MapId); + writer.Write((byte)game.Options.NumImpostors); + writer.Write((byte)game.Options.MaxPlayers); + writer.EndMessage(); + } + + writer.EndMessage(); + writer.EndMessage(); + } + + public static void Deserialize(IMessageReader reader) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file -- cgit v1.1-26-g67d0