]> git.deb.at Git - rhonda/impostor.git/commitdiff
Split ShipStatus to multiple classes, implement new door types
authorjs6pak <kubastaron@hotmail.com>
Sun, 4 Apr 2021 17:48:25 +0000 (19:48 +0200)
committerjs6pak <kubastaron@hotmail.com>
Sun, 4 Apr 2021 21:27:39 +0000 (23:27 +0200)
36 files changed:
src/Impostor.Api/Innersloth/Customization/ColorType.cs
src/Impostor.Api/Net/Inner/IGameNet.cs
src/Impostor.Api/Net/Inner/IInnerNetObject.cs
src/Impostor.Api/Net/Inner/Objects/IInnerShipStatus.cs [deleted file]
src/Impostor.Api/Net/Inner/Objects/ShipStatus/IInnerAirshipStatus.cs [new file with mode: 0644]
src/Impostor.Api/Net/Inner/Objects/ShipStatus/IInnerMiraShipStatus.cs [new file with mode: 0644]
src/Impostor.Api/Net/Inner/Objects/ShipStatus/IInnerPolusShipStatus.cs [new file with mode: 0644]
src/Impostor.Api/Net/Inner/Objects/ShipStatus/IInnerShipStatus.cs [new file with mode: 0644]
src/Impostor.Api/Net/Inner/Objects/ShipStatus/IInnerSkeldShipStatus.cs [new file with mode: 0644]
src/Impostor.Api/Net/Inner/RpcCalls.cs
src/Impostor.Server/Net/Inner/InnerNetObject.cs
src/Impostor.Server/Net/Inner/Objects/Components/InnerCustomNetworkTransform.Api.cs
src/Impostor.Server/Net/Inner/Objects/Components/InnerCustomNetworkTransform.cs
src/Impostor.Server/Net/Inner/Objects/Components/InnerPlayerPhysics.cs
src/Impostor.Server/Net/Inner/Objects/Components/InnerVoteBanSystem.cs
src/Impostor.Server/Net/Inner/Objects/InnerGameData.cs
src/Impostor.Server/Net/Inner/Objects/InnerLobbyBehaviour.cs
src/Impostor.Server/Net/Inner/Objects/InnerMeetingHud.cs
src/Impostor.Server/Net/Inner/Objects/InnerPlayerControl.Api.cs
src/Impostor.Server/Net/Inner/Objects/InnerPlayerControl.cs
src/Impostor.Server/Net/Inner/Objects/InnerPlayerInfo.cs
src/Impostor.Server/Net/Inner/Objects/InnerShipStatus.cs [deleted file]
src/Impostor.Server/Net/Inner/Objects/ShipStatus/InnerAirshipStatus.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/ShipStatus/InnerMiraShipStatus.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/ShipStatus/InnerPolusShipStatus.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/ShipStatus/InnerShipStatus.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/ShipStatus/InnerSkeldShipStatus.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/AutoDoorsSystemType.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/DoorsSystemType.cs
src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/ElectricalDoors.cs [new file with mode: 0644]
src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/HeliSabotageSystemType.cs
src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/MovingPlatformBehaviour.cs [new file with mode: 0644]
src/Impostor.Server/Net/State/Game.Api.cs
src/Impostor.Server/Net/State/Game.Data.cs
src/Impostor.Server/Net/State/GameNet.Api.cs
src/Impostor.Server/Net/State/GameNet.cs

index fc7be4cfaabd1d78ca4112059ab528c205bb10d3..d9e43a68adebbc1551cab910fb3c10dc682a4aac 100644 (file)
@@ -1,6 +1,6 @@
 namespace Impostor.Api.Innersloth.Customization
 {
-    public enum ColorType : byte
+    public enum ColorType
     {
         Red = 0,
         Blue = 1,
index 9cac0f2dbc4e864e33c7c849e51c4cfe0a0365e0..7b068d108cb359c90f869121101261837bcc96eb 100644 (file)
@@ -1,4 +1,5 @@
 using Impostor.Api.Net.Inner.Objects;
+using Impostor.Api.Net.Inner.Objects.ShipStatus;
 
 namespace Impostor.Api.Net.Inner
 {
index 8cfadb8e6019ffdd3520ec40d3bd2499bf03e6e5..db868b63c298f5ecc5c71fd63f1bc19812152beb 100644 (file)
@@ -1,9 +1,13 @@
-namespace Impostor.Api.Net.Inner
+using Impostor.Api.Games;
+
+namespace Impostor.Api.Net.Inner
 {
     public interface IInnerNetObject
     {
         public uint NetId { get; }
 
         public int OwnerId { get; }
+
+        public IGame Game { get; }
     }
 }
diff --git a/src/Impostor.Api/Net/Inner/Objects/IInnerShipStatus.cs b/src/Impostor.Api/Net/Inner/Objects/IInnerShipStatus.cs
deleted file mode 100644 (file)
index 79b9f96..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace Impostor.Api.Net.Inner.Objects
-{
-    public interface IInnerShipStatus : IInnerNetObject
-    {
-    }
-}
diff --git a/src/Impostor.Api/Net/Inner/Objects/ShipStatus/IInnerAirshipStatus.cs b/src/Impostor.Api/Net/Inner/Objects/ShipStatus/IInnerAirshipStatus.cs
new file mode 100644 (file)
index 0000000..2711b89
--- /dev/null
@@ -0,0 +1,6 @@
+namespace Impostor.Api.Net.Inner.Objects.ShipStatus
+{
+    public interface IInnerAirshipStatus : IInnerShipStatus
+    {
+    }
+}
diff --git a/src/Impostor.Api/Net/Inner/Objects/ShipStatus/IInnerMiraShipStatus.cs b/src/Impostor.Api/Net/Inner/Objects/ShipStatus/IInnerMiraShipStatus.cs
new file mode 100644 (file)
index 0000000..870a945
--- /dev/null
@@ -0,0 +1,6 @@
+namespace Impostor.Api.Net.Inner.Objects.ShipStatus
+{
+    public interface IInnerMiraShipStatus : IInnerShipStatus
+    {
+    }
+}
diff --git a/src/Impostor.Api/Net/Inner/Objects/ShipStatus/IInnerPolusShipStatus.cs b/src/Impostor.Api/Net/Inner/Objects/ShipStatus/IInnerPolusShipStatus.cs
new file mode 100644 (file)
index 0000000..5e336bd
--- /dev/null
@@ -0,0 +1,6 @@
+namespace Impostor.Api.Net.Inner.Objects.ShipStatus
+{
+    public interface IInnerPolusShipStatus : IInnerShipStatus
+    {
+    }
+}
diff --git a/src/Impostor.Api/Net/Inner/Objects/ShipStatus/IInnerShipStatus.cs b/src/Impostor.Api/Net/Inner/Objects/ShipStatus/IInnerShipStatus.cs
new file mode 100644 (file)
index 0000000..c00769d
--- /dev/null
@@ -0,0 +1,6 @@
+namespace Impostor.Api.Net.Inner.Objects.ShipStatus
+{
+    public interface IInnerShipStatus : IInnerNetObject
+    {
+    }
+}
diff --git a/src/Impostor.Api/Net/Inner/Objects/ShipStatus/IInnerSkeldShipStatus.cs b/src/Impostor.Api/Net/Inner/Objects/ShipStatus/IInnerSkeldShipStatus.cs
new file mode 100644 (file)
index 0000000..e0e9df1
--- /dev/null
@@ -0,0 +1,6 @@
+namespace Impostor.Api.Net.Inner.Objects.ShipStatus
+{
+    public interface IInnerSkeldShipStatus : IInnerShipStatus
+    {
+    }
+}
index b288df39c72f45d37a078335e3e9b6c024dc9145..44f85e7aaaf108141886b0316533e5d42db1fb7a 100644 (file)
@@ -32,7 +32,6 @@
         CloseDoorsOfType = 27,
         RepairSystem = 28,
         SetTasks = 29,
-        UpdateGameData = 30,
         ClimbLadder = 31,
         UsePlatform = 32,
     }
index 073e5811f424e969aabc1762c4617f76859450c5..4a1510414335b1231e3fa6749414dcbf1e363829 100644 (file)
@@ -1,4 +1,5 @@
 using System.Threading.Tasks;
+using Impostor.Api.Games;
 using Impostor.Api.Net;
 using Impostor.Api.Net.Inner;
 using Impostor.Api.Net.Messages;
@@ -10,10 +11,19 @@ namespace Impostor.Server.Net.Inner
     {
         private const int HostInheritId = -2;
 
+        protected InnerNetObject(Game game)
+        {
+            Game = game;
+        }
+
         public uint NetId { get; internal set; }
 
         public int OwnerId { get; internal set; }
 
+        public Game Game { get; }
+
+        IGame IInnerNetObject.Game => Game;
+
         public SpawnFlags SpawnFlags { get; internal set; }
 
         public bool IsOwnedBy(IClientPlayer player)
@@ -27,5 +37,10 @@ namespace Impostor.Server.Net.Inner
         public abstract ValueTask DeserializeAsync(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState);
 
         public abstract ValueTask<bool> HandleRpcAsync(ClientPlayer sender, ClientPlayer? target, RpcCalls call, IMessageReader reader);
+
+        public virtual ValueTask OnSpawnAsync()
+        {
+            return default;
+        }
     }
 }
index 2447aea6afe67aedee852a88d032129448da8ec2..b73b835f883c909df99220af17497d7bca384116 100644 (file)
@@ -12,14 +12,14 @@ namespace Impostor.Server.Net.Inner.Objects.Components
             var minSid = (ushort)(_lastSequenceId + 5U);
 
             // Snap in the server.
-            await SnapToAsync(_game.GetClientPlayer(OwnerId)!, position, minSid);
+            await SnapToAsync(Game.GetClientPlayer(OwnerId)!, position, minSid);
 
             // Broadcast to all clients.
-            using (var writer = _game.StartRpc(NetId, RpcCalls.SnapTo))
+            using (var writer = Game.StartRpc(NetId, RpcCalls.SnapTo))
             {
                 writer.Write(position);
                 writer.Write(_lastSequenceId);
-                await _game.FinishRpcAsync(writer);
+                await Game.FinishRpcAsync(writer);
             }
         }
     }
