]> git.deb.at Git - rhonda/impostor.git/commitdiff
Remove login from Impostor.Api assembly
authorAeonLucid <aeonlucid@outlook.com>
Sat, 24 Oct 2020 19:56:51 +0000 (21:56 +0200)
committerAeonLucid <aeonlucid@outlook.com>
Sat, 24 Oct 2020 19:56:51 +0000 (21:56 +0200)
114 files changed:
src/Impostor.Api/Events/Game/Net/PlayerChatEvent.cs
src/Impostor.Api/Events/Game/Net/PlayerDestroyedEvent.cs
src/Impostor.Api/Events/Game/Net/PlayerSpawnedEvent.cs
src/Impostor.Api/Extensions/MessageReaderExtensions.cs [deleted file]
src/Impostor.Api/Extensions/SystemTypesExtensions.cs
src/Impostor.Api/Games/Extensions/GameManagerExtensions.cs
src/Impostor.Api/Games/IGame.cs
src/Impostor.Api/Innersloth/AlterGameTags.cs [new file with mode: 0644]
src/Impostor.Api/Innersloth/ChatNoteType.cs [new file with mode: 0644]
src/Impostor.Api/Innersloth/Data/AlterGameTags.cs [deleted file]
src/Impostor.Api/Innersloth/Data/ChatNoteType.cs [deleted file]
src/Impostor.Api/Innersloth/Data/DeathReason.cs [deleted file]
src/Impostor.Api/Innersloth/Data/DisconnectReason.cs [deleted file]
src/Impostor.Api/Innersloth/Data/GameKeywords.cs [deleted file]
src/Impostor.Api/Innersloth/Data/GameStates.cs [deleted file]
src/Impostor.Api/Innersloth/Data/MapFlags.cs [deleted file]
src/Impostor.Api/Innersloth/Data/MapId.cs [deleted file]
src/Impostor.Api/Innersloth/DeathReason.cs [new file with mode: 0644]
src/Impostor.Api/Innersloth/DisconnectReason.cs [new file with mode: 0644]
src/Impostor.Api/Innersloth/GameKeywords.cs [new file with mode: 0644]
src/Impostor.Api/Innersloth/GameOptionsData.cs
src/Impostor.Api/Innersloth/GameStates.cs [new file with mode: 0644]
src/Impostor.Api/Innersloth/MapFlags.cs [new file with mode: 0644]
src/Impostor.Api/Innersloth/MapId.cs [new file with mode: 0644]
src/Impostor.Api/Innersloth/Net/GameDataTag.cs [deleted file]
src/Impostor.Api/Innersloth/Net/GameObject.cs [deleted file]
src/Impostor.Api/Innersloth/Net/IGameNet.cs [deleted file]
src/Impostor.Api/Innersloth/Net/InnerNetObject.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/Components/InnerCustomNetworkTransform.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/Components/InnerPlayerPhysics.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/Components/InnerVoteBanSystem.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/InnerGameData.PlayerInfo.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/InnerGameData.TaskInfo.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/InnerGameData.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/InnerLobbyBehaviour.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/InnerMeetingHud.PlayerVoteArea.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/InnerMeetingHud.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/InnerPlayerControl.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/InnerShipStatus.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/Systems/IActivatable.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/Systems/ISystemType.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/DoorsSystemType.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/HudOverrideSystemType.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/LifeSuppSystemType.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/MedScanSystem.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/ReactorSystemType.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/SabotageSystemType.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/SecurityCameraSystemType.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/SwitchSystem.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/Systems/SystemTypeHelpers.cs [deleted file]
src/Impostor.Api/Innersloth/Net/Objects/Systems/SystemTypes.cs [deleted file]
src/Impostor.Api/Innersloth/Net/RpcCalls.cs [deleted file]
src/Impostor.Api/Innersloth/Net/SpawnFlags.cs [deleted file]
src/Impostor.Api/Innersloth/SystemTypeHelpers.cs [new file with mode: 0644]
src/Impostor.Api/Innersloth/SystemTypes.cs [new file with mode: 0644]
src/Impostor.Api/Net/IClientPlayer.cs
src/Impostor.Api/Net/Inner/IGameNet.cs [new file with mode: 0644]
src/Impostor.Api/Net/Inner/IInnerNetObject.cs [new file with mode: 0644]
src/Impostor.Api/Net/Inner/Objects/IInnerGameData.cs [new file with mode: 0644]
src/Impostor.Api/Net/Inner/Objects/IInnerLobbyBehaviour.cs [new file with mode: 0644]
src/Impostor.Api/Net/Inner/Objects/IInnerPlayerControl.cs [new file with mode: 0644]
src/Impostor.Api/Net/Inner/Objects/IInnerShipStatus.cs [new file with mode: 0644]
src/Impostor.Api/Net/Inner/Objects/IInnerVoteBanSystem.cs [new file with mode: 0644]
src/Impostor.Api/Net/LimboStates.cs
src/Impostor.Api/Net/Messages/C2S/Message10AlterGameC2S.cs
src/Impostor.Api/Net/Messages/S2C/Message01JoinGameS2C.cs
src/Impostor.Api/Net/Messages/S2C/Message04RemovePlayerS2C.cs
src/Impostor.Api/Net/Messages/S2C/Message10AlterGameS2C.cs
src/Impostor.Api/Plugins/IPlugin.cs
src/Impostor.Server/Events/EventManager.cs
src/Impostor.Server/Events/Register/TemporaryEventRegister.cs
src/Impostor.Server/Extensions/MessageReaderExtensions.cs [new file with mode: 0644]
src/Impostor.Server/Extensions/NodeLocatorExtensions.cs
src/Impostor.Server/Net/Client.cs
src/Impostor.Server/Net/Factories/ClientFactory.cs
src/Impostor.Server/Net/Inner/GameDataTag.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/GameObject.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/InnerNetObject.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/Components/InnerCustomNetworkTransform.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/Components/InnerPlayerPhysics.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/Components/InnerVoteBanSystem.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/InnerGameData.PlayerInfo.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/InnerGameData.TaskInfo.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/InnerGameData.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/InnerLobbyBehaviour.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/InnerMeetingHud.PlayerVoteArea.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/InnerMeetingHud.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/InnerPlayerControl.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/InnerShipStatus.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/Systems/IActivatable.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/Systems/ISystemType.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/DoorsSystemType.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/HudOverrideSystemType.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/LifeSuppSystemType.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/MedScanSystem.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/ReactorSystemType.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/SabotageSystemType.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/SecurityCameraSystemType.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/SwitchSystem.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/RpcCalls.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/SpawnFlags.cs [new file with mode: 0644]
src/Impostor.Server/Net/Manager/ClientManager.cs
src/Impostor.Server/Net/Manager/GameManager.cs
src/Impostor.Server/Net/Redirector/ClientRedirector.cs
src/Impostor.Server/Net/State/ClientPlayer.Api.cs
src/Impostor.Server/Net/State/ClientPlayer.cs
src/Impostor.Server/Net/State/Game.Api.cs
src/Impostor.Server/Net/State/Game.Data.cs
src/Impostor.Server/Net/State/Game.Incoming.cs
src/Impostor.Server/Net/State/Game.Outgoing.cs
src/Impostor.Server/Net/State/Game.State.cs
src/Impostor.Server/Net/State/Game.cs
src/Impostor.Server/Net/State/GameNet.Api.cs [new file with mode: 0644]
src/Impostor.Server/Net/State/GameNet.cs

index bbf0256afbe9d1978e6cdefd6dd64812f533e402..cac481c20c4fdaf3a9513388636590a83a4ea9bd 100644 (file)
@@ -1,11 +1,11 @@
 using Impostor.Api.Games;