index e9e3dfb9ed05abada8e6b03341549bc12bbef9fe..d1a48a3a0b7dbd1285a4265f00615f624866c118 100644 (file)
@@ -17,18 +17,15 @@ namespace Impostor.Server.Net.Inner.Objects.Components
     {
         private readonly ILogger<InnerCustomNetworkTransform> _logger;
         private readonly InnerPlayerControl _playerControl;
-        private readonly Game _game;
         private readonly IEventManager _eventManager;
         private readonly ObjectPool<PlayerMovementEvent> _pool;
 
         private ushort _lastSequenceId;
 
-        public InnerCustomNetworkTransform(ILogger<InnerCustomNetworkTransform> logger, InnerPlayerControl playerControl, Game game, IEventManager eventManager, ObjectPool<PlayerMovementEvent> pool)
+        public InnerCustomNetworkTransform(Game game, ILogger<InnerCustomNetworkTransform> logger, InnerPlayerControl playerControl, IEventManager eventManager, ObjectPool<PlayerMovementEvent> pool) : base(game)
         {
             _logger = logger;
             _playerControl = playerControl;
-            _game = game;
-            _game = game;
             _eventManager = eventManager;
             _pool = pool;
         }
@@ -106,7 +103,7 @@ namespace Impostor.Server.Net.Inner.Objects.Components
             Velocity = velocity;
 
             var playerMovementEvent = _pool.Get();
-            playerMovementEvent.Reset(_game, sender, _playerControl);
+            playerMovementEvent.Reset(Game, sender, _playerControl);
             await _eventManager.CallAsync(playerMovementEvent);
             _pool.Return(playerMovementEvent);
         }
index 80daa38f2ccf67d5e885430798759d27a3426a9a..0f20750c69927510cf6ddef23bcd10c421e8b40b 100644 (file)
@@ -17,14 +17,12 @@ namespace Impostor.Server.Net.Inner.Objects.Components
         private readonly ILogger<InnerPlayerPhysics> _logger;
         private readonly InnerPlayerControl _playerControl;
         private readonly IEventManager _eventManager;
-        private readonly Game _game;
 
-        public InnerPlayerPhysics(ILogger<InnerPlayerPhysics> logger, InnerPlayerControl playerControl, IEventManager eventManager, Game game)
+        public InnerPlayerPhysics(Game game, ILogger<InnerPlayerPhysics> logger, InnerPlayerControl playerControl, IEventManager eventManager) : base(game)
         {
             _logger = logger;
             _playerControl = playerControl;
             _eventManager = eventManager;
-            _game = game;
         }
 
         public override ValueTask<bool> SerializeAsync(IMessageWriter writer, bool initialState)
@@ -39,27 +37,39 @@ namespace Impostor.Server.Net.Inner.Objects.Components
 
         public override async ValueTask<bool> HandleRpcAsync(ClientPlayer sender, ClientPlayer? target, RpcCalls call, IMessageReader reader)
         {
-            if (!await ValidateOwnership(call, sender) || !await ValidateImpostor(call, sender, _playerControl.PlayerInfo))
+            if (!await ValidateOwnership(call, sender))
             {
                 return false;
             }
 
-            int ventId;
-
             switch (call)
             {
                 case RpcCalls.EnterVent:
-                    Rpc19EnterVent.Deserialize(reader, out ventId);
-                    await _eventManager.CallAsync(new PlayerVentEvent(_game, sender, _playerControl, (VentLocation)ventId, true));
-                    break;
-
                 case RpcCalls.ExitVent:
-                    Rpc19EnterVent.Deserialize(reader, out ventId);
-                    await _eventManager.CallAsync(new PlayerVentEvent(_game, sender, _playerControl, (VentLocation)ventId, false));
+                    if (!await ValidateImpostor(call, sender, _playerControl.PlayerInfo))
+                    {
+                        return false;
+                    }
+
+                    int ventId;
+
+                    switch (call)
+                    {
+                        case RpcCalls.EnterVent:
+                            Rpc19EnterVent.Deserialize(reader, out ventId);
+                            break;
+                        case RpcCalls.ExitVent:
+                            Rpc20ExitVent.Deserialize(reader, out ventId);
+                            break;
+                        default:
+                            throw new ArgumentOutOfRangeException(nameof(call), call, null);
+                    }
+
+                    await _eventManager.CallAsync(new PlayerVentEvent(Game, sender, _playerControl, (VentLocation)ventId, call == RpcCalls.EnterVent));
                     break;
 
                 case RpcCalls.ClimbLadder:
-                    Rpc31ClimbLadder.Deserialize(reader, out byte ladderId, out byte lastClimbLadderSid);
+                    Rpc31ClimbLadder.Deserialize(reader, out var ladderId, out var lastClimbLadderSid);
                     break;
 
                 default:
index 3a310c88e42d9a858bc235ee0c63f54987e08d32..ac6304140d7fe45e1a8c67fa2a877f0274881d92 100644 (file)
@@ -17,7 +17,7 @@ namespace Impostor.Server.Net.Inner.Objects.Components
         private readonly ILogger<InnerVoteBanSystem> _logger;
         private readonly Dictionary<int, int[]> _votes;
 
-        public InnerVoteBanSystem(ILogger<InnerVoteBanSystem> logger)
+        public InnerVoteBanSystem(Game game, ILogger<InnerVoteBanSystem> logger) : base(game)
         {
             _logger = logger;
             _votes = new Dictionary<int, int[]>();
index bcbda030eaf0c373dced7cbb71aa5e48c6bb25af..0a29d63786ff3323e856c648d0d7ac456e0f115b 100644 (file)
@@ -18,17 +18,15 @@ 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, InnerPlayerInfo> _allPlayers;
 
-        public InnerGameData(ILogger<InnerGameData> logger, Game game, IServiceProvider serviceProvider)
+        public InnerGameData(Game game, ILogger<InnerGameData> logger, IServiceProvider serviceProvider) : base(game)
         {
             _logger = logger;
-            _game = game;
             _allPlayers = new ConcurrentDictionary<byte, InnerPlayerInfo>();
 
             Components.Add(this);
-            Components.Add(ActivatorUtilities.CreateInstance<InnerVoteBanSystem>(serviceProvider));
+            Components.Add(ActivatorUtilities.CreateInstance<InnerVoteBanSystem>(serviceProvider, game));
         }
 
         public int PlayerCount => _allPlayers.Count;
@@ -76,8 +74,25 @@ namespace Impostor.Server.Net.Inner.Objects
             }
             else
             {
-                // It'll send an message per dirty player
-                // throw new NotImplementedException("This shouldn't happen, according to Among Us disassembly.");
+                while (reader.Position < reader.Length)
+                {
+                    var inner = reader.ReadMessage();
+                    var playerInfo = this.GetPlayerById(inner.Tag);
+                    if (playerInfo != null)
+                    {
+                        playerInfo.Deserialize(inner);
+                    }
+                    else
+                    {
+                        playerInfo = new InnerPlayerInfo(inner.Tag);
+                        playerInfo.Deserialize(inner);
+
+                        if (!_allPlayers.TryAdd(playerInfo.PlayerId, playerInfo))
+                        {
+                            throw new ImpostorException("Failed to add player to InnerGameData.");
+                        }
+                    }
+                }
             }
         }
 
@@ -97,32 +112,6 @@ namespace Impostor.Server.Net.Inner.Objects
                     break;
                 }
 
-                case RpcCalls.UpdateGameData:
-                {
-                    while (reader.Position < reader.Length)
-                    {
-                        using var message = reader.ReadMessage();
-                        var player = GetPlayerById(message.Tag);
-                        if (player != null)
-                        {
-                            player.Deserialize(message);
-                        }
-                        else
-                        {
-                            var playerInfo = new InnerPlayerInfo(message.Tag);
-
-                            playerInfo.Deserialize(reader);
-
-                            if (!_allPlayers.TryAdd(playerInfo.PlayerId, playerInfo))
-                            {
-                                throw new ImpostorException("Failed to add player to InnerGameData.");
-                            }
-                        }
-                    }
-
-                    break;
-                }
-
                 default:
                     return await UnregisteredCall(call, sender);
             }
index 3a44fc525f7828121ea3b085fbf7d011dec08736..c897a6860cc333a4e62fc2086084b948f00d4f2a 100644 (file)
@@ -1,6 +1,5 @@
 using System;
 using System.Threading.Tasks;
-using Impostor.Api.Games;
 using Impostor.Api.Net;
 using Impostor.Api.Net.Inner;
 using Impostor.Api.Net.Inner.Objects;