-using Impostor.Api.Innersloth.Net.Objects;
+using Impostor.Api.Net.Inner.Objects;
 
 namespace Impostor.Api.Events.Net
 {
     public class PlayerChatEvent : IGameEvent
     {
-        public PlayerChatEvent(IGame game, InnerPlayerControl playerControl, string message)
+        public PlayerChatEvent(IGame game, IInnerPlayerControl playerControl, string message)
         {
             Game = game;
             PlayerControl = playerControl;
@@ -14,7 +14,7 @@ namespace Impostor.Api.Events.Net
 
         public IGame Game { get; }
 
-        public InnerPlayerControl PlayerControl { get; }
+        public IInnerPlayerControl PlayerControl { get; }
 
         public string Message { get; }
     }
index a3b2289efa3b9ed016da4df1532f20210b30b959..6d5d8c42b3730150b0be86f1dd2cf29ec0cef9fc 100644 (file)
@@ -1,11 +1,11 @@
 using Impostor.Api.Games;
-using Impostor.Api.Innersloth.Net.Objects;
+using Impostor.Api.Net.Inner.Objects;
 
 namespace Impostor.Api.Events.Net
 {
     public class PlayerDestroyedEvent : IGameEvent
     {
-        public PlayerDestroyedEvent(IGame game, InnerPlayerControl playerControl)
+        public PlayerDestroyedEvent(IGame game, IInnerPlayerControl playerControl)
         {
             Game = game;
             PlayerControl = playerControl;
@@ -13,6 +13,6 @@ namespace Impostor.Api.Events.Net
 
         public IGame Game { get; }
 
-        public InnerPlayerControl PlayerControl { get; }
+        public IInnerPlayerControl PlayerControl { get; }
     }
 }
\ No newline at end of file
index d91e0d13eebb85afe866a0b73e12601a5d9da73b..9b1664a987c7c8e3688c8a5b1b7838c92545aca2 100644 (file)
@@ -1,11 +1,11 @@
 using Impostor.Api.Games;
-using Impostor.Api.Innersloth.Net.Objects;
+using Impostor.Api.Net.Inner.Objects;
 
 namespace Impostor.Api.Events.Net
 {
     public class PlayerSpawnedEvent : IGameEvent
     {
-        public PlayerSpawnedEvent(IGame game, InnerPlayerControl playerControl)
+        public PlayerSpawnedEvent(IGame game, IInnerPlayerControl playerControl)
         {
             Game = game;
             PlayerControl = playerControl;
@@ -13,6 +13,6 @@ namespace Impostor.Api.Events.Net
 
         public IGame Game { get; }
 
-        public InnerPlayerControl PlayerControl { get; }
+        public IInnerPlayerControl PlayerControl { get; }
     }
 }
\ No newline at end of file
diff --git a/src/Impostor.Api/Extensions/MessageReaderExtensions.cs b/src/Impostor.Api/Extensions/MessageReaderExtensions.cs
deleted file mode 100644 (file)
index 94e7d99..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-using Impostor.Api.Games;
-using Impostor.Api.Innersloth.Net;
-using Impostor.Api.Net.Messages;
-
-namespace Impostor.Api
-{
-    public static class MessageReaderExtensions
-    {
-        public static T ReadNetObject<T>(this IMessageReader reader, IGame game)
-            where T : InnerNetObject
-        {
-            return game.FindObjectByNetId<T>(reader.ReadPackedUInt32());
-        }
-    }
-}
\ No newline at end of file
index e927e2e483ce64b87af448aed29ded597b9ddbc7..68f1efda1e9fa14a7eac51ade7c7a4a24246074f 100644 (file)
@@ -1,4 +1,4 @@
-using Impostor.Api.Innersloth.Net.Objects.Systems;
+using Impostor.Api.Innersloth;
 
 namespace Impostor.Api
 {
index 1f4bd5dc472ab78b55463689dba287cf0811622b..9a5a2b4f1eb29b646bf0b4541d0d02c4b57c9957 100644 (file)
@@ -1,6 +1,6 @@
 using System.Linq;
 using Impostor.Api.Games.Managers;
-using Impostor.Api.Innersloth.Data;
+using Impostor.Api.Innersloth;
 
 namespace Impostor.Api.Games
 {
index b098f7d1f069f444a82e25f31e26986b9d3db60e..17f67f1b84a6ef6e609d1ad54ede74b5f3bbcf0c 100644 (file)
@@ -2,9 +2,8 @@
 using System.Net;
 using System.Threading.Tasks;
 using Impostor.Api.Innersloth;
-using Impostor.Api.Innersloth.Data;
-using Impostor.Api.Innersloth.Net;
 using Impostor.Api.Net;
+using Impostor.Api.Net.Inner;
 using Impostor.Api.Net.Messages;
 
 namespace Impostor.Api.Games
@@ -35,9 +34,6 @@ namespace Impostor.Api.Games
 
         IClientPlayer GetClientPlayer(int clientId);
 
-        T FindObjectByNetId<T>(uint netId)
-            where T : InnerNetObject;
-
         /// <summary>
         ///     Send the message to all players.
         /// </summary>
diff --git a/src/Impostor.Api/Innersloth/AlterGameTags.cs b/src/Impostor.Api/Innersloth/AlterGameTags.cs
new file mode 100644 (file)
index 0000000..46d1b2e
--- /dev/null
@@ -0,0 +1,7 @@
+namespace Impostor.Api.Innersloth
+{
+    public enum AlterGameTags : byte
+    {
+        ChangePrivacy = 1,
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/ChatNoteType.cs b/src/Impostor.Api/Innersloth/ChatNoteType.cs
new file mode 100644 (file)
index 0000000..c163601
--- /dev/null
@@ -0,0 +1,7 @@
+namespace Impostor.Api.Innersloth
+{
+    public enum ChatNoteType : byte
+    {
+        DidVote = 0,
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Data/AlterGameTags.cs b/src/Impostor.Api/Innersloth/Data/AlterGameTags.cs
deleted file mode 100644 (file)
index ee13ae2..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Impostor.Api.Innersloth.Data
-{
-    public enum AlterGameTags : byte
-    {
-        ChangePrivacy = 1
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Data/ChatNoteType.cs b/src/Impostor.Api/Innersloth/Data/ChatNoteType.cs
deleted file mode 100644 (file)
index 04c3278..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Impostor.Api.Innersloth.Data
-{
-    public enum ChatNoteType : byte
-    {
-        DidVote = 0,
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Data/DeathReason.cs b/src/Impostor.Api/Innersloth/Data/DeathReason.cs
deleted file mode 100644 (file)
index c473bfb..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Impostor.Api.Innersloth.Data
-{
-    public enum DeathReason
-    {
-        Exile = 0,
-        Kill = 1,
-        Disconnect = 2
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Data/DisconnectReason.cs b/src/Impostor.Api/Innersloth/Data/DisconnectReason.cs
deleted file mode 100644 (file)
index e1a8e3a..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-namespace Impostor.Api.Innersloth.Data
-{
-    public enum DisconnectReason
-    {
-        ExitGame = 0,
-        // The game you tried to join is full.
-        // Check with the host to see if you can join next round.
-        GameFull = 1,
-        // The game you tried to join already started.
-        // Check with the host to see if you can join next round.
-        GameStarted = 2,
-        // Could not find the game you're looking for.
-        GameMissing = 3,
-        IncorrectGame = 18,
-        // For these a message can be given, specifying an empty message shows
-        // "An unknown error disconnected you from the server."
-        CustomMessage1 = 4,
-        Custom = 8,
-        // CustomMessage3 = 11,
-        // CustomMessage4 = 12,
-        // CustomMessage5 = 13,
-        // CustomMessage6 = 14,
-        // CustomMessage7 = 15,
-        // You are running an older version of the game.
-        // Please update to play with others.
-        IncorrectVersion = 5,
-        // You cannot rejoin that room.
-        // You were banned
-        Banned = 6,
-        // You can rejoin if the room hasn't started
-        // You were kicked
-        Kicked = 7,
-        // You were banned for hacking.
-        // Please stop.
-        Hacking = 10,
-        Destroy = 16,
-        // You disconnected from the host.
-        // If this happens often, check your WiFi strength.
-        //
-        // You disconnected from the server.
-        // If this happens often, check your network strength.
-        // This may also be a server issue.
-        Error = 17,
-        // The server stopped this game. Possibly due to inactivity.
-        ServerRequest = 19,
-        // The Among Us servers are overloaded.
-        // Sorry! Please try again later!
-        ServerFull = 20,
-        FocusLostBackground = 207,
-        IntentionalLeaving = 208,
-        FocusLost = 209,
-        NewConnection = 210
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Data/GameKeywords.cs b/src/Impostor.Api/Innersloth/Data/GameKeywords.cs
deleted file mode 100644 (file)
index f3b37cc..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-using System;
-
-namespace Impostor.Api.Innersloth.Data
-{
-    [Flags]
-    public enum GameKeywords : uint
-    {
-        All = 0,
-        Other = 1,
-        Spanish = 2,
-        Korean = 4,
-        Russian = 8,
-        Portuguese = 16,
-        Arabic = 32,
-        Filipone = 64,
-        Polish = 128,
-        English = 256
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Data/GameStates.cs b/src/Impostor.Api/Innersloth/Data/GameStates.cs
deleted file mode 100644 (file)
index 986e2d2..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Impostor.Api.Innersloth.Data
-{
-    public enum GameStates : byte
-    {
-        NotStarted = 0,
-        Started = 1,
-        Ended = 2,
-        Destroyed = 3
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Data/MapFlags.cs b/src/Impostor.Api/Innersloth/Data/MapFlags.cs
deleted file mode 100644 (file)
index 66e0c95..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-using System;
-
-namespace Impostor.Api.Innersloth.Data
-{
-    [Flags]
-    public enum MapFlags
-    {
-        Skeld = 1,
-        MiraHQ = 2,
-        Polus = 4
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Data/MapId.cs b/src/Impostor.Api/Innersloth/Data/MapId.cs
deleted file mode 100644 (file)
index 97d79d4..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Impostor.Api.Innersloth.Data
-{
-    public static class MapId
-    {
-        // TODO: Not sure if correct, check
-        public const int Skeld = 0;
-        public const int MiraHQ = 1;
-        public const int Polus = 2;
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/DeathReason.cs b/src/Impostor.Api/Innersloth/DeathReason.cs
new file mode 100644 (file)
index 0000000..a07ac05
--- /dev/null
@@ -0,0 +1,9 @@
+namespace Impostor.Api.Innersloth
+{
+    public enum DeathReason
+    {
+        Exile = 0,
+        Kill = 1,
+        Disconnect = 2,
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/DisconnectReason.cs b/src/Impostor.Api/Innersloth/DisconnectReason.cs
new file mode 100644 (file)
index 0000000..9526f58
--- /dev/null
@@ -0,0 +1,54 @@
+namespace Impostor.Api.Innersloth
+{
+    public enum DisconnectReason
+    {
+        ExitGame = 0,
+        // The game you tried to join is full.
+        // Check with the host to see if you can join next round.
+        GameFull = 1,
+        // The game you tried to join already started.
+        // Check with the host to see if you can join next round.
+        GameStarted = 2,
+        // Could not find the game you're looking for.
+        GameMissing = 3,
+        IncorrectGame = 18,
+        // For these a message can be given, specifying an empty message shows
+        // "An unknown error disconnected you from the server."
+        CustomMessage1 = 4,
+        Custom = 8,
+        // CustomMessage3 = 11,
+        // CustomMessage4 = 12,
+        // CustomMessage5 = 13,
+        // CustomMessage6 = 14,
+        // CustomMessage7 = 15,
+        // You are running an older version of the game.
+        // Please update to play with others.
+        IncorrectVersion = 5,
+        // You cannot rejoin that room.
+        // You were banned
+        Banned = 6,
+        // You can rejoin if the room hasn't started
+        // You were kicked
+        Kicked = 7,
+        // You were banned for hacking.
+        // Please stop.
+        Hacking = 10,
+        Destroy = 16,
+        // You disconnected from the host.
+        // If this happens often, check your WiFi strength.
+        //
+        // You disconnected from the server.
+        // If this happens often, check your network strength.
+        // This may also be a server issue.
+        Error = 17,
+        // The server stopped this game. Possibly due to inactivity.
+        ServerRequest = 19,
+        // The Among Us servers are overloaded.
+        // Sorry! Please try again later!
+        ServerFull = 20,
+        FocusLostBackground = 207,
+        IntentionalLeaving = 208,
+        FocusLost = 209,
+        NewConnection = 210,
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/GameKeywords.cs b/src/Impostor.Api/Innersloth/GameKeywords.cs
new file mode 100644 (file)
index 0000000..bbb463f
--- /dev/null
@@ -0,0 +1,19 @@
+using System;
+
+namespace Impostor.Api.Innersloth
+{
+    [Flags]
+    public enum GameKeywords : uint
+    {
+        All = 0,
+        Other = 1,
+        Spanish = 2,
+        Korean = 4,
+        Russian = 8,
+        Portuguese = 16,
+        Arabic = 32,
+        Filipone = 64,
+        Polish = 128,
+        English = 256,
+    }
+}
\ No newline at end of file
index 5ffc1ff9b07323ae785d5c0fbd8afe193475b0c3..f58f19170a5ac57f36f570832a26449af0d0de87 100644 (file)
@@ -1,6 +1,5 @@
 using System;
 using System.IO;
-using Impostor.Api.Innersloth.Data;
 using Impostor.Api.Net.Messages;
 
 namespace Impostor.Api.Innersloth
diff --git a/src/Impostor.Api/Innersloth/GameStates.cs b/src/Impostor.Api/Innersloth/GameStates.cs
new file mode 100644 (file)
index 0000000..8abc8c7
--- /dev/null
@@ -0,0 +1,10 @@
+namespace Impostor.Api.Innersloth
+{
+    public enum GameStates : byte
+    {
+        NotStarted = 0,
+        Started = 1,
+        Ended = 2,
+        Destroyed = 3
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/MapFlags.cs b/src/Impostor.Api/Innersloth/MapFlags.cs
new file mode 100644 (file)
index 0000000..ad462a2
--- /dev/null
@@ -0,0 +1,12 @@
+using System;
+
+namespace Impostor.Api.Innersloth
+{
+    [Flags]
+    public enum MapFlags
+    {
+        Skeld = 1,
+        MiraHQ = 2,
+        Polus = 4,
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/MapId.cs b/src/Impostor.Api/Innersloth/MapId.cs
new file mode 100644 (file)
index 0000000..c075d73
--- /dev/null
@@ -0,0 +1,10 @@
+namespace Impostor.Api.Innersloth
+{
+    public static class MapId
+    {
+        // TODO: Not sure if correct, check
+        public const int Skeld = 0;
+        public const int MiraHQ = 1;
+        public const int Polus = 2;
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/GameDataTag.cs b/src/Impostor.Api/Innersloth/Net/GameDataTag.cs
deleted file mode 100644 (file)
index ae2c879..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Impostor.Api.Innersloth.Net
-{
-    public static class GameDataTag
-    {
-        public const byte DataFlag = 1;
-        public const byte RpcFlag = 2;
-        public const byte SpawnFlag = 4;
-        public const byte DespawnFlag = 5;
-        public const byte SceneChangeFlag = 6;
-        public const byte ReadyFlag = 7;
-        public const byte ChangeSettingsFlag = 8;
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/GameObject.cs b/src/Impostor.Api/Innersloth/Net/GameObject.cs
deleted file mode 100644 (file)
index c58e4fb..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-using System.Collections.Generic;
-
-namespace Impostor.Api.Innersloth.Net
-{
-    public class GameObject
-    {
-        public GameObject()
-        {
-            Components = new List<object>();
-        }
-
-        protected List<object> Components { get; }
-
-        public List<T> GetComponentsInChildren<T>()
-        {
-            var result = new List<T>();
-
-            foreach (var component in Components)
-            {
-                if (component is T c)
-                {
-                    result.Add(c);
-                }
-            }
-
-            return result;
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/IGameNet.cs b/src/Impostor.Api/Innersloth/Net/IGameNet.cs
deleted file mode 100644 (file)
index b1061f0..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-using Impostor.Api.Innersloth.Net.Objects;
-using Impostor.Api.Innersloth.Net.Objects.Components;
-
-namespace Impostor.Api.Innersloth.Net
-{
-    public interface IGameNet
-    {
-        InnerLobbyBehaviour LobbyBehaviour { get; }
-
-        InnerGameData GameData { get; }
-
-        InnerVoteBanSystem VoteBan { get; }
-
-        InnerShipStatus ShipStatus { get; }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/InnerNetObject.cs b/src/Impostor.Api/Innersloth/Net/InnerNetObject.cs
deleted file mode 100644 (file)
index dc877a2..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-using System.Threading.Tasks;
-using Impostor.Api.Net;
-using Impostor.Api.Net.Messages;
-
-namespace Impostor.Api.Innersloth.Net
-{
-    public abstract class InnerNetObject : GameObject
-    {
-        private const int HostInheritId = -2;
-
-        public uint NetId { get; internal set; }
-
-        public int OwnerId { get; internal set; }
-
-        public SpawnFlags SpawnFlags { get; internal set; }
-
-        public abstract ValueTask HandleRpc(IClientPlayer sender, IClientPlayer? target, RpcCalls call, IMessageReader reader);
-
-        public abstract bool Serialize(IMessageWriter writer, bool initialState);
-
-        public abstract void Deserialize(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState);
-
-        public bool IsOwnedBy(IClientPlayer player)
-        {
-            return OwnerId == player.Client.Id ||
-                   (OwnerId == HostInheritId && player.IsHost);
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/Components/InnerCustomNetworkTransform.cs b/src/Impostor.Api/Innersloth/Net/Objects/Components/InnerCustomNetworkTransform.cs
deleted file mode 100644 (file)
index ae5f6fe..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-using System;
-using System.Numerics;
-using System.Threading.Tasks;
-using Impostor.Api.Net;
-using Impostor.Api.Net.Messages;
-using Microsoft.Extensions.Logging;
-
-namespace Impostor.Api.Innersloth.Net.Objects.Components
-{
-    public class InnerCustomNetworkTransform : InnerNetObject
-    {
-        private static readonly FloatRange XRange = new FloatRange(-40f, 40f);
-        private static readonly FloatRange YRange = new FloatRange(-40f, 40f);
-
-        private readonly ILogger<InnerCustomNetworkTransform> _logger;
-
-        private ushort _lastSequenceId;
-        private Vector2 _targetSyncPosition;
-        private Vector2 _targetSyncVelocity;
-
-        public InnerCustomNetworkTransform(ILogger<InnerCustomNetworkTransform> logger)
-        {
-            _logger = logger;
-        }
-
-        private static bool SidGreaterThan(ushort newSid, ushort prevSid)
-        {
-            var num = (ushort)(prevSid + (uint) short.MaxValue);
-
-            return (int) prevSid < (int) num
-                ? newSid > prevSid && newSid <= num
-                : newSid > prevSid || newSid <= num;
-        }
-
-        private static void WriteVector2(IMessageWriter writer, Vector2 vec)
-        {
-            writer.Write((ushort)(XRange.ReverseLerp(vec.X) * (double) ushort.MaxValue));
-            writer.Write((ushort)(YRange.ReverseLerp(vec.Y) * (double) ushort.MaxValue));
-        }
-
-        private static Vector2 ReadVector2(IMessageReader reader)
-        {
-            var v1 = reader.ReadUInt16() / (float) ushort.MaxValue;
-            var v2 = reader.ReadUInt16() / (float) ushort.MaxValue;
-
-            return new Vector2(XRange.Lerp(v1), YRange.Lerp(v2));
-        }
-
-        public override ValueTask HandleRpc(IClientPlayer sender, IClientPlayer? target, RpcCalls call, IMessageReader reader)
-        {
-            if (call == RpcCalls.SnapTo)
-            {
-                SnapTo(ReadVector2(reader), reader.ReadUInt16());
-            }
-            else
-            {
-                _logger.LogWarning("{0}: Unknown rpc call {1}", nameof(InnerCustomNetworkTransform), call);
-            }
-
-            return default;
-        }
-
-        public override bool Serialize(IMessageWriter writer, bool initialState)
-        {
-            if (initialState)
-            {
-                writer.Write(_lastSequenceId);
-                WriteVector2(writer, _targetSyncPosition);
-                WriteVector2(writer, _targetSyncVelocity);
-                return true;
-            }
-
-            // TODO: DirtyBits == 0 return false.
-            _lastSequenceId++;
-
-            writer.Write(_lastSequenceId);
-            WriteVector2(writer, _targetSyncPosition);
-            WriteVector2(writer, _targetSyncVelocity);
-            return true;
-        }
-
-        public override void Deserialize(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState)
-        {
-            var sequenceId = reader.ReadUInt16();
-
-            if (initialState)
-            {
-                _lastSequenceId = sequenceId;
-                _targetSyncPosition = ReadVector2(reader);
-                _targetSyncVelocity = ReadVector2(reader);
-            }
-            else
-            {
-                if (!sender.IsOwner(this))
-                {
-                    throw new ImpostorCheatException($"Client attempted to send unowned {nameof(InnerCustomNetworkTransform)} data");
-                }
-
-                if (target != null)
-                {
-                    throw new ImpostorCheatException($"Client attempted to send {nameof(InnerCustomNetworkTransform)} data to a specific player, must be broadcast");
-                }
-
-                if (!SidGreaterThan(sequenceId, _lastSequenceId))
-                {
-                    return;
-                }
-
-                _lastSequenceId = sequenceId;
-                _targetSyncPosition = ReadVector2(reader);
-                _targetSyncVelocity = ReadVector2(reader);
-            }
-        }
-
-        private void SnapTo(Vector2 position, ushort minSid)
-        {
-            if (SidGreaterThan(minSid, _lastSequenceId))
-            {
-                return;
-            }
-
-            _lastSequenceId = minSid;
-            _targetSyncPosition = position;
-            _targetSyncVelocity = Vector2.Zero;
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/Components/InnerPlayerPhysics.cs b/src/Impostor.Api/Innersloth/Net/Objects/Components/InnerPlayerPhysics.cs
deleted file mode 100644 (file)
index 5b1e883..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-using System;
-using System.Threading.Tasks;
-using Impostor.Api.Net;
-using Impostor.Api.Net.Messages;
-using Microsoft.Extensions.Logging;
-
-namespace Impostor.Api.Innersloth.Net.Objects.Components
-{
-    public class InnerPlayerPhysics : InnerNetObject
-    {
-        private readonly ILogger<InnerPlayerPhysics> _logger;
-
-        public InnerPlayerPhysics(ILogger<InnerPlayerPhysics> logger)
-        {
-            _logger = logger;
-        }
-
-        public override ValueTask HandleRpc(IClientPlayer sender, IClientPlayer? target, RpcCalls call, IMessageReader reader)
-        {
-            if (call != RpcCalls.EnterVent && call != RpcCalls.ExitVent)
-            {
-                _logger.LogWarning("{0}: Unknown rpc call {1}", nameof(InnerPlayerPhysics), call);
-                return default;
-            }
-
-            if (!sender.IsOwner(this))
-            {
-                throw new ImpostorCheatException($"Client sent {call} to an unowned {nameof(InnerPlayerControl)}");
-            }
-
-            if (target != null)
-            {
-                throw new ImpostorCheatException($"Client sent {call} to a specific player instead of broadcast");
-            }
-
-            if (!sender.Character.PlayerInfo.IsImpostor)
-            {
-                throw new ImpostorCheatException($"Client sent {call} as crewmate");
-            }
-
-            var ventId = reader.ReadPackedUInt32();
-            var ventEnter = call == RpcCalls.EnterVent;
-
-            // TODO: Do stuff.
-
-            return default;
-        }
-
-        public override bool Serialize(IMessageWriter writer, bool initialState)
-        {
-            throw new NotImplementedException();
-        }
-
-        public override void Deserialize(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState)
-        {
-            throw new NotImplementedException();
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/Components/InnerVoteBanSystem.cs b/src/Impostor.Api/Innersloth/Net/Objects/Components/InnerVoteBanSystem.cs
deleted file mode 100644 (file)
index 4b20af9..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using Impostor.Api.Net;
-using Impostor.Api.Net.Messages;
-using Microsoft.Extensions.Logging;
-
-namespace Impostor.Api.Innersloth.Net.Objects.Components
-{
-    public class InnerVoteBanSystem : InnerNetObject
-    {
-        private readonly ILogger<InnerVoteBanSystem> _logger;
-        private readonly Dictionary<int, int[]> _votes;
-
-        public InnerVoteBanSystem(ILogger<InnerVoteBanSystem> logger)
-        {
-            _logger = logger;
-            _votes = new Dictionary<int, int[]>();
-        }
-
-        public override ValueTask HandleRpc(IClientPlayer sender, IClientPlayer? target, RpcCalls call, IMessageReader reader)
-        {
-            if (call != RpcCalls.AddVote)
-            {
-                _logger.LogWarning("{0}: Unknown rpc call {1}", nameof(InnerVoteBanSystem), call);
-                return default;
-            }
-
-            var clientId = reader.ReadInt32();
-            if (clientId != sender.Client.Id)
-            {
-                throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.AddVote)} as other client");
-            }
-
-            if (target != null)
-            {
-                throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.CastVote)} to wrong destinition, must be broadcast");
-            }
-
-            var targetClientId = reader.ReadInt32();
-
-            // TODO: Use.
-
-            return default;
-        }
-
-        public override bool Serialize(IMessageWriter writer, bool initialState)
-        {
-            throw new NotImplementedException();
-        }
-
-        public override void Deserialize(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState)
-        {
-            if (!sender.IsHost)
-            {
-                throw new ImpostorCheatException($"Client attempted to send data for {nameof(InnerShipStatus)} as non-host");
-            }
-
-            var votes = _votes;
-            var unknown = reader.ReadByte();
-            if (unknown != 0)
-            {
-                for (var i = 0; i < unknown; i++)
-                {
-                    var v4 = reader.ReadInt32();
-                    if (v4 == 0)
-                    {
-                        break;
-                    }
-
-                    if (!votes.TryGetValue(v4, out var v12))
-                    {
-                        v12 = new int[3];
-                        votes[v4] = v12;
-                    }
-
-                    for (var j = 0; j < 3; j++)
-                    {
-                        v12[j] = reader.ReadPackedInt32();
-                    }
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/InnerGameData.PlayerInfo.cs b/src/Impostor.Api/Innersloth/Net/Objects/InnerGameData.PlayerInfo.cs
deleted file mode 100644 (file)
index 7ddd8a3..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Impostor.Api.Innersloth.Data;
-using Impostor.Api.Net.Messages;
-
-namespace Impostor.Api.Innersloth.Net.Objects
-{
-    public partial class InnerGameData
-    {
-        public class PlayerInfo
-        {
-            public PlayerInfo(byte playerId)
-            {
-                PlayerId = playerId;
-            }
-
-            public InnerPlayerControl Controller { get; internal set; }
-
-            public byte PlayerId { get; }
-
-            public string PlayerName { get; internal set; }
-
-            public byte ColorId { get; internal set; }
-
-            public uint HatId { get; internal set; }
-
-            public uint PetId { get; internal set; }
-
-            public uint SkinId { get; internal set; }
-
-            public bool Disconnected { get; internal set; }
-
-            public bool IsImpostor { get; internal set; }
-
-            public bool IsDead { get; internal set; }
-
-            public DeathReason LastDeathReason { get; internal set; }
-
-            public List<TaskInfo> Tasks { get; internal set; }
-
-            public void Serialize(IMessageWriter writer)
-            {
-                throw new NotImplementedException();
-            }
-
-            public void Deserialize(IMessageReader reader)
-            {
-                PlayerName = reader.ReadString();
-                ColorId = reader.ReadByte();
-                HatId = reader.ReadPackedUInt32();
-                PetId = reader.ReadPackedUInt32();
-                SkinId = reader.ReadPackedUInt32();
-                var flag = reader.ReadByte();
-                Disconnected = (flag & 1) > 0;
-                IsImpostor = (flag & 2) > 0;
-                IsDead = (flag & 4) > 0;
-                var taskCount = reader.ReadByte();
-                Tasks = new List<TaskInfo>();
-                for (var i = 0; i < taskCount; i++)
-                {
-                    Tasks.Add(new TaskInfo());
-                    Tasks[i].Deserialize(reader);
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/InnerGameData.TaskInfo.cs b/src/Impostor.Api/Innersloth/Net/Objects/InnerGameData.TaskInfo.cs
deleted file mode 100644 (file)
index cdca500..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-using Impostor.Api.Net.Messages;
-
-namespace Impostor.Api.Innersloth.Net.Objects
-{
-    public partial class InnerGameData
-    {
-        public class TaskInfo
-        {
-            public uint Id { get; internal set; }
-
-            public bool Complete { get; internal set; }
-
-            public void Serialize(IMessageWriter writer)
-            {
-                writer.WritePacked(Id);
-                writer.Write(Complete);
-            }
-
-            public void Deserialize(IMessageReader reader)
-            {
-                this.Id = reader.ReadPackedUInt32();
-                this.Complete = reader.ReadBoolean();
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/InnerGameData.cs b/src/Impostor.Api/Innersloth/Net/Objects/InnerGameData.cs
deleted file mode 100644 (file)
index 0ecd4df..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using Impostor.Api.Games;
-using Impostor.Api.Innersloth.Net.Objects.Components;
-using Impostor.Api.Net;
-using Impostor.Api.Net.Messages;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-
-namespace Impostor.Api.Innersloth.Net.Objects
-{
-    public partial class InnerGameData : InnerNetObject
-    {
-        private readonly ILogger<InnerGameData> _logger;
-        private readonly IGame _game;
-        private readonly ConcurrentDictionary<byte, PlayerInfo> _allPlayers;
-
-        public InnerGameData(ILogger<InnerGameData> logger, IGame game, IServiceProvider serviceProvider)
-        {
-            _logger = logger;
-            _game = game;
-            _allPlayers = new ConcurrentDictionary<byte, PlayerInfo>();
-
-            Components.Add(this);
-            Components.Add(ActivatorUtilities.CreateInstance<InnerVoteBanSystem>(serviceProvider));
-        }
-
-        public int PlayerCount => _allPlayers.Count;
-
-        public IReadOnlyDictionary<byte, PlayerInfo> Players => _allPlayers;
-
-        public PlayerInfo? GetPlayerById(byte id)
-        {
-            if (id == byte.MaxValue)
-            {
-                return null;
-            }
-
-            return _allPlayers.TryGetValue(id, out var player) ? player : null;
-        }
-
-        public override ValueTask HandleRpc(IClientPlayer sender, IClientPlayer? target, RpcCalls call, IMessageReader reader)
-        {
-            switch (call)
-            {
-                case RpcCalls.SetTasks:
-                {
-                    if (!sender.IsHost)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetTasks)} but was not a host");
-                    }
-
-                    if (target != null)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetTasks)} to a specific player instead of broadcast");
-                    }
-
-                    var playerId = reader.ReadByte();
-                    var taskTypeIds = reader.ReadBytesAndSize();
-
-                    SetTasks(playerId, taskTypeIds);
-                    break;
-                }
-
-                case RpcCalls.UpdateGameData:
-                {
-                    if (!sender.IsHost)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetTasks)} but was not a host");
-                    }
-
-                    if (target != null)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetTasks)} to a specific player instead of broadcast");
-                    }
-
-                    while (reader.Position < reader.Length)
-                    {
-                        var message = reader.ReadMessage();
-                        var player = GetPlayerById(message.Tag);
-                        if (player != null)
-                        {
-                            player.Deserialize(message);
-                        }
-                        else
-                        {
-                            var playerInfo = new PlayerInfo(message.Tag);
-
-                            playerInfo.Deserialize(reader);
-
-                            if (!_allPlayers.TryAdd(playerInfo.PlayerId, playerInfo))
-                            {
-                                throw new ImpostorException("Failed to add player to InnerGameData.");
-                            }
-                        }
-                    }
-
-                    break;
-                }
-
-                default:
-                {
-                    _logger.LogWarning("{0}: Unknown rpc call {1}", nameof(InnerGameData), call);
-                    break;
-                }
-            }
-
-            return default;
-        }
-
-        public override bool Serialize(IMessageWriter writer, bool initialState)
-        {
-            throw new NotImplementedException();
-        }
-
-        public override void Deserialize(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState)
-        {
-            if (!sender.IsHost)
-            {
-                throw new ImpostorCheatException($"Client attempted to send data for {nameof(InnerGameData)} as non-host");
-            }
-
-            if (initialState)
-            {
-                var num = reader.ReadPackedInt32();
-
-                for (var i = 0; i < num; i++)
-                {
-                    var playerId = reader.ReadByte();
-                    var playerInfo = new PlayerInfo(playerId);
-
-                    playerInfo.Deserialize(reader);
-
-                    if (!_allPlayers.TryAdd(playerInfo.PlayerId, playerInfo))
-                    {
-                        throw new ImpostorException("Failed to add player to InnerGameData.");
-                    }
-                }
-            }
-            else
-            {
-                throw new NotImplementedException("This shouldn't happen, according to Among Us disassembly.");
-            }
-        }
-
-        internal void AddPlayer(InnerPlayerControl control)
-        {
-            var playerId = control.PlayerId;
-            var playerInfo = new PlayerInfo(control.PlayerId);
-
-            if (_allPlayers.TryAdd(playerId, playerInfo))
-            {
-                control.PlayerInfo = playerInfo;
-            }
-        }
-
-        private void SetTasks(byte playerId, ReadOnlyMemory<byte> taskTypeIds)
-        {
-            var player = GetPlayerById(playerId);
-            if (player == null)
-            {
-                _logger.LogTrace("Could not set tasks for playerId {0}.", playerId);
-                return;
-            }
-
-            if (player.Disconnected)
-            {
-                return;
-            }
-
-            player.Tasks = new List<TaskInfo>(taskTypeIds.Length);
-
-            for (var i = 0; i < taskTypeIds.Length; i++)
-            {
-                player.Tasks.Add(new TaskInfo());
-                player.Tasks[i].Id = (uint)i;
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/InnerLobbyBehaviour.cs b/src/Impostor.Api/Innersloth/Net/Objects/InnerLobbyBehaviour.cs
deleted file mode 100644 (file)
index eac946e..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-using System.Threading.Tasks;
-using Impostor.Api.Games;
-using Impostor.Api.Net;
-using Impostor.Api.Net.Messages;
-
-namespace Impostor.Api.Innersloth.Net.Objects
-{
-    public class InnerLobbyBehaviour : InnerNetObject
-    {
-        private readonly IGame _game;
-
-        public InnerLobbyBehaviour(IGame game)
-        {
-            _game = game;
-
-            Components.Add(this);
-        }
-
-        public override ValueTask HandleRpc(IClientPlayer sender, IClientPlayer? target, RpcCalls call,
-            IMessageReader reader)
-        {
-            throw new System.NotImplementedException();
-        }
-
-        public override bool Serialize(IMessageWriter writer, bool initialState)
-        {
-            throw new System.NotImplementedException();
-        }
-
-        public override void Deserialize(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState)
-        {
-            throw new System.NotImplementedException();
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/InnerMeetingHud.PlayerVoteArea.cs b/src/Impostor.Api/Innersloth/Net/Objects/InnerMeetingHud.PlayerVoteArea.cs
deleted file mode 100644 (file)
index 82f0ef6..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-using Impostor.Api.Net.Messages;
-
-namespace Impostor.Api.Innersloth.Net.Objects
-{
-    public partial class InnerMeetingHud
-    {
-        public class PlayerVoteArea
-        {
-            private const byte VoteMask = 15;
-            private const byte ReportedBit = 32;
-            private const byte VotedBit = 64;
-            private const byte DeadBit = 128;
-
-            public PlayerVoteArea(InnerMeetingHud parent, byte targetPlayerId)
-            {
-                Parent = parent;
-                TargetPlayerId = targetPlayerId;
-            }
-
-            public InnerMeetingHud Parent { get; }
-
-            public byte TargetPlayerId { get; }
-
-            public bool IsDead { get; private set; }
-
-            public bool DidVote { get; private set; }
-
-            public bool DidReport { get; private set; }
-
-            public sbyte VotedFor { get; private set; }
-
-            internal void SetDead(bool didReport, bool isDead)
-            {
-                DidReport = didReport;
-                IsDead = isDead;
-            }
-
-            public void Deserialize(IMessageReader reader)
-            {
-                var num = reader.ReadByte();
-
-                VotedFor = (sbyte)((num & VoteMask) - 1);
-                IsDead = (num & DeadBit) > 0;
-                DidVote = (num & VotedBit) > 0;
-                DidReport = (num & ReportedBit) > 0;
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/InnerMeetingHud.cs b/src/Impostor.Api/Innersloth/Net/Objects/InnerMeetingHud.cs
deleted file mode 100644 (file)
index 51d918d..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-using System;
-using System.Linq;
-using System.Threading.Tasks;
-using Impostor.Api.Games;
-using Impostor.Api.Net;
-using Impostor.Api.Net.Messages;
-using Microsoft.Extensions.Logging;
-
-namespace Impostor.Api.Innersloth.Net.Objects
-{
-    public partial class InnerMeetingHud : InnerNetObject
-    {
-        private readonly ILogger<InnerMeetingHud> _logger;
-        private readonly IGame _game;
-        private readonly IGameNet _gameNet;
-        private PlayerVoteArea[] _playerStates;
-
-        public InnerMeetingHud(ILogger<InnerMeetingHud> logger, IGame game)
-        {
-            _logger = logger;
-            _game = game;
-            _gameNet = game.GameNet;
-            _playerStates = null;
-
-            Components.Add(this);
-        }
-
-        public byte ReporterId { get; private set; }
-
-        private void PopulateButtons(byte reporter)
-        {
-            _playerStates = _gameNet.GameData.Players
-                .Select(x =>
-                {
-                    var area = new PlayerVoteArea(this, x.Key);
-                    area.SetDead(x.Value.PlayerId == reporter, x.Value.Disconnected || x.Value.IsDead);
-                    return area;
-                })
-                .ToArray();
-        }
-
-        public override ValueTask HandleRpc(IClientPlayer sender, IClientPlayer? target, RpcCalls call, IMessageReader reader)
-        {
-            switch (call)
-            {
-                case RpcCalls.Close:
-                {
-                    if (!sender.IsHost)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.Close)} but was not a host");
-                    }
-
-                    if (target != null)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.Close)} to a specific player instead of broadcast");
-                    }
-
-                    break;
-                }
-
-                case RpcCalls.VotingComplete:
-                {
-                    if (!sender.IsHost)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.VotingComplete)} but was not a host");
-                    }
-
-                    if (target != null)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.VotingComplete)} to a specific player instead of broadcast");
-                    }
-
-                    var states = reader.ReadBytesAndSize();
-                    var playerId = reader.ReadByte();
-                    var tie = reader.ReadBoolean();
-                    break;
-                }
-
-                case RpcCalls.CastVote:
-                {
-                    var srcPlayerId = reader.ReadByte();
-                    if (srcPlayerId != sender.Character.PlayerId)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.CastVote)} to an unowned {nameof(InnerPlayerControl)}");
-                    }
-
-                    // Host broadcasts vote to others.
-                    if (sender.IsHost && target != null)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.CastVote)} to a specific player instead of broadcast");
-                    }
-
-                    // Player sends vote to host.
-                    if (target == null || !target.IsHost)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.CastVote)} to wrong destinition, must be host");
-                    }
-
-                    var targetPlayerId = reader.ReadByte();
-                    break;
-                }
-
-                default:
-                {
-                    _logger.LogWarning("{0}: Unknown rpc call {1}", nameof(InnerMeetingHud), call);
-                    break;
-                }
-            }
-
-            return default;
-        }
-
-        public override bool Serialize(IMessageWriter writer, bool initialState)
-        {
-            throw new NotImplementedException();
-        }
-
-        public override void Deserialize(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState)
-        {
-            if (!sender.IsHost)
-            {
-                throw new ImpostorCheatException($"Client attempted to send data for {nameof(InnerMeetingHud)} as non-host");
-            }
-
-            if (target != null)
-            {
-                throw new ImpostorCheatException($"Client attempted to send {nameof(InnerMeetingHud)} data to a specific player, must be broadcast");
-            }
-
-            if (initialState)
-            {
-                PopulateButtons(0);
-
-                foreach (var playerState in _playerStates)
-                {
-                    playerState.Deserialize(reader);
-
-                    if (playerState.DidReport)
-                    {
-                        ReporterId = playerState.TargetPlayerId;
-                    }
-                }
-            }
-            else
-            {
-                var num = reader.ReadPackedUInt32();
-
-                for (var i = 0; i < _playerStates.Length; i++)
-                {
-                    if ((num & 1 << i) != 0)
-                    {
-                        _playerStates[i].Deserialize(reader);
-                    }
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/InnerPlayerControl.cs b/src/Impostor.Api/Innersloth/Net/Objects/InnerPlayerControl.cs
deleted file mode 100644 (file)
index 6650ce7..0000000
+++ /dev/null
@@ -1,406 +0,0 @@
-using System;
-using System.Threading.Tasks;
-using Impostor.Api.Events.Managers;
-using Impostor.Api.Events.Net;
-using Impostor.Api.Games;
-using Impostor.Api.Innersloth.Data;
-using Impostor.Api.Innersloth.Net.Objects.Components;
-using Impostor.Api.Net;
-using Impostor.Api.Net.Messages;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-
-namespace Impostor.Api.Innersloth.Net.Objects
-{
-    public class InnerPlayerControl : InnerNetObject
-    {
-        private readonly ILogger<InnerPlayerControl> _logger;
-        private readonly IEventManager _eventManager;
-        private readonly IGame _game;
-
-        public InnerPlayerControl(ILogger<InnerPlayerControl> logger, IServiceProvider serviceProvider, IEventManager eventManager, IGame game)
-        {
-            _logger = logger;
-            _eventManager = eventManager;
-            _game = game;
-
-            Components.Add(this);
-            Components.Add(ActivatorUtilities.CreateInstance<InnerPlayerPhysics>(serviceProvider));
-            Components.Add(ActivatorUtilities.CreateInstance<InnerCustomNetworkTransform>(serviceProvider));
-
-            PlayerId = byte.MaxValue;
-        }
-
-        public bool IsNew { get; private set; }
-
-        public byte PlayerId { get; private set; }
-
-        public InnerGameData.PlayerInfo PlayerInfo { get; internal set; }
-
-        public override async ValueTask HandleRpc(IClientPlayer sender, IClientPlayer? target, RpcCalls call, IMessageReader reader)
-        {
-            switch (call)
-            {
-                // Play an animation.
-                case RpcCalls.PlayAnimation:
-                {
-                    if (!sender.IsOwner(this))
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.PlayAnimation)} to an unowned {nameof(InnerPlayerControl)}");
-                    }
-
-                    if (target != null)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.PlayAnimation)} to a specific player instead of broadcast");
-                    }
-
-                    var animation = reader.ReadByte();
-                    break;
-                }
-
-                // Complete a task.
-                case RpcCalls.CompleteTask:
-                {
-                    if (!sender.IsOwner(this))
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.CompleteTask)} to an unowned {nameof(InnerPlayerControl)}");
-                    }
-
-                    if (target != null)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.CompleteTask)} to a specific player instead of broadcast");
-                    }
-
-                    var index = reader.ReadPackedUInt32();
-                    break;
-                }
-
-                // Update GameOptions.
-                case RpcCalls.SyncSettings:
-                {
-                    if (!sender.IsHost)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SyncSettings)} but was not a host");
-                    }
-
-                    _game.Options.Deserialize(reader.ReadBytesAndSize());
-                    break;
-                }
-
-                // Set Impostors.
-                case RpcCalls.SetInfected:
-                {
-                    if (!sender.IsHost)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetInfected)} but was not a host");
-                    }
-
-                    var length = reader.ReadPackedInt32();
-
-                    for (var i = 0; i < length; i++)
-                    {
-                        var playerId = reader.ReadByte();
-                        var player = _game.GameNet.GameData.GetPlayerById(playerId);
-
-                        player.IsImpostor = true;
-                    }
-
-                    break;
-                }
-
-                // Player was voted out.
-                case RpcCalls.Exiled:
-                {
-                    if (!sender.IsHost)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.Exiled)} but was not a host");
-                    }
-
-                    if (target != null)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.Exiled)} to a specific player instead of broadcast");
-                    }
-
-                    // TODO: Not hit?
-                    Die(DeathReason.Exile);
-                    break;
-                }
-
-                // Validates the player name at the host.
-                case RpcCalls.CheckName:
-                {
-                    if (target == null || !target.IsHost)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.CheckName)} to the wrong player");
-                    }
-
-                    var name = reader.ReadString();
-                    break;
-                }
-
-                // Update the name of a player.
-                case RpcCalls.SetName:
-                {
-                    if (!sender.IsHost)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetName)} but was not a host");
-                    }
-
-                    if (target != null)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetName)} to a specific player instead of broadcast");
-                    }
-
-                    PlayerInfo.PlayerName = reader.ReadString();
-                    break;
-                }
-
-                // Validates the color at the host.
-                case RpcCalls.CheckColor:
-                {
-                    if (target == null || !target.IsHost)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.CheckColor)} to the wrong player");
-                    }
-
-                    var color = reader.ReadByte();
-                    break;
-                }
-
-                // Update the color of a player.
-                case RpcCalls.SetColor:
-                {
-                    if (!sender.IsHost)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetColor)} but was not a host");
-                    }
-
-                    if (target != null)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetColor)} to a specific player instead of broadcast");
-                    }
-
-                    PlayerInfo.ColorId = reader.ReadByte();
-                    break;
-                }
-
-                // Update the hat of a player.
-                case RpcCalls.SetHat:
-                {
-                    if (!sender.IsOwner(this))
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetHat)} to an unowned {nameof(InnerPlayerControl)}");
-                    }
-
-                    if (target != null)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetHat)} to a specific player instead of broadcast");
-                    }
-
-                    PlayerInfo.HatId = reader.ReadPackedUInt32();
-                    break;
-                }
-
-                case RpcCalls.SetSkin:
-                {
-                    if (!sender.IsOwner(this))
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetSkin)} to an unowned {nameof(InnerPlayerControl)}");
-                    }
-
-                    if (target != null)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetHat)} to a specific player instead of broadcast");
-                    }
-
-                    PlayerInfo.SkinId = reader.ReadPackedUInt32();
-                    break;
-                }
-
-                // TODO: (ANTICHEAT) Location check?
-                case RpcCalls.ReportDeadBody:
-                {
-                    if (!sender.IsOwner(this))
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.ReportDeadBody)} to an unowned {nameof(InnerPlayerControl)}");
-                    }
-
-                    if (target != null)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.ReportDeadBody)} to a specific player instead of broadcast");
-                    }
-
-                    var deadBodyPlayerId = reader.ReadByte();
-                    break;
-                }
-
-                // TODO: (ANTICHEAT) Cooldown check?
-                case RpcCalls.MurderPlayer:
-                {
-                    if (!sender.IsOwner(this))
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.MurderPlayer)} to an unowned {nameof(InnerPlayerControl)}");
-                    }
-
-                    if (target != null)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.MurderPlayer)} to a specific player instead of broadcast");
-                    }
-
-                    if (!sender.Character.PlayerInfo.IsImpostor)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.MurderPlayer)} as crewmate");
-                    }
-
-                    var player = reader.ReadNetObject<InnerPlayerControl>(_game);
-                    if (!player.PlayerInfo.IsDead)
-                    {
-                        player.Die(DeathReason.Kill);
-                    }
-
-                    break;
-                }
-
-                case RpcCalls.SendChat:
-                {
-                    if (!sender.IsOwner(this))
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SendChat)} to an unowned {nameof(InnerPlayerControl)}");
-                    }
-
-                    if (target != null)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SendChat)} to a specific player instead of broadcast");
-                    }
-
-                    var chat = reader.ReadString();
-
-                    await _eventManager.CallAsync(new PlayerChatEvent(_game, this, chat));
-                    break;
-                }
-
-                case RpcCalls.StartMeeting:
-                {
-                    if (!sender.IsHost)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.StartMeeting)} but was not a host");
-                    }
-
-                    if (target != null)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.StartMeeting)} to a specific player instead of broadcast");
-                    }
-
-                    var playerId = reader.ReadByte();
-                    var player = _game.GameNet.GameData.GetPlayerById(playerId);
-
-                    // Meeting started by "player", can also be null.
-                    break;
-                }
-
-                case RpcCalls.SetScanner:
-                {
-                    if (!sender.IsOwner(this))
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetScanner)} to an unowned {nameof(InnerPlayerControl)}");
-                    }
-
-                    if (target != null)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetScanner)} to a specific player instead of broadcast");
-                    }
-
-                    var on = reader.ReadBoolean();
-                    var count = reader.ReadByte();
-                    break;
-                }
-
-                case RpcCalls.SendChatNote:
-                {
-                    if (!sender.IsOwner(this))
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SendChatNote)} to an unowned {nameof(InnerPlayerControl)}");
-                    }
-
-                    if (target != null)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SendChatNote)} to a specific player instead of broadcast");
-                    }
-
-                    var playerId = reader.ReadByte();
-                    var chatNote = (ChatNoteType)reader.ReadByte();
-                    break;
-                }
-
-                case RpcCalls.SetPet:
-                {
-                    if (!sender.IsOwner(this))
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetPet)} to an unowned {nameof(InnerPlayerControl)}");
-                    }
-
-                    if (target != null)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetPet)} to a specific player instead of broadcast");
-                    }
-
-                    PlayerInfo.PetId = reader.ReadPackedUInt32();
-                    break;
-                }
-
-                // TODO: Understand this RPC
-                case RpcCalls.SetStartCounter:
-                {
-                    if (!sender.IsOwner(this))
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetStartCounter)} to an unowned {nameof(InnerPlayerControl)}");
-                    }
-
-                    if (target != null)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetStartCounter)} to a specific player instead of broadcast");
-                    }
-
-                    // Used to compare with LastStartCounter.
-                    var startCounter = reader.ReadPackedUInt32();
-
-                    // Is either start countdown or byte.MaxValue
-                    var secondsLeft = reader.ReadByte();
-                    break;
-                }
-
-                default:
-                {
-                    _logger.LogWarning("{0}: Unknown rpc call {1}", nameof(InnerPlayerControl), call);
-                    break;
-                }
-            }
-        }
-
-        public override bool Serialize(IMessageWriter writer, bool initialState)
-        {
-            throw new NotImplementedException();
-        }
-
-        public override void Deserialize(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState)
-        {
-            if (!sender.IsHost)
-            {
-                throw new ImpostorCheatException($"Client attempted to send data for {nameof(InnerPlayerControl)} as non-host");
-            }
-
-            if (initialState)
-            {
-                IsNew = reader.ReadBoolean();
-            }
-
-            PlayerId = reader.ReadByte();
-        }
-
-        private void Die(DeathReason reason)
-        {
-            PlayerInfo.IsDead = true;
-            PlayerInfo.LastDeathReason = reason;
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/InnerShipStatus.cs b/src/Impostor.Api/Innersloth/Net/Objects/InnerShipStatus.cs
deleted file mode 100644 (file)
index a33bd65..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using Impostor.Api.Games;
-using Impostor.Api.Innersloth.Net.Objects.Systems;
-using Impostor.Api.Innersloth.Net.Objects.Systems.ShipStatus;
-using Impostor.Api.Net;
-using Impostor.Api.Net.Messages;
-using Microsoft.Extensions.Logging;
-
-namespace Impostor.Api.Innersloth.Net.Objects
-{
-    public class InnerShipStatus : InnerNetObject
-    {
-        private readonly ILogger<InnerShipStatus> _logger;
-        private readonly IGame _game;
-        private readonly Dictionary<SystemTypes, ISystemType> _systems;
-
-        public InnerShipStatus(ILogger<InnerShipStatus> logger, IGame game)
-        {
-            _logger = logger;
-            _game = game;
-
-            _systems = new Dictionary<SystemTypes, ISystemType>
-            {
-                [SystemTypes.Electrical] = new SwitchSystem(),
-                [SystemTypes.MedBay] = new MedScanSystem(),
-                [SystemTypes.Reactor] = new ReactorSystemType(),
-                [SystemTypes.LifeSupp] = new LifeSuppSystemType(),
-                [SystemTypes.Security] = new SecurityCameraSystemType(),
-                [SystemTypes.Comms] = new HudOverrideSystemType(),
-                [SystemTypes.Doors] = new DoorsSystemType(_game),
-            };
-
-            _systems.Add(SystemTypes.Sabotage, new SabotageSystemType(new[]
-            {
-                (IActivatable)_systems[SystemTypes.Comms],
-                (IActivatable)_systems[SystemTypes.Reactor],
-                (IActivatable)_systems[SystemTypes.LifeSupp],
-                (IActivatable)_systems[SystemTypes.Electrical],
-            }));
-
-            Components.Add(this);
-        }
-
-        public override ValueTask HandleRpc(IClientPlayer sender, IClientPlayer? target, RpcCalls call, IMessageReader reader)
-        {
-            switch (call)
-            {
-                case RpcCalls.CloseDoorsOfType:
-                {
-                    if (target == null || !target.IsHost)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.CloseDoorsOfType)} to wrong destinition, must be host");
-                    }
-
-                    if (!sender.Character.PlayerInfo.IsImpostor)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.CloseDoorsOfType)} as crewmate");
-                    }
-
-                    var systemType = (SystemTypes)reader.ReadByte();
-
-                    break;
-                }
-
-                case RpcCalls.RepairSystem:
-                {
-                    if (target == null || !target.IsHost)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.RepairSystem)} to wrong destinition, must be host");
-                    }
-
-                    if (!sender.Character.PlayerInfo.IsImpostor)
-                    {
-                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.RepairSystem)} as crewmate");
-                    }
-
-                    var systemType = (SystemTypes)reader.ReadByte();
-                    var player = reader.ReadNetObject<InnerPlayerControl>(_game);
-                    var amount = reader.ReadByte();
-
-                    // TODO: Modify data (?)
-
-                    break;
-                }
-
-                default:
-                {
-                    _logger.LogWarning("{0}: Unknown rpc call {1}", nameof(InnerShipStatus), call);
-                    break;
-                }
-            }
-
-            return default;
-        }
-
-        public override bool Serialize(IMessageWriter writer, bool initialState)
-        {
-            throw new NotImplementedException();
-        }
-
-        public override void Deserialize(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState)
-        {
-            if (!sender.IsHost)
-            {
-                throw new ImpostorCheatException($"Client attempted to send data for {nameof(InnerShipStatus)} as non-host");
-            }
-
-            if (target != null)
-            {
-                throw new ImpostorCheatException($"Client attempted to send {nameof(InnerShipStatus)} data to a specific player, must be broadcast");
-            }
-
-            if (initialState)
-            {
-                // TODO: (_systems[SystemTypes.Doors] as DoorsSystemType).SetDoors();
-                foreach (var systemType in SystemTypeHelpers.AllTypes)
-                {
-                    if (_systems.TryGetValue(systemType, out var system))
-                    {
-                        system.Deserialize(reader, true);
-                    }
-                }
-            }
-            else
-            {
-                var count = reader.ReadPackedUInt32();
-
-                foreach (var systemType in SystemTypeHelpers.AllTypes)
-                {
-                    // TODO: Not sure what is going on here, check.
-                    if ((count & 1 << (int)(systemType & (SystemTypes.ShipTasks | SystemTypes.Doors))) != 0L)
-                    {
-                        if (_systems.TryGetValue(systemType, out var system))
-                        {
-                            system.Deserialize(reader, false);
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/Systems/IActivatable.cs b/src/Impostor.Api/Innersloth/Net/Objects/Systems/IActivatable.cs
deleted file mode 100644 (file)
index eaae0a2..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Impostor.Api.Innersloth.Net.Objects.Systems
-{
-    public interface IActivatable
-    {
-        bool IsActive { get; }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/Systems/ISystemType.cs b/src/Impostor.Api/Innersloth/Net/Objects/Systems/ISystemType.cs
deleted file mode 100644 (file)
index 0b25e94..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-using Impostor.Api.Net.Messages;
-
-namespace Impostor.Api.Innersloth.Net.Objects.Systems
-{
-    public interface ISystemType
-    {
-        void Serialize(IMessageWriter writer, bool initialState);
-
-        void Deserialize(IMessageReader reader, bool initialState);
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/DoorsSystemType.cs b/src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/DoorsSystemType.cs
deleted file mode 100644 (file)
index 05a2916..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Impostor.Api.Games;
-using Impostor.Api.Innersloth.Data;
-using Impostor.Api.Net.Messages;
-
-namespace Impostor.Api.Innersloth.Net.Objects.Systems.ShipStatus
-{
-    public class DoorsSystemType : ISystemType
-    {
-        // TODO: AutoDoors
-        private readonly Dictionary<int, bool> _doors;
-
-        public DoorsSystemType(IGame game)
-        {
-            // TODO: Check
-            var doorCount = game.Options.MapId switch
-            {
-                MapId.Skeld => 13,
-                MapId.MiraHQ => 2,
-                MapId.Polus => 12,
-                _ => throw new ArgumentOutOfRangeException()
-            };
-
-            _doors = new Dictionary<int, bool>(doorCount);
-
-            for (var i = 0; i < doorCount; i++)
-            {
-                _doors.Add(i, false);
-            }
-        }
-
-        public void Serialize(IMessageWriter writer, bool initialState)
-        {
-            throw new NotImplementedException();
-        }
-
-        public void Deserialize(IMessageReader reader, bool initialState)
-        {
-            if (initialState)
-            {
-                for (var i = 0; i < _doors.Count; i++)
-                {
-                    _doors[i] = reader.ReadBoolean();
-                }
-            }
-            else
-            {
-                var num = reader.ReadPackedUInt32();
-
-                for (var i = 0; i < _doors.Count; i++)
-                {
-                    if ((num & 1 << i) != 0)
-                    {
-                        _doors[i] = reader.ReadBoolean();
-                    }
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/HudOverrideSystemType.cs b/src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/HudOverrideSystemType.cs
deleted file mode 100644 (file)
index fe29bb0..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-using Impostor.Api.Net.Messages;
-
-namespace Impostor.Api.Innersloth.Net.Objects.Systems.ShipStatus
-{
-    public class HudOverrideSystemType : ISystemType, IActivatable
-    {
-        public bool IsActive { get; private set; }
-
-        public void Serialize(IMessageWriter writer, bool initialState)
-        {
-            throw new System.NotImplementedException();
-        }
-
-        public void Deserialize(IMessageReader reader, bool initialState)
-        {
-            IsActive = reader.ReadBoolean();
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/LifeSuppSystemType.cs b/src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/LifeSuppSystemType.cs
deleted file mode 100644 (file)
index fd8b01a..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-using System.Collections.Generic;
-using Impostor.Api.Net.Messages;
-
-namespace Impostor.Api.Innersloth.Net.Objects.Systems.ShipStatus
-{
-    public class LifeSuppSystemType : ISystemType, IActivatable
-    {
-        public LifeSuppSystemType()
-        {
-            Countdown = 10000f;
-            CompletedConsoles = new HashSet<int>();
-        }
-
-        public float Countdown { get; private set; }
-
-        public HashSet<int> CompletedConsoles { get; }
-
-        public bool IsActive => Countdown < 10000.0;
-
-        public void Serialize(IMessageWriter writer, bool initialState)
-        {
-            throw new System.NotImplementedException();
-        }
-
-        public void Deserialize(IMessageReader reader, bool initialState)
-        {
-            Countdown = reader.ReadSingle();
-
-            if (reader.Position >= reader.Length)
-            {
-                return;
-            }
-
-            CompletedConsoles.Clear(); // TODO: Thread safety
-
-            var num = reader.ReadPackedInt32();
-
-            for (var i = 0; i < num; i++)
-            {
-                CompletedConsoles.Add(reader.ReadPackedInt32());
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/MedScanSystem.cs b/src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/MedScanSystem.cs
deleted file mode 100644 (file)
index f93fb8e..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-using System.Collections.Generic;
-using Impostor.Api.Net.Messages;
-
-namespace Impostor.Api.Innersloth.Net.Objects.Systems.ShipStatus
-{
-    public class MedScanSystem : ISystemType
-    {
-        public MedScanSystem()
-        {
-            UsersList = new List<byte>();
-        }
-
-        public List<byte> UsersList { get; }
-
-        public void Serialize(IMessageWriter writer, bool initialState)
-        {
-            throw new System.NotImplementedException();
-        }
-
-        public void Deserialize(IMessageReader reader, bool initialState)
-        {
-            UsersList.Clear();
-
-            var num = reader.ReadPackedInt32();
-
-            for (var i = 0; i < num; i++)
-            {
-                UsersList.Add(reader.ReadByte());
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/ReactorSystemType.cs b/src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/ReactorSystemType.cs
deleted file mode 100644 (file)
index d3f1973..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Impostor.Api.Net.Messages;
-
-namespace Impostor.Api.Innersloth.Net.Objects.Systems.ShipStatus
-{
-    public class ReactorSystemType : ISystemType, IActivatable
-    {
-        public ReactorSystemType()
-        {
-            Countdown = 10000f;
-            UserConsolePairs = new HashSet<Tuple<byte, byte>>();
-        }
-
-        public float Countdown { get; private set; }
-
-        public HashSet<Tuple<byte, byte>> UserConsolePairs { get; }
-
-        public bool IsActive => Countdown < 10000.0;
-
-        public void Serialize(IMessageWriter writer, bool initialState)
-        {
-            throw new System.NotImplementedException();
-        }
-
-        public void Deserialize(IMessageReader reader, bool initialState)
-        {
-            Countdown = reader.ReadSingle();
-            UserConsolePairs.Clear(); // TODO: Thread safety
-
-            var count = reader.ReadPackedInt32();
-
-            for (var i = 0; i < count; i++)
-            {
-                UserConsolePairs.Add(new Tuple<byte, byte>(reader.ReadByte(), reader.ReadByte()));
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/SabotageSystemType.cs b/src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/SabotageSystemType.cs
deleted file mode 100644 (file)
index f442b91..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-using Impostor.Api.Net.Messages;
-
-namespace Impostor.Api.Innersloth.Net.Objects.Systems.ShipStatus
-{
-    public class SabotageSystemType : ISystemType
-    {
-        private readonly IActivatable[] _specials;
-
-        public SabotageSystemType(IActivatable[] specials)
-        {
-            _specials = specials;
-        }
-
-        public float Timer { get; set; }
-
-        public void Serialize(IMessageWriter writer, bool initialState)
-        {
-            throw new System.NotImplementedException();
-        }
-
-        public void Deserialize(IMessageReader reader, bool initialState)
-        {
-            Timer = reader.ReadSingle();
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/SecurityCameraSystemType.cs b/src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/SecurityCameraSystemType.cs
deleted file mode 100644 (file)
index 4e16b31..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-using Impostor.Api.Net.Messages;
-
-namespace Impostor.Api.Innersloth.Net.Objects.Systems.ShipStatus
-{
-    public class SecurityCameraSystemType : ISystemType
-    {
-        public byte InUse { get; internal set; }
-
-        public void Serialize(IMessageWriter writer, bool initialState)
-        {
-            throw new System.NotImplementedException();
-        }
-
-        public void Deserialize(IMessageReader reader, bool initialState)
-        {
-            InUse = reader.ReadByte();
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/SwitchSystem.cs b/src/Impostor.Api/Innersloth/Net/Objects/Systems/ShipStatus/SwitchSystem.cs
deleted file mode 100644 (file)
index 6d46d01..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-using Impostor.Api.Net.Messages;
-
-namespace Impostor.Api.Innersloth.Net.Objects.Systems.ShipStatus
-{
-    public class SwitchSystem : ISystemType, IActivatable
-    {
-        public byte ExpectedSwitches { get; set; }
-
-        public byte ActualSwitches { get; set; }
-
-        public byte Value { get; set; } = byte.MaxValue;
-
-        public bool IsActive { get; }
-
-        public void Serialize(IMessageWriter writer, bool initialState)
-        {
-            throw new System.NotImplementedException();
-        }
-
-        public void Deserialize(IMessageReader reader, bool initialState)
-        {
-            ExpectedSwitches = reader.ReadByte();
-            ActualSwitches = reader.ReadByte();
-            Value = reader.ReadByte();
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/Systems/SystemTypeHelpers.cs b/src/Impostor.Api/Innersloth/Net/Objects/Systems/SystemTypeHelpers.cs
deleted file mode 100644 (file)
index 46e68ff..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-using System.Linq;
-
-namespace Impostor.Api.Innersloth.Net.Objects.Systems
-{
-    internal class SystemTypeHelpers
-    {
-        public static readonly SystemTypes[] AllTypes;
-        public static readonly string[] Names;
-
-        static SystemTypeHelpers()
-        {
-            AllTypes = Enum.GetValues(typeof(SystemTypes)).Cast<SystemTypes>().ToArray();
-            Names = AllTypes.Select(x =>
-            {
-                return x switch
-                {
-                    SystemTypes.UpperEngine => "Upper Engine",
-                    SystemTypes.Nav => "Navigations",
-                    SystemTypes.LifeSupp => "O2",
-                    SystemTypes.LowerEngine => "Lower Engine",
-                    SystemTypes.LockerRoom => "Locker Room",
-                    _ => x.ToString()
-                };
-            }).ToArray();
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/Objects/Systems/SystemTypes.cs b/src/Impostor.Api/Innersloth/Net/Objects/Systems/SystemTypes.cs
deleted file mode 100644 (file)
index 0ff4220..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-namespace Impostor.Api.Innersloth.Net.Objects.Systems
-{
-    public enum SystemTypes : byte
-    {
-        Hallway,
-        Storage,
-        Cafeteria,
-        Reactor,
-        UpperEngine,
-        Nav,
-        Admin,
-        Electrical,
-        LifeSupp,
-        Shields,
-        MedBay,
-        Security,
-        Weapons,
-        LowerEngine,
-        Comms,
-        ShipTasks,
-        Doors,
-        Sabotage,
-        Decontamination,
-        Launchpad,
-        LockerRoom,
-        Laboratory,
-        Balcony,
-        Office,
-        Greenhouse,
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/RpcCalls.cs b/src/Impostor.Api/Innersloth/Net/RpcCalls.cs
deleted file mode 100644 (file)
index 86d068c..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-namespace Impostor.Api.Innersloth.Net
-{
-    public enum RpcCalls : byte
-    {
-        PlayAnimation = 0,
-        CompleteTask = 1,
-        SyncSettings = 2,
-        SetInfected = 3,
-        Exiled = 4,
-        CheckName = 5,
-        SetName = 6,
-        CheckColor = 7,
-        SetColor = 8,
-        SetHat = 9,
-        SetSkin = 10,
-        ReportDeadBody = 11,
-        MurderPlayer = 12,
-        SendChat = 13,
-        StartMeeting = 14,
-        SetScanner = 15,
-        SendChatNote = 16,
-        SetPet = 17,
-        SetStartCounter = 18,
-        EnterVent = 19,
-        ExitVent = 20,
-        SnapTo = 21,
-        Close = 22,
-        VotingComplete = 23,
-        CastVote = 24,
-        ClearVote = 25,
-        AddVote = 26,
-        CloseDoorsOfType = 27,
-        RepairSystem = 28,
-        SetTasks = 29,
-        UpdateGameData = 30,
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/Net/SpawnFlags.cs b/src/Impostor.Api/Innersloth/Net/SpawnFlags.cs
deleted file mode 100644 (file)
index 0372196..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-using System;
-
-namespace Impostor.Api.Innersloth.Net
-{
-    [Flags]
-    public enum SpawnFlags : byte
-    {
-        None = 0,
-        IsClientCharacter = 1,
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/SystemTypeHelpers.cs b/src/Impostor.Api/Innersloth/SystemTypeHelpers.cs
new file mode 100644 (file)
index 0000000..ad88c28
--- /dev/null
@@ -0,0 +1,28 @@
+using System;
+using System.Linq;
+
+namespace Impostor.Api.Innersloth
+{
+    internal class SystemTypeHelpers
+    {
+        public static readonly SystemTypes[] AllTypes;
+        public static readonly string[] Names;
+
+        static SystemTypeHelpers()
+        {
+            AllTypes = Enum.GetValues(typeof(SystemTypes)).Cast<SystemTypes>().ToArray();
+            Names = AllTypes.Select(x =>
+            {
+                return x switch
+                {
+                    SystemTypes.UpperEngine => "Upper Engine",
+                    SystemTypes.Nav => "Navigations",
+                    SystemTypes.LifeSupp => "O2",
+                    SystemTypes.LowerEngine => "Lower Engine",
+                    SystemTypes.LockerRoom => "Locker Room",
+                    _ => x.ToString()
+                };
+            }).ToArray();
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Api/Innersloth/SystemTypes.cs b/src/Impostor.Api/Innersloth/SystemTypes.cs
new file mode 100644 (file)
index 0000000..7e600a1
--- /dev/null
@@ -0,0 +1,31 @@
+namespace Impostor.Api.Innersloth
+{
+    public enum SystemTypes : byte
+    {
+        Hallway,
+        Storage,
+        Cafeteria,
+        Reactor,
+        UpperEngine,
+        Nav,
+        Admin,
+        Electrical,
+        LifeSupp,
+        Shields,
+        MedBay,
+        Security,
+        Weapons,
+        LowerEngine,
+        Comms,
+        ShipTasks,
+        Doors,
+        Sabotage,
+        Decontamination,
+        Launchpad,
+        LockerRoom,
+        Laboratory,
+        Balcony,
+        Office,
+        Greenhouse,
+    }
+}
\ No newline at end of file
index dcb8fc432725d908c7cef041c66ec8050b48263b..1a21bc3f10f47347ead898711871b74946899c15 100644 (file)
@@ -1,7 +1,7 @@
 using System.Threading.Tasks;
 using Impostor.Api.Games;
-using Impostor.Api.Innersloth.Net;
-using Impostor.Api.Innersloth.Net.Objects;
+using Impostor.Api.Net.Inner;
+using Impostor.Api.Net.Inner.Objects;
 
 namespace Impostor.Api.Net
 {
@@ -25,16 +25,16 @@ namespace Impostor.Api.Net
         /// </summary>
         LimboStates Limbo { get; set; }
 
-        InnerPlayerControl Character { get; }
+        IInnerPlayerControl Character { get; }
 
         public bool IsHost { get; }
 
         /// <summary>
-        ///     Checks if the specified <see cref="InnerNetObject"/> is owned by <see cref="IClientPlayer"/>.
+        ///     Checks if the specified <see cref="IInnerNetObject"/> is owned by <see cref="IClientPlayer"/>.
         /// </summary>
-        /// <param name="netObject">The <see cref="InnerNetObject"/>.</param>
+        /// <param name="netObject">The <see cref="IInnerNetObject"/>.</param>
         /// <returns>Returns true if owned by <see cref="IClientPlayer"/>.</returns>
-        bool IsOwner(InnerNetObject netObject);
+        bool IsOwner(IInnerNetObject netObject);
 
         ValueTask KickAsync();
 
diff --git a/src/Impostor.Api/Net/Inner/IGameNet.cs b/src/Impostor.Api/Net/Inner/IGameNet.cs
new file mode 100644 (file)
index 0000000..933a4de
--- /dev/null
@@ -0,0 +1,18 @@
+using Impostor.Api.Net.Inner.Objects;
+
+namespace Impostor.Api.Net.Inner
+{
+    /// <summary>
+    ///     Holds all data that is serialized over the network through GameData packets.
+    /// </summary>
+    public interface IGameNet
+    {
+        IInnerLobbyBehaviour LobbyBehaviour { get; }
+
+        IInnerGameData GameData { get; }
+
+        IInnerVoteBanSystem VoteBan { get; }
+
+        IInnerShipStatus ShipStatus { get; }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Api/Net/Inner/IInnerNetObject.cs b/src/Impostor.Api/Net/Inner/IInnerNetObject.cs
new file mode 100644 (file)
index 0000000..c171377
--- /dev/null
@@ -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/src/Impostor.Api/Net/Inner/Objects/IInnerGameData.cs b/src/Impostor.Api/Net/Inner/Objects/IInnerGameData.cs
new file mode 100644 (file)
index 0000000..f908289
--- /dev/null
@@ -0,0 +1,7 @@
+namespace Impostor.Api.Net.Inner.Objects
+{
+    public interface IInnerGameData : IInnerNetObject
+    {
+
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Api/Net/Inner/Objects/IInnerLobbyBehaviour.cs b/src/Impostor.Api/Net/Inner/Objects/IInnerLobbyBehaviour.cs
new file mode 100644 (file)
index 0000000..98f0f40
--- /dev/null
@@ -0,0 +1,7 @@
+namespace Impostor.Api.Net.Inner.Objects
+{
+    public interface IInnerLobbyBehaviour : IInnerNetObject
+    {
+
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Api/Net/Inner/Objects/IInnerPlayerControl.cs b/src/Impostor.Api/Net/Inner/Objects/IInnerPlayerControl.cs
new file mode 100644 (file)
index 0000000..1b5c3ba
--- /dev/null
@@ -0,0 +1,6 @@
+namespace Impostor.Api.Net.Inner.Objects
+{
+    public interface IInnerPlayerControl
+    {
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Api/Net/Inner/Objects/IInnerShipStatus.cs b/src/Impostor.Api/Net/Inner/Objects/IInnerShipStatus.cs
new file mode 100644 (file)
index 0000000..c0a05ae
--- /dev/null
@@ -0,0 +1,7 @@
+namespace Impostor.Api.Net.Inner.Objects
+{
+    public interface IInnerShipStatus : IInnerNetObject
+    {
+
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Api/Net/Inner/Objects/IInnerVoteBanSystem.cs b/src/Impostor.Api/Net/Inner/Objects/IInnerVoteBanSystem.cs
new file mode 100644 (file)
index 0000000..d0a816d
--- /dev/null
@@ -0,0 +1,7 @@
+namespace Impostor.Api.Net.Inner.Objects
+{
+    public interface IInnerVoteBanSystem : IInnerNetObject
+    {
+
+    }
+}
\ No newline at end of file
index d6e66bdc6308bafed6ccecb73641a60863a905c3..44c493e814f9f98418e3b0cf2529af7ae59ef53b 100644 (file)
@@ -8,6 +8,6 @@ namespace Impostor.Api.Net
         PreSpawn = 1,
         NotLimbo = 2,
         WaitingForHost = 4,
-        All = PreSpawn | NotLimbo | WaitingForHost
+        All = PreSpawn | NotLimbo | WaitingForHost,
     }
 }
\ No newline at end of file
index dd143c062acd77b4299b9eac3673e893be4037ea..330f3b5ba9091ef073f199be24032bf9ccdcb52d 100644 (file)
@@ -1,4 +1,4 @@
-using Impostor.Api.Innersloth.Data;
+using Impostor.Api.Innersloth;
 
 namespace Impostor.Api.Net.Messages.C2S
 {
index e683815fbfd87997da9e0be5f12a9d27f26c58dc..c45520105a5cd204aa55d38e1881faedf8fbf633 100644 (file)
@@ -1,5 +1,5 @@
 using System;
-using Impostor.Api.Innersloth.Data;
+using Impostor.Api.Innersloth;
 
 namespace Impostor.Api.Net.Messages.S2C
 {
index abbb844bc4816c92b3a1a0b57ca4deb3c86e81b5..77b447d05dabefa7c7e5eb24766b854f8b263a09 100644 (file)
@@ -1,4 +1,4 @@
-using Impostor.Api.Innersloth.Data;
+using Impostor.Api.Innersloth;
 
 namespace Impostor.Api.Net.Messages.S2C
 {
index 469cd84a02312c02766e45fc9798fcc8d2c540f2..fa155dfab80cba651e36c94e1e4f1e6ad2c518d0 100644 (file)
@@ -1,4 +1,4 @@
-using Impostor.Api.Innersloth.Data;
+using Impostor.Api.Innersloth;
 
 namespace Impostor.Api.Net.Messages.S2C
 {
index a4c3a5512821372180cb8763bf5ad0896b339e61..fd0f38f07b822f16dd43b72b7652f2a9588c956f 100644 (file)
@@ -1,7 +1,5 @@
 using System.Threading.Tasks;
 using Impostor.Api.Events;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Hosting;
 
 namespace Impostor.Api.Plugins
 {
index e5139d42fe7d2973d8e07f36862f9b94c64fa663..438c1c2bff2454db8b9345036d25708ceeb71725 100644 (file)
@@ -2,7 +2,6 @@
 using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Linq;
-using System.Reflection;
 using System.Threading.Tasks;
 using Impostor.Api.Events;
 using Impostor.Api.Events.Managers;
index 52cf629fa21abbd927158b9b6284aae0b39112e4..1446ad1eb1647b0b561d41f3efb7dd20cfe7c107 100644 (file)
@@ -4,7 +4,6 @@ using System.Collections.Generic;
 using System.Diagnostics;
 using System.Linq;
 using System.Threading;
-using Impostor.Api.Events;
 
 namespace Impostor.Server.Events.Register
 {
diff --git a/src/Impostor.Server/Extensions/MessageReaderExtensions.cs b/src/Impostor.Server/Extensions/MessageReaderExtensions.cs
new file mode 100644 (file)
index 0000000..5f25e89
--- /dev/null
@@ -0,0 +1,15 @@
+using Impostor.Api.Net.Messages;
+using Impostor.Server.Net.Inner;
+using Impostor.Server.Net.State;
+
+namespace Impostor.Server
+{
+    internal static class MessageReaderExtensions
+    {
+        public static T ReadNetObject<T>(this IMessageReader reader, Game game)
+            where T : InnerNetObject
+        {
+            return game.FindObjectByNetId<T>(reader.ReadPackedUInt32());
+        }
+    }
+}
\ No newline at end of file
index 671017d06d015e4060e3b89d9376d8305c9d358e..370bca6208f0b9c1eb1102f22d3b9b4247bd1d12 100644 (file)
@@ -1,13 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Text;
-using System.Threading.Tasks;
-
+using System.Threading.Tasks;
 using Impostor.Server.Net.Redirector;
 
-namespace Impostor.Server.Extensions
+namespace Impostor.Server
 {
     public static class NodeLocatorExtensions
     {
index 65defdf433f26917e714486b2d6ff86cf9828ec6..cceb48c807661bc3fe7ae938fed7c548f2e6e2d5 100644 (file)
@@ -3,14 +3,12 @@ using System.Threading.Tasks;
 using Impostor.Api;
 using Impostor.Api.Games;
 using Impostor.Api.Innersloth;
-using Impostor.Api.Innersloth.Data;
 using Impostor.Api.Net;
 using Impostor.Api.Net.Messages;
 using Impostor.Api.Net.Messages.C2S;
 using Impostor.Api.Net.Messages.S2C;
 using Impostor.Hazel;
 using Impostor.Server.Config;
-using Impostor.Server.Net.Hazel;
 using Impostor.Server.Net.Manager;
 using Microsoft.Extensions.Logging;
 
index c04044cd5847a31a3ff6d0b27d9e39371aa1d422..ad1fdc778e95cef00a3910599008ecd1ed3f4900 100644 (file)
@@ -1,6 +1,5 @@
 using System;
 using Impostor.Api.Net;
-using Impostor.Server.Net.Hazel;
 using Microsoft.Extensions.DependencyInjection;
 
 namespace Impostor.Server.Net.Factories
diff --git a/src/Impostor.Server/Net/Inner/GameDataTag.cs b/src/Impostor.Server/Net/Inner/GameDataTag.cs
new file mode 100644 (file)
index 0000000..fa9ddb8
--- /dev/null
@@ -0,0 +1,13 @@
+namespace Impostor.Server.Net.Inner
+{
+    public static class GameDataTag
+    {
+        public const byte DataFlag = 1;
+        public const byte RpcFlag = 2;
+        public const byte SpawnFlag = 4;
+        public const byte DespawnFlag = 5;
+        public const byte SceneChangeFlag = 6;
+        public const byte ReadyFlag = 7;
+        public const byte ChangeSettingsFlag = 8;
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/GameObject.cs b/src/Impostor.Server/Net/Inner/GameObject.cs
new file mode 100644 (file)
index 0000000..9b53d70
--- /dev/null
@@ -0,0 +1,29 @@
+using System.Collections.Generic;
+
+namespace Impostor.Server.Net.Inner
+{
+    internal class GameObject
+    {
+        public GameObject()
+        {
+            Components = new List<object>();
+        }
+
+        protected List<object> Components { get; }
+
+        public List<T> GetComponentsInChildren<T>()
+        {
+            var result = new List<T>();
+
+            foreach (var component in Components)
+            {
+                if (component is T c)
+                {
+                    result.Add(c);
+                }
+            }
+
+            return result;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/InnerNetObject.cs b/src/Impostor.Server/Net/Inner/InnerNetObject.cs
new file mode 100644 (file)
index 0000000..78f1a55
--- /dev/null
@@ -0,0 +1,31 @@
+using System.Threading.Tasks;
+using Impostor.Api.Net;
+using Impostor.Api.Net.Inner;
+using Impostor.Api.Net.Messages;
+using Impostor.Server.Net.State;
+
+namespace Impostor.Server.Net.Inner
+{
+    internal abstract class InnerNetObject : GameObject, IInnerNetObject
+    {
+        private const int HostInheritId = -2;
+
+        public uint NetId { get; internal set; }
+
+        public int OwnerId { get; internal set; }
+
+        public SpawnFlags SpawnFlags { get; internal set; }
+
+        public abstract ValueTask HandleRpc(ClientPlayer sender, ClientPlayer? target, RpcCalls call, IMessageReader reader);
+
+        public abstract bool Serialize(IMessageWriter writer, bool initialState);
+
+        public abstract void Deserialize(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState);
+
+        public bool IsOwnedBy(IClientPlayer player)
+        {
+            return OwnerId == player.Client.Id ||
+                   (OwnerId == HostInheritId && player.IsHost);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/Objects/Components/InnerCustomNetworkTransform.cs b/src/Impostor.Server/Net/Inner/Objects/Components/InnerCustomNetworkTransform.cs
new file mode 100644 (file)
index 0000000..75e331e
--- /dev/null
@@ -0,0 +1,129 @@
+using System.Numerics;
+using System.Threading.Tasks;
+using Impostor.Api;
+using Impostor.Api.Innersloth;
+using Impostor.Api.Net;
+using Impostor.Api.Net.Messages;
+using Impostor.Server.Net.State;
+using Microsoft.Extensions.Logging;
+
+namespace Impostor.Server.Net.Inner.Objects.Components
+{
+    internal class InnerCustomNetworkTransform : InnerNetObject
+    {
+        private static readonly FloatRange XRange = new FloatRange(-40f, 40f);
+        private static readonly FloatRange YRange = new FloatRange(-40f, 40f);
+
+        private readonly ILogger<InnerCustomNetworkTransform> _logger;
+
+        private ushort _lastSequenceId;
+        private Vector2 _targetSyncPosition;
+        private Vector2 _targetSyncVelocity;
+
+        public InnerCustomNetworkTransform(ILogger<InnerCustomNetworkTransform> logger)
+        {
+            _logger = logger;
+        }
+
+        private static bool SidGreaterThan(ushort newSid, ushort prevSid)
+        {
+            var num = (ushort)(prevSid + (uint) short.MaxValue);
+
+            return (int) prevSid < (int) num
+                ? newSid > prevSid && newSid <= num
+                : newSid > prevSid || newSid <= num;
+        }
+
+        private static void WriteVector2(IMessageWriter writer, Vector2 vec)
+        {
+            writer.Write((ushort)(XRange.ReverseLerp(vec.X) * (double) ushort.MaxValue));
+            writer.Write((ushort)(YRange.ReverseLerp(vec.Y) * (double) ushort.MaxValue));
+        }
+
+        private static Vector2 ReadVector2(IMessageReader reader)
+        {
+            var v1 = reader.ReadUInt16() / (float) ushort.MaxValue;
+            var v2 = reader.ReadUInt16() / (float) ushort.MaxValue;
+
+            return new Vector2(XRange.Lerp(v1), YRange.Lerp(v2));
+        }
+
+        public override ValueTask HandleRpc(ClientPlayer sender, ClientPlayer? target, RpcCalls call, IMessageReader reader)
+        {
+            if (call == RpcCalls.SnapTo)
+            {
+                SnapTo(ReadVector2(reader), reader.ReadUInt16());
+            }
+            else
+            {
+                _logger.LogWarning("{0}: Unknown rpc call {1}", nameof(InnerCustomNetworkTransform), call);
+            }
+
+            return default;
+        }
+
+        public override bool Serialize(IMessageWriter writer, bool initialState)
+        {
+            if (initialState)
+            {
+                writer.Write(_lastSequenceId);
+                WriteVector2(writer, _targetSyncPosition);
+                WriteVector2(writer, _targetSyncVelocity);
+                return true;
+            }
+
+            // TODO: DirtyBits == 0 return false.
+            _lastSequenceId++;
+
+            writer.Write(_lastSequenceId);
+            WriteVector2(writer, _targetSyncPosition);
+            WriteVector2(writer, _targetSyncVelocity);
+            return true;
+        }
+
+        public override void Deserialize(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState)
+        {
+            var sequenceId = reader.ReadUInt16();
+
+            if (initialState)
+            {
+                _lastSequenceId = sequenceId;
+                _targetSyncPosition = ReadVector2(reader);
+                _targetSyncVelocity = ReadVector2(reader);
+            }
+            else
+            {
+                if (!sender.IsOwner(this))
+                {
+                    throw new ImpostorCheatException($"Client attempted to send unowned {nameof(InnerCustomNetworkTransform)} data");
+                }
+
+                if (target != null)
+                {
+                    throw new ImpostorCheatException($"Client attempted to send {nameof(InnerCustomNetworkTransform)} data to a specific player, must be broadcast");
+                }
+
+                if (!SidGreaterThan(sequenceId, _lastSequenceId))
+                {
+                    return;
+                }
+
+                _lastSequenceId = sequenceId;
+                _targetSyncPosition = ReadVector2(reader);
+                _targetSyncVelocity = ReadVector2(reader);
+            }
+        }
+
+        private void SnapTo(Vector2 position, ushort minSid)
+        {
+            if (SidGreaterThan(minSid, _lastSequenceId))
+            {
+                return;
+            }
+
+            _lastSequenceId = minSid;
+            _targetSyncPosition = position;
+            _targetSyncVelocity = Vector2.Zero;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/Objects/Components/InnerPlayerPhysics.cs b/src/Impostor.Server/Net/Inner/Objects/Components/InnerPlayerPhysics.cs
new file mode 100644 (file)
index 0000000..08738f7
--- /dev/null
@@ -0,0 +1,61 @@
+using System;
+using System.Threading.Tasks;
+using Impostor.Api;
+using Impostor.Api.Net;
+using Impostor.Api.Net.Messages;
+using Impostor.Server.Net.State;
+using Microsoft.Extensions.Logging;
+
+namespace Impostor.Server.Net.Inner.Objects.Components
+{
+    internal class InnerPlayerPhysics : InnerNetObject
+    {
+        private readonly ILogger<InnerPlayerPhysics> _logger;
+
+        public InnerPlayerPhysics(ILogger<InnerPlayerPhysics> logger)
+        {
+            _logger = logger;
+        }
+
+        public override ValueTask HandleRpc(ClientPlayer sender, ClientPlayer? target, RpcCalls call, IMessageReader reader)
+        {
+            if (call != RpcCalls.EnterVent && call != RpcCalls.ExitVent)
+            {
+                _logger.LogWarning("{0}: Unknown rpc call {1}", nameof(InnerPlayerPhysics), call);
+                return default;
+            }
+
+            if (!sender.IsOwner(this))
+            {
+                throw new ImpostorCheatException($"Client sent {call} to an unowned {nameof(InnerPlayerControl)}");
+            }
+
+            if (target != null)
+            {
+                throw new ImpostorCheatException($"Client sent {call} to a specific player instead of broadcast");
+            }
+
+            if (!sender.Character.PlayerInfo.IsImpostor)
+            {
+                throw new ImpostorCheatException($"Client sent {call} as crewmate");
+            }
+
+            var ventId = reader.ReadPackedUInt32();
+            var ventEnter = call == RpcCalls.EnterVent;
+
+            // TODO: Do stuff.
+
+            return default;
+        }
+
+        public override bool Serialize(IMessageWriter writer, bool initialState)
+        {
+            throw new NotImplementedException();
+        }
+
+        public override void Deserialize(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/Objects/Components/InnerVoteBanSystem.cs b/src/Impostor.Server/Net/Inner/Objects/Components/InnerVoteBanSystem.cs
new file mode 100644 (file)
index 0000000..58b9b54
--- /dev/null
@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Impostor.Api;
+using Impostor.Api.Net;
+using Impostor.Api.Net.Inner.Objects;
+using Impostor.Api.Net.Messages;
+using Impostor.Server.Net.State;
+using Microsoft.Extensions.Logging;
+
+namespace Impostor.Server.Net.Inner.Objects.Components
+{
+    internal class InnerVoteBanSystem : InnerNetObject, IInnerVoteBanSystem
+    {
+        private readonly ILogger<InnerVoteBanSystem> _logger;
+        private readonly Dictionary<int, int[]> _votes;
+
+        public InnerVoteBanSystem(ILogger<InnerVoteBanSystem> logger)
+        {
+            _logger = logger;
+            _votes = new Dictionary<int, int[]>();
+        }
+
+        public override ValueTask HandleRpc(ClientPlayer sender, ClientPlayer? target, RpcCalls call, IMessageReader reader)
+        {
+            if (call != RpcCalls.AddVote)
+            {
+                _logger.LogWarning("{0}: Unknown rpc call {1}", nameof(InnerVoteBanSystem), call);
+                return default;
+            }
+
+            var clientId = reader.ReadInt32();
+            if (clientId != sender.Client.Id)
+            {
+                throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.AddVote)} as other client");
+            }
+
+            if (target != null)
+            {
+                throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.CastVote)} to wrong destinition, must be broadcast");
+            }
+
+            var targetClientId = reader.ReadInt32();
+
+            // TODO: Use.
+
+            return default;
+        }
+
+        public override bool Serialize(IMessageWriter writer, bool initialState)
+        {
+            throw new NotImplementedException();
+        }
+
+        public override void Deserialize(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState)
+        {
+            if (!sender.IsHost)
+            {
+                throw new ImpostorCheatException($"Client attempted to send data for {nameof(InnerShipStatus)} as non-host");
+            }
+
+            var votes = _votes;
+            var unknown = reader.ReadByte();
+            if (unknown != 0)
+            {
+                for (var i = 0; i < unknown; i++)
+                {
+                    var v4 = reader.ReadInt32();
+                    if (v4 == 0)
+                    {
+                        break;
+                    }
+
+                    if (!votes.TryGetValue(v4, out var v12))
+                    {
+                        v12 = new int[3];
+                        votes[v4] = v12;
+                    }
+
+                    for (var j = 0; j < 3; j++)
+                    {
+                        v12[j] = reader.ReadPackedInt32();
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/Objects/InnerGameData.PlayerInfo.cs b/src/Impostor.Server/Net/Inner/Objects/InnerGameData.PlayerInfo.cs
new file mode 100644 (file)
index 0000000..677aa5f
--- /dev/null
@@ -0,0 +1,67 @@
+using System;
+using System.Collections.Generic;
+using Impostor.Api.Innersloth;
+using Impostor.Api.Net.Messages;
+
+namespace Impostor.Server.Net.Inner.Objects
+{
+    internal partial class InnerGameData
+    {
+        public class PlayerInfo
+        {
+            public PlayerInfo(byte playerId)
+            {
+                PlayerId = playerId;
+            }
+
+            public InnerPlayerControl Controller { get; internal set; }
+
+            public byte PlayerId { get; }
+
+            public string PlayerName { get; internal set; }
+
+            public byte ColorId { get; internal set; }
+
+            public uint HatId { get; internal set; }
+
+            public uint PetId { get; internal set; }
+
+            public uint SkinId { get; internal set; }
+
+            public bool Disconnected { get; internal set; }
+
+            public bool IsImpostor { get; internal set; }
+
+            public bool IsDead { get; internal set; }
+
+            public DeathReason LastDeathReason { get; internal set; }
+
+            public List<TaskInfo> Tasks { get; internal set; }
+
+            public void Serialize(IMessageWriter writer)
+            {
+                throw new NotImplementedException();
+            }
+
+            public void Deserialize(IMessageReader reader)
+            {
+                PlayerName = reader.ReadString();
+                ColorId = reader.ReadByte();
+                HatId = reader.ReadPackedUInt32();
+                PetId = reader.ReadPackedUInt32();
+                SkinId = reader.ReadPackedUInt32();
+                var flag = reader.ReadByte();
+                Disconnected = (flag & 1) > 0;
+                IsImpostor = (flag & 2) > 0;
+                IsDead = (flag & 4) > 0;
+                var taskCount = reader.ReadByte();
+                Tasks = new List<TaskInfo>();
+                for (var i = 0; i < taskCount; i++)
+                {
+                    Tasks.Add(new TaskInfo());
+                    Tasks[i].Deserialize(reader);
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/Objects/InnerGameData.TaskInfo.cs b/src/Impostor.Server/Net/Inner/Objects/InnerGameData.TaskInfo.cs
new file mode 100644 (file)
index 0000000..5dfa5c2
--- /dev/null
@@ -0,0 +1,26 @@
+using Impostor.Api.Net.Messages;
+
+namespace Impostor.Server.Net.Inner.Objects
+{
+    internal partial class InnerGameData
+    {
+        public class TaskInfo
+        {
+            public uint Id { get; internal set; }
+
+            public bool Complete { get; internal set; }
+
+            public void Serialize(IMessageWriter writer)
+            {
+                writer.WritePacked(Id);
+                writer.Write(Complete);
+            }
+
+            public void Deserialize(IMessageReader reader)
+            {
+                this.Id = reader.ReadPackedUInt32();
+                this.Complete = reader.ReadBoolean();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/Objects/InnerGameData.cs b/src/Impostor.Server/Net/Inner/Objects/InnerGameData.cs
new file mode 100644 (file)
index 0000000..04cf1cd
--- /dev/null
@@ -0,0 +1,185 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Impostor.Api;
+using Impostor.Api.Net;
+using Impostor.Api.Net.Inner.Objects;
+using Impostor.Api.Net.Messages;
+using Impostor.Server.Net.Inner.Objects.Components;
+using Impostor.Server.Net.State;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+
+namespace Impostor.Server.Net.Inner.Objects
+{
+    internal partial class InnerGameData : InnerNetObject, IInnerGameData
+    {
+        private readonly ILogger<InnerGameData> _logger;
+        private readonly Game _game;
+        private readonly ConcurrentDictionary<byte, PlayerInfo> _allPlayers;
+
+        public InnerGameData(ILogger<InnerGameData> logger, Game game, IServiceProvider serviceProvider)
+        {
+            _logger = logger;
+            _game = game;
+            _allPlayers = new ConcurrentDictionary<byte, PlayerInfo>();
+
+            Components.Add(this);
+            Components.Add(ActivatorUtilities.CreateInstance<InnerVoteBanSystem>(serviceProvider));
+        }
+
+        public int PlayerCount => _allPlayers.Count;
+
+        public IReadOnlyDictionary<byte, PlayerInfo> Players => _allPlayers;
+
+        public PlayerInfo? GetPlayerById(byte id)
+        {
+            if (id == byte.MaxValue)
+            {
+                return null;
+            }
+
+            return _allPlayers.TryGetValue(id, out var player) ? player : null;
+        }
+
+        public override ValueTask HandleRpc(ClientPlayer sender, ClientPlayer? target, RpcCalls call,
+            IMessageReader reader)
+        {
+            switch (call)
+            {
+                case RpcCalls.SetTasks:
+                {
+                    if (!sender.IsHost)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetTasks)} but was not a host");
+                    }
+
+                    if (target != null)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetTasks)} to a specific player instead of broadcast");
+                    }
+
+                    var playerId = reader.ReadByte();
+                    var taskTypeIds = reader.ReadBytesAndSize();
+
+                    SetTasks(playerId, taskTypeIds);
+                    break;
+                }
+
+                case RpcCalls.UpdateGameData:
+                {
+                    if (!sender.IsHost)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetTasks)} but was not a host");
+                    }
+
+                    if (target != null)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetTasks)} to a specific player instead of broadcast");
+                    }
+
+                    while (reader.Position < reader.Length)
+                    {
+                        var message = reader.ReadMessage();
+                        var player = GetPlayerById(message.Tag);
+                        if (player != null)
+                        {
+                            player.Deserialize(message);
+                        }
+                        else
+                        {
+                            var playerInfo = new PlayerInfo(message.Tag);
+
+                            playerInfo.Deserialize(reader);
+
+                            if (!_allPlayers.TryAdd(playerInfo.PlayerId, playerInfo))
+                            {
+                                throw new ImpostorException("Failed to add player to InnerGameData.");
+                            }
+                        }
+                    }
+
+                    break;
+                }
+
+                default:
+                {
+                    _logger.LogWarning("{0}: Unknown rpc call {1}", nameof(InnerGameData), call);
+                    break;
+                }
+            }
+
+            return default;
+        }
+
+        public override bool Serialize(IMessageWriter writer, bool initialState)
+        {
+            throw new NotImplementedException();
+        }
+
+        public override void Deserialize(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState)
+        {
+            if (!sender.IsHost)
+            {
+                throw new ImpostorCheatException($"Client attempted to send data for {nameof(InnerGameData)} as non-host");
+            }
+
+            if (initialState)
+            {
+                var num = reader.ReadPackedInt32();
+
+                for (var i = 0; i < num; i++)
+                {
+                    var playerId = reader.ReadByte();
+                    var playerInfo = new PlayerInfo(playerId);
+
+                    playerInfo.Deserialize(reader);
+
+                    if (!_allPlayers.TryAdd(playerInfo.PlayerId, playerInfo))
+                    {
+                        throw new ImpostorException("Failed to add player to InnerGameData.");
+                    }
+                }
+            }
+            else
+            {
+                throw new NotImplementedException("This shouldn't happen, according to Among Us disassembly.");
+            }
+        }
+
+        internal void AddPlayer(InnerPlayerControl control)
+        {
+            var playerId = control.PlayerId;
+            var playerInfo = new PlayerInfo(control.PlayerId);
+
+            if (_allPlayers.TryAdd(playerId, playerInfo))
+            {
+                control.PlayerInfo = playerInfo;
+            }
+        }
+
+        private void SetTasks(byte playerId, ReadOnlyMemory<byte> taskTypeIds)
+        {
+            var player = GetPlayerById(playerId);
+            if (player == null)
+            {
+                _logger.LogTrace("Could not set tasks for playerId {0}.", playerId);
+                return;
+            }
+
+            if (player.Disconnected)
+            {
+                return;
+            }
+
+            player.Tasks = new List<TaskInfo>(taskTypeIds.Length);
+
+            for (var i = 0; i < taskTypeIds.Length; i++)
+            {
+                player.Tasks.Add(new TaskInfo());
+                player.Tasks[i].Id = (uint)i;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/Objects/InnerLobbyBehaviour.cs b/src/Impostor.Server/Net/Inner/Objects/InnerLobbyBehaviour.cs
new file mode 100644 (file)
index 0000000..63448ed
--- /dev/null
@@ -0,0 +1,36 @@
+using System.Threading.Tasks;
+using Impostor.Api.Games;
+using Impostor.Api.Net;
+using Impostor.Api.Net.Inner.Objects;
+using Impostor.Api.Net.Messages;
+using Impostor.Server.Net.State;
+
+namespace Impostor.Server.Net.Inner.Objects
+{
+    internal class InnerLobbyBehaviour : InnerNetObject, IInnerLobbyBehaviour
+    {
+        private readonly IGame _game;
+
+        public InnerLobbyBehaviour(IGame game)
+        {
+            _game = game;
+
+            Components.Add(this);
+        }
+
+        public override ValueTask HandleRpc(ClientPlayer sender, ClientPlayer? target, RpcCalls call, IMessageReader reader)
+        {
+            throw new System.NotImplementedException();
+        }
+
+        public override bool Serialize(IMessageWriter writer, bool initialState)
+        {
+            throw new System.NotImplementedException();
+        }
+
+        public override void Deserialize(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState)
+        {
+            throw new System.NotImplementedException();
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/Objects/InnerMeetingHud.PlayerVoteArea.cs b/src/Impostor.Server/Net/Inner/Objects/InnerMeetingHud.PlayerVoteArea.cs
new file mode 100644 (file)
index 0000000..fbf2510
--- /dev/null
@@ -0,0 +1,49 @@
+using Impostor.Api.Net.Messages;
+
+namespace Impostor.Server.Net.Inner.Objects
+{
+    internal partial class InnerMeetingHud
+    {
+        public class PlayerVoteArea
+        {
+            private const byte VoteMask = 15;
+            private const byte ReportedBit = 32;
+            private const byte VotedBit = 64;
+            private const byte DeadBit = 128;
+
+            public PlayerVoteArea(InnerMeetingHud parent, byte targetPlayerId)
+            {
+                Parent = parent;
+                TargetPlayerId = targetPlayerId;
+            }
+
+            public InnerMeetingHud Parent { get; }
+
+            public byte TargetPlayerId { get; }
+
+            public bool IsDead { get; private set; }
+
+            public bool DidVote { get; private set; }
+
+            public bool DidReport { get; private set; }
+
+            public sbyte VotedFor { get; private set; }
+
+            internal void SetDead(bool didReport, bool isDead)
+            {
+                DidReport = didReport;
+                IsDead = isDead;
+            }
+
+            public void Deserialize(IMessageReader reader)
+            {
+                var num = reader.ReadByte();
+
+                VotedFor = (sbyte)((num & VoteMask) - 1);
+                IsDead = (num & DeadBit) > 0;
+                DidVote = (num & VotedBit) > 0;
+                DidReport = (num & ReportedBit) > 0;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/Objects/InnerMeetingHud.cs b/src/Impostor.Server/Net/Inner/Objects/InnerMeetingHud.cs
new file mode 100644 (file)
index 0000000..42c9518
--- /dev/null
@@ -0,0 +1,160 @@
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using Impostor.Api;
+using Impostor.Api.Net;
+using Impostor.Api.Net.Messages;
+using Impostor.Server.Net.State;
+using Microsoft.Extensions.Logging;
+
+namespace Impostor.Server.Net.Inner.Objects
+{
+    internal partial class InnerMeetingHud : InnerNetObject
+    {
+        private readonly ILogger<InnerMeetingHud> _logger;
+        private readonly Game _game;
+        private readonly GameNet _gameNet;
+        private PlayerVoteArea[] _playerStates;
+
+        public InnerMeetingHud(ILogger<InnerMeetingHud> logger, Game game)
+        {
+            _logger = logger;
+            _game = game;
+            _gameNet = game.GameNet;
+            _playerStates = null;
+
+            Components.Add(this);
+        }
+
+        public byte ReporterId { get; private set; }
+
+        private void PopulateButtons(byte reporter)
+        {
+            _playerStates = _gameNet.GameData.Players
+                .Select(x =>
+                {
+                    var area = new PlayerVoteArea(this, x.Key);
+                    area.SetDead(x.Value.PlayerId == reporter, x.Value.Disconnected || x.Value.IsDead);
+                    return area;
+                })
+                .ToArray();
+        }
+
+        public override ValueTask HandleRpc(ClientPlayer sender, ClientPlayer? target, RpcCalls call,
+            IMessageReader reader)
+        {
+            switch (call)
+            {
+                case RpcCalls.Close:
+                {
+                    if (!sender.IsHost)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.Close)} but was not a host");
+                    }
+
+                    if (target != null)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.Close)} to a specific player instead of broadcast");
+                    }
+
+                    break;
+                }
+
+                case RpcCalls.VotingComplete:
+                {
+                    if (!sender.IsHost)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.VotingComplete)} but was not a host");
+                    }
+
+                    if (target != null)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.VotingComplete)} to a specific player instead of broadcast");
+                    }
+
+                    var states = reader.ReadBytesAndSize();
+                    var playerId = reader.ReadByte();
+                    var tie = reader.ReadBoolean();
+                    break;
+                }
+
+                case RpcCalls.CastVote:
+                {
+                    var srcPlayerId = reader.ReadByte();
+                    if (srcPlayerId != sender.Character.PlayerId)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.CastVote)} to an unowned {nameof(InnerPlayerControl)}");
+                    }
+
+                    // Host broadcasts vote to others.
+                    if (sender.IsHost && target != null)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.CastVote)} to a specific player instead of broadcast");
+                    }
+
+                    // Player sends vote to host.
+                    if (target == null || !target.IsHost)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.CastVote)} to wrong destinition, must be host");
+                    }
+
+                    var targetPlayerId = reader.ReadByte();
+                    break;
+                }
+
+                default:
+                {
+                    _logger.LogWarning("{0}: Unknown rpc call {1}", nameof(InnerMeetingHud), call);
+                    break;
+                }
+            }
+
+            return default;
+        }
+
+        public override bool Serialize(IMessageWriter writer, bool initialState)
+        {
+            throw new NotImplementedException();
+        }
+
+        public override void Deserialize(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState)
+        {
+            if (!sender.IsHost)
+            {
+                throw new ImpostorCheatException($"Client attempted to send data for {nameof(InnerMeetingHud)} as non-host");
+            }
+
+            if (target != null)
+            {
+                throw new ImpostorCheatException($"Client attempted to send {nameof(InnerMeetingHud)} data to a specific player, must be broadcast");
+            }
+
+            if (initialState)
+            {
+                PopulateButtons(0);
+
+                foreach (var playerState in _playerStates)
+                {
+                    playerState.Deserialize(reader);
+
+                    if (playerState.DidReport)
+                    {
+                        ReporterId = playerState.TargetPlayerId;
+                    }
+                }
+            }
+            else
+            {
+                var num = reader.ReadPackedUInt32();
+
+                for (var i = 0; i < _playerStates.Length; i++)
+                {
+                    if ((num & 1 << i) != 0)
+                    {
+                        _playerStates[i].Deserialize(reader);
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/Objects/InnerPlayerControl.cs b/src/Impostor.Server/Net/Inner/Objects/InnerPlayerControl.cs
new file mode 100644 (file)
index 0000000..d761771
--- /dev/null
@@ -0,0 +1,409 @@
+using System;
+using System.Threading.Tasks;
+using Impostor.Api;
+using Impostor.Api.Events.Managers;
+using Impostor.Api.Events.Net;
+using Impostor.Api.Innersloth;
+using Impostor.Api.Net;
+using Impostor.Api.Net.Inner.Objects;
+using Impostor.Api.Net.Messages;
+using Impostor.Server.Net.Inner.Objects.Components;
+using Impostor.Server.Net.State;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+
+namespace Impostor.Server.Net.Inner.Objects
+{
+    internal class InnerPlayerControl : InnerNetObject, IInnerPlayerControl
+    {
+        private readonly ILogger<InnerPlayerControl> _logger;
+        private readonly IEventManager _eventManager;
+        private readonly Game _game;
+
+        public InnerPlayerControl(ILogger<InnerPlayerControl> logger, IServiceProvider serviceProvider, IEventManager eventManager, Game game)
+        {
+            _logger = logger;
+            _eventManager = eventManager;
+            _game = game;
+
+            Components.Add(this);
+            Components.Add(ActivatorUtilities.CreateInstance<InnerPlayerPhysics>(serviceProvider));
+            Components.Add(ActivatorUtilities.CreateInstance<InnerCustomNetworkTransform>(serviceProvider));
+
+            PlayerId = byte.MaxValue;
+        }
+
+        public bool IsNew { get; private set; }
+
+        public byte PlayerId { get; private set; }
+
+        public InnerGameData.PlayerInfo PlayerInfo { get; internal set; }
+
+        public override async ValueTask HandleRpc(ClientPlayer sender, ClientPlayer? target, RpcCalls call,
+            IMessageReader reader)
+        {
+            switch (call)
+            {
+                // Play an animation.
+                case RpcCalls.PlayAnimation:
+                {
+                    if (!sender.IsOwner(this))
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.PlayAnimation)} to an unowned {nameof(InnerPlayerControl)}");
+                    }
+
+                    if (target != null)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.PlayAnimation)} to a specific player instead of broadcast");
+                    }
+
+                    var animation = reader.ReadByte();
+                    break;
+                }
+
+                // Complete a task.
+                case RpcCalls.CompleteTask:
+                {
+                    if (!sender.IsOwner(this))
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.CompleteTask)} to an unowned {nameof(InnerPlayerControl)}");
+                    }
+
+                    if (target != null)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.CompleteTask)} to a specific player instead of broadcast");
+                    }
+
+                    var index = reader.ReadPackedUInt32();
+                    break;
+                }
+
+                // Update GameOptions.
+                case RpcCalls.SyncSettings:
+                {
+                    if (!sender.IsHost)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SyncSettings)} but was not a host");
+                    }
+
+                    _game.Options.Deserialize(reader.ReadBytesAndSize());
+                    break;
+                }
+
+                // Set Impostors.
+                case RpcCalls.SetInfected:
+                {
+                    if (!sender.IsHost)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetInfected)} but was not a host");
+                    }
+
+                    var length = reader.ReadPackedInt32();
+
+                    for (var i = 0; i < length; i++)
+                    {
+                        var playerId = reader.ReadByte();
+                        var player = _game.GameNet.GameData.GetPlayerById(playerId);
+
+                        player.IsImpostor = true;
+                    }
+
+                    break;
+                }
+
+                // Player was voted out.
+                case RpcCalls.Exiled:
+                {
+                    if (!sender.IsHost)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.Exiled)} but was not a host");
+                    }
+
+                    if (target != null)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.Exiled)} to a specific player instead of broadcast");
+                    }
+
+                    // TODO: Not hit?
+                    Die(DeathReason.Exile);
+                    break;
+                }
+
+                // Validates the player name at the host.
+                case RpcCalls.CheckName:
+                {
+                    if (target == null || !target.IsHost)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.CheckName)} to the wrong player");
+                    }
+
+                    var name = reader.ReadString();
+                    break;
+                }
+
+                // Update the name of a player.
+                case RpcCalls.SetName:
+                {
+                    if (!sender.IsHost)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetName)} but was not a host");
+                    }
+
+                    if (target != null)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetName)} to a specific player instead of broadcast");
+                    }
+
+                    PlayerInfo.PlayerName = reader.ReadString();
+                    break;
+                }
+
+                // Validates the color at the host.
+                case RpcCalls.CheckColor:
+                {
+                    if (target == null || !target.IsHost)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.CheckColor)} to the wrong player");
+                    }
+
+                    var color = reader.ReadByte();
+                    break;
+                }
+
+                // Update the color of a player.
+                case RpcCalls.SetColor:
+                {
+                    if (!sender.IsHost)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetColor)} but was not a host");
+                    }
+
+                    if (target != null)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetColor)} to a specific player instead of broadcast");
+                    }
+
+                    PlayerInfo.ColorId = reader.ReadByte();
+                    break;
+                }
+
+                // Update the hat of a player.
+                case RpcCalls.SetHat:
+                {
+                    if (!sender.IsOwner(this))
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetHat)} to an unowned {nameof(InnerPlayerControl)}");
+                    }
+
+                    if (target != null)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetHat)} to a specific player instead of broadcast");
+                    }
+
+                    PlayerInfo.HatId = reader.ReadPackedUInt32();
+                    break;
+                }
+
+                case RpcCalls.SetSkin:
+                {
+                    if (!sender.IsOwner(this))
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetSkin)} to an unowned {nameof(InnerPlayerControl)}");
+                    }
+
+                    if (target != null)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetHat)} to a specific player instead of broadcast");
+                    }
+
+                    PlayerInfo.SkinId = reader.ReadPackedUInt32();
+                    break;
+                }
+
+                // TODO: (ANTICHEAT) Location check?
+                case RpcCalls.ReportDeadBody:
+                {
+                    if (!sender.IsOwner(this))
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.ReportDeadBody)} to an unowned {nameof(InnerPlayerControl)}");
+                    }
+
+                    if (target != null)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.ReportDeadBody)} to a specific player instead of broadcast");
+                    }
+
+                    var deadBodyPlayerId = reader.ReadByte();
+                    break;
+                }
+
+                // TODO: (ANTICHEAT) Cooldown check?
+                case RpcCalls.MurderPlayer:
+                {
+                    if (!sender.IsOwner(this))
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.MurderPlayer)} to an unowned {nameof(InnerPlayerControl)}");
+                    }
+
+                    if (target != null)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.MurderPlayer)} to a specific player instead of broadcast");
+                    }
+
+                    if (!sender.Character.PlayerInfo.IsImpostor)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.MurderPlayer)} as crewmate");
+                    }
+
+                    var player = reader.ReadNetObject<InnerPlayerControl>(_game);
+                    if (!player.PlayerInfo.IsDead)
+                    {
+                        player.Die(DeathReason.Kill);
+                    }
+
+                    break;
+                }
+
+                case RpcCalls.SendChat:
+                {
+                    if (!sender.IsOwner(this))
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SendChat)} to an unowned {nameof(InnerPlayerControl)}");
+                    }
+
+                    if (target != null)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SendChat)} to a specific player instead of broadcast");
+                    }
+
+                    var chat = reader.ReadString();
+
+                    await _eventManager.CallAsync(new PlayerChatEvent(_game, this, chat));
+                    break;
+                }
+
+                case RpcCalls.StartMeeting:
+                {
+                    if (!sender.IsHost)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.StartMeeting)} but was not a host");
+                    }
+
+                    if (target != null)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.StartMeeting)} to a specific player instead of broadcast");
+                    }
+
+                    var playerId = reader.ReadByte();
+                    var player = _game.GameNet.GameData.GetPlayerById(playerId);
+
+                    // Meeting started by "player", can also be null.
+                    break;
+                }
+
+                case RpcCalls.SetScanner:
+                {
+                    if (!sender.IsOwner(this))
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetScanner)} to an unowned {nameof(InnerPlayerControl)}");
+                    }
+
+                    if (target != null)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetScanner)} to a specific player instead of broadcast");
+                    }
+
+                    var on = reader.ReadBoolean();
+                    var count = reader.ReadByte();
+                    break;
+                }
+
+                case RpcCalls.SendChatNote:
+                {
+                    if (!sender.IsOwner(this))
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SendChatNote)} to an unowned {nameof(InnerPlayerControl)}");
+                    }
+
+                    if (target != null)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SendChatNote)} to a specific player instead of broadcast");
+                    }
+
+                    var playerId = reader.ReadByte();
+                    var chatNote = (ChatNoteType)reader.ReadByte();
+                    break;
+                }
+
+                case RpcCalls.SetPet:
+                {
+                    if (!sender.IsOwner(this))
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetPet)} to an unowned {nameof(InnerPlayerControl)}");
+                    }
+
+                    if (target != null)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetPet)} to a specific player instead of broadcast");
+                    }
+
+                    PlayerInfo.PetId = reader.ReadPackedUInt32();
+                    break;
+                }
+
+                // TODO: Understand this RPC
+                case RpcCalls.SetStartCounter:
+                {
+                    if (!sender.IsOwner(this))
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetStartCounter)} to an unowned {nameof(InnerPlayerControl)}");
+                    }
+
+                    if (target != null)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.SetStartCounter)} to a specific player instead of broadcast");
+                    }
+
+                    // Used to compare with LastStartCounter.
+                    var startCounter = reader.ReadPackedUInt32();
+
+                    // Is either start countdown or byte.MaxValue
+                    var secondsLeft = reader.ReadByte();
+                    break;
+                }
+
+                default:
+                {
+                    _logger.LogWarning("{0}: Unknown rpc call {1}", nameof(InnerPlayerControl), call);
+                    break;
+                }
+            }
+        }
+
+        public override bool Serialize(IMessageWriter writer, bool initialState)
+        {
+            throw new NotImplementedException();
+        }
+
+        public override void Deserialize(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState)
+        {
+            if (!sender.IsHost)
+            {
+                throw new ImpostorCheatException($"Client attempted to send data for {nameof(InnerPlayerControl)} as non-host");
+            }
+
+            if (initialState)
+            {
+                IsNew = reader.ReadBoolean();
+            }
+
+            PlayerId = reader.ReadByte();
+        }
+
+        private void Die(DeathReason reason)
+        {
+            PlayerInfo.IsDead = true;
+            PlayerInfo.LastDeathReason = reason;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/Objects/InnerShipStatus.cs b/src/Impostor.Server/Net/Inner/Objects/InnerShipStatus.cs
new file mode 100644 (file)
index 0000000..cab8be1
--- /dev/null
@@ -0,0 +1,148 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Impostor.Api;
+using Impostor.Api.Innersloth;
+using Impostor.Api.Net;
+using Impostor.Api.Net.Inner.Objects;
+using Impostor.Api.Net.Messages;
+using Impostor.Server.Net.Inner.Objects.Systems;
+using Impostor.Server.Net.Inner.Objects.Systems.ShipStatus;
+using Impostor.Server.Net.State;
+using Microsoft.Extensions.Logging;
+
+namespace Impostor.Server.Net.Inner.Objects
+{
+    internal class InnerShipStatus : InnerNetObject, IInnerShipStatus
+    {
+        private readonly ILogger<InnerShipStatus> _logger;
+        private readonly Game _game;
+        private readonly Dictionary<SystemTypes, ISystemType> _systems;
+
+        public InnerShipStatus(ILogger<InnerShipStatus> logger, Game game)
+        {
+            _logger = logger;
+            _game = game;
+
+            _systems = new Dictionary<SystemTypes, ISystemType>
+            {
+                [SystemTypes.Electrical] = new SwitchSystem(),
+                [SystemTypes.MedBay] = new MedScanSystem(),
+                [SystemTypes.Reactor] = new ReactorSystemType(),
+                [SystemTypes.LifeSupp] = new LifeSuppSystemType(),
+                [SystemTypes.Security] = new SecurityCameraSystemType(),
+                [SystemTypes.Comms] = new HudOverrideSystemType(),
+                [SystemTypes.Doors] = new DoorsSystemType(_game),
+            };
+
+            _systems.Add(SystemTypes.Sabotage, new SabotageSystemType(new[]
+            {
+                (IActivatable)_systems[SystemTypes.Comms],
+                (IActivatable)_systems[SystemTypes.Reactor],
+                (IActivatable)_systems[SystemTypes.LifeSupp],
+                (IActivatable)_systems[SystemTypes.Electrical],
+            }));
+
+            Components.Add(this);
+        }
+
+        public override ValueTask HandleRpc(ClientPlayer sender, ClientPlayer? target, RpcCalls call,
+            IMessageReader reader)
+        {
+            switch (call)
+            {
+                case RpcCalls.CloseDoorsOfType:
+                {
+                    if (target == null || !target.IsHost)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.CloseDoorsOfType)} to wrong destinition, must be host");
+                    }
+
+                    if (!sender.Character.PlayerInfo.IsImpostor)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.CloseDoorsOfType)} as crewmate");
+                    }
+
+                    var systemType = (SystemTypes)reader.ReadByte();
+
+                    break;
+                }
+
+                case RpcCalls.RepairSystem:
+                {
+                    if (target == null || !target.IsHost)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.RepairSystem)} to wrong destinition, must be host");
+                    }
+
+                    if (!sender.Character.PlayerInfo.IsImpostor)
+                    {
+                        throw new ImpostorCheatException($"Client sent {nameof(RpcCalls.RepairSystem)} as crewmate");
+                    }
+
+                    var systemType = (SystemTypes)reader.ReadByte();
+                    var player = reader.ReadNetObject<InnerPlayerControl>(_game);
+                    var amount = reader.ReadByte();
+
+                    // TODO: Modify data (?)
+
+                    break;
+                }
+
+                default:
+                {
+                    _logger.LogWarning("{0}: Unknown rpc call {1}", nameof(InnerShipStatus), call);
+                    break;
+                }
+            }
+
+            return default;
+        }
+
+        public override bool Serialize(IMessageWriter writer, bool initialState)
+        {
+            throw new NotImplementedException();
+        }
+
+        public override void Deserialize(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState)
+        {
+            if (!sender.IsHost)
+            {
+                throw new ImpostorCheatException($"Client attempted to send data for {nameof(InnerShipStatus)} as non-host");
+            }
+
+            if (target != null)
+            {
+                throw new ImpostorCheatException($"Client attempted to send {nameof(InnerShipStatus)} data to a specific player, must be broadcast");
+            }
+
+            if (initialState)
+            {
+                // TODO: (_systems[SystemTypes.Doors] as DoorsSystemType).SetDoors();
+                foreach (var systemType in SystemTypeHelpers.AllTypes)
+                {
+                    if (_systems.TryGetValue(systemType, out var system))
+                    {
+                        system.Deserialize(reader, true);
+                    }
+                }
+            }
+            else
+            {
+                var count = reader.ReadPackedUInt32();
+
+                foreach (var systemType in SystemTypeHelpers.AllTypes)
+                {
+                    // TODO: Not sure what is going on here, check.
+                    if ((count & 1 << (int)(systemType & (SystemTypes.ShipTasks | SystemTypes.Doors))) != 0L)
+                    {
+                        if (_systems.TryGetValue(systemType, out var system))
+                        {
+                            system.Deserialize(reader, false);
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/Objects/Systems/IActivatable.cs b/src/Impostor.Server/Net/Inner/Objects/Systems/IActivatable.cs
new file mode 100644 (file)
index 0000000..e595b25
--- /dev/null
@@ -0,0 +1,7 @@
+namespace Impostor.Server.Net.Inner.Objects.Systems
+{
+    public interface IActivatable
+    {
+        bool IsActive { get; }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/Objects/Systems/ISystemType.cs b/src/Impostor.Server/Net/Inner/Objects/Systems/ISystemType.cs
new file mode 100644 (file)
index 0000000..a6ef88e
--- /dev/null
@@ -0,0 +1,11 @@
+using Impostor.Api.Net.Messages;
+
+namespace Impostor.Server.Net.Inner.Objects.Systems
+{
+    public interface ISystemType
+    {
+        void Serialize(IMessageWriter writer, bool initialState);
+
+        void Deserialize(IMessageReader reader, bool initialState);
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/DoorsSystemType.cs b/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/DoorsSystemType.cs
new file mode 100644 (file)
index 0000000..fc01578
--- /dev/null
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using Impostor.Api.Games;
+using Impostor.Api.Innersloth;
+using Impostor.Api.Net.Messages;
+
+namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus
+{
+    public class DoorsSystemType : ISystemType
+    {
+        // TODO: AutoDoors
+        private readonly Dictionary<int, bool> _doors;
+
+        public DoorsSystemType(IGame game)
+        {
+            // TODO: Check
+            var doorCount = game.Options.MapId switch
+            {
+                MapId.Skeld => 13,
+                MapId.MiraHQ => 2,
+                MapId.Polus => 12,
+                _ => throw new ArgumentOutOfRangeException()
+            };
+
+            _doors = new Dictionary<int, bool>(doorCount);
+
+            for (var i = 0; i < doorCount; i++)
+            {
+                _doors.Add(i, false);
+            }
+        }
+
+        public void Serialize(IMessageWriter writer, bool initialState)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void Deserialize(IMessageReader reader, bool initialState)
+        {
+            if (initialState)
+            {
+                for (var i = 0; i < _doors.Count; i++)
+                {
+                    _doors[i] = reader.ReadBoolean();
+                }
+            }
+            else
+            {
+                var num = reader.ReadPackedUInt32();
+
+                for (var i = 0; i < _doors.Count; i++)
+                {
+                    if ((num & 1 << i) != 0)
+                    {
+                        _doors[i] = reader.ReadBoolean();
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/HudOverrideSystemType.cs b/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/HudOverrideSystemType.cs
new file mode 100644 (file)
index 0000000..42aa8d3
--- /dev/null
@@ -0,0 +1,19 @@
+using Impostor.Api.Net.Messages;
+
+namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus
+{
+    public class HudOverrideSystemType : ISystemType, IActivatable
+    {
+        public bool IsActive { get; private set; }
+
+        public void Serialize(IMessageWriter writer, bool initialState)
+        {
+            throw new System.NotImplementedException();
+        }
+
+        public void Deserialize(IMessageReader reader, bool initialState)
+        {
+            IsActive = reader.ReadBoolean();
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/LifeSuppSystemType.cs b/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/LifeSuppSystemType.cs
new file mode 100644 (file)
index 0000000..f644024
--- /dev/null
@@ -0,0 +1,44 @@
+using System.Collections.Generic;
+using Impostor.Api.Net.Messages;
+
+namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus
+{
+    public class LifeSuppSystemType : ISystemType, IActivatable
+    {
+        public LifeSuppSystemType()
+        {
+            Countdown = 10000f;
+            CompletedConsoles = new HashSet<int>();
+        }
+
+        public float Countdown { get; private set; }
+
+        public HashSet<int> CompletedConsoles { get; }
+
+        public bool IsActive => Countdown < 10000.0;
+
+        public void Serialize(IMessageWriter writer, bool initialState)
+        {
+            throw new System.NotImplementedException();
+        }
+
+        public void Deserialize(IMessageReader reader, bool initialState)
+        {
+            Countdown = reader.ReadSingle();
+
+            if (reader.Position >= reader.Length)
+            {
+                return;
+            }
+
+            CompletedConsoles.Clear(); // TODO: Thread safety
+
+            var num = reader.ReadPackedInt32();
+
+            for (var i = 0; i < num; i++)
+            {
+                CompletedConsoles.Add(reader.ReadPackedInt32());
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/MedScanSystem.cs b/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/MedScanSystem.cs
new file mode 100644 (file)
index 0000000..007b9d0
--- /dev/null
@@ -0,0 +1,32 @@
+using System.Collections.Generic;
+using Impostor.Api.Net.Messages;
+
+namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus
+{
+    public class MedScanSystem : ISystemType
+    {
+        public MedScanSystem()
+        {
+            UsersList = new List<byte>();
+        }
+
+        public List<byte> UsersList { get; }
+
+        public void Serialize(IMessageWriter writer, bool initialState)
+        {
+            throw new System.NotImplementedException();
+        }
+
+        public void Deserialize(IMessageReader reader, bool initialState)
+        {
+            UsersList.Clear();
+
+            var num = reader.ReadPackedInt32();
+
+            for (var i = 0; i < num; i++)
+            {
+                UsersList.Add(reader.ReadByte());
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/ReactorSystemType.cs b/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/ReactorSystemType.cs
new file mode 100644 (file)
index 0000000..4380918
--- /dev/null
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using Impostor.Api.Net.Messages;
+
+namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus
+{
+    public class ReactorSystemType : ISystemType, IActivatable
+    {
+        public ReactorSystemType()
+        {
+            Countdown = 10000f;
+            UserConsolePairs = new HashSet<Tuple<byte, byte>>();
+        }
+
+        public float Countdown { get; private set; }
+
+        public HashSet<Tuple<byte, byte>> UserConsolePairs { get; }
+
+        public bool IsActive => Countdown < 10000.0;
+
+        public void Serialize(IMessageWriter writer, bool initialState)
+        {
+            throw new System.NotImplementedException();
+        }
+
+        public void Deserialize(IMessageReader reader, bool initialState)
+        {
+            Countdown = reader.ReadSingle();
+            UserConsolePairs.Clear(); // TODO: Thread safety
+
+            var count = reader.ReadPackedInt32();
+
+            for (var i = 0; i < count; i++)
+            {
+                UserConsolePairs.Add(new Tuple<byte, byte>(reader.ReadByte(), reader.ReadByte()));
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/SabotageSystemType.cs b/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/SabotageSystemType.cs
new file mode 100644 (file)
index 0000000..193cfe8
--- /dev/null
@@ -0,0 +1,26 @@
+using Impostor.Api.Net.Messages;
+
+namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus
+{
+    public class SabotageSystemType : ISystemType
+    {
+        private readonly IActivatable[] _specials;
+
+        public SabotageSystemType(IActivatable[] specials)
+        {
+            _specials = specials;
+        }
+
+        public float Timer { get; set; }
+
+        public void Serialize(IMessageWriter writer, bool initialState)
+        {
+            throw new System.NotImplementedException();
+        }
+
+        public void Deserialize(IMessageReader reader, bool initialState)
+        {
+            Timer = reader.ReadSingle();
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/SecurityCameraSystemType.cs b/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/SecurityCameraSystemType.cs
new file mode 100644 (file)
index 0000000..df41b68
--- /dev/null
@@ -0,0 +1,19 @@
+using Impostor.Api.Net.Messages;
+
+namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus
+{
+    public class SecurityCameraSystemType : ISystemType
+    {
+        public byte InUse { get; internal set; }
+
+        public void Serialize(IMessageWriter writer, bool initialState)
+        {
+            throw new System.NotImplementedException();
+        }
+
+        public void Deserialize(IMessageReader reader, bool initialState)
+        {
+            InUse = reader.ReadByte();
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/SwitchSystem.cs b/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/SwitchSystem.cs
new file mode 100644 (file)
index 0000000..925774a
--- /dev/null
@@ -0,0 +1,27 @@
+using Impostor.Api.Net.Messages;
+
+namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus
+{
+    public class SwitchSystem : ISystemType, IActivatable
+    {
+        public byte ExpectedSwitches { get; set; }
+
+        public byte ActualSwitches { get; set; }
+
+        public byte Value { get; set; } = byte.MaxValue;
+
+        public bool IsActive { get; }
+
+        public void Serialize(IMessageWriter writer, bool initialState)
+        {
+            throw new System.NotImplementedException();
+        }
+
+        public void Deserialize(IMessageReader reader, bool initialState)
+        {
+            ExpectedSwitches = reader.ReadByte();
+            ActualSwitches = reader.ReadByte();
+            Value = reader.ReadByte();
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/RpcCalls.cs b/src/Impostor.Server/Net/Inner/RpcCalls.cs
new file mode 100644 (file)
index 0000000..ce48965
--- /dev/null
@@ -0,0 +1,37 @@
+namespace Impostor.Server.Net.Inner
+{
+    public enum RpcCalls : byte
+    {
+        PlayAnimation = 0,
+        CompleteTask = 1,
+        SyncSettings = 2,
+        SetInfected = 3,
+        Exiled = 4,
+        CheckName = 5,
+        SetName = 6,
+        CheckColor = 7,
+        SetColor = 8,
+        SetHat = 9,
+        SetSkin = 10,
+        ReportDeadBody = 11,
+        MurderPlayer = 12,
+        SendChat = 13,
+        StartMeeting = 14,
+        SetScanner = 15,
+        SendChatNote = 16,
+        SetPet = 17,
+        SetStartCounter = 18,
+        EnterVent = 19,
+        ExitVent = 20,
+        SnapTo = 21,
+        Close = 22,
+        VotingComplete = 23,
+        CastVote = 24,
+        ClearVote = 25,
+        AddVote = 26,
+        CloseDoorsOfType = 27,
+        RepairSystem = 28,
+        SetTasks = 29,
+        UpdateGameData = 30,
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Inner/SpawnFlags.cs b/src/Impostor.Server/Net/Inner/SpawnFlags.cs
new file mode 100644 (file)
index 0000000..1860098
--- /dev/null
@@ -0,0 +1,11 @@
+using System;
+
+namespace Impostor.Server.Net.Inner
+{
+    [Flags]
+    public enum SpawnFlags : byte
+    {
+        None = 0,
+        IsClientCharacter = 1,
+    }
+}
\ No newline at end of file
index f6d4c40d8548dfac89e41ad65083c06922a507b7..828ca60ce9926dcc9fb54a9d93e691089d3cb18e 100644 (file)
@@ -3,7 +3,6 @@ using System.Collections.Generic;
 using System.Threading;
 using System.Threading.Tasks;
 using Impostor.Api.Innersloth;
-using Impostor.Api.Innersloth.Data;
 using Impostor.Api.Net;
 using Impostor.Api.Net.Manager;
 using Impostor.Api.Net.Messages;
@@ -11,7 +10,6 @@ using Impostor.Api.Net.Messages.S2C;
 using Impostor.Hazel;
 using Impostor.Server.Config;
 using Impostor.Server.Net.Factories;
-using Impostor.Server.Net.Hazel;
 using Microsoft.Extensions.Logging;
 
 namespace Impostor.Server.Net.Manager
index a7ea1dc3a0b09f2adb619b9cf31f7bbaa493f22f..1cf68fa4196e0f0323883db77dca387a5cde3913 100644 (file)
@@ -10,9 +10,7 @@ using Impostor.Api.Events.Managers;
 using Impostor.Api.Games;
 using Impostor.Api.Games.Managers;
 using Impostor.Api.Innersloth;
-using Impostor.Api.Innersloth.Data;
 using Impostor.Server.Config;
-using Impostor.Server.Extensions;
 using Impostor.Server.Net.Redirector;
 using Impostor.Server.Net.State;
 using Microsoft.Extensions.DependencyInjection;
index cab531b55585be0b7fd07e404ab901c43b8ef1a7..3dad4b34d9badb0fea62d6434ef7d2f7bccb9f00 100644 (file)
@@ -1,6 +1,5 @@
 using System.Threading.Tasks;
 using Impostor.Api.Innersloth;
-using Impostor.Api.Innersloth.Data;
 using Impostor.Api.Net.Messages;
 using Impostor.Api.Net.Messages.C2S;
 using Impostor.Api.Net.Messages.S2C;
index b8b48f5a29d0bc451d997b16ab1f824017c97384..e617cfb23b17540521fa4860c526c4b0a83a4ff0 100644 (file)
@@ -1,5 +1,6 @@
 using Impostor.Api.Games;
 using Impostor.Api.Net;
+using Impostor.Api.Net.Inner.Objects;
 
 namespace Impostor.Server.Net.State
 {
@@ -10,5 +11,8 @@ namespace Impostor.Server.Net.State
 
         /// <inheritdoc />
         IGame IClientPlayer.Game => Game;
+
+        /// <inheritdoc />
+        IInnerPlayerControl IClientPlayer.Character => Character;
     }
 }
\ No newline at end of file
index 86a6a212a6c62236953c42fa180236529f13abf0..5f2dc93e09c5677420ab4c206872db59b499c24d 100644 (file)
@@ -1,9 +1,9 @@
 using System;
 using System.Threading;
 using System.Threading.Tasks;
-using Impostor.Api.Innersloth.Net;
-using Impostor.Api.Innersloth.Net.Objects;
 using Impostor.Api.Net;
+using Impostor.Api.Net.Inner;
+using Impostor.Server.Net.Inner.Objects;
 using Microsoft.Extensions.Logging;
 
 namespace Impostor.Server.Net.State
@@ -48,7 +48,7 @@ namespace Impostor.Server.Net.State
         }
 
         /// <inheritdoc />
-        public bool IsOwner(InnerNetObject netObject)
+        public bool IsOwner(IInnerNetObject netObject)
         {
             return Client.Id == netObject.OwnerId;
         }
index f7c73fbe7beec7c63b5c20b213d6cff3d26e11e2..0a764e37a7d0d606c90ae66a3ac7d3e6851393bc 100644 (file)
@@ -1,6 +1,6 @@
 using Impostor.Api.Games;
-using Impostor.Api.Innersloth.Net;
 using Impostor.Api.Net;
+using Impostor.Api.Net.Inner;
 
 namespace Impostor.Server.Net.State
 {
index b327edccad6ff3886f27e34aac81d8efb43dcdea..f3a8ff961b6e0c41413d228b47cc5c83352196de 100644 (file)
@@ -4,13 +4,13 @@ using System.Threading;
 using System.Threading.Tasks;
 using Impostor.Api;
 using Impostor.Api.Events.Net;
-using Impostor.Api.Innersloth.Data;
-using Impostor.Api.Innersloth.Net;
-using Impostor.Api.Innersloth.Net.Objects;
-using Impostor.Api.Innersloth.Net.Objects.Components;
+using Impostor.Api.Innersloth;
 using Impostor.Api.Net.Messages;
 using Impostor.Api.Net.Messages.S2C;
 using Impostor.Hazel;
+using Impostor.Server.Net.Inner;
+using Impostor.Server.Net.Inner.Objects;
+using Impostor.Server.Net.Inner.Objects.Components;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Logging;
 
@@ -237,7 +237,7 @@ namespace Impostor.Server.Net.State
                         var netId = reader.ReadPackedUInt32();
                         if (_allObjectsFast.TryGetValue(netId, out var obj))
                         {
-                            obj.HandleRpc(sender, target, (RpcCalls) reader.ReadByte(), reader);
+                            await obj.HandleRpc(sender, target, (RpcCalls) reader.ReadByte(), reader);
                         }
                         else
                         {
index 308bed476dc9bf46c350bd09c29789a92a1aface..4d1342b92c9a9f22c3339ccc793fee0621c315ce 100644 (file)
@@ -2,7 +2,7 @@
 using System.Threading;
 using System.Threading.Tasks;
 using Impostor.Api.Games;
-using Impostor.Api.Innersloth.Data;
+using Impostor.Api.Innersloth;
 using Impostor.Api.Net;
 using Impostor.Api.Net.Messages;
 using Impostor.Hazel;
index ca77abefb2fe178a2c1c87e5d74da440998657c7..3f2ef680da0c7415ddf201ca22e9ecc38a0d601a 100644 (file)
@@ -1,6 +1,6 @@
 using System.Linq;
 using System.Threading.Tasks;
-using Impostor.Api.Innersloth.Data;
+using Impostor.Api.Innersloth;
 using Impostor.Api.Net;
 using Impostor.Api.Net.Messages;
 using Impostor.Api.Net.Messages.S2C;
index bfa9893ae08ee0ea9df34365228a010c0fff239b..27b65a850526dd8f1a6fac4c374e29fbfc2ade7c 100644 (file)
@@ -2,7 +2,7 @@
 using System.Threading.Tasks;
 using Impostor.Api;
 using Impostor.Api.Events;
-using Impostor.Api.Innersloth.Data;
+using Impostor.Api.Innersloth;
 using Impostor.Api.Net;
 using Impostor.Api.Net.Messages;
 using Impostor.Hazel;
index 01c7903b330177cb91be6cdd422eae1977305f57..b48a5b2d5b15bc1acc616a7a7b24ec29c7cd1bd7 100644 (file)
@@ -7,8 +7,6 @@ using System.Threading.Tasks;
 using Impostor.Api.Events.Managers;
 using Impostor.Api.Games;
 using Impostor.Api.Innersloth;
-using Impostor.Api.Innersloth.Data;
-using Impostor.Api.Innersloth.Net;
 using Impostor.Api.Net;
 using Impostor.Api.Net.Messages;
 using Impostor.Api.Net.Messages.S2C;
diff --git a/src/Impostor.Server/Net/State/GameNet.Api.cs b/src/Impostor.Server/Net/State/GameNet.Api.cs
new file mode 100644 (file)
index 0000000..34ea0fe
--- /dev/null
@@ -0,0 +1,17 @@
+using Impostor.Api.Net.Inner;
+using Impostor.Api.Net.Inner.Objects;
+
+namespace Impostor.Server.Net.State
+{
+    /// <inheritdoc />
+    internal partial class GameNet : IGameNet
+    {
+        IInnerLobbyBehaviour IGameNet.LobbyBehaviour => LobbyBehaviour;
+
+        IInnerGameData IGameNet.GameData => GameData;
+
+        IInnerVoteBanSystem IGameNet.VoteBan => VoteBan;
+
+        IInnerShipStatus IGameNet.ShipStatus => ShipStatus;
+    }
+}
\ No newline at end of file
index f29aa323d3f9097eda17351c1878776b642e7a7f..c5542f9d01ab53ffa137d75ca35f72acbfcffa12 100644 (file)
@@ -1,13 +1,9 @@
-using Impostor.Api.Innersloth.Net;
-using Impostor.Api.Innersloth.Net.Objects;
-using Impostor.Api.Innersloth.Net.Objects.Components;
+using Impostor.Server.Net.Inner.Objects;
+using Impostor.Server.Net.Inner.Objects.Components;
 
 namespace Impostor.Server.Net.State
 {
-    /// <summary>
-    ///     Holds all data that is serialized over the network through GameData packets.
-    /// </summary>
-    public class GameNet : IGameNet
+    internal partial class GameNet
     {
         public InnerLobbyBehaviour LobbyBehaviour { get; internal set; }