@@ -11,12 +10,8 @@ namespace Impostor.Server.Net.Inner.Objects
 {
     internal class InnerLobbyBehaviour : InnerNetObject, IInnerLobbyBehaviour
     {
-        private readonly IGame _game;
-
-        public InnerLobbyBehaviour(IGame game)
+        public InnerLobbyBehaviour(Game game) : base(game)
         {
-            _game = game;
-
             Components.Add(this);
         }
 
index a40602836d3d8564402102b813bdace3bf9f17cf..f774cd0c0e6026c147e42be4fb82e5cf7fc14d2b 100644 (file)
@@ -20,18 +20,14 @@ namespace Impostor.Server.Net.Inner.Objects
     {
         private readonly ILogger<InnerMeetingHud> _logger;
         private readonly IEventManager _eventManager;
-        private readonly Game _game;
-        private readonly GameNet _gameNet;
 
         [AllowNull]
         private PlayerVoteArea[] _playerStates;
 
-        public InnerMeetingHud(ILogger<InnerMeetingHud> logger, IEventManager eventManager, Game game)
+        public InnerMeetingHud(Game game, ILogger<InnerMeetingHud> logger, IEventManager eventManager) : base(game)
         {
             _logger = logger;
             _eventManager = eventManager;
-            _game = game;
-            _gameNet = game.GameNet;
             _playerStates = null;
 
             Components.Add(this);
@@ -132,7 +128,7 @@ namespace Impostor.Server.Net.Inner.Objects
 
         private void PopulateButtons(byte reporter)
         {
-            _playerStates = _gameNet.GameData!.Players
+            _playerStates = Game.GameNet.GameData!.Players
                 .Select(x =>
                 {
                     var area = new PlayerVoteArea(this, x.Key);
@@ -146,15 +142,15 @@ namespace Impostor.Server.Net.Inner.Objects
         {
             if (playerId != byte.MaxValue)
             {
-                var player = _game.GameNet.GameData!.GetPlayerById(playerId);
+                var player = Game.GameNet.GameData!.GetPlayerById(playerId);
                 if (player?.Controller != null)
                 {
                     player.Controller.Die(DeathReason.Exile);
-                    await _eventManager.CallAsync(new PlayerExileEvent(_game, sender, player.Controller));
+                    await _eventManager.CallAsync(new PlayerExileEvent(Game, sender, player.Controller));
                 }
             }
 
-            await _eventManager.CallAsync(new MeetingEndedEvent(_game, this));
+            await _eventManager.CallAsync(new MeetingEndedEvent(Game, this));
         }
 
         private async ValueTask<bool> HandleCastVote(ClientPlayer sender, ClientPlayer? target, byte playerId, sbyte suspectPlayerId)
index a2382e2beccf0c72ccdc59b075e2a83f3c5cded6..8804bee9006f3dd8d44718f00cf65902074e9106 100644 (file)
@@ -22,52 +22,52 @@ namespace Impostor.Server.Net.Inner.Objects
         {
             PlayerInfo.PlayerName = name;
 
-            using var writer = _game.StartRpc(NetId, RpcCalls.SetName);
+            using var writer = Game.StartRpc(NetId, RpcCalls.SetName);
             writer.Write(name);
-            await _game.FinishRpcAsync(writer);
+            await Game.FinishRpcAsync(writer);
         }
 
         public async ValueTask SetColorAsync(ColorType color)
         {
             PlayerInfo.Color = color;
 
-            using var writer = _game.StartRpc(NetId, RpcCalls.SetColor);
+            using var writer = Game.StartRpc(NetId, RpcCalls.SetColor);
             Rpc08SetColor.Serialize(writer, color);
-            await _game.FinishRpcAsync(writer);
+            await Game.FinishRpcAsync(writer);
         }
 
         public async ValueTask SetHatAsync(HatType hat)
         {
             PlayerInfo.Hat = hat;
 
-            using var writer = _game.StartRpc(NetId, RpcCalls.SetHat);
+            using var writer = Game.StartRpc(NetId, RpcCalls.SetHat);
             Rpc09SetHat.Serialize(writer, hat);
-            await _game.FinishRpcAsync(writer);
+            await Game.FinishRpcAsync(writer);
         }
 
         public async ValueTask SetPetAsync(PetType pet)
         {
             PlayerInfo.Pet = pet;
 
-            using var writer = _game.StartRpc(NetId, RpcCalls.SetPet);
+            using var writer = Game.StartRpc(NetId, RpcCalls.SetPet);
             Rpc17SetPet.Serialize(writer, pet);
-            await _game.FinishRpcAsync(writer);
+            await Game.FinishRpcAsync(writer);
         }
 
         public async ValueTask SetSkinAsync(SkinType skin)
         {
             PlayerInfo.Skin = skin;
 
-            using var writer = _game.StartRpc(NetId, RpcCalls.SetSkin);
+            using var writer = Game.StartRpc(NetId, RpcCalls.SetSkin);
             Rpc10SetSkin.Serialize(writer, skin);
-            await _game.FinishRpcAsync(writer);
+            await Game.FinishRpcAsync(writer);
         }
 
         public async ValueTask SendChatAsync(string text)
         {
-            using var writer = _game.StartRpc(NetId, RpcCalls.SendChat);
+            using var writer = Game.StartRpc(NetId, RpcCalls.SendChat);
             writer.Write(text);
-            await _game.FinishRpcAsync(writer);
+            await Game.FinishRpcAsync(writer);
         }
 
         public async ValueTask SendChatToPlayerAsync(string text, IInnerPlayerControl? player = null)
@@ -77,9 +77,9 @@ namespace Impostor.Server.Net.Inner.Objects
                 player = this;
             }
 
-            using var writer = _game.StartRpc(NetId, RpcCalls.SendChat);
+            using var writer = Game.StartRpc(NetId, RpcCalls.SendChat);
             writer.Write(text);
-            await _game.FinishRpcAsync(writer, player.OwnerId);
+            await Game.FinishRpcAsync(writer, player.OwnerId);
         }
 
         public async ValueTask MurderPlayerAsync(IInnerPlayerControl target)
@@ -101,11 +101,11 @@ namespace Impostor.Server.Net.Inner.Objects
 
             ((InnerPlayerControl)target).Die(DeathReason.Kill);
 
-            using var writer = _game.StartRpc(NetId, RpcCalls.MurderPlayer);
+            using var writer = Game.StartRpc(NetId, RpcCalls.MurderPlayer);
             Rpc12MurderPlayer.Serialize(writer, target);
-            await _game.FinishRpcAsync(writer);
+            await Game.FinishRpcAsync(writer);
 
-            await _eventManager.CallAsync(new PlayerMurderEvent(_game, _game.GetClientPlayer(OwnerId)!, this, target));
+            await _eventManager.CallAsync(new PlayerMurderEvent(Game, Game.GetClientPlayer(OwnerId)!, this, target));
         }
 
         public async ValueTask ExileAsync()
@@ -119,12 +119,12 @@ namespace Impostor.Server.Net.Inner.Objects
             Die(DeathReason.Exile);
 
             // Send RPC.
-            using var writer = _game.StartRpc(NetId, RpcCalls.Exiled);
+            using var writer = Game.StartRpc(NetId, RpcCalls.Exiled);
             Rpc04Exiled.Serialize(writer);
-            await _game.FinishRpcAsync(writer);
+            await Game.FinishRpcAsync(writer);
 
             // Notify plugins.
-            await _eventManager.CallAsync(new PlayerExileEvent(_game, _game.GetClientPlayer(OwnerId)!, this));
+            await _eventManager.CallAsync(new PlayerExileEvent(Game, Game.GetClientPlayer(OwnerId)!, this));
         }
     }
 }
index bf4ed8c5d0951d9b37b727c6c55403a9c20b988e..06191a18f2c473d1d99c5b3ce317bd9f88f82d7e 100644 (file)
@@ -26,18 +26,16 @@ namespace Impostor.Server.Net.Inner.Objects
 
         private readonly ILogger<InnerPlayerControl> _logger;
         private readonly IEventManager _eventManager;
-        private readonly Game _game;
         private readonly IDateTimeProvider _dateTimeProvider;
 
-        public InnerPlayerControl(ILogger<InnerPlayerControl> logger, IServiceProvider serviceProvider, IEventManager eventManager, Game game, IDateTimeProvider dateTimeProvider)
+        public InnerPlayerControl(Game game, ILogger<InnerPlayerControl> logger, IServiceProvider serviceProvider, IEventManager eventManager, IDateTimeProvider dateTimeProvider) : base(game)
         {
             _logger = logger;
             _eventManager = eventManager;
-            _game = game;
             _dateTimeProvider = dateTimeProvider;
 
-            Physics = ActivatorUtilities.CreateInstance<InnerPlayerPhysics>(serviceProvider, this, _eventManager, _game);
-            NetworkTransform = ActivatorUtilities.CreateInstance<InnerCustomNetworkTransform>(serviceProvider, this, _game);
+            Physics = ActivatorUtilities.CreateInstance<InnerPlayerPhysics>(serviceProvider, this, _eventManager, game);
+            NetworkTransform = ActivatorUtilities.CreateInstance<InnerCustomNetworkTransform>(serviceProvider, this, game);
 
             Components.Add(this);
             Components.Add(Physics);
@@ -115,7 +113,7 @@ namespace Impostor.Server.Net.Inner.Objects
                         return false;
                     }
 
-                    Rpc02SyncSettings.Deserialize(reader, _game.Options);
+                    Rpc02SyncSettings.Deserialize(reader, Game.Options);
                     break;
                 }
 
@@ -215,7 +213,7 @@ namespace Impostor.Server.Net.Inner.Objects
                         return false;
                     }
 
-                    Rpc12MurderPlayer.Deserialize(reader, _game, out var murdered);
+                    Rpc12MurderPlayer.Deserialize(reader, Game, out var murdered);
                     return await HandleMurderPlayer(sender, murdered);
                 }
 
@@ -317,7 +315,7 @@ namespace Impostor.Server.Net.Inner.Objects
             if (task != null)
             {
                 task.Complete = true;
-                await _eventManager.CallAsync(new PlayerCompletedTaskEvent(_game, sender, this, task));
+                await _eventManager.CallAsync(new PlayerCompletedTaskEvent(Game, sender, this, task));
             }
             else
             {
@@ -329,16 +327,16 @@ namespace Impostor.Server.Net.Inner.Objects
         {
             for (var i = 0; i < infectedIds.Length; i++)
             {
-                var player = _game.GameNet.GameData!.GetPlayerById(infectedIds.Span[i]);
+                var player = Game.GameNet.GameData!.GetPlayerById(infectedIds.Span[i]);
                 if (player != null)
                 {
                     player.IsImpostor = true;
                 }
             }
 
-            if (_game.GameState == GameStates.Starting)
+            if (Game.GameState == GameStates.Starting)
             {
-                await _game.StartedAsync();
+                await Game.StartedAsync();
             }
         }
 
@@ -375,7 +373,7 @@ namespace Impostor.Server.Net.Inner.Objects
 
         private async ValueTask<bool> HandleSetName(ClientPlayer sender, string name)
         {
-            if (_game.GameState == GameStates.Started)
+            if (Game.GameState == GameStates.Started)
             {
                 if (await sender.Client.ReportCheatAsync(RpcCalls.SetColor, "Client tried to set a name midgame"))
                 {
@@ -385,7 +383,7 @@ namespace Impostor.Server.Net.Inner.Objects
 
             if (sender.IsOwner(this))
             {
-                if (_game.Players.Any(x => x.Character != null && x.Character != this && x.Character.PlayerInfo.PlayerName == name))
+                if (Game.Players.Any(x => x.Character != null && x.Character != this && x.Character.PlayerInfo.PlayerName == name))
                 {
                     if (await sender.Client.ReportCheatAsync(RpcCalls.SetName, "Client sent name that is already used"))
                     {
@@ -411,14 +409,14 @@ namespace Impostor.Server.Net.Inner.Objects
 
                 var expected = RequestedPlayerName.Dequeue();
 
-                if (_game.Players.Any(x => x.Character != null && x.Character != this && x.Character.PlayerInfo.PlayerName == expected))
+                if (Game.Players.Any(x => x.Character != null && x.Character != this && x.Character.PlayerInfo.PlayerName == expected))
                 {
                     var i = 1;
                     while (true)
                     {
                         string text = expected + " " + i;
 
-                        if (_game.Players.All(x => x.Character == null || x.Character == this || x.Character.PlayerInfo.PlayerName != text))
+                        if (Game.Players.All(x => x.Character == null || x.Character == this || x.Character.PlayerInfo.PlayerName != text))
                         {
                             expected = text;
                             break;
@@ -458,7 +456,7 @@ namespace Impostor.Server.Net.Inner.Objects
 
         private async ValueTask<bool> HandleSetColor(ClientPlayer sender, ColorType color)
         {
-            if (_game.GameState == GameStates.Started)
+            if (Game.GameState == GameStates.Started)
             {
                 if (await sender.Client.ReportCheatAsync(RpcCalls.SetColor, "Client tried to set a color midgame"))
                 {
@@ -468,7 +466,7 @@ namespace Impostor.Server.Net.Inner.Objects
 
             if (sender.IsOwner(this))
             {
-                if (_game.Players.Any(x => x.Character != null && x.Character != this && x.Character.PlayerInfo.Color == color))
+                if (Game.Players.Any(x => x.Character != null && x.Character != this && x.Character.PlayerInfo.Color == color))
                 {
                     if (await sender.Client.ReportCheatAsync(RpcCalls.SetColor, "Client sent a color that is already used"))
                     {
@@ -486,7 +484,7 @@ namespace Impostor.Server.Net.Inner.Objects
 
                 var expected = RequestedColorId.Dequeue();
 
-                while (_game.Players.Any(x => x.Character != null && x.Character != this && x.Character.PlayerInfo.Color == expected))
+                while (Game.Players.Any(x => x.Character != null && x.Character != this && x.Character.PlayerInfo.Color == expected))
                 {
                     expected = (ColorType)(((byte)expected + 1) % ColorsCount);
                 }
@@ -506,7 +504,7 @@ namespace Impostor.Server.Net.Inner.Objects
 
         private async ValueTask<bool> HandleSetHat(ClientPlayer sender, HatType hat)
         {
-            if (_game.GameState == GameStates.Started && await sender.Client.ReportCheatAsync(RpcCalls.SetHat, "Client tried to change hat while not in lobby"))
+            if (Game.GameState == GameStates.Started && await sender.Client.ReportCheatAsync(RpcCalls.SetHat, "Client tried to change hat while not in lobby"))
             {
                 return false;
             }
@@ -518,7 +516,7 @@ namespace Impostor.Server.Net.Inner.Objects
 
         private async ValueTask<bool> HandleSetSkin(ClientPlayer sender, SkinType skin)
         {
-            if (_game.GameState == GameStates.Started && await sender.Client.ReportCheatAsync(RpcCalls.SetSkin, "Client tried to change skin while not in lobby"))
+            if (Game.GameState == GameStates.Started && await sender.Client.ReportCheatAsync(RpcCalls.SetSkin, "Client tried to change skin while not in lobby"))
             {
                 return false;
             }
@@ -530,7 +528,7 @@ namespace Impostor.Server.Net.Inner.Objects
 
         private async ValueTask<bool> HandleMurderPlayer(ClientPlayer sender, IInnerPlayerControl? target)
         {
-            if (!PlayerInfo.CanMurder(_game, _dateTimeProvider))
+            if (!PlayerInfo.CanMurder(Game, _dateTimeProvider))
             {
                 if (await sender.Client.ReportCheatAsync(RpcCalls.MurderPlayer, "Client tried to murder too fast"))
                 {
@@ -551,7 +549,7 @@ namespace Impostor.Server.Net.Inner.Objects
             if (target != null && !target.PlayerInfo.IsDead)
             {
                 ((InnerPlayerControl)target).Die(DeathReason.Kill);
-                await _eventManager.CallAsync(new PlayerMurderEvent(_game, sender, this, target));
+                await _eventManager.CallAsync(new PlayerMurderEvent(Game, sender, this, target));
             }
 
             return true;
@@ -559,7 +557,7 @@ namespace Impostor.Server.Net.Inner.Objects
 
         private async ValueTask<bool> HandleSendChat(ClientPlayer sender, string message)
         {
-            var @event = new PlayerChatEvent(_game, sender, this, message);
+            var @event = new PlayerChatEvent(Game, sender, this, message);
             await _eventManager.CallAsync(@event);
 
             return !@event.IsCancelled;
@@ -567,13 +565,13 @@ namespace Impostor.Server.Net.Inner.Objects
 
         private async ValueTask HandleStartMeeting(byte targetId)
         {
-            var deadPlayer = _game.GameNet.GameData!.GetPlayerById(targetId)?.Controller;
-            await _eventManager.CallAsync(new PlayerStartMeetingEvent(_game, _game.GetClientPlayer(this.OwnerId)!, this, deadPlayer));
+            var deadPlayer = Game.GameNet.GameData!.GetPlayerById(targetId)?.Controller;
+            await _eventManager.CallAsync(new PlayerStartMeetingEvent(Game, Game.GetClientPlayer(this.OwnerId)!, this, deadPlayer));
         }
 
         private async ValueTask<bool> HandleSetPet(ClientPlayer sender, PetType pet)
         {
-            if (_game.GameState == GameStates.Started && await sender.Client.ReportCheatAsync(RpcCalls.SetPet, "Client tried to change pet while not in lobby"))
+            if (Game.GameState == GameStates.Started && await sender.Client.ReportCheatAsync(RpcCalls.SetPet, "Client tried to change pet while not in lobby"))
             {
                 return false;
             }
@@ -595,7 +593,7 @@ namespace Impostor.Server.Net.Inner.Objects
 
             if (startCounter != -1)
             {
-                await _eventManager.CallAsync(new PlayerSetStartCounterEvent(_game, sender, this, (byte)startCounter));
+                await _eventManager.CallAsync(new PlayerSetStartCounterEvent(Game, sender, this, (byte)startCounter));
             }
 
             return true;
index 1d488fbdcd21a61aecb6201eccd742a044904cd7..763782a32b985ce164fb0a8dd97a8c24d0b61443 100644 (file)
@@ -59,15 +59,23 @@ namespace Impostor.Server.Net.Inner.Objects
         public void Deserialize(IMessageReader reader)
         {
             PlayerName = reader.ReadString();
-            Color = (ColorType)reader.ReadByte();
+            Color = (ColorType)reader.ReadPackedInt32();
             Hat = (HatType)reader.ReadPackedUInt32();
             Pet = (PetType)reader.ReadPackedUInt32();
             Skin = (SkinType)reader.ReadPackedUInt32();
+
             var flag = reader.ReadByte();
             Disconnected = (flag & 1) > 0;
             IsImpostor = (flag & 2) > 0;
             IsDead = (flag & 4) > 0;
+
             var taskCount = reader.ReadByte();
+
+            if (Tasks.Count != taskCount)
+            {
+                Tasks = new List<InnerGameData.TaskInfo>(taskCount);
+            }
+
             for (var i = 0; i < taskCount; i++)
             {
                 Tasks[i] ??= new InnerGameData.TaskInfo();
diff --git a/src/Impostor.Server/Net/Inner/Objects/InnerShipStatus.cs b/src/Impostor.Server/Net/Inner/Objects/InnerShipStatus.cs
deleted file mode 100644 (file)
index dd8b511..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-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;
-using Impostor.Api.Net.Inner.Objects;
-using Impostor.Api.Net.Messages;
-using Impostor.Api.Net.Messages.Rpcs;
-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] = game.Options.Map == MapTypes.Airship ? new HeliSabotageSystemType() : 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<bool> SerializeAsync(IMessageWriter writer, bool initialState)
-        {
-            throw new NotImplementedException();
-        }
-
-        public override async ValueTask DeserializeAsync(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState)
-        {
-            if (!await ValidateHost(CheatContext.Deserialize, sender) || !await ValidateBroadcast(CheatContext.Deserialize, sender, target))
-            {
-                return;
-            }
-
-            while (reader.Position < reader.Length)
-            {
-                IMessageReader messageReader = reader.ReadMessage();
-                SystemTypes type = (SystemTypes)messageReader.Tag;
-                if (_systems.TryGetValue(type, out var value))
-                {
-                    value.Deserialize(messageReader, initialState);
-                }
-            }
-        }
-
-        public override async ValueTask<bool> HandleRpcAsync(ClientPlayer sender, ClientPlayer? target, RpcCalls call, IMessageReader reader)
-        {
-            if (!await ValidateCmd(call, sender, target))
-            {
-                return false;
-            }
-
-            switch (call)
-            {
-                case RpcCalls.CloseDoorsOfType:
-                {
-                    if (!await ValidateImpostor(call, sender, sender.Character!.PlayerInfo))
-                    {
-                        return false;
-                    }
-
-                    Rpc27CloseDoorsOfType.Deserialize(reader, out var systemType);
-                    break;
-                }
-
-                case RpcCalls.RepairSystem:
-                {
-                    Rpc28RepairSystem.Deserialize(reader, _game, out var systemType, out var player, out var amount);
-
-                    if (systemType == SystemTypes.Sabotage && !await ValidateImpostor(call, sender, sender.Character!.PlayerInfo))
-                    {
-                        return false;
-                    }
-
-                    break;
-                }
-
-                default:
-                    return await UnregisteredCall(call, sender);
-            }
-
-            return true;
-        }
-    }
-}
diff --git a/src/Impostor.Server/Net/Inner/Objects/ShipStatus/InnerAirshipStatus.cs b/src/Impostor.Server/Net/Inner/Objects/ShipStatus/InnerAirshipStatus.cs
new file mode 100644 (file)
index 0000000..8776a8c
--- /dev/null
@@ -0,0 +1,31 @@
+using System.Collections.Generic;
+using Impostor.Api.Innersloth;
+using Impostor.Api.Net.Inner.Objects.ShipStatus;
+using Impostor.Server.Net.Inner.Objects.Systems;
+using Impostor.Server.Net.Inner.Objects.Systems.ShipStatus;
+using Impostor.Server.Net.State;
+
+namespace Impostor.Server.Net.Inner.Objects.ShipStatus
+{
+    internal class InnerAirshipStatus : InnerShipStatus, IInnerAirshipStatus
+    {
+        public InnerAirshipStatus(Game game) : base(game)
+        {
+        }
+
+        public override Dictionary<int, bool> Doors { get; } = new Dictionary<int, bool>(21);
+
+        protected override void AddSystems(Dictionary<SystemTypes, ISystemType> systems)
+        {
+            base.AddSystems(systems);
+
+            systems.Add(SystemTypes.Doors, new DoorsSystemType(Doors));
+            systems.Add(SystemTypes.Comms, new HudOverrideSystemType());
+            systems.Add(SystemTypes.GapRoom, new MovingPlatformBehaviour());
+            systems.Add(SystemTypes.Reactor, new HeliSabotageSystemType());
+            systems.Add(SystemTypes.Decontamination, new ElectricalDoors(Doors));
+            systems.Add(SystemTypes.Decontamination2, new AutoDoorsSystemType(Doors));
+            systems.Add(SystemTypes.Security, new SecurityCameraSystemType());
+        }
+    }
+}
diff --git a/src/Impostor.Server/Net/Inner/Objects/ShipStatus/InnerMiraShipStatus.cs b/src/Impostor.Server/Net/Inner/Objects/ShipStatus/InnerMiraShipStatus.cs
new file mode 100644 (file)
index 0000000..04d033f
--- /dev/null
@@ -0,0 +1,27 @@
+using System.Collections.Generic;
+using Impostor.Api.Innersloth;
+using Impostor.Api.Net.Inner.Objects.ShipStatus;
+using Impostor.Server.Net.Inner.Objects.Systems;
+using Impostor.Server.Net.Inner.Objects.Systems.ShipStatus;
+using Impostor.Server.Net.State;
+
+namespace Impostor.Server.Net.Inner.Objects.ShipStatus
+{
+    internal class InnerMiraShipStatus : InnerShipStatus, IInnerMiraShipStatus
+    {
+        public InnerMiraShipStatus(Game game) : base(game)
+        {
+        }
+
+        public override Dictionary<int, bool> Doors { get; } = new Dictionary<int, bool>(0);
+
+        protected override void AddSystems(Dictionary<SystemTypes, ISystemType> systems)
+        {
+            base.AddSystems(systems);
+
+            systems.Add(SystemTypes.Comms, new HudOverrideSystemType());
+            systems.Add(SystemTypes.Reactor, new ReactorSystemType());
+            systems.Add(SystemTypes.LifeSupp, new LifeSuppSystemType());
+        }
+    }
+}
diff --git a/src/Impostor.Server/Net/Inner/Objects/ShipStatus/InnerPolusShipStatus.cs b/src/Impostor.Server/Net/Inner/Objects/ShipStatus/InnerPolusShipStatus.cs
new file mode 100644 (file)
index 0000000..7ec077d
--- /dev/null
@@ -0,0 +1,28 @@
+using System.Collections.Generic;
+using Impostor.Api.Innersloth;
+using Impostor.Api.Net.Inner.Objects.ShipStatus;
+using Impostor.Server.Net.Inner.Objects.Systems;
+using Impostor.Server.Net.Inner.Objects.Systems.ShipStatus;
+using Impostor.Server.Net.State;
+
+namespace Impostor.Server.Net.Inner.Objects.ShipStatus
+{
+    internal class InnerPolusShipStatus : InnerShipStatus, IInnerPolusShipStatus
+    {
+        public InnerPolusShipStatus(Game game) : base(game)
+        {
+        }
+
+        public override Dictionary<int, bool> Doors { get; } = new Dictionary<int, bool>(12);
+
+        protected override void AddSystems(Dictionary<SystemTypes, ISystemType> systems)
+        {
+            base.AddSystems(systems);
+
+            systems.Add(SystemTypes.Doors, new DoorsSystemType(Doors));
+            systems.Add(SystemTypes.Comms, new HudOverrideSystemType());
+            systems.Add(SystemTypes.Security, new SecurityCameraSystemType());
+            systems.Add(SystemTypes.Laboratory, new ReactorSystemType());
+        }
+    }
+}
diff --git a/src/Impostor.Server/Net/Inner/Objects/ShipStatus/InnerShipStatus.cs b/src/Impostor.Server/Net/Inner/Objects/ShipStatus/InnerShipStatus.cs
new file mode 100644 (file)
index 0000000..418adef
--- /dev/null
@@ -0,0 +1,110 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Impostor.Api;
+using Impostor.Api.Innersloth;
+using Impostor.Api.Net;
+using Impostor.Api.Net.Inner;
+using Impostor.Api.Net.Inner.Objects.ShipStatus;
+using Impostor.Api.Net.Messages;
+using Impostor.Api.Net.Messages.Rpcs;
+using Impostor.Server.Net.Inner.Objects.Systems;
+using Impostor.Server.Net.Inner.Objects.Systems.ShipStatus;
+using Impostor.Server.Net.State;
+
+namespace Impostor.Server.Net.Inner.Objects.ShipStatus
+{
+    internal abstract class InnerShipStatus : InnerNetObject, IInnerShipStatus
+    {
+        private readonly Dictionary<SystemTypes, ISystemType> _systems = new Dictionary<SystemTypes, ISystemType>();
+
+        protected InnerShipStatus(Game game) : base(game)
+        {
+            Components.Add(this);
+        }
+
+        public abstract Dictionary<int, bool> Doors { get; }
+
+        public override ValueTask OnSpawnAsync()
+        {
+            for (var i = 0; i < Doors.Count; i++)
+            {
+                Doors.Add(i, false);
+            }
+
+            AddSystems(_systems);
+            _systems.Add(SystemTypes.Sabotage, new SabotageSystemType(_systems.Values.OfType<IActivatable>().ToArray()));
+
+            return base.OnSpawnAsync();
+        }
+
+        public override ValueTask<bool> SerializeAsync(IMessageWriter writer, bool initialState)
+        {
+            throw new NotImplementedException();
+        }
+
+        public override async ValueTask DeserializeAsync(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState)
+        {
+            if (!await ValidateHost(CheatContext.Deserialize, sender) || !await ValidateBroadcast(CheatContext.Deserialize, sender, target))
+            {
+                return;
+            }
+
+            while (reader.Position < reader.Length)
+            {
+                var messageReader = reader.ReadMessage();
+                var type = (SystemTypes)messageReader.Tag;
+                if (_systems.TryGetValue(type, out var value))
+                {
+                    value.Deserialize(messageReader, initialState);
+                }
+            }
+        }
+
+        public override async ValueTask<bool> HandleRpcAsync(ClientPlayer sender, ClientPlayer? target, RpcCalls call, IMessageReader reader)
+        {
+            if (!await ValidateCmd(call, sender, target))
+            {
+                return false;
+            }
+
+            switch (call)
+            {
+                case RpcCalls.CloseDoorsOfType:
+                {
+                    if (!await ValidateImpostor(call, sender, sender.Character!.PlayerInfo))
+                    {
+                        return false;
+                    }
+
+                    Rpc27CloseDoorsOfType.Deserialize(reader, out var systemType);
+                    break;
+                }
+
+                case RpcCalls.RepairSystem:
+                {
+                    Rpc28RepairSystem.Deserialize(reader, Game, out var systemType, out var player, out var amount);
+
+                    if (systemType == SystemTypes.Sabotage && !await ValidateImpostor(call, sender, sender.Character!.PlayerInfo))
+                    {
+                        return false;
+                    }
+
+                    break;
+                }
+
+                default:
+                    return await UnregisteredCall(call, sender);
+            }
+
+            return true;
+        }
+
+        protected virtual void AddSystems(Dictionary<SystemTypes, ISystemType> systems)
+        {
+            systems.Add(SystemTypes.Electrical, new SwitchSystem());
+            systems.Add(SystemTypes.MedBay, new MedScanSystem());
+        }
+    }
+}
diff --git a/src/Impostor.Server/Net/Inner/Objects/ShipStatus/InnerSkeldShipStatus.cs b/src/Impostor.Server/Net/Inner/Objects/ShipStatus/InnerSkeldShipStatus.cs
new file mode 100644 (file)
index 0000000..12df2f3
--- /dev/null
@@ -0,0 +1,29 @@
+using System.Collections.Generic;
+using Impostor.Api.Innersloth;
+using Impostor.Api.Net.Inner.Objects.ShipStatus;
+using Impostor.Server.Net.Inner.Objects.Systems;
+using Impostor.Server.Net.Inner.Objects.Systems.ShipStatus;
+using Impostor.Server.Net.State;
+
+namespace Impostor.Server.Net.Inner.Objects.ShipStatus
+{
+    internal class InnerSkeldShipStatus : InnerShipStatus, IInnerSkeldShipStatus
+    {
+        public InnerSkeldShipStatus(Game game) : base(game)
+        {
+        }
+
+        public override Dictionary<int, bool> Doors { get; } = new Dictionary<int, bool>(13);
+
+        protected override void AddSystems(Dictionary<SystemTypes, ISystemType> systems)
+        {
+            base.AddSystems(systems);
+
+            systems.Add(SystemTypes.Doors, new AutoDoorsSystemType(Doors));
+            systems.Add(SystemTypes.Comms, new HudOverrideSystemType());
+            systems.Add(SystemTypes.Security, new SecurityCameraSystemType());
+            systems.Add(SystemTypes.Reactor, new ReactorSystemType());
+            systems.Add(SystemTypes.LifeSupp, new LifeSuppSystemType());
+        }
+    }
+}
diff --git a/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/AutoDoorsSystemType.cs b/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/AutoDoorsSystemType.cs
new file mode 100644 (file)
index 0000000..5a14575
--- /dev/null
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using Impostor.Api.Net.Messages;
+
+namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus
+{
+    public class AutoDoorsSystemType : ISystemType
+    {
+        private readonly Dictionary<int, bool> _doors;
+
+        public AutoDoorsSystemType(Dictionary<int, bool> doors)
+        {
+            _doors = doors;
+        }
+
+        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();
+                    }
+                }
+            }
+        }
+    }
+}
index 03ba1df9264452cd4684e3269dbf864964b02597..2bc71301b76f727eeed9eec084609841c771adf9 100644 (file)
@@ -1,6 +1,5 @@
-using System;
+using System;
 using System.Collections.Generic;
-using Impostor.Api.Games;
 using Impostor.Api.Innersloth;
 using Impostor.Api.Net.Messages;
 
@@ -8,26 +7,12 @@ namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus
 {
     public class DoorsSystemType : ISystemType
     {
-        // TODO: AutoDoors
+        private readonly Dictionary<SystemTypes, float> _timers = new Dictionary<SystemTypes, float>();
         private readonly Dictionary<int, bool> _doors;
 
-        public DoorsSystemType(IGame game)
+        public DoorsSystemType(Dictionary<int, bool> doors)
         {
-            var doorCount = game.Options.Map switch
-            {
-                MapTypes.Skeld => 13,
-                MapTypes.MiraHQ => 2,
-                MapTypes.Polus => 12,
-                MapTypes.Airship => 21, // TODO do the toilet doors count? 21 yes, 17 no
-                _ => throw new ArgumentOutOfRangeException(),
-            };
-
-            _doors = new Dictionary<int, bool>(doorCount);
-
-            for (var i = 0; i < doorCount; i++)
-            {
-                _doors.Add(i, false);
-            }
+            _doors = doors;
         }
 
         public void Serialize(IMessageWriter writer, bool initialState)
@@ -37,24 +22,18 @@ namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus
 
         public void Deserialize(IMessageReader reader, bool initialState)
         {
-            if (initialState)
+            var num = reader.ReadByte();
+            for (var i = 0; i < num; i++)
             {
-                for (var i = 0; i < _doors.Count; i++)
-                {
-                    _doors[i] = reader.ReadBoolean();
-                }
+                var systemType = (SystemTypes)reader.ReadByte();
+                var value = reader.ReadSingle();
+
+                _timers[systemType] = value;
             }
-            else
-            {
-                var num = reader.ReadPackedUInt32();
 
-                for (var i = 0; i < _doors.Count; i++)
-                {
-                    if ((num & 1 << i) != 0)
-                    {
-                        _doors[i] = reader.ReadBoolean();
-                    }
-                }
+            for (var j = 0; j < _doors.Count; j++)
+            {
+                _doors[j] = reader.ReadBoolean();
             }
         }
     }
diff --git a/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/ElectricalDoors.cs b/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/ElectricalDoors.cs
new file mode 100644 (file)
index 0000000..cadb995
--- /dev/null
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using Impostor.Api.Net.Messages;
+
+namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus
+{
+    public class ElectricalDoors : ISystemType
+    {
+        private readonly Dictionary<int, bool> _doors;
+
+        public ElectricalDoors(Dictionary<int, bool> doors)
+        {
+            _doors = doors;
+        }
+
+        public void Serialize(IMessageWriter writer, bool initialState)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void Deserialize(IMessageReader reader, bool initialState)
+        {
+            var num = reader.ReadUInt32();
+            for (var i = 0; i < _doors.Count; i++)
+            {
+                _doors[i] = (num & (ulong)(1L << (i & 31))) > 0UL;
+            }
+        }
+    }
+}
index 1d6be32065534592748cbe5dcf217995ed07a372..d72ed5b635e2e9c523f61f61e224f384a8d8d4c6 100644 (file)
@@ -1,7 +1,6 @@
 using System;
 using System.Collections.Generic;
 using Impostor.Api.Net.Messages;
-using Microsoft.Extensions.Logging;
 
 namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus
 {
diff --git a/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/MovingPlatformBehaviour.cs b/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/MovingPlatformBehaviour.cs
new file mode 100644 (file)
index 0000000..82cfb1f
--- /dev/null
@@ -0,0 +1,22 @@
+using System;
+using Impostor.Api.Net.Messages;
+
+namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus
+{
+    public class MovingPlatformBehaviour : ISystemType, IActivatable
+    {
+        public bool IsActive { get; private set; }
+
+        public void Serialize(IMessageWriter writer, bool initialState)
+        {
+            throw new NotImplementedException();
+        }
+
+        public void Deserialize(IMessageReader reader, bool initialState)
+        {
+            var sid = reader.ReadByte();
+            var targetId = reader.ReadUInt32();
+            var isLeft = reader.ReadBoolean();
+        }
+    }
+}
index 44257e7636e7872a18b3054c92f15e55f8c9d1c8..a35858568fa0c36e5b357f8c39e0651f632f9405 100644 (file)
@@ -8,7 +8,6 @@ using Impostor.Api.Net;
 using Impostor.Api.Net.Inner;
 using Impostor.Api.Net.Messages;
 using Impostor.Hazel;
-using Impostor.Server.Net.Inner;
 
 namespace Impostor.Server.Net.State
 {
index e6914708693fdac8f2d2ff3254e778795b66cf19..74b3c7bba6f2381f0e297cb7eba9b99a6af9f422 100644 (file)
@@ -10,6 +10,7 @@ using Impostor.Server.Events.Player;
 using Impostor.Server.Net.Inner;
 using Impostor.Server.Net.Inner.Objects;
 using Impostor.Server.Net.Inner.Objects.Components;
+using Impostor.Server.Net.Inner.Objects.ShipStatus;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Logging;
 
@@ -32,15 +33,15 @@ namespace Impostor.Server.Net.State
 
         private static readonly Type[] SpawnableObjects =
         {
-            typeof(InnerShipStatus), // ShipStatus
+            typeof(InnerSkeldShipStatus),
             typeof(InnerMeetingHud),
             typeof(InnerLobbyBehaviour),
             typeof(InnerGameData),
             typeof(InnerPlayerControl),
-            typeof(InnerShipStatus), // HeadQuarters
-            typeof(InnerShipStatus), // PlanetMap
-            typeof(InnerShipStatus), // AprilShipStatus
-            typeof(InnerShipStatus), // Airship
+            typeof(InnerMiraShipStatus),
+            typeof(InnerPolusShipStatus),
+            typeof(InnerSkeldShipStatus), // April fools skeld
+            typeof(InnerAirshipStatus),
         };
 
         private readonly List<InnerNetObject> _allObjects = new List<InnerNetObject>();
@@ -349,6 +350,8 @@ namespace Impostor.Server.Net.State
                     break;
                 }
             }
+
+            await netObj.OnSpawnAsync();
         }
 
         private async ValueTask OnDestroyAsync(InnerNetObject netObj)
index 4fed52763c8b9f7cddf2da2191a2fb7ef62aefac..3af856ce4637cecd24f80704bdb0da4e217522ff 100644 (file)
@@ -1,5 +1,6 @@
 using Impostor.Api.Net.Inner;
 using Impostor.Api.Net.Inner.Objects;
+using Impostor.Api.Net.Inner.Objects.ShipStatus;
 
 namespace Impostor.Server.Net.State
 {
index 37e0cbd91ca330d4588af867415ad0763bcb060d..bb7a8e253414a3b06b2fd7202aa8b938c48c5959 100644 (file)
@@ -1,5 +1,6 @@
 using Impostor.Server.Net.Inner.Objects;
 using Impostor.Server.Net.Inner.Objects.Components;
+using Impostor.Server.Net.Inner.Objects.ShipStatus;
 
 namespace Impostor.Server.Net.State
 {