diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 727dfd76..6cf141eb 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "cake.tool": { - "version": "0.38.5", + "version": "1.1.0", "commands": [ "dotnet-cake" ] diff --git a/appveyor.yml b/appveyor.yml index ce3b999a..ca2bc2cb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -30,7 +30,6 @@ test: off artifacts: - path: ./build/*.zip - - path: ./build/*.tar.gz - path: ./build/*.nupkg - path: ./build/*.snupkg diff --git a/build.cake b/build.cake index 13a2ae96..25a5e17b 100644 --- a/build.cake +++ b/build.cake @@ -1,6 +1,6 @@ -#addin "nuget:?package=SharpZipLib&Version=1.3.0" -#addin "nuget:?package=Cake.Compression&Version=0.2.4" -#addin "nuget:?package=Cake.FileHelpers&Version=3.3.0" +#addin "nuget:?package=SharpZipLib&Version=1.3.1" +#addin "nuget:?package=Cake.Compression&Version=0.2.6" +#addin "nuget:?package=Cake.FileHelpers&Version=4.0.1" var buildId = EnvironmentVariable("GITHUB_RUN_NUMBER") ?? EnvironmentVariable("APPVEYOR_BUILD_VERSION"); var buildRelease = EnvironmentVariable("APPVEYOR_REPO_TAG") == "true"; diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 81faf42b..10f1890a 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -3,5 +3,9 @@ 1.3.0 dev + + + + diff --git a/src/Impostor.Api/Events/Announcements/IAnnouncementRequestEvent.cs b/src/Impostor.Api/Events/Announcements/IAnnouncementRequestEvent.cs index b4eaa015..a0e54452 100644 --- a/src/Impostor.Api/Events/Announcements/IAnnouncementRequestEvent.cs +++ b/src/Impostor.Api/Events/Announcements/IAnnouncementRequestEvent.cs @@ -3,40 +3,40 @@ using Impostor.Api.Innersloth; namespace Impostor.Api.Events.Announcements { /// - /// Event fired after client requests a announcement. + /// Event fired after client requests a announcement. /// public interface IAnnouncementRequestEvent : IEvent { public interface IResponse { /// - /// Gets or sets FreeWeekendState, currently unused by the client. + /// Gets or sets FreeWeekendState, currently unused by the client. /// public FreeWeekendState FreeWeekendState { get; set; } /// - /// Gets or sets a value indicating whether announcement should be loaded from client's cache, can save some bytes. + /// Gets or sets a value indicating whether announcement should be loaded from client's cache, can save some bytes. /// public bool UseCached { get; set; } /// - /// Gets or sets announcement, should be null when is set to true. + /// Gets or sets announcement, should be null when is set to true. /// public Announcement? Announcement { get; set; } } /// - /// Gets client's last announcement id. + /// Gets client's last announcement id. /// public int Id { get; } /// - /// Gets client's language. + /// Gets client's language. /// public Language Language { get; } /// - /// Gets or sets plugin made response. + /// Gets or sets plugin made response. /// public IResponse Response { get; set; } } diff --git a/src/Impostor.Api/Events/Attributes/EventListenerAttribute.cs b/src/Impostor.Api/Events/Attributes/EventListenerAttribute.cs index b31d2d1a..da1e4896 100644 --- a/src/Impostor.Api/Events/Attributes/EventListenerAttribute.cs +++ b/src/Impostor.Api/Events/Attributes/EventListenerAttribute.cs @@ -17,18 +17,18 @@ namespace Impostor.Api.Events } /// - /// The priority of the event listener. + /// Gets or sets the priority of the event listener. /// public EventPriority Priority { get; set; } /// - /// The events that the listener is listening to. + /// Gets or sets the event that the listener is listening to. /// public Type? Event { get; set; } /// - /// If set to true, the listener will be called regardless of the . + /// Gets or sets a value indicating whether the listener will be called regardless of the . /// public bool IgnoreCancelled { get; set; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Events/Game/IGameCreatedEvent.cs b/src/Impostor.Api/Events/Game/IGameCreatedEvent.cs index ef45f1db..48c8d7cc 100644 --- a/src/Impostor.Api/Events/Game/IGameCreatedEvent.cs +++ b/src/Impostor.Api/Events/Game/IGameCreatedEvent.cs @@ -3,7 +3,7 @@ namespace Impostor.Api.Events { /// - /// Called whenever a new is created. + /// Called whenever a new is created. /// public interface IGameCreatedEvent : IGameEvent { diff --git a/src/Impostor.Api/Events/Game/IGameDestroyedEvent.cs b/src/Impostor.Api/Events/Game/IGameDestroyedEvent.cs index 7ff7b460..e598aaea 100644 --- a/src/Impostor.Api/Events/Game/IGameDestroyedEvent.cs +++ b/src/Impostor.Api/Events/Game/IGameDestroyedEvent.cs @@ -3,7 +3,7 @@ namespace Impostor.Api.Events { /// - /// Called whenever a new is destroyed. + /// Called whenever a new is destroyed. /// public interface IGameDestroyedEvent : IGameEvent { diff --git a/src/Impostor.Api/Events/Game/IGameEvent.cs b/src/Impostor.Api/Events/Game/IGameEvent.cs index c9ae5790..c188af3f 100644 --- a/src/Impostor.Api/Events/Game/IGameEvent.cs +++ b/src/Impostor.Api/Events/Game/IGameEvent.cs @@ -5,7 +5,7 @@ namespace Impostor.Api.Events public interface IGameEvent : IEvent { /// - /// Gets the this event belongs to. + /// Gets the this event belongs to. /// IGame Game { get; } } diff --git a/src/Impostor.Api/Events/Game/IGameStartingEvent.cs b/src/Impostor.Api/Events/Game/IGameStartingEvent.cs index 5998bf24..3ba450ea 100644 --- a/src/Impostor.Api/Events/Game/IGameStartingEvent.cs +++ b/src/Impostor.Api/Events/Game/IGameStartingEvent.cs @@ -3,7 +3,7 @@ /// /// Called when the game is going to start. /// When this is called, not all players are initialized properly yet. - /// If you want to get correct player states, use . + /// If you want to get correct player states, use . /// public interface IGameStartingEvent : IGameEvent { diff --git a/src/Impostor.Api/Events/Game/Player/IPlayerCompletedTaskEvent.cs b/src/Impostor.Api/Events/Game/Player/IPlayerCompletedTaskEvent.cs index 78ccd2d6..a5e32285 100644 --- a/src/Impostor.Api/Events/Game/Player/IPlayerCompletedTaskEvent.cs +++ b/src/Impostor.Api/Events/Game/Player/IPlayerCompletedTaskEvent.cs @@ -1,5 +1,4 @@ -using Impostor.Api.Innersloth; -using Impostor.Api.Net.Inner.Objects; +using Impostor.Api.Net.Inner.Objects; namespace Impostor.Api.Events.Player { diff --git a/src/Impostor.Api/Events/Game/Player/IPlayerEvent.cs b/src/Impostor.Api/Events/Game/Player/IPlayerEvent.cs index 247fe645..d8269ffb 100644 --- a/src/Impostor.Api/Events/Game/Player/IPlayerEvent.cs +++ b/src/Impostor.Api/Events/Game/Player/IPlayerEvent.cs @@ -6,14 +6,14 @@ namespace Impostor.Api.Events.Player public interface IPlayerEvent : IGameEvent { /// - /// Gets the that triggered this . + /// Gets the that triggered this . /// IClientPlayer ClientPlayer { get; } /// - /// Gets the networked that triggered this . - /// This belongs to the . + /// Gets the networked that triggered this . + /// This belongs to the . /// IInnerPlayerControl PlayerControl { get; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Events/Game/Player/IPlayerStartMeetingEvent.cs b/src/Impostor.Api/Events/Game/Player/IPlayerStartMeetingEvent.cs index 1a28115e..016d131d 100644 --- a/src/Impostor.Api/Events/Game/Player/IPlayerStartMeetingEvent.cs +++ b/src/Impostor.Api/Events/Game/Player/IPlayerStartMeetingEvent.cs @@ -5,7 +5,7 @@ namespace Impostor.Api.Events.Player public interface IPlayerStartMeetingEvent : IPlayerEvent { /// - /// Gets the player who's body got reported. Is null when the meeting started by Emergency call button + /// Gets the player who's body got reported. Is null when the meeting started by Emergency call button. /// IInnerPlayerControl? Body { get; } } diff --git a/src/Impostor.Api/Events/IEvent.cs b/src/Impostor.Api/Events/IEvent.cs index 796898e1..3bdb3a67 100644 --- a/src/Impostor.Api/Events/IEvent.cs +++ b/src/Impostor.Api/Events/IEvent.cs @@ -3,4 +3,4 @@ public interface IEvent { } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Events/IEventCancelable.cs b/src/Impostor.Api/Events/IEventCancelable.cs index 319f02a2..1902284e 100644 --- a/src/Impostor.Api/Events/IEventCancelable.cs +++ b/src/Impostor.Api/Events/IEventCancelable.cs @@ -3,8 +3,8 @@ public interface IEventCancelable : IEvent { /// - /// True if the event was cancelled. + /// Gets or sets a value indicating whether the event was cancelled. /// bool IsCancelled { get; set; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Events/IEventListener.cs b/src/Impostor.Api/Events/IEventListener.cs index 76392fcc..f3e8e410 100644 --- a/src/Impostor.Api/Events/IEventListener.cs +++ b/src/Impostor.Api/Events/IEventListener.cs @@ -3,4 +3,4 @@ public interface IEventListener { } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Events/IManualEventListener.cs b/src/Impostor.Api/Events/IManualEventListener.cs index b5c140ef..1b054f75 100644 --- a/src/Impostor.Api/Events/IManualEventListener.cs +++ b/src/Impostor.Api/Events/IManualEventListener.cs @@ -4,10 +4,10 @@ namespace Impostor.Api.Events { public interface IManualEventListener : IEventListener { + EventPriority Priority { get; set; } + public bool CanExecute(); public ValueTask Execute(IEvent @event); - - EventPriority Priority { get; set; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Events/Managers/IEventManager.cs b/src/Impostor.Api/Events/Managers/IEventManager.cs index 07a7f7cf..3d73768a 100644 --- a/src/Impostor.Api/Events/Managers/IEventManager.cs +++ b/src/Impostor.Api/Events/Managers/IEventManager.cs @@ -16,20 +16,20 @@ namespace Impostor.Api.Events.Managers where TListener : IEventListener; /// - /// Returns true if an event with the type is registered. + /// Returns true if an event with the type is registered. /// - /// True if the is registered. + /// True if the is registered. /// Type of the event. bool IsRegistered() where TEvent : IEvent; /// - /// Call all the event listeners for the type . + /// Call all the event listeners for the type . /// /// The event argument. /// Type of the event. - /// A representing the asynchronous operation. + /// A representing the asynchronous operation. ValueTask CallAsync(TEvent @event) where TEvent : IEvent; } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Exceptions/ImpostorConfigException.cs b/src/Impostor.Api/Exceptions/ImpostorConfigException.cs index 1e59a9ba..01b20d4c 100644 --- a/src/Impostor.Api/Exceptions/ImpostorConfigException.cs +++ b/src/Impostor.Api/Exceptions/ImpostorConfigException.cs @@ -9,10 +9,6 @@ namespace Impostor.Api { } - protected ImpostorConfigException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } - public ImpostorConfigException(string? message) : base(message) { } @@ -20,5 +16,9 @@ namespace Impostor.Api public ImpostorConfigException(string? message, Exception? innerException) : base(message, innerException) { } + + protected ImpostorConfigException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } } } diff --git a/src/Impostor.Api/Exceptions/ImpostorException.cs b/src/Impostor.Api/Exceptions/ImpostorException.cs index 188c50e8..03891942 100644 --- a/src/Impostor.Api/Exceptions/ImpostorException.cs +++ b/src/Impostor.Api/Exceptions/ImpostorException.cs @@ -9,10 +9,6 @@ namespace Impostor.Api { } - protected ImpostorException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } - public ImpostorException(string? message) : base(message) { } @@ -20,5 +16,9 @@ namespace Impostor.Api public ImpostorException(string? message, Exception? innerException) : base(message, innerException) { } + + protected ImpostorException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Exceptions/ImpostorProtocolException.cs b/src/Impostor.Api/Exceptions/ImpostorProtocolException.cs index 864602d0..513e590e 100644 --- a/src/Impostor.Api/Exceptions/ImpostorProtocolException.cs +++ b/src/Impostor.Api/Exceptions/ImpostorProtocolException.cs @@ -9,10 +9,6 @@ namespace Impostor.Api { } - protected ImpostorProtocolException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } - public ImpostorProtocolException(string? message) : base(message) { } @@ -20,5 +16,9 @@ namespace Impostor.Api public ImpostorProtocolException(string? message, Exception? innerException) : base(message, innerException) { } + + protected ImpostorProtocolException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } } } diff --git a/src/Impostor.Api/Extensions/SpanReaderExtensions.cs b/src/Impostor.Api/Extensions/SpanReaderExtensions.cs index c103ee7b..78e5a456 100644 --- a/src/Impostor.Api/Extensions/SpanReaderExtensions.cs +++ b/src/Impostor.Api/Extensions/SpanReaderExtensions.cs @@ -5,7 +5,7 @@ using System.Runtime.CompilerServices; namespace Impostor.Api { /// - /// Priovides a StreamReader-like api throught extensions + /// Priovides a StreamReader-like api throught extensions. /// public static class SpanReaderExtensions { @@ -53,11 +53,11 @@ namespace Impostor.Api } /// - /// Advances the position of by the size of . + /// Advances the position of by the size of . /// /// Type that will be read. /// input "stream"/span. - /// The original input + /// The original input. [MethodImpl(MethodImplOptions.AggressiveInlining)] private static unsafe ReadOnlySpan Advance(ref ReadOnlySpan input) where T : unmanaged @@ -67,4 +67,4 @@ namespace Impostor.Api return original; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Extensions/SystemTypesExtensions.cs b/src/Impostor.Api/Extensions/SystemTypesExtensions.cs index 68f1efda..4238b4d0 100644 --- a/src/Impostor.Api/Extensions/SystemTypesExtensions.cs +++ b/src/Impostor.Api/Extensions/SystemTypesExtensions.cs @@ -9,4 +9,4 @@ namespace Impostor.Api return SystemTypeHelpers.Names[(int)type]; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Games/Extensions/GameExtensions.cs b/src/Impostor.Api/Games/Extensions/GameExtensions.cs index a7369781..e30050f9 100644 --- a/src/Impostor.Api/Games/Extensions/GameExtensions.cs +++ b/src/Impostor.Api/Games/Extensions/GameExtensions.cs @@ -39,4 +39,4 @@ namespace Impostor.Api.Games return game.SendToAsync(writer, player.Client); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Games/Extensions/GameManagerExtensions.cs b/src/Impostor.Api/Games/Extensions/GameManagerExtensions.cs index 6a95b3d4..de9a0669 100644 --- a/src/Impostor.Api/Games/Extensions/GameManagerExtensions.cs +++ b/src/Impostor.Api/Games/Extensions/GameManagerExtensions.cs @@ -11,4 +11,4 @@ namespace Impostor.Api.Games return manager.Games.Count(game => map.HasFlag((MapFlags)(1 << (byte)game.Options.Map))); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Games/GameCode.cs b/src/Impostor.Api/Games/GameCode.cs index 2c30e7e9..e24c28a4 100644 --- a/src/Impostor.Api/Games/GameCode.cs +++ b/src/Impostor.Api/Games/GameCode.cs @@ -48,19 +48,19 @@ namespace Impostor.Api.Games public static GameCode From(string value) => new GameCode(value); - /// + /// public bool Equals(GameCode other) { return Code == other.Code && Value == other.Value; } - /// + /// public override bool Equals(object? obj) { return obj is GameCode other && Equals(other); } - /// + /// public override int GetHashCode() { return HashCode.Combine(Code, Value); @@ -71,4 +71,4 @@ namespace Impostor.Api.Games return Code; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Games/GameJoinError.cs b/src/Impostor.Api/Games/GameJoinError.cs index 4889ea96..7fcb0f94 100644 --- a/src/Impostor.Api/Games/GameJoinError.cs +++ b/src/Impostor.Api/Games/GameJoinError.cs @@ -41,8 +41,8 @@ /// Custom error by a plugin. /// /// - /// A custom message can be set in . + /// A custom message can be set in . /// Custom, } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Games/GameJoinResult.cs b/src/Impostor.Api/Games/GameJoinResult.cs index b33a2b66..4b25c8f3 100644 --- a/src/Impostor.Api/Games/GameJoinResult.cs +++ b/src/Impostor.Api/Games/GameJoinResult.cs @@ -45,4 +45,4 @@ namespace Impostor.Api.Games return new GameJoinResult(error); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Games/IGame.cs b/src/Impostor.Api/Games/IGame.cs index 57c3fcd2..ecc11f81 100644 --- a/src/Impostor.Api/Games/IGame.cs +++ b/src/Impostor.Api/Games/IGame.cs @@ -29,7 +29,7 @@ namespace Impostor.Api.Games bool IsPublic { get; } /// - /// Gets or sets display name on game list. + /// Gets or sets display name on game list. /// string? DisplayName { get; set; } @@ -37,34 +37,33 @@ namespace Impostor.Api.Games int HostId { get; } - IClientPlayer GetClientPlayer(int clientId); + IClientPlayer? GetClientPlayer(int clientId); T? FindObjectByNetId(uint netId) where T : IInnerNetObject; /// - /// Adds an to the ban list of this game. - /// Prevents all future joins from this . - /// - /// This does not kick the player with that from the lobby. + /// Adds an to the ban list of this game. + /// Prevents all future joins from this . + /// This does not kick the player with that from the lobby. /// /// - /// The to ban. + /// The to ban. /// void BanIp(IPAddress ipAddress); /// - /// Syncs the internal to all players. + /// Syncs the internal to all players. /// Necessary to do if you modified it, otherwise it won't be used. /// - /// A representing the asynchronous operation. + /// A representing the asynchronous operation. ValueTask SyncSettingsAsync(); /// /// Sets game's privacy. /// /// Privacy to set. - /// A representing the asynchronous operation. + /// A representing the asynchronous operation. ValueTask SetPrivacyAsync(bool isPublic); /// @@ -72,7 +71,7 @@ namespace Impostor.Api.Games /// /// Message to send. /// Required limbo state of the player. - /// A representing the asynchronous operation. + /// A representing the asynchronous operation. ValueTask SendToAllAsync(IMessageWriter writer, LimboStates states = LimboStates.NotLimbo); /// @@ -81,7 +80,7 @@ namespace Impostor.Api.Games /// Message to send. /// The player to exclude from sending the message. /// Required limbo state of the player. - /// A representing the asynchronous operation. + /// A representing the asynchronous operation. ValueTask SendToAllExceptAsync(IMessageWriter writer, int senderId, LimboStates states = LimboStates.NotLimbo); /// @@ -89,7 +88,7 @@ namespace Impostor.Api.Games /// /// Message to send. /// ID of the client. - /// A representing the asynchronous operation. + /// A representing the asynchronous operation. ValueTask SendToAsync(IMessageWriter writer, int id); } } diff --git a/src/Impostor.Api/Games/IGameCodeFactory.cs b/src/Impostor.Api/Games/IGameCodeFactory.cs index f264fe00..38f047fb 100644 --- a/src/Impostor.Api/Games/IGameCodeFactory.cs +++ b/src/Impostor.Api/Games/IGameCodeFactory.cs @@ -4,4 +4,4 @@ { GameCode Create(); } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Games/Managers/IGameManager.cs b/src/Impostor.Api/Games/Managers/IGameManager.cs index 7ee403fd..cdf8558c 100644 --- a/src/Impostor.Api/Games/Managers/IGameManager.cs +++ b/src/Impostor.Api/Games/Managers/IGameManager.cs @@ -12,4 +12,4 @@ namespace Impostor.Api.Games.Managers ValueTask CreateAsync(GameOptionsData options); } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Impostor.Api.csproj b/src/Impostor.Api/Impostor.Api.csproj index 188f2a67..4cd5e425 100644 --- a/src/Impostor.Api/Impostor.Api.csproj +++ b/src/Impostor.Api/Impostor.Api.csproj @@ -2,7 +2,7 @@ netstandard2.1 - ProjectRules.ruleset + ../ProjectRules.ruleset 9 true enable @@ -15,11 +15,17 @@ Impostor.Api Among Us;Impostor;Impostor Plugin https://raw.githubusercontent.com/Impostor/Impostor/dev/docs/images/logo_64.png + logo_64.png https://github.com/Impostor/Impostor git https://github.com/Impostor/Impostor + true + + + + @@ -33,4 +39,4 @@ - \ No newline at end of file + diff --git a/src/Impostor.Api/Innersloth/AlterGameTags.cs b/src/Impostor.Api/Innersloth/AlterGameTags.cs index 46d1b2ee..a1d9c425 100644 --- a/src/Impostor.Api/Innersloth/AlterGameTags.cs +++ b/src/Impostor.Api/Innersloth/AlterGameTags.cs @@ -4,4 +4,4 @@ { ChangePrivacy = 1, } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Innersloth/ChatNoteType.cs b/src/Impostor.Api/Innersloth/ChatNoteType.cs index c1636017..697b0311 100644 --- a/src/Impostor.Api/Innersloth/ChatNoteType.cs +++ b/src/Impostor.Api/Innersloth/ChatNoteType.cs @@ -4,4 +4,4 @@ { DidVote = 0, } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Innersloth/DeathReason.cs b/src/Impostor.Api/Innersloth/DeathReason.cs index a07ac056..8b8a430f 100644 --- a/src/Impostor.Api/Innersloth/DeathReason.cs +++ b/src/Impostor.Api/Innersloth/DeathReason.cs @@ -6,4 +6,4 @@ 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 index 9526f58b..21cdc944 100644 --- a/src/Impostor.Api/Innersloth/DisconnectReason.cs +++ b/src/Impostor.Api/Innersloth/DisconnectReason.cs @@ -3,52 +3,66 @@ public enum DisconnectReason { ExitGame = 0, + Destroy = 16, + // 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. + + // 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 + + // For this a message can be given, specifying an empty message shows // "An unknown error disconnected you from the server." - CustomMessage1 = 4, + // 4, 12, 13, 14, 15 also count as Custom 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 were banned from { GameCode ?? "the room" } // You cannot rejoin that room. - // You were banned Banned = 6, - // You can rejoin if the room hasn't started - // You were kicked + + // You were kicked from { GameCode ?? "the room" } + // You can rejoin if the room hasn't started. Kicked = 7, + // You were banned for hacking. // Please stop. Hacking = 10, - Destroy = 16, + + // GameModes.LocalGame: // You disconnected from the host. // If this happens often, check your WiFi strength. // + // GameModes.OnlineGame: // 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, + + // You may not join another game for another { BanMinutesLeft } minutes after intentionally disconnecting. IntentionalLeaving = 208, + + // You were disconnected because Among Us was suspended by another app. FocusLost = 209, + NewConnection = 210, } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Innersloth/GameCodeParser.cs b/src/Impostor.Api/Innersloth/GameCodeParser.cs index 9717cff2..f4743c56 100644 --- a/src/Impostor.Api/Innersloth/GameCodeParser.cs +++ b/src/Impostor.Api/Innersloth/GameCodeParser.cs @@ -9,36 +9,11 @@ namespace Impostor.Api.Innersloth public static class GameCodeParser { private const string V2 = "QWXRTYLPESDFGHUJKZOCVBINMA"; - private static readonly int[] V2Map = { - 25, - 21, - 19, - 10, - 8, - 11, - 12, - 13, - 22, - 15, - 16, - 6, - 24, - 23, - 18, - 7, - 0, - 3, - 9, - 4, - 14, - 20, - 1, - 2, - 5, - 17 - }; + + private static readonly int[] V2Map = Enumerable.Range(65, 26).Select(v => V2.IndexOf((char)v)).ToArray(); + private static readonly RNGCryptoServiceProvider Random = new RNGCryptoServiceProvider(); - + public static string IntToGameName(int input) { // V2. @@ -57,22 +32,6 @@ namespace Impostor.Api.Innersloth #endif } - private static string IntToGameNameV2(int input) - { - var a = input & 0x3FF; - var b = (input >> 10) & 0xFFFFF; - - return new string(new [] - { - V2[a % 26], - V2[a / 26], - V2[b % 26], - V2[b / 26 % 26], - V2[b / (26 * 26) % 26], - V2[b / (26 * 26 * 26) % 26] - }); - } - public static int GameNameToInt(string code) { var upper = code.ToUpperInvariant(); @@ -80,7 +39,7 @@ namespace Impostor.Api.Innersloth { return -1; } - + var len = code.Length; if (len == 6) { @@ -91,24 +50,9 @@ namespace Impostor.Api.Innersloth { return code[0] | ((code[1] | ((code[2] | (code[3] << 8)) << 8)) << 8); } - + return -1; } - - private static int GameNameToIntV2(string code) - { - var a = V2Map[code[0] - 65]; - var b = V2Map[code[1] - 65]; - var c = V2Map[code[2] - 65]; - var d = V2Map[code[3] - 65]; - var e = V2Map[code[4] - 65]; - var f = V2Map[code[5] - 65]; - - var one = (a + 26 * b) & 0x3FF; - var two = (c + 26 * (d + 26 * (e + 26 * f))); - - return (int) (one | ((two << 10) & 0x3FFFFC00) | 0x80000000); - } public static int GenerateCode(int len) { @@ -116,7 +60,7 @@ namespace Impostor.Api.Innersloth { throw new ArgumentException("should be 4 or 6", nameof(len)); } - + // Generate random bytes. #if NETSTANDARD2_0 var data = new byte[len]; @@ -124,7 +68,7 @@ namespace Impostor.Api.Innersloth Span data = stackalloc byte[len]; #endif Random.GetBytes(data); - + // Convert to their char representation. Span dataChar = stackalloc char[len]; for (var i = 0; i < len; i++) @@ -138,5 +82,36 @@ namespace Impostor.Api.Innersloth return GameNameToInt(new string(dataChar)); #endif } + + private static string IntToGameNameV2(int input) + { + var a = input & 0x3FF; + var b = (input >> 10) & 0xFFFFF; + + return new string(new[] + { + V2[a % 26], + V2[a / 26], + V2[b % 26], + V2[(b / 26) % 26], + V2[(b / (26 * 26)) % 26], + V2[(b / (26 * 26 * 26)) % 26], + }); + } + + private static int GameNameToIntV2(string code) + { + var a = V2Map[code[0] - 65]; + var b = V2Map[code[1] - 65]; + var c = V2Map[code[2] - 65]; + var d = V2Map[code[3] - 65]; + var e = V2Map[code[4] - 65]; + var f = V2Map[code[5] - 65]; + + var one = (a + (26 * b)) & 0x3FF; + var two = c + (26 * (d + (26 * (e + (26 * f))))); + + return (int)(one | ((two << 10) & 0x3FFFFC00) | 0x80000000); + } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Innersloth/GameKeywords.cs b/src/Impostor.Api/Innersloth/GameKeywords.cs index bbb463f7..4b3c6705 100644 --- a/src/Impostor.Api/Innersloth/GameKeywords.cs +++ b/src/Impostor.Api/Innersloth/GameKeywords.cs @@ -16,4 +16,4 @@ namespace Impostor.Api.Innersloth Polish = 128, English = 256, } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Innersloth/GameOptionsData.cs b/src/Impostor.Api/Innersloth/GameOptionsData.cs index 3d648445..5530c887 100644 --- a/src/Impostor.Api/Innersloth/GameOptionsData.cs +++ b/src/Impostor.Api/Innersloth/GameOptionsData.cs @@ -7,130 +7,130 @@ namespace Impostor.Api.Innersloth public class GameOptionsData { /// - /// The latest major version of the game client. + /// The latest major version of the game client. /// public const int LatestVersion = 4; /// - /// Gets or sets host's version of the game. + /// Gets or sets host's version of the game. /// public byte Version { get; set; } = LatestVersion; /// - /// Gets or sets the maximum amount of players for this lobby. + /// Gets or sets the maximum amount of players for this lobby. /// public byte MaxPlayers { get; set; } = 10; /// - /// Gets or sets the language of the lobby as per enum. + /// Gets or sets the language of the lobby as per enum. /// public GameKeywords Keywords { get; set; } = GameKeywords.English; /// - /// Gets or sets the Map selected for this lobby. + /// Gets or sets the Map selected for this lobby. /// public MapTypes Map { get; set; } = MapTypes.Skeld; /// - /// Gets or sets the Player speed modifier. + /// Gets or sets the Player speed modifier. /// public float PlayerSpeedMod { get; set; } = 1f; /// - /// Gets or sets the Light modifier for the players that are members of the crew as a multiplier value. + /// Gets or sets the Light modifier for the players that are members of the crew as a multiplier value. /// public float CrewLightMod { get; set; } = 1f; /// - /// Gets or sets the Light modifier for the players that are Impostors as a multiplier value. + /// Gets or sets the Light modifier for the players that are Impostors as a multiplier value. /// public float ImpostorLightMod { get; set; } = 1f; /// - /// Gets or sets the Impostor cooldown to kill in seconds. + /// Gets or sets the Impostor cooldown to kill in seconds. /// public float KillCooldown { get; set; } = 15f; /// - /// Gets or sets the number of common tasks. + /// Gets or sets the number of common tasks. /// public int NumCommonTasks { get; set; } = 1; /// - /// Gets or sets the number of long tasks. + /// Gets or sets the number of long tasks. /// public int NumLongTasks { get; set; } = 1; /// - /// Gets or sets the number of short tasks. + /// Gets or sets the number of short tasks. /// public int NumShortTasks { get; set; } = 2; /// - /// Gets or sets the maximum amount of emergency meetings each player can call during the game in seconds. + /// Gets or sets the maximum amount of emergency meetings each player can call during the game in seconds. /// public int NumEmergencyMeetings { get; set; } = 1; /// - /// Gets or sets the cooldown between each time any player can call an emergency meeting in seconds. + /// Gets or sets the cooldown between each time any player can call an emergency meeting in seconds. /// public int EmergencyCooldown { get; set; } = 15; /// - /// Gets or sets the number of impostors for this lobby. + /// Gets or sets the number of impostors for this lobby. /// public int NumImpostors { get; set; } = 1; /// - /// Gets or sets a value indicating whether ghosts (dead crew members) can do tasks. + /// Gets or sets a value indicating whether ghosts (dead crew members) can do tasks. /// public bool GhostsDoTasks { get; set; } = true; /// - /// Gets or sets the Kill as per values in . + /// Gets or sets the Kill as per values in . /// public KillDistances KillDistance { get; set; } = KillDistances.Normal; /// - /// Gets or sets the time for discussion before voting time in seconds. + /// Gets or sets the time for discussion before voting time in seconds. /// public int DiscussionTime { get; set; } = 15; /// - /// Gets or sets the time for voting in seconds. + /// Gets or sets the time for voting in seconds. /// public int VotingTime { get; set; } = 120; /// - /// Gets or sets a value indicating whether an ejected player is an impostor or not. + /// Gets or sets a value indicating whether an ejected player is an impostor or not. /// public bool ConfirmImpostor { get; set; } = true; /// - /// Gets or sets a value indicating whether players are able to see tasks being performed by other players. + /// Gets or sets a value indicating whether players are able to see tasks being performed by other players. /// /// - /// By being set to true, tasks such as Empty Garbage, Submit Scan, Clear asteroids, Prime shields execution will be visible to other players. + /// By being set to true, tasks such as Empty Garbage, Submit Scan, Clear asteroids, Prime shields execution will be visible to other players. /// public bool VisualTasks { get; set; } = true; /// - /// Gets or sets a value indicating whether the vote is anonymous. + /// Gets or sets a value indicating whether the vote is anonymous. /// public bool AnonymousVotes { get; set; } /// - /// Gets or sets the task bar update mode as per values in . + /// Gets or sets the task bar update mode as per values in . /// public TaskBarUpdate TaskBarUpdate { get; set; } = TaskBarUpdate.Always; /// - /// Gets or sets a value indicating whether the GameOptions are the default ones. + /// Gets or sets a value indicating whether the GameOptions are the default ones. /// public bool IsDefaults { get; set; } = true; /// - /// Deserialize a packet/message to a new GameOptionsData object. + /// Deserialize a packet/message to a new GameOptionsData object. /// /// Message reader object containing the raw message. /// GameOptionsData object. @@ -142,7 +142,7 @@ namespace Impostor.Api.Innersloth } /// - /// Serializes this instance of GameOptionsData object to a specified BinaryWriter. + /// Serializes this instance of GameOptionsData object to a specified BinaryWriter. /// /// The stream to write the message to. /// The version of the game. @@ -198,7 +198,7 @@ namespace Impostor.Api.Innersloth } /// - /// Deserialize a ReadOnlyMemory object to this instance of the GameOptionsData object. + /// Deserialize a ReadOnlyMemory object to this instance of the GameOptionsData object. /// /// Memory containing the message/packet. public void Deserialize(ReadOnlyMemory memory) diff --git a/src/Impostor.Api/Innersloth/GameOverReason.cs b/src/Impostor.Api/Innersloth/GameOverReason.cs index 6a95d374..5c30036c 100644 --- a/src/Impostor.Api/Innersloth/GameOverReason.cs +++ b/src/Impostor.Api/Innersloth/GameOverReason.cs @@ -7,9 +7,7 @@ ImpostorByVote = 2, ImpostorByKill = 3, ImpostorBySabotage = 4, - - // Unused (?) ImpostorDisconnect = 5, HumansDisconnect = 6, } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Innersloth/GameStates.cs b/src/Impostor.Api/Innersloth/GameStates.cs index f5aaa9cc..8e791de7 100644 --- a/src/Impostor.Api/Innersloth/GameStates.cs +++ b/src/Impostor.Api/Innersloth/GameStates.cs @@ -8,4 +8,4 @@ Ended = 3, Destroyed = 4, } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Innersloth/GameVersion.cs b/src/Impostor.Api/Innersloth/GameVersion.cs index c11933ee..50155895 100644 --- a/src/Impostor.Api/Innersloth/GameVersion.cs +++ b/src/Impostor.Api/Innersloth/GameVersion.cs @@ -7,4 +7,4 @@ namespace Impostor.Api.Innersloth return (year * 25000) + (month * 1800) + (day * 50) + rev; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Innersloth/MapFlags.cs b/src/Impostor.Api/Innersloth/MapFlags.cs index ad462a27..9b0d8f02 100644 --- a/src/Impostor.Api/Innersloth/MapFlags.cs +++ b/src/Impostor.Api/Innersloth/MapFlags.cs @@ -9,4 +9,4 @@ namespace Impostor.Api.Innersloth MiraHQ = 2, Polus = 4, } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Innersloth/MapTypes.cs b/src/Impostor.Api/Innersloth/MapTypes.cs index 2b5ede98..2706933a 100644 --- a/src/Impostor.Api/Innersloth/MapTypes.cs +++ b/src/Impostor.Api/Innersloth/MapTypes.cs @@ -6,4 +6,4 @@ MiraHQ = 1, Polus = 2, } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Innersloth/RegionInfo.cs b/src/Impostor.Api/Innersloth/RegionInfo.cs index c78978bd..51580db1 100644 --- a/src/Impostor.Api/Innersloth/RegionInfo.cs +++ b/src/Impostor.Api/Innersloth/RegionInfo.cs @@ -13,22 +13,11 @@ namespace Impostor.Api.Innersloth } public string Name { get; } + public string Ping { get; } + public IReadOnlyList Servers { get; } - public void Serialize(BinaryWriter writer) - { - writer.Write(0); - writer.Write(Name); - writer.Write(Ping); - writer.Write(Servers.Count); - - foreach (var server in Servers) - { - server.Serialize(writer); - } - } - public static RegionInfo Deserialize(BinaryReader reader) { var unknown = reader.ReadInt32(); @@ -44,5 +33,18 @@ namespace Impostor.Api.Innersloth return new RegionInfo(name, ping, servers); } + + public void Serialize(BinaryWriter writer) + { + writer.Write(0); + writer.Write(Name); + writer.Write(Ping); + writer.Write(Servers.Count); + + foreach (var server in Servers) + { + server.Serialize(writer); + } + } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Innersloth/ServerInfo.cs b/src/Impostor.Api/Innersloth/ServerInfo.cs index 77858234..21ba1ea7 100644 --- a/src/Impostor.Api/Innersloth/ServerInfo.cs +++ b/src/Impostor.Api/Innersloth/ServerInfo.cs @@ -5,24 +5,18 @@ namespace Impostor.Api.Innersloth { public class ServerInfo { - public string Name { get; } - public string Ip { get; } - public ushort Port { get; } - public ServerInfo(string name, string ip, ushort port) { Name = name; Ip = ip; Port = port; } - - public void Serialize(BinaryWriter writer) - { - writer.Write(Name); - writer.Write(IPAddress.Parse(Ip).GetAddressBytes()); - writer.Write(Port); - writer.Write(0); - } + + public string Name { get; } + + public string Ip { get; } + + public ushort Port { get; } public static ServerInfo Deserialize(BinaryReader reader) { @@ -30,8 +24,16 @@ namespace Impostor.Api.Innersloth var ip = new IPAddress(reader.ReadBytes(4)).ToString(); var port = reader.ReadUInt16(); var unknown = reader.ReadInt32(); - + return new ServerInfo(name, ip, port); } + + public void Serialize(BinaryWriter writer) + { + writer.Write(Name); + writer.Write(IPAddress.Parse(Ip).GetAddressBytes()); + writer.Write(Port); + writer.Write(0); + } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Innersloth/SystemTypeHelpers.cs b/src/Impostor.Api/Innersloth/SystemTypeHelpers.cs index ad88c28a..e9ba29be 100644 --- a/src/Impostor.Api/Innersloth/SystemTypeHelpers.cs +++ b/src/Impostor.Api/Innersloth/SystemTypeHelpers.cs @@ -20,9 +20,9 @@ namespace Impostor.Api.Innersloth SystemTypes.LifeSupp => "O2", SystemTypes.LowerEngine => "Lower Engine", SystemTypes.LockerRoom => "Locker Room", - _ => x.ToString() + _ => 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 index 7f91718b..6a072e77 100644 --- a/src/Impostor.Api/Innersloth/SystemTypes.cs +++ b/src/Impostor.Api/Innersloth/SystemTypes.cs @@ -3,40 +3,69 @@ public enum SystemTypes : byte { Hallway = 0, + Storage = 1, + Cafeteria = 2, + Reactor = 3, + UpperEngine = 4, + Nav = 5, + Admin = 6, + Electrical = 7, + LifeSupp = 8, + Shields = 9, + MedBay = 10, + Security = 11, + Weapons = 12, + LowerEngine = 13, + Comms = 14, + ShipTasks = 15, + Doors = 16, + Sabotage = 17, + /// - /// Decontam on Mira and bottom decontam on Polus + /// Decontam on Mira and bottom decontam on Polus /// Decontamination = 18, + Launchpad = 19, + LockerRoom = 20, + Laboratory = 21, + Balcony = 22, + Office = 23, + Greenhouse = 24, + Dropship = 25, + /// - /// Top decontam on Polus + /// Top decontam on Polus /// Decontamination2 = 26, + Outside = 27, + Specimens = 28, - BoilerRoom = 29 + + BoilerRoom = 29, } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Innersloth/TaskBarUpdate.cs b/src/Impostor.Api/Innersloth/TaskBarUpdate.cs index f4d7c1f6..ea9a5fc5 100644 --- a/src/Impostor.Api/Innersloth/TaskBarUpdate.cs +++ b/src/Impostor.Api/Innersloth/TaskBarUpdate.cs @@ -4,6 +4,6 @@ { Always = 0, Meetings = 1, - Never = 2 + Never = 2, } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Innersloth/TaskTypes.cs b/src/Impostor.Api/Innersloth/TaskTypes.cs index 8b15354a..d4794796 100644 --- a/src/Impostor.Api/Innersloth/TaskTypes.cs +++ b/src/Impostor.Api/Innersloth/TaskTypes.cs @@ -46,4 +46,4 @@ RecordTemperature = 41, RebootWifi = 42, } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Innersloth/TextBox.cs b/src/Impostor.Api/Innersloth/TextBox.cs index 9533d83a..1928ce28 100644 --- a/src/Impostor.Api/Innersloth/TextBox.cs +++ b/src/Impostor.Api/Innersloth/TextBox.cs @@ -7,4 +7,4 @@ return i == ' ' || (i >= 'A' && i <= 'Z') || (i >= 'a' && i <= 'z') || (i >= '0' && i <= '9') || (i >= 'À' && i <= 'ÿ') || (i >= 'Ѐ' && i <= 'џ') || (i >= 'ㄱ' && i <= 'ㆎ') || (i >= '가' && i <= '힣'); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Net/IClient.cs b/src/Impostor.Api/Net/IClient.cs index 1ba59447..d9631d7d 100644 --- a/src/Impostor.Api/Net/IClient.cs +++ b/src/Impostor.Api/Net/IClient.cs @@ -29,7 +29,7 @@ namespace Impostor.Api.Net string Name { get; } /// - /// Gets mods sent by client in modded handshake. + /// Gets mods sent by client in modded handshake. /// ISet Mods { get; } @@ -57,7 +57,7 @@ namespace Impostor.Api.Net IDictionary Items { get; } /// - /// Gets or sets the current game data of the . + /// Gets the current game data of the . /// IClientPlayer? Player { get; } @@ -68,16 +68,16 @@ namespace Impostor.Api.Net ValueTask HandleDisconnectAsync(string reason); /// - /// Disconnect the client with a . + /// Disconnect the client with a . /// /// /// The message to show to the player. /// /// - /// Only used when is set to . + /// Only used when is set to . /// /// - /// A representing the asynchronous operation. + /// A representing the asynchronous operation. /// ValueTask DisconnectAsync(DisconnectReason reason, string? message = null); } diff --git a/src/Impostor.Api/Net/IClientPlayer.cs b/src/Impostor.Api/Net/IClientPlayer.cs index 60702101..f11c8737 100644 --- a/src/Impostor.Api/Net/IClientPlayer.cs +++ b/src/Impostor.Api/Net/IClientPlayer.cs @@ -6,7 +6,7 @@ using Impostor.Api.Net.Inner.Objects; namespace Impostor.Api.Net { /// - /// Represents a player in . + /// Represents a player in . /// public interface IClientPlayer { @@ -16,7 +16,7 @@ namespace Impostor.Api.Net IClient Client { get; } /// - /// Gets the game where the belongs to. + /// Gets the game where the belongs to. /// IGame Game { get; } @@ -30,10 +30,10 @@ namespace Impostor.Api.Net public bool IsHost { get; } /// - /// Checks if the specified is owned by . + /// Checks if the specified is owned by . /// - /// The . - /// Returns true if owned by . + /// The . + /// Returns true if owned by . bool IsOwner(IInnerNetObject netObject); ValueTask KickAsync(); diff --git a/src/Impostor.Api/Net/IConnection.cs b/src/Impostor.Api/Net/IConnection.cs index 94f9b8be..fa998414 100644 --- a/src/Impostor.Api/Net/IConnection.cs +++ b/src/Impostor.Api/Net/IConnection.cs @@ -2,6 +2,5 @@ { public interface IConnection { - } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Net/IHazelConnection.cs b/src/Impostor.Api/Net/IHazelConnection.cs index 4e6c4b3f..e2a9cfbf 100644 --- a/src/Impostor.Api/Net/IHazelConnection.cs +++ b/src/Impostor.Api/Net/IHazelConnection.cs @@ -20,7 +20,7 @@ namespace Impostor.Api.Net bool IsConnected { get; } /// - /// Gets the client of the connection. + /// Gets or sets the client of the connection. /// IClient? Client { get; set; } @@ -28,14 +28,14 @@ namespace Impostor.Api.Net /// Sends a message writer to the connection. /// /// The message. - /// + /// Task that must be awaited. ValueTask SendAsync(IMessageWriter writer); /// /// Disconnects the client and invokes the disconnect handler. /// /// A reason. - /// + /// Task that must be awaited. ValueTask DisconnectAsync(string? reason); } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Net/Inner/IGameNet.cs b/src/Impostor.Api/Net/Inner/IGameNet.cs index 933a4de6..9cac0f2d 100644 --- a/src/Impostor.Api/Net/Inner/IGameNet.cs +++ b/src/Impostor.Api/Net/Inner/IGameNet.cs @@ -7,12 +7,12 @@ namespace Impostor.Api.Net.Inner /// public interface IGameNet { - IInnerLobbyBehaviour LobbyBehaviour { get; } + IInnerLobbyBehaviour? LobbyBehaviour { get; } - IInnerGameData GameData { get; } + IInnerGameData? GameData { get; } - IInnerVoteBanSystem VoteBan { get; } + IInnerVoteBanSystem? VoteBan { get; } - IInnerShipStatus ShipStatus { 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 index c1713779..8cfadb8e 100644 --- a/src/Impostor.Api/Net/Inner/IInnerNetObject.cs +++ b/src/Impostor.Api/Net/Inner/IInnerNetObject.cs @@ -6,4 +6,4 @@ public int OwnerId { get; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Net/Inner/Objects/Components/IInnerCustomNetworkTransform.cs b/src/Impostor.Api/Net/Inner/Objects/Components/IInnerCustomNetworkTransform.cs index 2dd47094..5ad4763c 100644 --- a/src/Impostor.Api/Net/Inner/Objects/Components/IInnerCustomNetworkTransform.cs +++ b/src/Impostor.Api/Net/Inner/Objects/Components/IInnerCustomNetworkTransform.cs @@ -16,7 +16,7 @@ namespace Impostor.Api.Net.Inner.Objects.Components Vector2 Velocity { get; } /// - /// Snaps the current to the given position . + /// Snaps the current to the given position . /// /// The target position. /// Task that must be awaited. diff --git a/src/Impostor.Api/Net/Inner/Objects/IInnerPlayerControl.cs b/src/Impostor.Api/Net/Inner/Objects/IInnerPlayerControl.cs index 0ee065ad..711f878b 100644 --- a/src/Impostor.Api/Net/Inner/Objects/IInnerPlayerControl.cs +++ b/src/Impostor.Api/Net/Inner/Objects/IInnerPlayerControl.cs @@ -7,30 +7,30 @@ namespace Impostor.Api.Net.Inner.Objects public interface IInnerPlayerControl : IInnerNetObject { /// - /// Gets the assigned by the client of the host of the game. + /// Gets the assigned by the client of the host of the game. /// byte PlayerId { get; } /// - /// Gets the of the . + /// Gets the of the . /// Contains vent logic. /// IInnerPlayerPhysics Physics { get; } /// - /// Gets the of the . + /// Gets the of the . /// Contains position data about the player. /// IInnerCustomNetworkTransform NetworkTransform { get; } /// - /// Gets the of the . + /// Gets the of the . /// Contains metadata about the player. /// IInnerPlayerInfo PlayerInfo { get; } /// - /// Sets the name of the current . + /// Sets the name of the current . /// Visible to all players. /// /// A name for the player. @@ -38,7 +38,7 @@ namespace Impostor.Api.Net.Inner.Objects ValueTask SetNameAsync(string name); /// - /// Sets the color of the current . + /// Sets the color of the current . /// Visible to all players. /// /// A color for the player. @@ -46,7 +46,7 @@ namespace Impostor.Api.Net.Inner.Objects ValueTask SetColorAsync(ColorType colorType); /// - /// Sets the hat of the current . + /// Sets the hat of the current . /// Visible to all players. /// /// An hat for the player. @@ -54,7 +54,7 @@ namespace Impostor.Api.Net.Inner.Objects ValueTask SetHatAsync(HatType hatType); /// - /// Sets the pet of the current . + /// Sets the pet of the current . /// Visible to all players. /// /// A pet for the player. @@ -62,7 +62,7 @@ namespace Impostor.Api.Net.Inner.Objects ValueTask SetPetAsync(PetType petType); /// - /// Sets the skin of the current . + /// Sets the skin of the current . /// Visible to all players. /// /// A skin for the player. @@ -70,7 +70,7 @@ namespace Impostor.Api.Net.Inner.Objects ValueTask SetSkinAsync(SkinType skinType); /// - /// Send a chat message as the current . + /// Send a chat message as the current . /// Visible to all players. /// /// The message to send. @@ -78,7 +78,7 @@ namespace Impostor.Api.Net.Inner.Objects ValueTask SendChatAsync(string text); /// - /// Send a chat message as the current . + /// Send a chat message as the current . /// Visible to only the current. /// /// The message to send. @@ -90,7 +90,7 @@ namespace Impostor.Api.Net.Inner.Objects ValueTask SendChatToPlayerAsync(string text, IInnerPlayerControl? player = null); /// - /// Murder player. + /// Murder player. /// /// Target player to murder. /// Thrown when player is not the impostor. diff --git a/src/Impostor.Api/Net/Inner/Objects/IInnerShipStatus.cs b/src/Impostor.Api/Net/Inner/Objects/IInnerShipStatus.cs index c0a05aea..79b9f964 100644 --- a/src/Impostor.Api/Net/Inner/Objects/IInnerShipStatus.cs +++ b/src/Impostor.Api/Net/Inner/Objects/IInnerShipStatus.cs @@ -2,6 +2,5 @@ { 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 index d0a816dc..8d8b4ac6 100644 --- a/src/Impostor.Api/Net/Inner/Objects/IInnerVoteBanSystem.cs +++ b/src/Impostor.Api/Net/Inner/Objects/IInnerVoteBanSystem.cs @@ -2,6 +2,5 @@ { public interface IInnerVoteBanSystem : IInnerNetObject { - } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Net/Inner/Objects/ITaskInfo.cs b/src/Impostor.Api/Net/Inner/Objects/ITaskInfo.cs index 2b6dd86f..f4e54b15 100644 --- a/src/Impostor.Api/Net/Inner/Objects/ITaskInfo.cs +++ b/src/Impostor.Api/Net/Inner/Objects/ITaskInfo.cs @@ -1,5 +1,4 @@ using Impostor.Api.Innersloth; -using Impostor.Api.Net.Messages; namespace Impostor.Api.Net.Inner.Objects { diff --git a/src/Impostor.Api/Net/Inner/RpcCalls.cs b/src/Impostor.Api/Net/Inner/RpcCalls.cs index f82d2e89..e75f80ec 100644 --- a/src/Impostor.Api/Net/Inner/RpcCalls.cs +++ b/src/Impostor.Api/Net/Inner/RpcCalls.cs @@ -33,6 +33,6 @@ RepairSystem = 28, SetTasks = 29, UpdateGameData = 30, - CustomRpc = byte.MaxValue + CustomRpc = byte.MaxValue, } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Net/LimboStates.cs b/src/Impostor.Api/Net/LimboStates.cs index 44c493e8..5d1242d4 100644 --- a/src/Impostor.Api/Net/LimboStates.cs +++ b/src/Impostor.Api/Net/LimboStates.cs @@ -10,4 +10,4 @@ namespace Impostor.Api.Net WaitingForHost = 4, All = PreSpawn | NotLimbo | WaitingForHost, } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Net/Manager/IClientManager.cs b/src/Impostor.Api/Net/Manager/IClientManager.cs index 92bf89f0..737e42f3 100644 --- a/src/Impostor.Api/Net/Manager/IClientManager.cs +++ b/src/Impostor.Api/Net/Manager/IClientManager.cs @@ -6,4 +6,4 @@ namespace Impostor.Api.Net.Manager { IEnumerable Clients { get; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Net/Messages/C2S/Message00HostGameC2S.cs b/src/Impostor.Api/Net/Messages/C2S/Message00HostGameC2S.cs index 7d7ee558..e81e861f 100644 --- a/src/Impostor.Api/Net/Messages/C2S/Message00HostGameC2S.cs +++ b/src/Impostor.Api/Net/Messages/C2S/Message00HostGameC2S.cs @@ -14,9 +14,9 @@ namespace Impostor.Api.Net.Messages.C2S /// /// Deserialize a packet. /// - /// with 0. + /// with 0. /// The chat type selected in the client of the player. - /// Deserialized . + /// Deserialized . public static GameOptionsData Deserialize(IMessageReader reader, out ChatType chatType) { var gameOptionsData = GameOptionsData.DeserializeCreate(reader); diff --git a/src/Impostor.Api/Net/Messages/C2S/Message01JoinGameC2S.cs b/src/Impostor.Api/Net/Messages/C2S/Message01JoinGameC2S.cs index 58a85120..e7771e7c 100644 --- a/src/Impostor.Api/Net/Messages/C2S/Message01JoinGameC2S.cs +++ b/src/Impostor.Api/Net/Messages/C2S/Message01JoinGameC2S.cs @@ -1,4 +1,5 @@ -using Impostor.Api.Games; +using System; +using Impostor.Api.Games; namespace Impostor.Api.Net.Messages.C2S { @@ -6,7 +7,7 @@ namespace Impostor.Api.Net.Messages.C2S { public static void Serialize(IMessageWriter writer) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } public static void Deserialize(IMessageReader reader, out GameCode gameCode) diff --git a/src/Impostor.Api/Net/Messages/C2S/Message04RemovePlayerC2S.cs b/src/Impostor.Api/Net/Messages/C2S/Message04RemovePlayerC2S.cs index 99cdcfa7..a3bcedfc 100644 --- a/src/Impostor.Api/Net/Messages/C2S/Message04RemovePlayerC2S.cs +++ b/src/Impostor.Api/Net/Messages/C2S/Message04RemovePlayerC2S.cs @@ -1,10 +1,12 @@ -namespace Impostor.Api.Net.Messages.C2S +using System; + +namespace Impostor.Api.Net.Messages.C2S { public class Message04RemovePlayerC2S { public static void Serialize(IMessageWriter writer) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } public static void Deserialize(IMessageReader reader, out int playerId, out byte reason) @@ -13,4 +15,4 @@ reason = reader.ReadByte(); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Net/Messages/C2S/Message08EndGameC2S.cs b/src/Impostor.Api/Net/Messages/C2S/Message08EndGameC2S.cs index 7ca5e3a6..d264294c 100644 --- a/src/Impostor.Api/Net/Messages/C2S/Message08EndGameC2S.cs +++ b/src/Impostor.Api/Net/Messages/C2S/Message08EndGameC2S.cs @@ -1,4 +1,5 @@ -using Impostor.Api.Innersloth; +using System; +using Impostor.Api.Innersloth; namespace Impostor.Api.Net.Messages.C2S { @@ -6,7 +7,7 @@ namespace Impostor.Api.Net.Messages.C2S { public static void Serialize(IMessageWriter writer) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } public static void Deserialize(IMessageReader reader, out GameOverReason gameOverReason) @@ -15,4 +16,4 @@ namespace Impostor.Api.Net.Messages.C2S reader.ReadBoolean(); // showAd } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Net/Messages/C2S/Message10AlterGameC2S.cs b/src/Impostor.Api/Net/Messages/C2S/Message10AlterGameC2S.cs index 330f3b5b..57db6690 100644 --- a/src/Impostor.Api/Net/Messages/C2S/Message10AlterGameC2S.cs +++ b/src/Impostor.Api/Net/Messages/C2S/Message10AlterGameC2S.cs @@ -1,4 +1,5 @@ -using Impostor.Api.Innersloth; +using System; +using Impostor.Api.Innersloth; namespace Impostor.Api.Net.Messages.C2S { @@ -6,7 +7,7 @@ namespace Impostor.Api.Net.Messages.C2S { public static void Serialize(IMessageWriter writer) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } public static void Deserialize(IMessageReader reader, out AlterGameTags gameTag, out bool isPublic) @@ -17,4 +18,4 @@ namespace Impostor.Api.Net.Messages.C2S isPublic = slice.ReadBoolean(); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Net/Messages/C2S/Message11KickPlayerC2S.cs b/src/Impostor.Api/Net/Messages/C2S/Message11KickPlayerC2S.cs index 7c5b8b98..acafcee0 100644 --- a/src/Impostor.Api/Net/Messages/C2S/Message11KickPlayerC2S.cs +++ b/src/Impostor.Api/Net/Messages/C2S/Message11KickPlayerC2S.cs @@ -1,10 +1,12 @@ -namespace Impostor.Api.Net.Messages.C2S +using System; + +namespace Impostor.Api.Net.Messages.C2S { public class Message11KickPlayerC2S { public static void Serialize(IMessageWriter writer) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } public static void Deserialize(IMessageReader reader, out int playerId, out bool isBan) @@ -13,4 +15,4 @@ isBan = reader.ReadBoolean(); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Net/Messages/C2S/Message16GetGameListC2S.cs b/src/Impostor.Api/Net/Messages/C2S/Message16GetGameListC2S.cs index bc32d5ee..72be48d7 100644 --- a/src/Impostor.Api/Net/Messages/C2S/Message16GetGameListC2S.cs +++ b/src/Impostor.Api/Net/Messages/C2S/Message16GetGameListC2S.cs @@ -1,4 +1,5 @@ -using Impostor.Api.Innersloth; +using System; +using Impostor.Api.Innersloth; namespace Impostor.Api.Net.Messages.C2S { @@ -6,7 +7,7 @@ namespace Impostor.Api.Net.Messages.C2S { public static void Serialize(IMessageWriter writer) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } public static void Deserialize(IMessageReader reader, out GameOptionsData options, out ChatType chatType) diff --git a/src/Impostor.Api/Net/Messages/IMessageReader.cs b/src/Impostor.Api/Net/Messages/IMessageReader.cs index 1eb82d1f..397ad5ad 100644 --- a/src/Impostor.Api/Net/Messages/IMessageReader.cs +++ b/src/Impostor.Api/Net/Messages/IMessageReader.cs @@ -18,7 +18,7 @@ namespace Impostor.Api.Net.Messages byte[] Buffer { get; } /// - /// Gets the offset of our current in the entire . + /// Gets the offset of our current in the entire . /// int Offset { get; } diff --git a/src/Impostor.Api/Net/Messages/IMessageWriter.cs b/src/Impostor.Api/Net/Messages/IMessageWriter.cs index 0f4b7fad..fd500adc 100644 --- a/src/Impostor.Api/Net/Messages/IMessageWriter.cs +++ b/src/Impostor.Api/Net/Messages/IMessageWriter.cs @@ -74,7 +74,7 @@ namespace Impostor.Api.Net.Messages void Write(string value); /// - /// Writes a to the message. + /// Writes a to the message. /// /// Value to write. void Write(IPAddress value); diff --git a/src/Impostor.Api/Net/Messages/IMessageWriterProvider.cs b/src/Impostor.Api/Net/Messages/IMessageWriterProvider.cs index f3989393..16a48ecf 100644 --- a/src/Impostor.Api/Net/Messages/IMessageWriterProvider.cs +++ b/src/Impostor.Api/Net/Messages/IMessageWriterProvider.cs @@ -3,14 +3,14 @@ public interface IMessageWriterProvider { /// - /// Retrieves a from the internal pool. - /// Make sure to call when you are done! + /// Retrieves a from the internal pool. + /// Make sure to call when you are done!. /// /// - /// Whether to send the message as or . + /// Whether to send the message as or . /// Reliable packets will ensure delivery while unreliable packets may be lost. /// - /// A from the pool. + /// A from the pool. IMessageWriter Get(MessageType sendOption = MessageType.Unreliable); } } diff --git a/src/Impostor.Api/Net/Messages/MessageFlags.cs b/src/Impostor.Api/Net/Messages/MessageFlags.cs index aea0c60d..2ebf475d 100644 --- a/src/Impostor.Api/Net/Messages/MessageFlags.cs +++ b/src/Impostor.Api/Net/Messages/MessageFlags.cs @@ -19,4 +19,4 @@ public const byte GetGameList = 9; public const byte GetGameListV2 = 16; } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Net/Messages/MessageType.cs b/src/Impostor.Api/Net/Messages/MessageType.cs index 16043585..50acb524 100644 --- a/src/Impostor.Api/Net/Messages/MessageType.cs +++ b/src/Impostor.Api/Net/Messages/MessageType.cs @@ -29,4 +29,4 @@ namespace Impostor.Api.Net.Messages /// Reliable, } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Net/Messages/S2C/Message00HostGameS2C.cs b/src/Impostor.Api/Net/Messages/S2C/Message00HostGameS2C.cs index 8402d100..8fef2251 100644 --- a/src/Impostor.Api/Net/Messages/S2C/Message00HostGameS2C.cs +++ b/src/Impostor.Api/Net/Messages/S2C/Message00HostGameS2C.cs @@ -17,4 +17,4 @@ namespace Impostor.Api.Net.Messages.S2C throw new NotImplementedException(); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Net/Messages/S2C/Message01JoinGameS2C.cs b/src/Impostor.Api/Net/Messages/S2C/Message01JoinGameS2C.cs index c4552010..74fdc405 100644 --- a/src/Impostor.Api/Net/Messages/S2C/Message01JoinGameS2C.cs +++ b/src/Impostor.Api/Net/Messages/S2C/Message01JoinGameS2C.cs @@ -44,7 +44,7 @@ namespace Impostor.Api.Net.Messages.S2C public static void Deserialize(IMessageReader reader) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Net/Messages/S2C/Message04RemovePlayerS2C.cs b/src/Impostor.Api/Net/Messages/S2C/Message04RemovePlayerS2C.cs index 77b447d0..bcdca048 100644 --- a/src/Impostor.Api/Net/Messages/S2C/Message04RemovePlayerS2C.cs +++ b/src/Impostor.Api/Net/Messages/S2C/Message04RemovePlayerS2C.cs @@ -1,4 +1,5 @@ -using Impostor.Api.Innersloth; +using System; +using Impostor.Api.Innersloth; namespace Impostor.Api.Net.Messages.S2C { @@ -23,7 +24,7 @@ namespace Impostor.Api.Net.Messages.S2C public static void Deserialize(IMessageReader reader) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Net/Messages/S2C/Message07JoinedGameS2C.cs b/src/Impostor.Api/Net/Messages/S2C/Message07JoinedGameS2C.cs index da6eb40c..857fea1b 100644 --- a/src/Impostor.Api/Net/Messages/S2C/Message07JoinedGameS2C.cs +++ b/src/Impostor.Api/Net/Messages/S2C/Message07JoinedGameS2C.cs @@ -1,4 +1,6 @@ -namespace Impostor.Api.Net.Messages.S2C +using System; + +namespace Impostor.Api.Net.Messages.S2C { public static class Message07JoinedGameS2C { @@ -25,7 +27,7 @@ public static void Deserialize(IMessageReader reader) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Net/Messages/S2C/Message10AlterGameS2C.cs b/src/Impostor.Api/Net/Messages/S2C/Message10AlterGameS2C.cs index fa155dfa..40c949d3 100644 --- a/src/Impostor.Api/Net/Messages/S2C/Message10AlterGameS2C.cs +++ b/src/Impostor.Api/Net/Messages/S2C/Message10AlterGameS2C.cs @@ -1,4 +1,5 @@ -using Impostor.Api.Innersloth; +using System; +using Impostor.Api.Innersloth; namespace Impostor.Api.Net.Messages.S2C { @@ -20,7 +21,7 @@ namespace Impostor.Api.Net.Messages.S2C public static void Deserialize(IMessageReader reader) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Net/Messages/S2C/Message11KickPlayerS2C.cs b/src/Impostor.Api/Net/Messages/S2C/Message11KickPlayerS2C.cs index 1e2b6efc..7ffdb7b5 100644 --- a/src/Impostor.Api/Net/Messages/S2C/Message11KickPlayerS2C.cs +++ b/src/Impostor.Api/Net/Messages/S2C/Message11KickPlayerS2C.cs @@ -1,4 +1,6 @@ -namespace Impostor.Api.Net.Messages.S2C +using System; + +namespace Impostor.Api.Net.Messages.S2C { public class Message11KickPlayerS2C { @@ -18,7 +20,7 @@ public static void Deserialize(IMessageReader reader) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Net/Messages/S2C/Message12WaitForHostS2C.cs b/src/Impostor.Api/Net/Messages/S2C/Message12WaitForHostS2C.cs index 5964b1c5..8cf9046f 100644 --- a/src/Impostor.Api/Net/Messages/S2C/Message12WaitForHostS2C.cs +++ b/src/Impostor.Api/Net/Messages/S2C/Message12WaitForHostS2C.cs @@ -1,4 +1,6 @@ -namespace Impostor.Api.Net.Messages.S2C +using System; + +namespace Impostor.Api.Net.Messages.S2C { public class Message12WaitForHostS2C { @@ -17,7 +19,7 @@ public static void Deserialize(IMessageReader reader) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Net/Messages/S2C/Message13RedirectS2C.cs b/src/Impostor.Api/Net/Messages/S2C/Message13RedirectS2C.cs index 4b93b0ee..0576c71d 100644 --- a/src/Impostor.Api/Net/Messages/S2C/Message13RedirectS2C.cs +++ b/src/Impostor.Api/Net/Messages/S2C/Message13RedirectS2C.cs @@ -1,4 +1,5 @@ -using System.Net; +using System; +using System.Net; namespace Impostor.Api.Net.Messages.S2C { @@ -19,7 +20,7 @@ namespace Impostor.Api.Net.Messages.S2C public static void Deserialize(IMessageReader reader) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Net/Messages/S2C/Message16GetGameListS2C.cs b/src/Impostor.Api/Net/Messages/S2C/Message16GetGameListS2C.cs index 7b641929..a09259ba 100644 --- a/src/Impostor.Api/Net/Messages/S2C/Message16GetGameListS2C.cs +++ b/src/Impostor.Api/Net/Messages/S2C/Message16GetGameListS2C.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Impostor.Api.Games; namespace Impostor.Api.Net.Messages.S2C @@ -33,7 +34,7 @@ namespace Impostor.Api.Net.Messages.S2C public static void Deserialize(IMessageReader reader) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } } } diff --git a/src/Impostor.Api/Plugins/IPlugin.cs b/src/Impostor.Api/Plugins/IPlugin.cs index fd0f38f0..9f1efcf5 100644 --- a/src/Impostor.Api/Plugins/IPlugin.cs +++ b/src/Impostor.Api/Plugins/IPlugin.cs @@ -11,4 +11,4 @@ namespace Impostor.Api.Plugins ValueTask ReloadAsync(); } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Plugins/IPluginStartup.cs b/src/Impostor.Api/Plugins/IPluginStartup.cs index aa6a35f8..e9d85857 100644 --- a/src/Impostor.Api/Plugins/IPluginStartup.cs +++ b/src/Impostor.Api/Plugins/IPluginStartup.cs @@ -9,4 +9,4 @@ namespace Impostor.Api.Plugins void ConfigureServices(IServiceCollection services); } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Plugins/ImpostorPluginAttribute.cs b/src/Impostor.Api/Plugins/ImpostorPluginAttribute.cs index b31bd478..e2d6b024 100644 --- a/src/Impostor.Api/Plugins/ImpostorPluginAttribute.cs +++ b/src/Impostor.Api/Plugins/ImpostorPluginAttribute.cs @@ -21,4 +21,4 @@ namespace Impostor.Api.Plugins public string Version { get; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/Plugins/PluginBase.cs b/src/Impostor.Api/Plugins/PluginBase.cs index 03843638..9d6f2b4f 100644 --- a/src/Impostor.Api/Plugins/PluginBase.cs +++ b/src/Impostor.Api/Plugins/PluginBase.cs @@ -19,4 +19,4 @@ namespace Impostor.Api.Plugins return default; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Api/ProjectRules.ruleset b/src/Impostor.Api/ProjectRules.ruleset deleted file mode 100644 index 51021f56..00000000 --- a/src/Impostor.Api/ProjectRules.ruleset +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Impostor.Api/Properties/AssemblyInfo.cs b/src/Impostor.Api/Properties/AssemblyInfo.cs index c02e44af..30143b8f 100644 --- a/src/Impostor.Api/Properties/AssemblyInfo.cs +++ b/src/Impostor.Api/Properties/AssemblyInfo.cs @@ -1,3 +1,3 @@ using System.Runtime.CompilerServices; -[assembly:InternalsVisibleTo("Impostor.Server")] \ No newline at end of file +[assembly: InternalsVisibleTo("Impostor.Server")] diff --git a/src/Impostor.Api/Reactor/PluginSide.cs b/src/Impostor.Api/Reactor/PluginSide.cs index 30c588c7..4523dfc6 100644 --- a/src/Impostor.Api/Reactor/PluginSide.cs +++ b/src/Impostor.Api/Reactor/PluginSide.cs @@ -1,22 +1,22 @@ namespace Impostor.Api.Reactor { /// - /// Plugin side used in modded handshake + /// Plugin side used in modded handshake. /// public enum PluginSide : byte { /// - /// Required by both sides, reject connection if missing on the other side + /// Required by both sides, reject connection if missing on the other side /// Both, /// - /// Required only by client + /// Required only by client /// ClientOnly, /// - /// Required only by server + /// Required only by server /// ServerOnly, } diff --git a/src/Impostor.Api/Unity/Mathf.cs b/src/Impostor.Api/Unity/Mathf.cs index c907f816..5ab93c74 100644 --- a/src/Impostor.Api/Unity/Mathf.cs +++ b/src/Impostor.Api/Unity/Mathf.cs @@ -3,13 +3,13 @@ public static class Mathf { /// - /// Clamps the given value between the given minimum float and maximum float values. Returns the given value if it is within the min and max range. + /// Clamps the given value between the given minimum float and maximum float values. Returns the given value if it is within the min and max range. /// /// The floating point value to restrict inside the range defined by the min and max values. /// The minimum floating point value to compare against. /// The maximum floating point value to compare against. /// - /// The float result between the min and max values. + /// The float result between the min and max values. /// public static float Clamp(float value, float min, float max) { @@ -26,7 +26,7 @@ } /// - /// Clamps value between 0 and 1 and returns value. + /// Clamps value between 0 and 1 and returns value. /// /// Value. /// Clamped value. @@ -41,13 +41,13 @@ } /// - /// Linearly interpolates between a and b by t. + /// Linearly interpolates between a and b by t. /// /// The start value. /// The end value. /// The interpolation value between the two floats. /// - /// The interpolated float result between the two float values. + /// The interpolated float result between the two float values. /// public static float Lerp(float a, float b, float t) => a + ((b - a) * Clamp01(t)); diff --git a/src/Impostor.Benchmarks/Data/MessageReader_Bytes.cs b/src/Impostor.Benchmarks/Data/MessageReader_Bytes.cs index 2aba724e..7788f0e8 100644 --- a/src/Impostor.Benchmarks/Data/MessageReader_Bytes.cs +++ b/src/Impostor.Benchmarks/Data/MessageReader_Bytes.cs @@ -41,7 +41,7 @@ namespace Impostor.Benchmarks.Data public bool ReadBoolean() { - byte val = FastByte(); + var val = FastByte(); return val != 0; } @@ -88,7 +88,7 @@ namespace Impostor.Benchmarks.Data float output = 0; fixed (byte* bufPtr = &this.Buffer[Position]) { - byte* outPtr = (byte*)&output; + var outPtr = (byte*)&output; *outPtr = *bufPtr; *(outPtr + 1) = *(bufPtr + 1); @@ -134,13 +134,13 @@ namespace Impostor.Benchmarks.Data public uint ReadPackedUInt32() { - bool readMore = true; - int shift = 0; + var readMore = true; + var shift = 0; uint output = 0; while (readMore) { - byte b = FastByte(); + var b = FastByte(); if (b >= 0x80) { readMore = true; diff --git a/src/Impostor.Benchmarks/Data/MessageReader_Bytes_Pooled.cs b/src/Impostor.Benchmarks/Data/MessageReader_Bytes_Pooled.cs index 11033362..3c88ffb7 100644 --- a/src/Impostor.Benchmarks/Data/MessageReader_Bytes_Pooled.cs +++ b/src/Impostor.Benchmarks/Data/MessageReader_Bytes_Pooled.cs @@ -65,7 +65,7 @@ namespace Impostor.Benchmarks.Data public bool ReadBoolean() { - byte val = FastByte(); + var val = FastByte(); return val != 0; } @@ -112,7 +112,7 @@ namespace Impostor.Benchmarks.Data float output = 0; fixed (byte* bufPtr = &this.Buffer[Position]) { - byte* outPtr = (byte*)&output; + var outPtr = (byte*)&output; *outPtr = *bufPtr; *(outPtr + 1) = *(bufPtr + 1); @@ -158,13 +158,13 @@ namespace Impostor.Benchmarks.Data public uint ReadPackedUInt32() { - bool readMore = true; - int shift = 0; + var readMore = true; + var shift = 0; uint output = 0; while (readMore) { - byte b = FastByte(); + var b = FastByte(); if (b >= 0x80) { readMore = true; diff --git a/src/Impostor.Benchmarks/Data/MessageReader_Bytes_Pooled_Improved.cs b/src/Impostor.Benchmarks/Data/MessageReader_Bytes_Pooled_Improved.cs index 00668479..cb5d18dc 100644 --- a/src/Impostor.Benchmarks/Data/MessageReader_Bytes_Pooled_Improved.cs +++ b/src/Impostor.Benchmarks/Data/MessageReader_Bytes_Pooled_Improved.cs @@ -1,10 +1,6 @@ using System; using System.Buffers.Binary; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; using System.Runtime.CompilerServices; -using System.Text; using Microsoft.Extensions.ObjectPool; namespace Impostor.Benchmarks.Data diff --git a/src/Impostor.Benchmarks/Data/MessageWriter.cs b/src/Impostor.Benchmarks/Data/MessageWriter.cs index 94ff4418..b55b7970 100644 --- a/src/Impostor.Benchmarks/Data/MessageWriter.cs +++ b/src/Impostor.Benchmarks/Data/MessageWriter.cs @@ -9,8 +9,6 @@ namespace Impostor.Benchmarks.Data { public class MessageWriter { - private static int BufferSize = 64000; - public MessageType SendOption { get; private set; } private Stack messageStarts = new Stack(); @@ -34,7 +32,7 @@ namespace Impostor.Benchmarks.Data { if (includeHeader) { - byte[] output = new byte[this.Length]; + var output = new byte[this.Length]; System.Buffer.BlockCopy(this.Buffer, 0, output, 0, this.Length); return output; } @@ -43,17 +41,17 @@ namespace Impostor.Benchmarks.Data switch (this.SendOption) { case MessageType.Reliable: - { - byte[] output = new byte[this.Length - 3]; - System.Buffer.BlockCopy(this.Buffer, 3, output, 0, this.Length - 3); - return output; - } + { + var output = new byte[this.Length - 3]; + System.Buffer.BlockCopy(this.Buffer, 3, output, 0, this.Length - 3); + return output; + } case MessageType.Unreliable: - { - byte[] output = new byte[this.Length - 1]; - System.Buffer.BlockCopy(this.Buffer, 1, output, 0, this.Length - 1); - return output; - } + { + var output = new byte[this.Length - 1]; + System.Buffer.BlockCopy(this.Buffer, 1, output, 0, this.Length - 1); + return output; + } default: throw new ArgumentOutOfRangeException(); } @@ -89,7 +87,7 @@ namespace Impostor.Benchmarks.Data public void EndMessage() { var lastMessageStart = messageStarts.Pop(); - ushort length = (ushort)(this.Position - lastMessageStart - 3); // Minus length and type byte + var length = (ushort)(this.Position - lastMessageStart - 3); // Minus length and type byte this.Buffer[lastMessageStart] = (byte)length; this.Buffer[lastMessageStart + 1] = (byte)(length >> 8); } @@ -175,7 +173,7 @@ namespace Impostor.Benchmarks.Data { fixed (byte* ptr = &this.Buffer[this.Position]) { - byte* valuePtr = (byte*)&value; + var valuePtr = (byte*)&value; *ptr = *valuePtr; *(ptr + 1) = *(valuePtr + 1); @@ -262,7 +260,7 @@ namespace Impostor.Benchmarks.Data { do { - byte b = (byte)(value & 0xFF); + var b = (byte)(value & 0xFF); if (value >= 0x80) { b |= 0x80; @@ -277,7 +275,7 @@ namespace Impostor.Benchmarks.Data public void Write(MessageWriter msg, bool includeHeader) { - int offset = 0; + var offset = 0; if (!includeHeader) { switch (msg.SendOption) @@ -300,8 +298,8 @@ namespace Impostor.Benchmarks.Data byte b; unsafe { - int i = 1; - byte* bp = (byte*)&i; + var i = 1; + var bp = (byte*)&i; b = *bp; } diff --git a/src/Impostor.Benchmarks/Data/Span/MessageReader_Span.cs b/src/Impostor.Benchmarks/Data/Span/MessageReader_Span.cs index 5636dbed..3a7edecb 100644 --- a/src/Impostor.Benchmarks/Data/Span/MessageReader_Span.cs +++ b/src/Impostor.Benchmarks/Data/Span/MessageReader_Span.cs @@ -1,6 +1,5 @@ using System; using System.Buffers.Binary; -using Impostor.Hazel; namespace Impostor.Benchmarks.Data.Span { diff --git a/src/Impostor.Benchmarks/Tests/MessageReaderBenchmark.cs b/src/Impostor.Benchmarks/Tests/MessageReaderBenchmark.cs index abf16428..dbaf2279 100644 --- a/src/Impostor.Benchmarks/Tests/MessageReaderBenchmark.cs +++ b/src/Impostor.Benchmarks/Tests/MessageReaderBenchmark.cs @@ -4,10 +4,8 @@ using BenchmarkDotNet.Attributes; using Impostor.Benchmarks.Data; using Impostor.Benchmarks.Data.Pool; using Impostor.Benchmarks.Extensions; -using Impostor.Hazel; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.ObjectPool; -using MessageWriter = Impostor.Benchmarks.Data.MessageWriter; namespace Impostor.Benchmarks.Tests { @@ -24,7 +22,7 @@ namespace Impostor.Benchmarks.Tests message.StartMessage(1); message.Write((ushort)3100); message.Write((byte)100); - message.Write((int) int.MaxValue); + message.Write((int)int.MaxValue); message.WritePacked(int.MaxValue); message.EndMessage(); diff --git a/src/Impostor.Client.App/Impostor.Client.App.csproj b/src/Impostor.Client.App/Impostor.Client.App.csproj index 886e26e8..3e5adc84 100644 --- a/src/Impostor.Client.App/Impostor.Client.App.csproj +++ b/src/Impostor.Client.App/Impostor.Client.App.csproj @@ -1,16 +1,16 @@ - - Exe - net5.0 - + + Exe + net5.0 + - - - + + + - - - + + + diff --git a/src/Impostor.Client.App/Program.cs b/src/Impostor.Client.App/Program.cs index aa8866ad..ba039a57 100644 --- a/src/Impostor.Client.App/Program.cs +++ b/src/Impostor.Client.App/Program.cs @@ -1,5 +1,4 @@ -using System; -using System.Net; +using System.Net; using System.Threading; using System.Threading.Tasks; using Impostor.Api.Innersloth; @@ -31,7 +30,7 @@ namespace Impostor.Client.App Message00HostGameC2S.Serialize(writeGameCreate, new GameOptionsData { MaxPlayers = 4, - NumImpostors = 2 + NumImpostors = 2, }); // TODO: ObjectPool for MessageReaders diff --git a/src/Impostor.Client/Impostor.Client.csproj b/src/Impostor.Client/Impostor.Client.csproj index 28b6ed3c..cbde5b66 100644 --- a/src/Impostor.Client/Impostor.Client.csproj +++ b/src/Impostor.Client/Impostor.Client.csproj @@ -1,12 +1,12 @@ - - net5.0 - + + net5.0 + - - - - + + + + diff --git a/src/Impostor.Hazel/NetworkConnection.cs b/src/Impostor.Hazel/NetworkConnection.cs index 282fe107..9e81c5cc 100644 --- a/src/Impostor.Hazel/NetworkConnection.cs +++ b/src/Impostor.Hazel/NetworkConnection.cs @@ -37,15 +37,11 @@ namespace Impostor.Hazel public long GetIP4Address() { - if (IPMode == IPMode.IPv4) - { - return ((IPEndPoint)this.RemoteEndPoint).Address.Address; - } - else - { - var bytes = ((IPEndPoint)this.RemoteEndPoint).Address.GetAddressBytes(); - return BitConverter.ToInt64(bytes, bytes.Length - 8); - } + var bytes = this.RemoteEndPoint.Address.GetAddressBytes(); + + return IPMode == IPMode.IPv4 + ? (uint)((bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0]) & 0x0FFFFFFFF) + : BitConverter.ToInt64(bytes, bytes.Length - 8); } /// diff --git a/src/Impostor.Hazel/Udp/UdpServerConnection.cs b/src/Impostor.Hazel/Udp/UdpServerConnection.cs index 22eed988..8d3426e3 100644 --- a/src/Impostor.Hazel/Udp/UdpServerConnection.cs +++ b/src/Impostor.Hazel/Udp/UdpServerConnection.cs @@ -88,7 +88,7 @@ namespace Impostor.Hazel.Udp if (disposing) { - SendDisconnect(); + _ = SendDisconnect(); } base.Dispose(disposing); diff --git a/src/Impostor.Patcher/Impostor.Patcher.Cli/Impostor.Patcher.Cli.csproj b/src/Impostor.Patcher/Impostor.Patcher.Cli/Impostor.Patcher.Cli.csproj index c59fa878..7835c4ff 100644 --- a/src/Impostor.Patcher/Impostor.Patcher.Cli/Impostor.Patcher.Cli.csproj +++ b/src/Impostor.Patcher/Impostor.Patcher.Cli/Impostor.Patcher.Cli.csproj @@ -1,19 +1,19 @@ - - Impostor.Cli - net5.0 - win-x64;linux-x64;linux-arm;linux-arm64;osx-x64 - Exe - true - + + Impostor.Cli + net5.0 + win-x64;linux-x64;linux-arm;linux-arm64;osx-x64 + Exe + true + - - - + + + - - - + + + diff --git a/src/Impostor.Patcher/Impostor.Patcher.Cli/Program.cs b/src/Impostor.Patcher/Impostor.Patcher.Cli/Program.cs index 76653a1b..26c00d9c 100644 --- a/src/Impostor.Patcher/Impostor.Patcher.Cli/Program.cs +++ b/src/Impostor.Patcher/Impostor.Patcher.Cli/Program.cs @@ -23,7 +23,7 @@ namespace Impostor.Patcher.Cli "--name", () => AmongUsModifier.DefaultRegionName, "Name for server region" - ) + ), }; rootCommand.Handler = CommandHandler.Create((address, name) => diff --git a/src/Impostor.Patcher/Impostor.Patcher.Shared/AmongUsModifier.cs b/src/Impostor.Patcher/Impostor.Patcher.Shared/AmongUsModifier.cs index 7c1ced26..d3b6de7e 100644 --- a/src/Impostor.Patcher/Impostor.Patcher.Shared/AmongUsModifier.cs +++ b/src/Impostor.Patcher/Impostor.Patcher.Shared/AmongUsModifier.cs @@ -63,7 +63,7 @@ namespace Impostor.Patcher.Shared var libraries = new List { - steamApps + steamApps, }; var vdf = Path.Combine(steamApps, "libraryfolders.vdf"); @@ -174,7 +174,7 @@ namespace Impostor.Patcher.Shared var ip = ipAddress.ToString(); var region = new RegionInfo(RegionName, ip, new[] { - new ServerInfo($"{RegionName}-Master-1", ip, port) + new ServerInfo($"{RegionName}-Master-1", ip, port), }); region.Serialize(writer); @@ -246,4 +246,4 @@ namespace Impostor.Patcher.Shared public event EventHandler Error; public event EventHandler Saved; } -} \ No newline at end of file +} diff --git a/src/Impostor.Patcher/Impostor.Patcher.Shared/Configuration.cs b/src/Impostor.Patcher/Impostor.Patcher.Shared/Configuration.cs index b256156c..56bf2974 100644 --- a/src/Impostor.Patcher/Impostor.Patcher.Shared/Configuration.cs +++ b/src/Impostor.Patcher/Impostor.Patcher.Shared/Configuration.cs @@ -62,4 +62,4 @@ namespace Impostor.Patcher.Shared } } } -} \ No newline at end of file +} diff --git a/src/Impostor.Patcher/Impostor.Patcher.Shared/Events/ErrorEventArgs.cs b/src/Impostor.Patcher/Impostor.Patcher.Shared/Events/ErrorEventArgs.cs index 7211d5d3..b7925d3d 100644 --- a/src/Impostor.Patcher/Impostor.Patcher.Shared/Events/ErrorEventArgs.cs +++ b/src/Impostor.Patcher/Impostor.Patcher.Shared/Events/ErrorEventArgs.cs @@ -11,4 +11,4 @@ namespace Impostor.Patcher.Shared.Events public string Message { get; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Patcher/Impostor.Patcher.Shared/Events/SavedEventArgs.cs b/src/Impostor.Patcher/Impostor.Patcher.Shared/Events/SavedEventArgs.cs index c91d0719..a0f08ae4 100644 --- a/src/Impostor.Patcher/Impostor.Patcher.Shared/Events/SavedEventArgs.cs +++ b/src/Impostor.Patcher/Impostor.Patcher.Shared/Events/SavedEventArgs.cs @@ -13,4 +13,4 @@ namespace Impostor.Patcher.Shared.Events public string IpAddress { get; } public ushort Port { get; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Patcher/Impostor.Patcher.Shared/Impostor.Patcher.Shared.csproj b/src/Impostor.Patcher/Impostor.Patcher.Shared/Impostor.Patcher.Shared.csproj index 8d71e56c..3039810f 100644 --- a/src/Impostor.Patcher/Impostor.Patcher.Shared/Impostor.Patcher.Shared.csproj +++ b/src/Impostor.Patcher/Impostor.Patcher.Shared/Impostor.Patcher.Shared.csproj @@ -1,11 +1,11 @@ - - netstandard2.0;netstandard2.1 - + + netstandard2.0;netstandard2.1 + + + + + - - - - diff --git a/src/Impostor.Patcher/Impostor.Patcher.Shared/Innersloth/RegionInfo.cs b/src/Impostor.Patcher/Impostor.Patcher.Shared/Innersloth/RegionInfo.cs index 01b74d1d..77fbb6be 100644 --- a/src/Impostor.Patcher/Impostor.Patcher.Shared/Innersloth/RegionInfo.cs +++ b/src/Impostor.Patcher/Impostor.Patcher.Shared/Innersloth/RegionInfo.cs @@ -45,4 +45,4 @@ namespace Impostor.Patcher.Shared.Innersloth return new RegionInfo(name, ping, servers); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Patcher/Impostor.Patcher.Shared/Innersloth/ServerInfo.cs b/src/Impostor.Patcher/Impostor.Patcher.Shared/Innersloth/ServerInfo.cs index 7203c848..4768377a 100644 --- a/src/Impostor.Patcher/Impostor.Patcher.Shared/Innersloth/ServerInfo.cs +++ b/src/Impostor.Patcher/Impostor.Patcher.Shared/Innersloth/ServerInfo.cs @@ -15,7 +15,7 @@ namespace Impostor.Patcher.Shared.Innersloth Ip = ip; Port = port; } - + public void Serialize(BinaryWriter writer) { writer.Write(Name); @@ -30,8 +30,8 @@ namespace Impostor.Patcher.Shared.Innersloth var ip = new IPAddress(reader.ReadBytes(4)).ToString(); var port = reader.ReadUInt16(); var unknown = reader.ReadInt32(); - + return new ServerInfo(name, ip, port); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Patcher/Impostor.Patcher.WinForms/Forms/FrmMain.Designer.cs b/src/Impostor.Patcher/Impostor.Patcher.WinForms/Forms/FrmMain.Designer.cs index 0f6320b4..4667c454 100644 --- a/src/Impostor.Patcher/Impostor.Patcher.WinForms/Forms/FrmMain.Designer.cs +++ b/src/Impostor.Patcher/Impostor.Patcher.WinForms/Forms/FrmMain.Designer.cs @@ -81,7 +81,7 @@ this.lblUrl.Name = "lblUrl"; this.lblUrl.Size = new System.Drawing.Size(212, 13); this.lblUrl.TabIndex = 5; - this.lblUrl.Text = "https://github.com/AeonLucid/Impostor"; + this.lblUrl.Text = "https://github.com/Impostor/Impostor"; this.lblUrl.Click += new System.EventHandler(this.lblUrl_Click); // // label3 @@ -138,4 +138,4 @@ private System.Windows.Forms.Label label3; private System.Windows.Forms.ComboBox comboIp; } -} \ No newline at end of file +} diff --git a/src/Impostor.Patcher/Impostor.Patcher.WinForms/Forms/FrmMain.cs b/src/Impostor.Patcher/Impostor.Patcher.WinForms/Forms/FrmMain.cs index 5c06669e..dd3696f5 100644 --- a/src/Impostor.Patcher/Impostor.Patcher.WinForms/Forms/FrmMain.cs +++ b/src/Impostor.Patcher/Impostor.Patcher.WinForms/Forms/FrmMain.cs @@ -95,7 +95,7 @@ namespace Impostor.Patcher.WinForms.Forms private void lblUrl_Click(object sender, EventArgs e) { - Process.Start("https://github.com/AeonLucid/Impostor"); + Process.Start("https://github.com/Impostor/Impostor"); } private void RefreshComboIps() @@ -111,4 +111,4 @@ namespace Impostor.Patcher.WinForms.Forms } } } -} \ No newline at end of file +} diff --git a/src/Impostor.Patcher/Impostor.Patcher.WinForms/Impostor.Patcher.WinForms.csproj b/src/Impostor.Patcher/Impostor.Patcher.WinForms/Impostor.Patcher.WinForms.csproj index 71494365..83f6e269 100644 --- a/src/Impostor.Patcher/Impostor.Patcher.WinForms/Impostor.Patcher.WinForms.csproj +++ b/src/Impostor.Patcher/Impostor.Patcher.WinForms/Impostor.Patcher.WinForms.csproj @@ -1,22 +1,22 @@  - - - Impostor - {804CF172-0C87-4423-9688-BD97D549891E} - WinExe - net472 - true - Copyright © AeonLucid 2020 - icon.ico - true - true - - - - - - - + + Impostor + {804CF172-0C87-4423-9688-BD97D549891E} + WinExe + net472 + true + Copyright © AeonLucid 2020 + icon.ico + true + true + - \ No newline at end of file + + + + + + + + diff --git a/src/Impostor.Patcher/Impostor.Patcher.WinForms/Program.cs b/src/Impostor.Patcher/Impostor.Patcher.WinForms/Program.cs index 7ca90353..f4814906 100644 --- a/src/Impostor.Patcher/Impostor.Patcher.WinForms/Program.cs +++ b/src/Impostor.Patcher/Impostor.Patcher.WinForms/Program.cs @@ -14,4 +14,4 @@ namespace Impostor.Patcher.WinForms Application.Run(new FrmMain()); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Plugins.Debugger/DebugPlugin.cs b/src/Impostor.Plugins.Debugger/DebugPlugin.cs index 8f57e89e..a978619b 100644 --- a/src/Impostor.Plugins.Debugger/DebugPlugin.cs +++ b/src/Impostor.Plugins.Debugger/DebugPlugin.cs @@ -10,4 +10,4 @@ namespace Impostor.Plugins.Debugger public class DebugPlugin : PluginBase { } -} \ No newline at end of file +} diff --git a/src/Impostor.Plugins.Debugger/DebugPluginStartup.cs b/src/Impostor.Plugins.Debugger/DebugPluginStartup.cs index cc36ce66..c39ce314 100644 --- a/src/Impostor.Plugins.Debugger/DebugPluginStartup.cs +++ b/src/Impostor.Plugins.Debugger/DebugPluginStartup.cs @@ -32,4 +32,4 @@ namespace Impostor.Plugins.Debugger }); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Plugins.Debugger/Impostor.Plugins.Debugger.csproj b/src/Impostor.Plugins.Debugger/Impostor.Plugins.Debugger.csproj index 9518e48e..8fce4f88 100644 --- a/src/Impostor.Plugins.Debugger/Impostor.Plugins.Debugger.csproj +++ b/src/Impostor.Plugins.Debugger/Impostor.Plugins.Debugger.csproj @@ -1,16 +1,16 @@  - - net5.0 - Library - + + net5.0 + Library + - - - + + + - - - + + + - \ No newline at end of file + diff --git a/src/Impostor.Plugins.Example/ExamplePlugin.cs b/src/Impostor.Plugins.Example/ExamplePlugin.cs index 139e42c0..73fea6ad 100644 --- a/src/Impostor.Plugins.Example/ExamplePlugin.cs +++ b/src/Impostor.Plugins.Example/ExamplePlugin.cs @@ -29,7 +29,7 @@ namespace Impostor.Plugins.Example var game = await _gameManager.CreateAsync(new GameOptionsData()); game.DisplayName = "Example game"; await game.SetPrivacyAsync(true); - + _logger.LogInformation("Created game {0}.", game.Code.Code); } diff --git a/src/Impostor.Plugins.Example/Handlers/PlayerEventListener.cs b/src/Impostor.Plugins.Example/Handlers/PlayerEventListener.cs index 0190d3b1..c62433c6 100644 --- a/src/Impostor.Plugins.Example/Handlers/PlayerEventListener.cs +++ b/src/Impostor.Plugins.Example/Handlers/PlayerEventListener.cs @@ -94,7 +94,7 @@ namespace Impostor.Plugins.Example.Handlers [EventListener] public void OnPlayerStartMeetingEvent(IPlayerStartMeetingEvent e) { - _logger.LogDebug($"Player {e.PlayerControl.PlayerInfo.PlayerName} start meeting, reason: " + (e.Body==null ? "Emergency call button" : "Found the body of the player "+e.Body.PlayerInfo.PlayerName)); + _logger.LogDebug($"Player {e.PlayerControl.PlayerInfo.PlayerName} start meeting, reason: " + (e.Body == null ? "Emergency call button" : "Found the body of the player " + e.Body.PlayerInfo.PlayerName)); } } } diff --git a/src/Impostor.Plugins.Example/Impostor.Plugins.Example.csproj b/src/Impostor.Plugins.Example/Impostor.Plugins.Example.csproj index dd4724dc..f0ebef3d 100644 --- a/src/Impostor.Plugins.Example/Impostor.Plugins.Example.csproj +++ b/src/Impostor.Plugins.Example/Impostor.Plugins.Example.csproj @@ -3,7 +3,7 @@ netstandard2.1 - + diff --git a/src/Impostor.Server/Config/AnnouncementsServerConfig.cs b/src/Impostor.Server/Config/AnnouncementsServerConfig.cs index 5d61ac04..43f8f8ff 100644 --- a/src/Impostor.Server/Config/AnnouncementsServerConfig.cs +++ b/src/Impostor.Server/Config/AnnouncementsServerConfig.cs @@ -4,10 +4,10 @@ namespace Impostor.Server.Config { internal class AnnouncementsServerConfig { - private string? _resolvedListenIp; - public const string Section = "AnnouncementsServer"; + private string? _resolvedListenIp; + public bool Enabled { get; set; } = true; public string ListenIp { get; set; } = "0.0.0.0"; diff --git a/src/Impostor.Server/Config/DebugConfig.cs b/src/Impostor.Server/Config/DebugConfig.cs index 630d1b48..72529de3 100644 --- a/src/Impostor.Server/Config/DebugConfig.cs +++ b/src/Impostor.Server/Config/DebugConfig.cs @@ -6,6 +6,6 @@ public bool GameRecorderEnabled { get; set; } - public string GameRecorderPath { get; set; } + public string GameRecorderPath { get; set; } = string.Empty; } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Config/DisconnectMessages.cs b/src/Impostor.Server/Config/DisconnectMessages.cs index a86735f8..6bf8e728 100644 --- a/src/Impostor.Server/Config/DisconnectMessages.cs +++ b/src/Impostor.Server/Config/DisconnectMessages.cs @@ -16,4 +16,4 @@ public const string UsernameIllegalCharacters = "Your username contains illegal characters, please remove them."; } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Config/ServerConfig.cs b/src/Impostor.Server/Config/ServerConfig.cs index 1c584333..7ed3ae64 100644 --- a/src/Impostor.Server/Config/ServerConfig.cs +++ b/src/Impostor.Server/Config/ServerConfig.cs @@ -4,11 +4,11 @@ namespace Impostor.Server.Config { internal class ServerConfig { + public const string Section = "Server"; + private string? _resolvedPublicIp; private string? _resolvedListenIp; - public const string Section = "Server"; - public string PublicIp { get; set; } = "127.0.0.1"; public ushort PublicPort { get; set; } = 22023; diff --git a/src/Impostor.Server/Config/ServerRedirectorConfig.cs b/src/Impostor.Server/Config/ServerRedirectorConfig.cs index 0ccfa0d4..686ad7fd 100644 --- a/src/Impostor.Server/Config/ServerRedirectorConfig.cs +++ b/src/Impostor.Server/Config/ServerRedirectorConfig.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace Impostor.Server.Config { @@ -10,15 +11,17 @@ namespace Impostor.Server.Config public bool Master { get; set; } - public NodeLocator Locator { get; set; } + public NodeLocator? Locator { get; set; } - public List Nodes { get; set; } + public List? Nodes { get; set; } public class NodeLocator { + [AllowNull] public string Redis { get; set; } + [AllowNull] public string UdpMasterEndpoint { get; set; } } } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Config/ServerRedirectorNode.cs b/src/Impostor.Server/Config/ServerRedirectorNode.cs index d11b60ff..c4795123 100644 --- a/src/Impostor.Server/Config/ServerRedirectorNode.cs +++ b/src/Impostor.Server/Config/ServerRedirectorNode.cs @@ -1,9 +1,13 @@ -namespace Impostor.Server.Config +using System.Diagnostics.CodeAnalysis; + +namespace Impostor.Server.Config { public class ServerRedirectorNode { + [AllowNull] public string Ip { get; set; } + [AllowNull] public ushort Port { get; set; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Constants.cs b/src/Impostor.Server/Constants.cs index 62d90b29..ce0114aa 100644 --- a/src/Impostor.Server/Constants.cs +++ b/src/Impostor.Server/Constants.cs @@ -5,4 +5,4 @@ public const int SpawnTimeout = 2500; public const int ConnectionTimeout = 2500; } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Events/EventHandler.cs b/src/Impostor.Server/Events/EventHandler.cs index 190f7f39..e185c9a1 100644 --- a/src/Impostor.Server/Events/EventHandler.cs +++ b/src/Impostor.Server/Events/EventHandler.cs @@ -5,20 +5,20 @@ namespace Impostor.Server.Events { internal readonly struct EventHandler { - public EventHandler(IEventListener o, IRegisteredEventListener listener) + public EventHandler(IEventListener? o, IRegisteredEventListener listener) { Object = o; Listener = listener; } - public IEventListener Object { get; } + public IEventListener? Object { get; } public IRegisteredEventListener Listener { get; } - public void Deconstruct(out IEventListener o, out IRegisteredEventListener listener) + public void Deconstruct(out IEventListener? o, out IRegisteredEventListener listener) { o = Object; listener = Listener; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Events/EventManager.cs b/src/Impostor.Server/Events/EventManager.cs index 0cc6e541..4ab2d153 100644 --- a/src/Impostor.Server/Events/EventManager.cs +++ b/src/Impostor.Server/Events/EventManager.cs @@ -27,7 +27,7 @@ namespace Impostor.Server.Events } /// - public IDisposable RegisterListener(TListener listener, Func, Task> invoker = null) + public IDisposable RegisterListener(TListener listener, Func, Task>? invoker = null) where TListener : IEventListener { if (listener == null) diff --git a/src/Impostor.Server/Events/Game/GameEndedEvent.cs b/src/Impostor.Server/Events/Game/GameEndedEvent.cs index 4ec4dcf9..b0704cfc 100644 --- a/src/Impostor.Server/Events/Game/GameEndedEvent.cs +++ b/src/Impostor.Server/Events/Game/GameEndedEvent.cs @@ -13,7 +13,7 @@ namespace Impostor.Server.Events } public IGame Game { get; } - + public GameOverReason GameOverReason { get; } } } diff --git a/src/Impostor.Server/Events/MultiDisposable.cs b/src/Impostor.Server/Events/MultiDisposable.cs index b68f0640..b1e2348b 100644 --- a/src/Impostor.Server/Events/MultiDisposable.cs +++ b/src/Impostor.Server/Events/MultiDisposable.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; namespace Impostor.Server.Events { /// - /// Disposes multiple . + /// Disposes multiple . /// internal class MultiDisposable : IDisposable { diff --git a/src/Impostor.Server/Events/Register/IRegisteredEventListener.cs b/src/Impostor.Server/Events/Register/IRegisteredEventListener.cs index 479a3f64..3b39bc9b 100644 --- a/src/Impostor.Server/Events/Register/IRegisteredEventListener.cs +++ b/src/Impostor.Server/Events/Register/IRegisteredEventListener.cs @@ -10,6 +10,6 @@ namespace Impostor.Server.Events.Register EventPriority Priority { get; } - ValueTask InvokeAsync(object eventHandler, object @event, IServiceProvider provider); + ValueTask InvokeAsync(object? eventHandler, object @event, IServiceProvider provider); } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Events/Register/InvokedRegisteredEventListener.cs b/src/Impostor.Server/Events/Register/InvokedRegisteredEventListener.cs index a21c3b1f..adec183b 100644 --- a/src/Impostor.Server/Events/Register/InvokedRegisteredEventListener.cs +++ b/src/Impostor.Server/Events/Register/InvokedRegisteredEventListener.cs @@ -19,9 +19,9 @@ namespace Impostor.Server.Events.Register public EventPriority Priority => _innerObject.Priority; - public ValueTask InvokeAsync(object eventHandler, object @event, IServiceProvider provider) + public ValueTask InvokeAsync(object? eventHandler, object @event, IServiceProvider provider) { return new ValueTask(_invoker(() => _innerObject.InvokeAsync(eventHandler, @event, provider).AsTask())); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Events/Register/ManualRegisteredEventListener.cs b/src/Impostor.Server/Events/Register/ManualRegisteredEventListener.cs index e81e8f84..394f47d3 100644 --- a/src/Impostor.Server/Events/Register/ManualRegisteredEventListener.cs +++ b/src/Impostor.Server/Events/Register/ManualRegisteredEventListener.cs @@ -6,8 +6,6 @@ namespace Impostor.Server.Events.Register { internal class ManualRegisteredEventListener : IRegisteredEventListener { - public Type EventType { get; } = typeof(object); - private readonly IManualEventListener _manualEventListener; public ManualRegisteredEventListener(IManualEventListener manualEventListener) @@ -15,9 +13,11 @@ namespace Impostor.Server.Events.Register _manualEventListener = manualEventListener; } + public Type EventType { get; } = typeof(object); + public EventPriority Priority => _manualEventListener.Priority; - public ValueTask InvokeAsync(object eventHandler, object @event, IServiceProvider provider) + public ValueTask InvokeAsync(object? eventHandler, object @event, IServiceProvider provider) { if (@event is IEvent typedEvent) { diff --git a/src/Impostor.Server/Events/Register/RegisteredEventListener.cs b/src/Impostor.Server/Events/Register/RegisteredEventListener.cs index 120a45ed..76d2a2af 100644 --- a/src/Impostor.Server/Events/Register/RegisteredEventListener.cs +++ b/src/Impostor.Server/Events/Register/RegisteredEventListener.cs @@ -15,7 +15,7 @@ namespace Impostor.Server.Events.Register private static readonly PropertyInfo IsCancelledProperty = typeof(IEventCancelable).GetProperty(nameof(IEventCancelable.IsCancelled))!; private static readonly ConcurrentDictionary Instances = new ConcurrentDictionary(); - private readonly Func _invoker; + private readonly Func _invoker; private readonly Type _eventListenerType; public RegisteredEventListener(Type eventType, MethodInfo method, EventListenerAttribute attribute, Type eventListenerType) @@ -38,12 +38,52 @@ namespace Impostor.Server.Events.Register public string Method { get; } - public ValueTask InvokeAsync(object eventHandler, object @event, IServiceProvider provider) + public static IReadOnlyList FromType(Type type) + { + return Instances.GetOrAdd(type, t => + { + return t.GetMethods() + .Where(m => !m.IsStatic && m.GetCustomAttributes(typeof(EventListenerAttribute), false).Any()) + .SelectMany(m => FromMethod(t, m)) + .ToArray(); + }); + } + + public static IEnumerable FromMethod(Type listenerType, MethodInfo methodType) + { + // Get the return type. + var returnType = methodType.ReturnType; + + if (returnType != typeof(void) && returnType != typeof(ValueTask)) + { + throw new InvalidOperationException($"The method {methodType.GetFriendlyName()} does not return void or ValueTask."); + } + + // Register the event. + foreach (var attribute in methodType.GetCustomAttributes(false)) + { + var eventType = attribute.Event; + + if (eventType == null) + { + if (methodType.GetParameters().Length == 0 || !typeof(IEvent).IsAssignableFrom(methodType.GetParameters()[0].ParameterType)) + { + throw new InvalidOperationException($"The first parameter of the method {methodType.GetFriendlyName()} should be the type {nameof(IEvent)}."); + } + + eventType = methodType.GetParameters()[0].ParameterType; + } + + yield return new RegisteredEventListener(eventType, methodType, attribute, listenerType); + } + } + + public ValueTask InvokeAsync(object? eventHandler, object @event, IServiceProvider provider) { return _invoker(eventHandler, @event, provider); } - private Func CreateInvoker(MethodInfo method, bool ignoreCancelled) + private Func CreateInvoker(MethodInfo method, bool ignoreCancelled) { var instance = Expression.Parameter(typeof(object), "instance"); var eventParameter = Expression.Parameter(typeof(object), "event"); @@ -119,48 +159,8 @@ namespace Impostor.Server.Events.Register throw new InvalidOperationException($"The method {method.GetFriendlyName()} must return void or ValueTask."); } - return Expression.Lambda>(invoke, instance, eventParameter, provider) + return Expression.Lambda>(invoke, instance, eventParameter, provider) .Compile(); } - - public static IReadOnlyList FromType(Type type) - { - return Instances.GetOrAdd(type, t => - { - return t.GetMethods() - .Where(m => !m.IsStatic && m.GetCustomAttributes(typeof(EventListenerAttribute), false).Any()) - .SelectMany(m => FromMethod(t, m)) - .ToArray(); - }); - } - - public static IEnumerable FromMethod(Type listenerType, MethodInfo methodType) - { - // Get the return type. - var returnType = methodType.ReturnType; - - if (returnType != typeof(void) && returnType != typeof(ValueTask)) - { - throw new InvalidOperationException($"The method {methodType.GetFriendlyName()} does not return void or ValueTask."); - } - - // Register the event. - foreach (var attribute in methodType.GetCustomAttributes(false)) - { - var eventType = attribute.Event; - - if (eventType == null) - { - if (methodType.GetParameters().Length == 0 || !typeof(IEvent).IsAssignableFrom(methodType.GetParameters()[0].ParameterType)) - { - throw new InvalidOperationException($"The first parameter of the method {methodType.GetFriendlyName()} should be the type {nameof(IEvent)}."); - } - - eventType = methodType.GetParameters()[0].ParameterType; - } - - yield return new RegisteredEventListener(eventType, methodType, attribute, listenerType); - } - } } } diff --git a/src/Impostor.Server/Events/Register/TemporaryEventRegister.cs b/src/Impostor.Server/Events/Register/TemporaryEventRegister.cs index 1446ad1e..f2bfee25 100644 --- a/src/Impostor.Server/Events/Register/TemporaryEventRegister.cs +++ b/src/Impostor.Server/Events/Register/TemporaryEventRegister.cs @@ -56,4 +56,4 @@ namespace Impostor.Server.Events.Register } } } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Events/Register/WrappedRegisteredEventListener.cs b/src/Impostor.Server/Events/Register/WrappedRegisteredEventListener.cs index dd668c5d..d1a66ee8 100644 --- a/src/Impostor.Server/Events/Register/WrappedRegisteredEventListener.cs +++ b/src/Impostor.Server/Events/Register/WrappedRegisteredEventListener.cs @@ -19,9 +19,9 @@ namespace Impostor.Server.Events.Register public EventPriority Priority => _innerObject.Priority; - public ValueTask InvokeAsync(object eventHandler, object @event, IServiceProvider provider) + public ValueTask InvokeAsync(object? eventHandler, object @event, IServiceProvider provider) { return _innerObject.InvokeAsync(_object, @event, provider); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Extensions/NodeLocatorExtensions.cs b/src/Impostor.Server/Extensions/NodeLocatorExtensions.cs index 370bca62..96ceb4d4 100644 --- a/src/Impostor.Server/Extensions/NodeLocatorExtensions.cs +++ b/src/Impostor.Server/Extensions/NodeLocatorExtensions.cs @@ -10,4 +10,4 @@ namespace Impostor.Server return await nodeLocator.FindAsync(gameCode) != null; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Extensions/TypeExtensions.cs b/src/Impostor.Server/Extensions/TypeExtensions.cs index 55d42fbd..a49cb5e2 100644 --- a/src/Impostor.Server/Extensions/TypeExtensions.cs +++ b/src/Impostor.Server/Extensions/TypeExtensions.cs @@ -45,7 +45,7 @@ namespace Impostor.Server /// /// The method. /// True if the parameters should be included in the name. - /// Friendly name of the method + /// Friendly name of the method. public static string GetFriendlyName(this MethodBase method, bool showParameters = true) { var str = method.Name; @@ -64,4 +64,4 @@ namespace Impostor.Server return str; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Impostor.Server.csproj b/src/Impostor.Server/Impostor.Server.csproj index 663f7af4..ba444fc8 100644 --- a/src/Impostor.Server/Impostor.Server.csproj +++ b/src/Impostor.Server/Impostor.Server.csproj @@ -6,9 +6,10 @@ win-x64;linux-x64;linux-arm;linux-arm64;osx-x64 true icon.ico - ProjectRules.ruleset + ../ProjectRules.ruleset enable false + true @@ -24,13 +25,13 @@ - + - - + + - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Impostor.Server/Net/AnnouncementsService.cs b/src/Impostor.Server/Net/AnnouncementsService.cs index a58abf27..6ca0bb9a 100644 --- a/src/Impostor.Server/Net/AnnouncementsService.cs +++ b/src/Impostor.Server/Net/AnnouncementsService.cs @@ -24,7 +24,7 @@ namespace Impostor.Server.Net private readonly AnnouncementsServerConfig _config; private readonly ObjectPool _readerPool; private readonly IEventManager _eventManager; - private UdpConnectionListener _connection; + private UdpConnectionListener? _connection; public AnnouncementsService(ILogger logger, IOptions config, ObjectPool readerPool, IEventManager eventManager) { @@ -42,7 +42,7 @@ namespace Impostor.Server.Net { AddressFamily.InterNetwork => IPMode.IPv4, AddressFamily.InterNetworkV6 => IPMode.IPv6, - _ => throw new InvalidOperationException() + _ => throw new InvalidOperationException(), }; _connection = new UdpConnectionListener(endpoint, _readerPool, mode) @@ -58,7 +58,11 @@ namespace Impostor.Server.Net public async Task StopAsync(CancellationToken cancellationToken) { _logger.LogWarning("Announcements server is shutting down!"); - await _connection.DisposeAsync(); + + if (_connection != null) + { + await _connection.DisposeAsync(); + } } private async ValueTask OnNewConnection(NewConnectionEventArgs e) diff --git a/src/Impostor.Server/Net/Client.cs b/src/Impostor.Server/Net/Client.cs index f26de402..45718e58 100644 --- a/src/Impostor.Server/Net/Client.cs +++ b/src/Impostor.Server/Net/Client.cs @@ -131,7 +131,7 @@ namespace Impostor.Server.Net return; } - await Player.Game.HandleStartGame(reader); + await Player!.Game.HandleStartGame(reader); break; } @@ -151,7 +151,7 @@ namespace Impostor.Server.Net out var playerId, out var reason); - await Player.Game.HandleRemovePlayer(playerId, (DisconnectReason)reason); + await Player!.Game.HandleRemovePlayer(playerId, (DisconnectReason)reason); break; } @@ -168,7 +168,7 @@ namespace Impostor.Server.Net // Handle packet. using var readerCopy = reader.Copy(); - var verified = await Player.Game.HandleGameDataAsync(readerCopy, Player, toPlayer); + var verified = await Player!.Game.HandleGameDataAsync(readerCopy, Player, toPlayer); if (verified) { // Broadcast packet to all other players. @@ -202,7 +202,7 @@ namespace Impostor.Server.Net reader, out var gameOverReason); - await Player.Game.HandleEndGame(reader, gameOverReason); + await Player!.Game.HandleEndGame(reader, gameOverReason); break; } @@ -223,7 +223,7 @@ namespace Impostor.Server.Net return; } - await Player.Game.HandleAlterGame(reader, Player, value); + await Player!.Game.HandleAlterGame(reader, Player, value); break; } @@ -239,7 +239,7 @@ namespace Impostor.Server.Net out var playerId, out var isBan); - await Player.Game.HandleKickPlayer(playerId, isBan); + await Player!.Game.HandleKickPlayer(playerId, isBan); break; } diff --git a/src/Impostor.Server/Net/ClientBase.cs b/src/Impostor.Server/Net/ClientBase.cs index 7bff06ef..78bcb9ec 100644 --- a/src/Impostor.Server/Net/ClientBase.cs +++ b/src/Impostor.Server/Net/ClientBase.cs @@ -64,7 +64,6 @@ namespace Impostor.Server.Net public abstract ValueTask HandleDisconnectAsync(string reason); - public async ValueTask DisconnectAsync(DisconnectReason reason, string? message = null) { if (!Connection.IsConnected) diff --git a/src/Impostor.Server/Net/Factories/IClientFactory.cs b/src/Impostor.Server/Net/Factories/IClientFactory.cs index bec1b79b..a72a23ba 100644 --- a/src/Impostor.Server/Net/Factories/IClientFactory.cs +++ b/src/Impostor.Server/Net/Factories/IClientFactory.cs @@ -8,4 +8,4 @@ namespace Impostor.Server.Net.Factories { ClientBase Create(IHazelConnection connection, string name, int clientVersion, ISet mods); } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Net/GameCodeFactory.cs b/src/Impostor.Server/Net/GameCodeFactory.cs index 2a0553fc..f8b0de47 100644 --- a/src/Impostor.Server/Net/GameCodeFactory.cs +++ b/src/Impostor.Server/Net/GameCodeFactory.cs @@ -9,4 +9,4 @@ namespace Impostor.Server.Net return GameCode.Create(); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Net/Hazel/HazelConnection.cs b/src/Impostor.Server/Net/Hazel/HazelConnection.cs index 45d2be82..e663dec1 100644 --- a/src/Impostor.Server/Net/Hazel/HazelConnection.cs +++ b/src/Impostor.Server/Net/Hazel/HazelConnection.cs @@ -25,14 +25,14 @@ namespace Impostor.Server.Net.Hazel public bool IsConnected => InnerConnection.State == ConnectionState.Connected; - public IClient Client { get; set; } + public IClient? Client { get; set; } public ValueTask SendAsync(IMessageWriter writer) { return InnerConnection.SendAsync(writer); } - public ValueTask DisconnectAsync(string reason) + public ValueTask DisconnectAsync(string? reason) { return InnerConnection.Disconnect(reason); } diff --git a/src/Impostor.Server/Net/Inner/GameObject.cs b/src/Impostor.Server/Net/Inner/GameObject.cs index 9b53d708..7fd4f012 100644 --- a/src/Impostor.Server/Net/Inner/GameObject.cs +++ b/src/Impostor.Server/Net/Inner/GameObject.cs @@ -26,4 +26,4 @@ namespace Impostor.Server.Net.Inner 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 index 9579fe0a..8cbea9a2 100644 --- a/src/Impostor.Server/Net/Inner/InnerNetObject.cs +++ b/src/Impostor.Server/Net/Inner/InnerNetObject.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Threading.Tasks; +using System.Threading.Tasks; using Impostor.Api.Net; using Impostor.Api.Net.Inner; using Impostor.Api.Net.Messages; @@ -29,6 +28,7 @@ namespace Impostor.Server.Net.Inner public abstract ValueTask HandleRpcAsync(ClientPlayer sender, ClientPlayer? target, RpcCalls call, IMessageReader reader); + // TODO move to Reactor.Impostor plugin protected ValueTask HandleCustomRpc(IMessageReader reader, Game game) { var lengthOrShortId = reader.ReadPackedInt32(); @@ -39,8 +39,6 @@ namespace Impostor.Server.Net.Inner var id = reader.ReadPackedInt32(); - // TODO handle custom rpcs - return ValueTask.FromResult(true); } } diff --git a/src/Impostor.Server/Net/Inner/Objects/Components/InnerCustomNetworkTransform.Api.cs b/src/Impostor.Server/Net/Inner/Objects/Components/InnerCustomNetworkTransform.Api.cs index 56ff96e5..0e70bd64 100644 --- a/src/Impostor.Server/Net/Inner/Objects/Components/InnerCustomNetworkTransform.Api.cs +++ b/src/Impostor.Server/Net/Inner/Objects/Components/InnerCustomNetworkTransform.Api.cs @@ -11,7 +11,7 @@ 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)) diff --git a/src/Impostor.Server/Net/Inner/Objects/Components/InnerCustomNetworkTransform.cs b/src/Impostor.Server/Net/Inner/Objects/Components/InnerCustomNetworkTransform.cs index 80dd6adf..ff5c21d5 100644 --- a/src/Impostor.Server/Net/Inner/Objects/Components/InnerCustomNetworkTransform.cs +++ b/src/Impostor.Server/Net/Inner/Objects/Components/InnerCustomNetworkTransform.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Numerics; +using System.Numerics; using System.Threading.Tasks; using Impostor.Api; using Impostor.Api.Events.Managers; @@ -23,10 +22,6 @@ namespace Impostor.Server.Net.Inner.Objects.Components private ushort _lastSequenceId; - public Vector2 Position { get; private set; } - - public Vector2 Velocity { get; private set; } - public InnerCustomNetworkTransform(ILogger logger, InnerPlayerControl playerControl, Game game, IEventManager eventManager, ObjectPool pool) { _logger = logger; @@ -37,14 +32,9 @@ namespace Impostor.Server.Net.Inner.Objects.Components _pool = pool; } - private static bool SidGreaterThan(ushort newSid, ushort prevSid) - { - var num = (ushort)(prevSid + (uint)short.MaxValue); + public Vector2 Position { get; private set; } - return (int)prevSid < (int)num - ? newSid > prevSid && newSid <= num - : newSid > prevSid || newSid <= num; - } + public Vector2 Velocity { get; private set; } public override ValueTask SerializeAsync(IMessageWriter writer, bool initialState) { @@ -120,6 +110,15 @@ namespace Impostor.Server.Net.Inner.Objects.Components _pool.Return(playerMovementEvent); } + 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 ValueTask SnapToAsync(IClientPlayer sender, Vector2 position, ushort minSid) { if (!SidGreaterThan(minSid, _lastSequenceId)) diff --git a/src/Impostor.Server/Net/Inner/Objects/Components/InnerPlayerPhysics.cs b/src/Impostor.Server/Net/Inner/Objects/Components/InnerPlayerPhysics.cs index 69f8dcd8..4eb5f8a1 100644 --- a/src/Impostor.Server/Net/Inner/Objects/Components/InnerPlayerPhysics.cs +++ b/src/Impostor.Server/Net/Inner/Objects/Components/InnerPlayerPhysics.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Threading.Tasks; using Impostor.Api.Events.Managers; using Impostor.Api.Innersloth; diff --git a/src/Impostor.Server/Net/Inner/Objects/InnerLobbyBehaviour.cs b/src/Impostor.Server/Net/Inner/Objects/InnerLobbyBehaviour.cs index 78be5bd2..3dfd7415 100644 --- a/src/Impostor.Server/Net/Inner/Objects/InnerLobbyBehaviour.cs +++ b/src/Impostor.Server/Net/Inner/Objects/InnerLobbyBehaviour.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; using Impostor.Api.Games; using Impostor.Api.Net; using Impostor.Api.Net.Inner.Objects; @@ -20,17 +21,17 @@ namespace Impostor.Server.Net.Inner.Objects public override ValueTask SerializeAsync(IMessageWriter writer, bool initialState) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } public override ValueTask DeserializeAsync(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } public override ValueTask HandleRpcAsync(ClientPlayer sender, ClientPlayer? target, RpcCalls call, IMessageReader reader) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } } } diff --git a/src/Impostor.Server/Net/Inner/Objects/InnerMeetingHud.Api.cs b/src/Impostor.Server/Net/Inner/Objects/InnerMeetingHud.Api.cs index 5d120c5c..0219fbab 100644 --- a/src/Impostor.Server/Net/Inner/Objects/InnerMeetingHud.Api.cs +++ b/src/Impostor.Server/Net/Inner/Objects/InnerMeetingHud.Api.cs @@ -4,6 +4,5 @@ namespace Impostor.Server.Net.Inner.Objects { internal partial class InnerMeetingHud : IInnerMeetingHud { - } -} \ 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 index fbf25102..48f551b9 100644 --- a/src/Impostor.Server/Net/Inner/Objects/InnerMeetingHud.PlayerVoteArea.cs +++ b/src/Impostor.Server/Net/Inner/Objects/InnerMeetingHud.PlayerVoteArea.cs @@ -29,12 +29,6 @@ namespace Impostor.Server.Net.Inner.Objects 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(); @@ -44,6 +38,12 @@ namespace Impostor.Server.Net.Inner.Objects DidVote = (num & VotedBit) > 0; DidReport = (num & ReportedBit) > 0; } + + internal void SetDead(bool didReport, bool isDead) + { + DidReport = didReport; + IsDead = isDead; + } } } -} \ 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 index 96d829fb..a2d6f0e7 100644 --- a/src/Impostor.Server/Net/Inner/Objects/InnerMeetingHud.cs +++ b/src/Impostor.Server/Net/Inner/Objects/InnerMeetingHud.cs @@ -1,5 +1,5 @@ using System; -using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading.Tasks; using Impostor.Api; @@ -21,6 +21,8 @@ namespace Impostor.Server.Net.Inner.Objects private readonly IEventManager _eventManager; private readonly Game _game; private readonly GameNet _gameNet; + + [AllowNull] private PlayerVoteArea[] _playerStates; public InnerMeetingHud(ILogger logger, IEventManager eventManager, Game game) @@ -36,18 +38,6 @@ namespace Impostor.Server.Net.Inner.Objects 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 SerializeAsync(IMessageWriter writer, bool initialState) { throw new NotImplementedException(); @@ -142,12 +132,24 @@ namespace Impostor.Server.Net.Inner.Objects return true; } + 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(); + } + private async ValueTask HandleVotingComplete(ClientPlayer sender, ReadOnlyMemory states, byte playerId, bool tie) { if (playerId != byte.MaxValue) { - var player = _game.GameNet.GameData.GetPlayerById(playerId); - if (player != null) + 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)); diff --git a/src/Impostor.Server/Net/Inner/Objects/InnerPlayerControl.Api.cs b/src/Impostor.Server/Net/Inner/Objects/InnerPlayerControl.Api.cs index e55f0792..604c6e64 100644 --- a/src/Impostor.Server/Net/Inner/Objects/InnerPlayerControl.Api.cs +++ b/src/Impostor.Server/Net/Inner/Objects/InnerPlayerControl.Api.cs @@ -104,7 +104,7 @@ namespace Impostor.Server.Net.Inner.Objects Rpc12MurderPlayer.Serialize(writer, target); 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() @@ -123,7 +123,7 @@ namespace Impostor.Server.Net.Inner.Objects 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)); } } } diff --git a/src/Impostor.Server/Net/Inner/Objects/InnerPlayerControl.cs b/src/Impostor.Server/Net/Inner/Objects/InnerPlayerControl.cs index 8391ed08..8cd808db 100644 --- a/src/Impostor.Server/Net/Inner/Objects/InnerPlayerControl.cs +++ b/src/Impostor.Server/Net/Inner/Objects/InnerPlayerControl.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading.Tasks; using Impostor.Api; @@ -20,6 +21,8 @@ namespace Impostor.Server.Net.Inner.Objects { internal partial class InnerPlayerControl : InnerNetObject { + private static readonly byte ColorsCount = (byte)Enum.GetValues().Length; + private readonly ILogger _logger; private readonly IEventManager _eventManager; private readonly Game _game; @@ -50,6 +53,7 @@ namespace Impostor.Server.Net.Inner.Objects public InnerCustomNetworkTransform NetworkTransform { get; } + [AllowNull] public InnerPlayerInfo PlayerInfo { get; internal set; } internal Queue RequestedPlayerName { get; } = new Queue(); @@ -76,12 +80,6 @@ namespace Impostor.Server.Net.Inner.Objects PlayerId = reader.ReadByte(); } - internal void Die(DeathReason reason) - { - PlayerInfo.IsDead = true; - PlayerInfo.LastDeathReason = reason; - } - public override async ValueTask HandleRpcAsync(ClientPlayer sender, ClientPlayer? target, RpcCalls call, IMessageReader reader) { switch (call) @@ -297,6 +295,12 @@ namespace Impostor.Server.Net.Inner.Objects return true; } + internal void Die(DeathReason reason) + { + PlayerInfo.IsDead = true; + PlayerInfo.LastDeathReason = reason; + } + private async ValueTask HandleCompleteTask(ClientPlayer sender, uint taskId) { var task = PlayerInfo.Tasks.ElementAtOrDefault((int)taskId); @@ -316,7 +320,7 @@ 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; @@ -428,8 +432,6 @@ namespace Impostor.Server.Net.Inner.Objects return true; } - private static readonly byte ColorsCount = (byte)Enum.GetValues().Length; - private async ValueTask HandleCheckColor(ClientPlayer sender, ColorType color) { if ((byte)color > ColorsCount) @@ -537,7 +539,7 @@ namespace Impostor.Server.Net.Inner.Objects PlayerInfo.LastMurder = _dateTimeProvider.UtcNow; - if (!target.PlayerInfo.IsDead) + if (target != null && !target.PlayerInfo.IsDead) { ((InnerPlayerControl)target).Die(DeathReason.Kill); await _eventManager.CallAsync(new PlayerMurderEvent(_game, sender, this, target)); @@ -556,8 +558,8 @@ 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 HandleSetPet(ClientPlayer sender, PetType pet) diff --git a/src/Impostor.Server/Net/Inner/Objects/InnerPlayerInfo.cs b/src/Impostor.Server/Net/Inner/Objects/InnerPlayerInfo.cs index 301fc088..1d488fbd 100644 --- a/src/Impostor.Server/Net/Inner/Objects/InnerPlayerInfo.cs +++ b/src/Impostor.Server/Net/Inner/Objects/InnerPlayerInfo.cs @@ -15,11 +15,11 @@ namespace Impostor.Server.Net.Inner.Objects PlayerId = playerId; } - public InnerPlayerControl Controller { get; internal set; } + public InnerPlayerControl? Controller { get; internal set; } public byte PlayerId { get; } - public string PlayerName { get; internal set; } + public string PlayerName { get; internal set; } = string.Empty; public ColorType Color { get; internal set; } @@ -37,7 +37,7 @@ namespace Impostor.Server.Net.Inner.Objects public DeathReason LastDeathReason { get; internal set; } - public List Tasks { get; internal set; } + public List Tasks { get; internal set; } = new List(0); public DateTimeOffset LastMurder { get; set; } diff --git a/src/Impostor.Server/Net/Inner/Objects/Systems/IActivatable.cs b/src/Impostor.Server/Net/Inner/Objects/Systems/IActivatable.cs index e595b25a..66a164c7 100644 --- a/src/Impostor.Server/Net/Inner/Objects/Systems/IActivatable.cs +++ b/src/Impostor.Server/Net/Inner/Objects/Systems/IActivatable.cs @@ -4,4 +4,4 @@ { 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 index a6ef88e5..441d7c35 100644 --- a/src/Impostor.Server/Net/Inner/Objects/Systems/ISystemType.cs +++ b/src/Impostor.Server/Net/Inner/Objects/Systems/ISystemType.cs @@ -8,4 +8,4 @@ namespace Impostor.Server.Net.Inner.Objects.Systems 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 index 64b1f5f0..df374bff 100644 --- a/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/DoorsSystemType.cs +++ b/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/DoorsSystemType.cs @@ -18,7 +18,7 @@ namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus MapTypes.Skeld => 13, MapTypes.MiraHQ => 2, MapTypes.Polus => 12, - _ => throw new ArgumentOutOfRangeException() + _ => throw new ArgumentOutOfRangeException(), }; _doors = new Dictionary(doorCount); @@ -57,4 +57,4 @@ namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus } } } -} \ 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 index 42aa8d37..4349233f 100644 --- a/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/HudOverrideSystemType.cs +++ b/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/HudOverrideSystemType.cs @@ -1,4 +1,5 @@ -using Impostor.Api.Net.Messages; +using System; +using Impostor.Api.Net.Messages; namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus { @@ -8,7 +9,7 @@ namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus public void Serialize(IMessageWriter writer, bool initialState) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } public void Deserialize(IMessageReader reader, bool initialState) @@ -16,4 +17,4 @@ namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus 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 index f6440243..681ebe16 100644 --- a/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/LifeSuppSystemType.cs +++ b/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/LifeSuppSystemType.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Impostor.Api.Net.Messages; namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus @@ -19,7 +20,7 @@ namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus public void Serialize(IMessageWriter writer, bool initialState) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } public void Deserialize(IMessageReader reader, bool initialState) @@ -41,4 +42,4 @@ namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus } } } -} \ 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 index 007b9d0a..4c2287fe 100644 --- a/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/MedScanSystem.cs +++ b/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/MedScanSystem.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Impostor.Api.Net.Messages; namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus @@ -14,7 +15,7 @@ namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus public void Serialize(IMessageWriter writer, bool initialState) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } public void Deserialize(IMessageReader reader, bool initialState) @@ -29,4 +30,4 @@ namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus } } } -} \ 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 index 43809184..7bc2ab37 100644 --- a/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/ReactorSystemType.cs +++ b/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/ReactorSystemType.cs @@ -20,7 +20,7 @@ namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus public void Serialize(IMessageWriter writer, bool initialState) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } public void Deserialize(IMessageReader reader, bool initialState) @@ -36,4 +36,4 @@ namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus } } } -} \ 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 index 193cfe80..73c10c38 100644 --- a/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/SabotageSystemType.cs +++ b/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/SabotageSystemType.cs @@ -1,4 +1,5 @@ -using Impostor.Api.Net.Messages; +using System; +using Impostor.Api.Net.Messages; namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus { @@ -15,7 +16,7 @@ namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus public void Serialize(IMessageWriter writer, bool initialState) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } public void Deserialize(IMessageReader reader, bool initialState) @@ -23,4 +24,4 @@ namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus 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 index df41b68e..d7964556 100644 --- a/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/SecurityCameraSystemType.cs +++ b/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/SecurityCameraSystemType.cs @@ -1,4 +1,5 @@ -using Impostor.Api.Net.Messages; +using System; +using Impostor.Api.Net.Messages; namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus { @@ -8,7 +9,7 @@ namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus public void Serialize(IMessageWriter writer, bool initialState) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } public void Deserialize(IMessageReader reader, bool initialState) @@ -16,4 +17,4 @@ namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus 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 index 925774ab..eb2b5726 100644 --- a/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/SwitchSystem.cs +++ b/src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/SwitchSystem.cs @@ -1,4 +1,5 @@ -using Impostor.Api.Net.Messages; +using System; +using Impostor.Api.Net.Messages; namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus { @@ -14,7 +15,7 @@ namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus public void Serialize(IMessageWriter writer, bool initialState) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } public void Deserialize(IMessageReader reader, bool initialState) @@ -24,4 +25,4 @@ namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus Value = reader.ReadByte(); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Net/Inner/SpawnFlags.cs b/src/Impostor.Server/Net/Inner/SpawnFlags.cs index 1860098c..28c2a1ab 100644 --- a/src/Impostor.Server/Net/Inner/SpawnFlags.cs +++ b/src/Impostor.Server/Net/Inner/SpawnFlags.cs @@ -8,4 +8,4 @@ namespace Impostor.Server.Net.Inner None = 0, IsClientCharacter = 1, } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Net/Manager/ClientManager.Api.cs b/src/Impostor.Server/Net/Manager/ClientManager.Api.cs index 6cbe5bf6..1ff970da 100644 --- a/src/Impostor.Server/Net/Manager/ClientManager.Api.cs +++ b/src/Impostor.Server/Net/Manager/ClientManager.Api.cs @@ -8,4 +8,4 @@ namespace Impostor.Server.Net.Manager { IEnumerable IClientManager.Clients => _clients.Values; } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Net/Manager/ClientManager.cs b/src/Impostor.Server/Net/Manager/ClientManager.cs index 32359f8f..6ee4515f 100644 --- a/src/Impostor.Server/Net/Manager/ClientManager.cs +++ b/src/Impostor.Server/Net/Manager/ClientManager.cs @@ -18,12 +18,12 @@ namespace Impostor.Server.Net.Manager { internal partial class ClientManager { - private static HashSet SupportedVersions { get; } = new HashSet + private static readonly HashSet SupportedVersions = new HashSet { GameVersion.GetVersion(2021, 3, 5), // 2021.3.5 }; - private static string ServerBrand { get; } = $"Impostor {DotnetUtils.GetVersion()}"; + private static readonly string ServerBrand = $"Impostor {DotnetUtils.GetVersion()}"; private readonly ILogger _logger; private readonly ConcurrentDictionary _clients; diff --git a/src/Impostor.Server/Net/Manager/GameManager.cs b/src/Impostor.Server/Net/Manager/GameManager.cs index 8d883a41..b10e7916 100644 --- a/src/Impostor.Server/Net/Manager/GameManager.cs +++ b/src/Impostor.Server/Net/Manager/GameManager.cs @@ -42,46 +42,9 @@ namespace Impostor.Server.Net.Manager IEnumerable IGameManager.Games => _games.Select(kv => kv.Value); - IGame IGameManager.Find(GameCode code) => Find(code); + IGame? IGameManager.Find(GameCode code) => Find(code); - public async ValueTask CreateAsync(GameOptionsData options) - { - // TODO: Prevent duplicates when using server redirector using INodeProvider. - var (success, game) = await TryCreateAsync(options); - - for (int i = 0; i < 10 && !success; i++) - { - (success, game) = await TryCreateAsync(options); - } - - if (!success) - { - throw new ImpostorException("Could not create new game"); // TODO: Fix generic exception. - } - - return game; - } - - private async ValueTask<(bool success, Game game)> TryCreateAsync(GameOptionsData options) - { - var gameCode = _gameCodeFactory.Create(); - var gameCodeStr = gameCode.Code; - var game = ActivatorUtilities.CreateInstance(_serviceProvider, _publicIp, gameCode, options); - - if (await _nodeLocator.ExistsAsync(gameCodeStr) || !_games.TryAdd(gameCode, game)) - { - return (false, null); - } - - await _nodeLocator.SaveAsync(gameCodeStr, _publicIp); - _logger.LogDebug("Created game with code {0}.", game.Code); - - await _eventManager.CallAsync(new GameCreatedEvent(game)); - - return (true, game); - } - - public Game Find(GameCode code) + public Game? Find(GameCode code) { _games.TryGetValue(code, out var game); return game; @@ -146,5 +109,42 @@ namespace Impostor.Server.Net.Manager await _eventManager.CallAsync(new GameDestroyedEvent(game)); } + + public async ValueTask CreateAsync(GameOptionsData options) + { + // TODO: Prevent duplicates when using server redirector using INodeProvider. + var (success, game) = await TryCreateAsync(options); + + for (var i = 0; i < 10 && !success; i++) + { + (success, game) = await TryCreateAsync(options); + } + + if (!success || game == null) + { + throw new ImpostorException("Could not create new game"); // TODO: Fix generic exception. + } + + return game; + } + + private async ValueTask<(bool Success, Game? Game)> TryCreateAsync(GameOptionsData options) + { + var gameCode = _gameCodeFactory.Create(); + var gameCodeStr = gameCode.Code; + var game = ActivatorUtilities.CreateInstance(_serviceProvider, _publicIp, gameCode, options); + + if (await _nodeLocator.ExistsAsync(gameCodeStr) || !_games.TryAdd(gameCode, game)) + { + return (false, null); + } + + await _nodeLocator.SaveAsync(gameCodeStr, _publicIp); + _logger.LogDebug("Created game with code {0}.", game.Code); + + await _eventManager.CallAsync(new GameCreatedEvent(game)); + + return (true, game); + } } } diff --git a/src/Impostor.Server/Net/Matchmaker.cs b/src/Impostor.Server/Net/Matchmaker.cs index e700703c..a5518dc3 100644 --- a/src/Impostor.Server/Net/Matchmaker.cs +++ b/src/Impostor.Server/Net/Matchmaker.cs @@ -18,7 +18,7 @@ namespace Impostor.Server.Net private readonly ObjectPool _readerPool; private readonly ILogger _logger; private readonly ILogger _connectionLogger; - private UdpConnectionListener _connection; + private UdpConnectionListener? _connection; public Matchmaker( ILogger logger, @@ -38,18 +38,23 @@ namespace Impostor.Server.Net { AddressFamily.InterNetwork => IPMode.IPv4, AddressFamily.InterNetworkV6 => IPMode.IPv6, - _ => throw new InvalidOperationException() + _ => throw new InvalidOperationException(), }; - _connection = new UdpConnectionListener(ipEndPoint, _readerPool, mode); - _connection.NewConnection = OnNewConnection; + _connection = new UdpConnectionListener(ipEndPoint, _readerPool, mode) + { + NewConnection = OnNewConnection, + }; await _connection.StartAsync(); } public async ValueTask StopAsync() { - await _connection.DisposeAsync(); + if (_connection != null) + { + await _connection.DisposeAsync(); + } } private async ValueTask OnNewConnection(NewConnectionEventArgs e) diff --git a/src/Impostor.Server/Net/Redirector/ClientRedirector.cs b/src/Impostor.Server/Net/Redirector/ClientRedirector.cs index afae57e8..0cfa76d0 100644 --- a/src/Impostor.Server/Net/Redirector/ClientRedirector.cs +++ b/src/Impostor.Server/Net/Redirector/ClientRedirector.cs @@ -10,7 +10,6 @@ using Impostor.Server.Config; using Impostor.Server.Net.Hazel; using Impostor.Server.Net.Manager; using Serilog; -using ILogger = Serilog.ILogger; namespace Impostor.Server.Net.Redirector { diff --git a/src/Impostor.Server/Net/Redirector/INodeLocator.cs b/src/Impostor.Server/Net/Redirector/INodeLocator.cs index 12563b9a..1c3391a9 100644 --- a/src/Impostor.Server/Net/Redirector/INodeLocator.cs +++ b/src/Impostor.Server/Net/Redirector/INodeLocator.cs @@ -5,10 +5,10 @@ namespace Impostor.Server.Net.Redirector { public interface INodeLocator { - ValueTask FindAsync(string gameCode); + ValueTask FindAsync(string gameCode); ValueTask SaveAsync(string gameCode, IPEndPoint endPoint); ValueTask RemoveAsync(string gameCode); } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Net/Redirector/INodeProvider.cs b/src/Impostor.Server/Net/Redirector/INodeProvider.cs index 318fcb2d..fb7240c8 100644 --- a/src/Impostor.Server/Net/Redirector/INodeProvider.cs +++ b/src/Impostor.Server/Net/Redirector/INodeProvider.cs @@ -6,4 +6,4 @@ namespace Impostor.Server.Net.Redirector { IPEndPoint Get(); } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Net/Redirector/NodeLocatorNoOp.cs b/src/Impostor.Server/Net/Redirector/NodeLocatorNoOp.cs index fd4cd56f..baef6db4 100644 --- a/src/Impostor.Server/Net/Redirector/NodeLocatorNoOp.cs +++ b/src/Impostor.Server/Net/Redirector/NodeLocatorNoOp.cs @@ -5,10 +5,10 @@ namespace Impostor.Server.Net.Redirector { public class NodeLocatorNoOp : INodeLocator { - public ValueTask FindAsync(string gameCode) => ValueTask.FromResult(default(IPEndPoint)); + public ValueTask FindAsync(string gameCode) => ValueTask.FromResult(default(IPEndPoint)); public ValueTask SaveAsync(string gameCode, IPEndPoint endPoint) => ValueTask.CompletedTask; public ValueTask RemoveAsync(string gameCode) => ValueTask.CompletedTask; } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Net/Redirector/NodeLocatorRedis.cs b/src/Impostor.Server/Net/Redirector/NodeLocatorRedis.cs index 0b6fdff8..f4595e35 100644 --- a/src/Impostor.Server/Net/Redirector/NodeLocatorRedis.cs +++ b/src/Impostor.Server/Net/Redirector/NodeLocatorRedis.cs @@ -16,7 +16,7 @@ namespace Impostor.Server.Net.Redirector _cache = cache; } - public async ValueTask FindAsync(string gameCode) + public async ValueTask FindAsync(string gameCode) { var entry = await _cache.GetStringAsync(gameCode); if (entry == null) @@ -40,4 +40,4 @@ namespace Impostor.Server.Net.Redirector await _cache.RemoveAsync(gameCode); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Net/Redirector/NodeLocatorUDP.cs b/src/Impostor.Server/Net/Redirector/NodeLocatorUDP.cs index 2539a8f2..c75392ad 100644 --- a/src/Impostor.Server/Net/Redirector/NodeLocatorUDP.cs +++ b/src/Impostor.Server/Net/Redirector/NodeLocatorUDP.cs @@ -14,9 +14,9 @@ namespace Impostor.Server.Net.Redirector { private readonly ILogger _logger; private readonly bool _isMaster; - private readonly IPEndPoint _server; - private readonly UdpClient _client; - private readonly ConcurrentDictionary _availableNodes; + private readonly IPEndPoint? _server; + private readonly UdpClient? _client; + private readonly ConcurrentDictionary? _availableNodes; public NodeLocatorUdp(ILogger logger, IOptions config) { @@ -31,7 +31,7 @@ namespace Impostor.Server.Net.Redirector { _isMaster = false; - if (!IPEndPoint.TryParse(config.Value.Locator.UdpMasterEndpoint, out var endpoint)) + if (!IPEndPoint.TryParse(config.Value.Locator!.UdpMasterEndpoint, out var endpoint)) { throw new ArgumentException("UdpMasterEndpoint should be in the ip:port format."); } @@ -54,13 +54,9 @@ namespace Impostor.Server.Net.Redirector { _logger.LogDebug("Received update {0} -> {1}", gameCode, ip); - _availableNodes.AddOrUpdate( + _availableNodes!.AddOrUpdate( gameCode, - s => new AvailableNode - { - Endpoint = ip, - LastUpdated = DateTimeOffset.UtcNow, - }, + s => new AvailableNode(ip, DateTimeOffset.UtcNow), (s, node) => { node.Endpoint = ip; @@ -78,14 +74,14 @@ namespace Impostor.Server.Net.Redirector } } - public ValueTask FindAsync(string gameCode) + public ValueTask FindAsync(string gameCode) { if (!_isMaster) { return ValueTask.FromResult(default(IPEndPoint)); } - if (_availableNodes.TryGetValue(gameCode, out var node)) + if (_availableNodes!.TryGetValue(gameCode, out var node)) { if (node.Expired) { @@ -93,7 +89,7 @@ namespace Impostor.Server.Net.Redirector return ValueTask.FromResult(default(IPEndPoint)); } - return ValueTask.FromResult(node.Endpoint); + return ValueTask.FromResult(node.Endpoint)!; } return ValueTask.FromResult(default(IPEndPoint)); @@ -106,14 +102,14 @@ namespace Impostor.Server.Net.Redirector return ValueTask.CompletedTask; } - _availableNodes.TryRemove(gameCode, out _); + _availableNodes!.TryRemove(gameCode, out _); return ValueTask.CompletedTask; } public ValueTask SaveAsync(string gameCode, IPEndPoint endPoint) { var data = Encoding.UTF8.GetBytes($"{gameCode},{endPoint}"); - _client.Send(data, data.Length, _server); + _client!.Send(data, data.Length, _server); return ValueTask.CompletedTask; } @@ -124,6 +120,12 @@ namespace Impostor.Server.Net.Redirector private class AvailableNode { + public AvailableNode(IPEndPoint endpoint, DateTimeOffset lastUpdated) + { + Endpoint = endpoint; + LastUpdated = lastUpdated; + } + public IPEndPoint Endpoint { get; set; } public DateTimeOffset LastUpdated { get; set; } diff --git a/src/Impostor.Server/Net/Redirector/NodeLocatorUDPService.cs b/src/Impostor.Server/Net/Redirector/NodeLocatorUDPService.cs index 3706bb49..781e91f3 100644 --- a/src/Impostor.Server/Net/Redirector/NodeLocatorUDPService.cs +++ b/src/Impostor.Server/Net/Redirector/NodeLocatorUDPService.cs @@ -25,7 +25,7 @@ namespace Impostor.Server.Net.Redirector _nodeLocator = (NodeLocatorUdp)nodeLocator; _logger = logger; - if (!IPEndPoint.TryParse(options.Value.Locator.UdpMasterEndpoint, out var endpoint)) + if (!IPEndPoint.TryParse(options.Value.Locator!.UdpMasterEndpoint, out var endpoint)) { throw new ArgumentException("UdpMasterEndpoint should be in the ip:port format."); } diff --git a/src/Impostor.Server/Net/Redirector/NodeProviderConfig.cs b/src/Impostor.Server/Net/Redirector/NodeProviderConfig.cs index 4e19c43c..7e2982e8 100644 --- a/src/Impostor.Server/Net/Redirector/NodeProviderConfig.cs +++ b/src/Impostor.Server/Net/Redirector/NodeProviderConfig.cs @@ -40,4 +40,4 @@ namespace Impostor.Server.Net.Redirector } } } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Net/State/ClientPlayer.cs b/src/Impostor.Server/Net/State/ClientPlayer.cs index ceb73b49..b615c064 100644 --- a/src/Impostor.Server/Net/State/ClientPlayer.cs +++ b/src/Impostor.Server/Net/State/ClientPlayer.cs @@ -17,7 +17,7 @@ namespace Impostor.Server.Net.State public ClientPlayer(ILogger logger, ClientBase client, Game game) { _logger = logger; - _spawnTimeout = new Timer(RunSpawnTimeout, null, -1, -1); + _spawnTimeout = new Timer(RunSpawnTimeout!, null, -1, -1); Game = game; Client = client; @@ -35,7 +35,7 @@ namespace Impostor.Server.Net.State public bool IsHost => Game?.Host == this; - public string Scene { get; internal set; } + public string? Scene { get; internal set; } public RuntimePlatform? Platform { get; internal set; } diff --git a/src/Impostor.Server/Net/State/Game.Api.cs b/src/Impostor.Server/Net/State/Game.Api.cs index a2996915..44257e76 100644 --- a/src/Impostor.Server/Net/State/Game.Api.cs +++ b/src/Impostor.Server/Net/State/Game.Api.cs @@ -25,7 +25,7 @@ namespace Impostor.Server.Net.State public async ValueTask SyncSettingsAsync() { - if (Host.Character == null) + if (Host?.Character == null) { throw new ImpostorException("Attempted to set infected when the host was not spawned."); } diff --git a/src/Impostor.Server/Net/State/Game.Data.cs b/src/Impostor.Server/Net/State/Game.Data.cs index a2eaa09d..9e5fd014 100644 --- a/src/Impostor.Server/Net/State/Game.Data.cs +++ b/src/Impostor.Server/Net/State/Game.Data.cs @@ -1,14 +1,10 @@ using System; using System.Collections.Generic; -using System.Threading; using System.Threading.Tasks; using Impostor.Api; -using Impostor.Api.Innersloth; using Impostor.Api.Net.Inner; using Impostor.Api.Net.Messages; -using Impostor.Api.Net.Messages.S2C; using Impostor.Api.Unity; -using Impostor.Hazel; using Impostor.Server.Events.Meeting; using Impostor.Server.Events.Player; using Impostor.Server.Net.Inner; @@ -47,124 +43,24 @@ namespace Impostor.Server.Net.State }; private readonly List _allObjects = new List(); + private readonly Dictionary _allObjectsFast = new Dictionary(); - private int _gamedataInitialized; - - private async ValueTask OnSpawnAsync(InnerNetObject netObj) + public T? FindObjectByNetId(uint netId) + where T : IInnerNetObject { - switch (netObj) + if (_allObjectsFast.TryGetValue(netId, out var obj)) { - case InnerLobbyBehaviour lobby: - { - GameNet.LobbyBehaviour = lobby; - break; - } - - case InnerGameData data: - { - GameNet.GameData = data; - break; - } - - case InnerVoteBanSystem voteBan: - { - GameNet.VoteBan = voteBan; - break; - } - - case InnerShipStatus shipStatus: - { - GameNet.ShipStatus = shipStatus; - break; - } - - case InnerPlayerControl control: - { - // Hook up InnerPlayerControl <-> IClientPlayer. - if (!TryGetPlayer(control.OwnerId, out var player)) - { - throw new ImpostorException("Failed to find player that spawned the InnerPlayerControl"); - } - - player.Character = control; - player.DisableSpawnTimeout(); - - // Hook up InnerPlayerControl <-> InnerPlayerControl.PlayerInfo. - control.PlayerInfo = GameNet.GameData.GetPlayerById(control.PlayerId)!; - - if (control.PlayerInfo == null) - { - GameNet.GameData.AddPlayer(control); - } - - if (control.PlayerInfo != null) - { - control.PlayerInfo!.Controller = control; - } - - await _eventManager.CallAsync(new PlayerSpawnedEvent(this, player, control)); - - break; - } - - case InnerMeetingHud meetingHud: - { - await _eventManager.CallAsync(new MeetingStartedEvent(this, meetingHud)); - break; - } + return (T)(IInnerNetObject)obj; } - } - private async ValueTask OnDestroyAsync(InnerNetObject netObj) - { - switch (netObj) - { - case InnerLobbyBehaviour: - { - GameNet.LobbyBehaviour = null; - break; - } - - case InnerGameData: - { - GameNet.GameData = null; - break; - } - - case InnerVoteBanSystem: - { - GameNet.VoteBan = null; - break; - } - - case InnerShipStatus: - { - GameNet.ShipStatus = null; - break; - } - - case InnerPlayerControl control: - { - // Remove InnerPlayerControl <-> IClientPlayer. - if (TryGetPlayer(control.OwnerId, out var player)) - { - player.Character = null; - } - - await _eventManager.CallAsync(new PlayerDestroyedEvent(this, player, control)); - - break; - } - - - } + return default; } public async ValueTask HandleGameDataAsync(IMessageReader parent, ClientPlayer sender, bool toPlayer) { // Find target player. - ClientPlayer target = null; + ClientPlayer? target = null; if (toPlayer) { @@ -232,7 +128,7 @@ namespace Impostor.Server.Net.State var objectId = reader.ReadPackedUInt32(); if (objectId < SpawnableObjects.Length) { - var innerNetObject = (InnerNetObject) ActivatorUtilities.CreateInstance(_serviceProvider, SpawnableObjects[objectId], this); + var innerNetObject = (InnerNetObject)ActivatorUtilities.CreateInstance(_serviceProvider, SpawnableObjects[objectId], this); var ownerClientId = reader.ReadPackedInt32(); // Prevent fake client from being broadcasted. @@ -242,7 +138,7 @@ namespace Impostor.Server.Net.State return false; } - innerNetObject.SpawnFlags = (SpawnFlags) reader.ReadByte(); + innerNetObject.SpawnFlags = (SpawnFlags)reader.ReadByte(); var components = innerNetObject.GetComponentsInChildren(); var componentsCount = reader.ReadPackedInt32(); @@ -393,6 +289,113 @@ namespace Impostor.Server.Net.State return true; } + private async ValueTask OnSpawnAsync(InnerNetObject netObj) + { + switch (netObj) + { + case InnerLobbyBehaviour lobby: + { + GameNet.LobbyBehaviour = lobby; + break; + } + + case InnerGameData data: + { + GameNet.GameData = data; + break; + } + + case InnerVoteBanSystem voteBan: + { + GameNet.VoteBan = voteBan; + break; + } + + case InnerShipStatus shipStatus: + { + GameNet.ShipStatus = shipStatus; + break; + } + + case InnerPlayerControl control: + { + // Hook up InnerPlayerControl <-> IClientPlayer. + if (!TryGetPlayer(control.OwnerId, out var player)) + { + throw new ImpostorException("Failed to find player that spawned the InnerPlayerControl"); + } + + player.Character = control; + player.DisableSpawnTimeout(); + + // Hook up InnerPlayerControl <-> InnerPlayerControl.PlayerInfo. + var playerInfo = GameNet.GameData!.GetPlayerById(control.PlayerId); + + if (playerInfo != null) + { + playerInfo.Controller = control; + control.PlayerInfo = playerInfo; + } + else + { + GameNet.GameData.AddPlayer(control); + } + + await _eventManager.CallAsync(new PlayerSpawnedEvent(this, player, control)); + + break; + } + + case InnerMeetingHud meetingHud: + { + await _eventManager.CallAsync(new MeetingStartedEvent(this, meetingHud)); + break; + } + } + } + + private async ValueTask OnDestroyAsync(InnerNetObject netObj) + { + switch (netObj) + { + case InnerLobbyBehaviour: + { + GameNet.LobbyBehaviour = null; + break; + } + + case InnerGameData: + { + GameNet.GameData = null; + break; + } + + case InnerVoteBanSystem: + { + GameNet.VoteBan = null; + break; + } + + case InnerShipStatus: + { + GameNet.ShipStatus = null; + break; + } + + case InnerPlayerControl control: + { + // Remove InnerPlayerControl <-> IClientPlayer. + if (TryGetPlayer(control.OwnerId, out var player)) + { + player.Character = null; + await _eventManager.CallAsync(new PlayerDestroyedEvent(this, player, control)); + } + + break; + } + } + } + private bool AddNetObject(InnerNetObject obj) { if (_allObjectsFast.ContainsKey(obj.NetId)) @@ -417,16 +420,5 @@ namespace Impostor.Server.Net.State obj.NetId = uint.MaxValue; } - - public T? FindObjectByNetId(uint netId) - where T : IInnerNetObject - { - if (_allObjectsFast.TryGetValue(netId, out var obj)) - { - return (T)(IInnerNetObject)obj; - } - - return default; - } } } diff --git a/src/Impostor.Server/Net/State/Game.Incoming.cs b/src/Impostor.Server/Net/State/Game.Incoming.cs index 547224db..8f9df626 100644 --- a/src/Impostor.Server/Net/State/Game.Incoming.cs +++ b/src/Impostor.Server/Net/State/Game.Incoming.cs @@ -29,6 +29,74 @@ namespace Impostor.Server.Net.State await _eventManager.CallAsync(new GameStartingEvent(this)); } + public async ValueTask HandleEndGame(IMessageReader message, GameOverReason gameOverReason) + { + GameState = GameStates.Ended; + + // Broadcast end of the game. + using (var packet = MessageWriter.Get(MessageType.Reliable)) + { + message.CopyTo(packet); + await SendToAllAsync(packet); + } + + // Put all players in the correct limbo state. + foreach (var player in _players) + { + player.Value.Limbo = LimboStates.PreSpawn; + } + + await _eventManager.CallAsync(new GameEndedEvent(this, gameOverReason)); + } + + public async ValueTask HandleAlterGame(IMessageReader message, IClientPlayer sender, bool isPublic) + { + IsPublic = isPublic; + + using var packet = MessageWriter.Get(MessageType.Reliable); + message.CopyTo(packet); + await SendToAllExceptAsync(packet, sender.Client.Id); + + await _eventManager.CallAsync(new GameAlterEvent(this, isPublic)); + } + + public async ValueTask HandleRemovePlayer(int playerId, DisconnectReason reason) + { + await PlayerRemove(playerId); + + // It's possible that the last player was removed, so check if the game is still around. + if (GameState == GameStates.Destroyed) + { + return; + } + + using var packet = MessageWriter.Get(MessageType.Reliable); + WriteRemovePlayerMessage(packet, false, playerId, reason); + await SendToAllExceptAsync(packet, playerId); + } + + public async ValueTask HandleKickPlayer(int playerId, bool isBan) + { + _logger.LogInformation("{0} - Player {1} has left.", Code, playerId); + + using var message = MessageWriter.Get(MessageType.Reliable); + + // Send message to everyone that this player was kicked. + WriteKickPlayerMessage(message, false, playerId, isBan); + + await SendToAllAsync(message); + await PlayerRemove(playerId, isBan); + + // Remove the player from everyone's game. + WriteRemovePlayerMessage( + message, + true, + playerId, + isBan ? DisconnectReason.Banned : DisconnectReason.Kicked); + + await SendToAllExceptAsync(message, playerId); + } + public async ValueTask AddClientAsync(ClientBase client) { var hasLock = false; @@ -53,10 +121,34 @@ namespace Impostor.Server.Net.State return GameJoinResult.FromError(GameJoinError.InvalidClient); } + private async ValueTask HandleJoinGameNew(ClientPlayer sender, bool isNew) + { + _logger.LogInformation("{0} - Player {1} ({2}) is joining.", Code, sender.Client.Name, sender.Client.Id); + + // Add player to the game. + if (isNew) + { + await PlayerAdd(sender); + } + + sender.InitializeSpawnTimeout(); + + using (var message = MessageWriter.Get(MessageType.Reliable)) + { + WriteJoinedGameMessage(message, false, sender); + WriteAlterGameMessage(message, false, IsPublic); + + sender.Limbo = LimboStates.NotLimbo; + + await SendToAsync(message, sender.Client.Id); + await BroadcastJoinMessage(message, true, sender); + } + } + private async ValueTask AddClientSafeAsync(ClientBase client) { // Check if the IP of the player is banned. - if (client.Connection != null && _bannedIps.Contains(client.Connection.EndPoint.Address)) + if (_bannedIps.Contains(client.Connection.EndPoint.Address)) { return GameJoinResult.FromError(GameJoinError.Banned); } @@ -132,98 +224,6 @@ namespace Impostor.Server.Net.State return GameJoinResult.CreateSuccess(player); } - public async ValueTask HandleEndGame(IMessageReader message, GameOverReason gameOverReason) - { - GameState = GameStates.Ended; - - // Broadcast end of the game. - using (var packet = MessageWriter.Get(MessageType.Reliable)) - { - message.CopyTo(packet); - await SendToAllAsync(packet); - } - - // Put all players in the correct limbo state. - foreach (var player in _players) - { - player.Value.Limbo = LimboStates.PreSpawn; - } - - await _eventManager.CallAsync(new GameEndedEvent(this, gameOverReason)); - } - - public async ValueTask HandleAlterGame(IMessageReader message, IClientPlayer sender, bool isPublic) - { - IsPublic = isPublic; - - using var packet = MessageWriter.Get(MessageType.Reliable); - message.CopyTo(packet); - await SendToAllExceptAsync(packet, sender.Client.Id); - - await _eventManager.CallAsync(new GameAlterEvent(this, isPublic)); - } - - public async ValueTask HandleRemovePlayer(int playerId, DisconnectReason reason) - { - await PlayerRemove(playerId); - - // It's possible that the last player was removed, so check if the game is still around. - if (GameState == GameStates.Destroyed) - { - return; - } - - using var packet = MessageWriter.Get(MessageType.Reliable); - WriteRemovePlayerMessage(packet, false, playerId, reason); - await SendToAllExceptAsync(packet, playerId); - } - - public async ValueTask HandleKickPlayer(int playerId, bool isBan) - { - _logger.LogInformation("{0} - Player {1} has left.", Code, playerId); - - using var message = MessageWriter.Get(MessageType.Reliable); - - // Send message to everyone that this player was kicked. - WriteKickPlayerMessage(message, false, playerId, isBan); - - await SendToAllAsync(message); - await PlayerRemove(playerId, isBan); - - // Remove the player from everyone's game. - WriteRemovePlayerMessage( - message, - true, - playerId, - isBan ? DisconnectReason.Banned : DisconnectReason.Kicked); - - await SendToAllExceptAsync(message, playerId); - } - - private async ValueTask HandleJoinGameNew(ClientPlayer sender, bool isNew) - { - _logger.LogInformation("{0} - Player {1} ({2}) is joining.", Code, sender.Client.Name, sender.Client.Id); - - // Add player to the game. - if (isNew) - { - await PlayerAdd(sender); - } - - sender.InitializeSpawnTimeout(); - - using (var message = MessageWriter.Get(MessageType.Reliable)) - { - WriteJoinedGameMessage(message, false, sender); - WriteAlterGameMessage(message, false, IsPublic); - - sender.Limbo = LimboStates.NotLimbo; - - await SendToAsync(message, sender.Client.Id); - await BroadcastJoinMessage(message, true, sender); - } - } - private async ValueTask HandleJoinGameNext(ClientPlayer sender, bool isNew) { _logger.LogInformation("{0} - Player {1} ({2}) is rejoining.", Code, sender.Client.Name, sender.Client.Id); diff --git a/src/Impostor.Server/Net/State/Game.Outgoing.cs b/src/Impostor.Server/Net/State/Game.Outgoing.cs index 21b60670..5c84f947 100644 --- a/src/Impostor.Server/Net/State/Game.Outgoing.cs +++ b/src/Impostor.Server/Net/State/Game.Outgoing.cs @@ -55,7 +55,7 @@ namespace Impostor.Server.Net.State writer.StartMessage(GameDataTag.RpcFlag); writer.WritePacked(targetNetId); - writer.Write((byte) callId); + writer.Write((byte)callId); return writer; } diff --git a/src/Impostor.Server/Net/State/Game.State.cs b/src/Impostor.Server/Net/State/Game.State.cs index 927548e7..9f9d9047 100644 --- a/src/Impostor.Server/Net/State/Game.State.cs +++ b/src/Impostor.Server/Net/State/Game.State.cs @@ -66,7 +66,7 @@ namespace Impostor.Server.Net.State await MigrateHost(); } - if (isBan && player.Client.Connection != null) + if (isBan) { BanIp(player.Client.Connection.EndPoint.Address); } diff --git a/src/Impostor.Server/Net/State/Game.cs b/src/Impostor.Server/Net/State/Game.cs index 6ca2fd68..823c049f 100644 --- a/src/Impostor.Server/Net/State/Game.cs +++ b/src/Impostor.Server/Net/State/Game.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Net; using System.Numerics; @@ -66,8 +67,6 @@ namespace Impostor.Server.Net.State public GameStates GameState { get; private set; } - internal GameNet GameNet { get; } - public GameOptionsData Options { get; } public IDictionary Items { get; } @@ -78,7 +77,9 @@ namespace Impostor.Server.Net.State public IEnumerable Players => _players.Select(p => p.Value); - public bool TryGetPlayer(int id, out ClientPlayer player) + internal GameNet GameNet { get; } + + public bool TryGetPlayer(int id, [MaybeNullWhen(false)] out ClientPlayer player) { if (_players.TryGetValue(id, out var result)) { @@ -90,11 +91,16 @@ namespace Impostor.Server.Net.State return false; } - public IClientPlayer GetClientPlayer(int clientId) + public IClientPlayer? GetClientPlayer(int clientId) { return _players.TryGetValue(clientId, out var clientPlayer) ? clientPlayer : null; } + public ValueTask EndAsync() + { + return _gameManager.RemoveAsync(Code); + } + internal async ValueTask StartedAsync() { if (GameState == GameStates.Starting) @@ -111,11 +117,6 @@ namespace Impostor.Server.Net.State } } - public ValueTask EndAsync() - { - return _gameManager.RemoveAsync(Code); - } - private ValueTask BroadcastJoinMessage(IMessageWriter message, bool clear, ClientPlayer player) { Message01JoinGameS2C.SerializeJoin(message, clear, Code, player.Client.Id, HostId); @@ -127,7 +128,7 @@ namespace Impostor.Server.Net.State { return Players .Where(filter) - .Select(p => p.Client.Connection); + .Select(p => p.Client.Connection)!; } } } diff --git a/src/Impostor.Server/Net/State/GameNet.Api.cs b/src/Impostor.Server/Net/State/GameNet.Api.cs index 34ea0fe6..4fed5276 100644 --- a/src/Impostor.Server/Net/State/GameNet.Api.cs +++ b/src/Impostor.Server/Net/State/GameNet.Api.cs @@ -6,12 +6,12 @@ namespace Impostor.Server.Net.State /// internal partial class GameNet : IGameNet { - IInnerLobbyBehaviour IGameNet.LobbyBehaviour => LobbyBehaviour; + IInnerLobbyBehaviour? IGameNet.LobbyBehaviour => LobbyBehaviour; - IInnerGameData IGameNet.GameData => GameData; + IInnerGameData? IGameNet.GameData => GameData; - IInnerVoteBanSystem IGameNet.VoteBan => VoteBan; + IInnerVoteBanSystem? IGameNet.VoteBan => VoteBan; - IInnerShipStatus IGameNet.ShipStatus => ShipStatus; + IInnerShipStatus? IGameNet.ShipStatus => ShipStatus; } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Net/State/GameNet.cs b/src/Impostor.Server/Net/State/GameNet.cs index c5542f9d..37e0cbd9 100644 --- a/src/Impostor.Server/Net/State/GameNet.cs +++ b/src/Impostor.Server/Net/State/GameNet.cs @@ -5,12 +5,12 @@ namespace Impostor.Server.Net.State { internal partial class GameNet { - public InnerLobbyBehaviour LobbyBehaviour { get; internal set; } + public InnerLobbyBehaviour? LobbyBehaviour { get; internal set; } - public InnerGameData GameData { get; internal set; } + public InnerGameData? GameData { get; internal set; } - public InnerVoteBanSystem VoteBan { get; internal set; } + public InnerVoteBanSystem? VoteBan { get; internal set; } - public InnerShipStatus ShipStatus { get; internal set; } + public InnerShipStatus? ShipStatus { get; internal set; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Plugins/AssemblyInformation.cs b/src/Impostor.Server/Plugins/AssemblyInformation.cs index 5f6aee11..df1bf84e 100644 --- a/src/Impostor.Server/Plugins/AssemblyInformation.cs +++ b/src/Impostor.Server/Plugins/AssemblyInformation.cs @@ -6,7 +6,7 @@ namespace Impostor.Server.Plugins { public class AssemblyInformation : IAssemblyInformation { - private Assembly _assembly; + private Assembly? _assembly; public AssemblyInformation(AssemblyName assemblyName, string path, bool isPlugin) { @@ -35,4 +35,4 @@ namespace Impostor.Server.Plugins return _assembly; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Plugins/IAssemblyInformation.cs b/src/Impostor.Server/Plugins/IAssemblyInformation.cs index fb36e92a..f724cf29 100644 --- a/src/Impostor.Server/Plugins/IAssemblyInformation.cs +++ b/src/Impostor.Server/Plugins/IAssemblyInformation.cs @@ -11,4 +11,4 @@ namespace Impostor.Server.Plugins Assembly Load(AssemblyLoadContext context); } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Plugins/LoadedAssemblyInformation.cs b/src/Impostor.Server/Plugins/LoadedAssemblyInformation.cs index 720367cc..5f7d0bbc 100644 --- a/src/Impostor.Server/Plugins/LoadedAssemblyInformation.cs +++ b/src/Impostor.Server/Plugins/LoadedAssemblyInformation.cs @@ -22,4 +22,4 @@ namespace Impostor.Server.Plugins return _assembly; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Plugins/PluginConfig.cs b/src/Impostor.Server/Plugins/PluginConfig.cs index 22dc9e90..66afceb3 100644 --- a/src/Impostor.Server/Plugins/PluginConfig.cs +++ b/src/Impostor.Server/Plugins/PluginConfig.cs @@ -8,4 +8,4 @@ namespace Impostor.Server.Plugins public List LibraryPaths { get; set; } = new List(); } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Plugins/PluginInformation.cs b/src/Impostor.Server/Plugins/PluginInformation.cs index e6a5b6c8..f9f61a1f 100644 --- a/src/Impostor.Server/Plugins/PluginInformation.cs +++ b/src/Impostor.Server/Plugins/PluginInformation.cs @@ -8,9 +8,9 @@ namespace Impostor.Server.Plugins { private readonly ImpostorPluginAttribute _attribute; - public PluginInformation(IPluginStartup startup, Type pluginType) + public PluginInformation(IPluginStartup? startup, Type pluginType) { - _attribute = pluginType.GetCustomAttribute(); + _attribute = pluginType.GetCustomAttribute()!; Startup = startup; PluginType = pluginType; @@ -24,15 +24,15 @@ namespace Impostor.Server.Plugins public string Version => _attribute.Version; - public IPluginStartup Startup { get; } + public IPluginStartup? Startup { get; } public Type PluginType { get; } - public IPlugin Instance { get; set; } + public IPlugin? Instance { get; set; } public override string ToString() { return $"{Package} {Name} ({Version}) by {Author}"; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Plugins/PluginLoader.cs b/src/Impostor.Server/Plugins/PluginLoader.cs index 4b5d07a5..90b9caf8 100644 --- a/src/Impostor.Server/Plugins/PluginLoader.cs +++ b/src/Impostor.Server/Plugins/PluginLoader.cs @@ -47,7 +47,7 @@ namespace Impostor.Server.Plugins // Some plugins may be referencing another Impostor.Api version and try to load it. // We want to only use the one shipped with the server. - if (name.Name.Equals("Impostor.Api")) + if (name.Name == "Impostor.Api") { return typeof(IPlugin).Assembly; } @@ -104,18 +104,18 @@ namespace Impostor.Server.Plugins plugin.First())); } - foreach (var plugin in plugins.Where(plugin => plugin.Startup != null)) + foreach (var plugin in plugins) { - plugin.Startup.ConfigureHost(builder); + plugin.Startup?.ConfigureHost(builder); } builder.ConfigureServices(services => { services.AddHostedService(provider => ActivatorUtilities.CreateInstance(provider, plugins)); - foreach (var plugin in plugins.Where(plugin => plugin.Startup != null)) + foreach (var plugin in plugins) { - plugin.Startup.ConfigureServices(services); + plugin.Startup?.ConfigureServices(services); } }); diff --git a/src/Impostor.Server/Plugins/PluginLoaderException.cs b/src/Impostor.Server/Plugins/PluginLoaderException.cs index 64424a14..740cc468 100644 --- a/src/Impostor.Server/Plugins/PluginLoaderException.cs +++ b/src/Impostor.Server/Plugins/PluginLoaderException.cs @@ -10,10 +10,6 @@ namespace Impostor.Server.Plugins { } - protected PluginLoaderException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } - public PluginLoaderException(string? message) : base(message) { } @@ -21,5 +17,9 @@ namespace Impostor.Server.Plugins public PluginLoaderException(string? message, Exception? innerException) : base(message, innerException) { } + + protected PluginLoaderException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Plugins/PluginLoaderService.cs b/src/Impostor.Server/Plugins/PluginLoaderService.cs index 0afbc223..40e13b5b 100644 --- a/src/Impostor.Server/Plugins/PluginLoaderService.cs +++ b/src/Impostor.Server/Plugins/PluginLoaderService.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Threading; using System.Threading.Tasks; using Impostor.Api.Plugins; @@ -32,7 +31,7 @@ namespace Impostor.Server.Plugins _logger.LogInformation("Enabling plugin {0}.", plugin); // Create instance and inject services. - plugin.Instance = (IPlugin) ActivatorUtilities.CreateInstance(_serviceProvider, plugin.PluginType); + plugin.Instance = (IPlugin)ActivatorUtilities.CreateInstance(_serviceProvider, plugin.PluginType); // Enable plugin. await plugin.Instance.EnableAsync(); @@ -41,20 +40,25 @@ namespace Impostor.Server.Plugins _logger.LogInformation( _plugins.Count == 1 ? "Loaded {0} plugin." - : "Loaded {0} plugins.", _plugins.Count); + : "Loaded {0} plugins.", + _plugins.Count + ); } public async Task StopAsync(CancellationToken cancellationToken) { // Disable all plugins with a valid instance set. // In the case of a failed startup, some can be null. - foreach (var plugin in _plugins.Where(plugin => plugin.Instance != null)) + foreach (var plugin in _plugins) { - _logger.LogInformation("Disabling plugin {0}.", plugin); + if (plugin.Instance != null) + { + _logger.LogInformation("Disabling plugin {0}.", plugin); - // Disable plugin. - await plugin.Instance.DisableAsync(); + // Disable plugin. + await plugin.Instance.DisableAsync(); + } } } } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Program.cs b/src/Impostor.Server/Program.cs index 109c6be0..ab582caa 100644 --- a/src/Impostor.Server/Program.cs +++ b/src/Impostor.Server/Program.cs @@ -128,7 +128,7 @@ namespace Impostor.Server if (redirector.Enabled) { - if (!string.IsNullOrEmpty(redirector.Locator.Redis)) + if (!string.IsNullOrEmpty(redirector.Locator?.Redis)) { // When joining a game, it retrieves the game server ip from redis. // When a game has been created on this node, it stores the game code with its ip in redis. @@ -141,7 +141,7 @@ namespace Impostor.Server options.InstanceName = "ImpostorRedis"; }); } - else if (!string.IsNullOrEmpty(redirector.Locator.UdpMasterEndpoint)) + else if (!string.IsNullOrEmpty(redirector.Locator?.UdpMasterEndpoint)) { services.AddSingleton(); diff --git a/src/Impostor.Server/ProjectRules.ruleset b/src/Impostor.Server/ProjectRules.ruleset deleted file mode 100644 index fd6daac0..00000000 --- a/src/Impostor.Server/ProjectRules.ruleset +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Impostor.Server/Properties/AssemblyInfo.cs b/src/Impostor.Server/Properties/AssemblyInfo.cs index 84c51585..eed7af61 100644 --- a/src/Impostor.Server/Properties/AssemblyInfo.cs +++ b/src/Impostor.Server/Properties/AssemblyInfo.cs @@ -1,5 +1,5 @@ using System.Runtime.CompilerServices; -[assembly:InternalsVisibleTo("Impostor.Benchmarks")] -[assembly:InternalsVisibleTo("Impostor.Tests")] -[assembly:InternalsVisibleTo("Impostor.Tools.ServerReplay")] +[assembly: InternalsVisibleTo("Impostor.Benchmarks")] +[assembly: InternalsVisibleTo("Impostor.Tests")] +[assembly: InternalsVisibleTo("Impostor.Tools.ServerReplay")] diff --git a/src/Impostor.Server/Recorder/PacketRecorder.cs b/src/Impostor.Server/Recorder/PacketRecorder.cs index c8efdb35..905e0262 100644 --- a/src/Impostor.Server/Recorder/PacketRecorder.cs +++ b/src/Impostor.Server/Recorder/PacketRecorder.cs @@ -17,7 +17,7 @@ using Microsoft.Extensions.Options; namespace Impostor.Server.Recorder { /// - /// Records all packets received in . + /// Records all packets received in . /// internal class PacketRecorder : BackgroundService { @@ -31,7 +31,7 @@ namespace Impostor.Server.Recorder { var name = $"session_{DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}.dat"; - _path = Path.Combine(options.Value.GameRecorderPath, name); + _path = Path.Combine(options.Value.GameRecorderPath!, name); _logger = logger; _pool = pool; @@ -42,6 +42,89 @@ namespace Impostor.Server.Recorder }); } + public async Task WriteConnectAsync(ClientRecorder client) + { + _logger.LogTrace("Writing Connect."); + + var context = _pool.Get(); + + try + { + WritePacketHeader(context, RecordedPacketType.Connect); + WriteClient(context, client, true); + WriteLength(context); + + await WriteAsync(context.Stream!); + } + finally + { + _pool.Return(context); + } + } + + public async Task WriteDisconnectAsync(ClientRecorder client, string reason) + { + _logger.LogTrace("Writing Disconnect."); + + var context = _pool.Get(); + + try + { + WritePacketHeader(context, RecordedPacketType.Disconnect); + WriteClient(context, client, false); + context.Writer.Write(reason); + WriteLength(context); + + await WriteAsync(context.Stream!); + } + finally + { + _pool.Return(context); + } + } + + public async Task WriteMessageAsync(ClientRecorder client, IMessageReader reader, MessageType messageType) + { + _logger.LogTrace("Writing Message."); + + var context = _pool.Get(); + + try + { + WritePacketHeader(context, RecordedPacketType.Message); + WriteClient(context, client, false); + WritePacket(context, reader, messageType); + WriteLength(context); + + await WriteAsync(context.Stream!); + } + finally + { + _pool.Return(context); + } + } + + public async Task WriteGameCreatedAsync(ClientRecorder client, GameCode gameCode) + { + _logger.LogTrace("Writing GameCreated {0}.", gameCode); + + var context = _pool.Get(); + + try + { + WritePacketHeader(context, RecordedPacketType.GameCreated); + WriteClient(context, client, false); + WriteGameCode(context, gameCode); + WriteLength(context); + + await WriteAsync(context.Stream!); + } + finally + { + _pool.Return(context); + } + } + protected override async Task ExecuteAsync(CancellationToken stoppingToken) { _startTime = DateTimeOffset.UtcNow; @@ -70,89 +153,6 @@ namespace Impostor.Server.Recorder await writer.DisposeAsync(); } - public async Task WriteConnectAsync(ClientRecorder client) - { - _logger.LogTrace("Writing Connect."); - - var context = _pool.Get(); - - try - { - WritePacketHeader(context, RecordedPacketType.Connect); - WriteClient(context, client, true); - WriteLength(context); - - await WriteAsync(context.Stream); - } - finally - { - _pool.Return(context); - } - } - - public async Task WriteDisconnectAsync(ClientRecorder client, string reason) - { - _logger.LogTrace("Writing Disconnect."); - - var context = _pool.Get(); - - try - { - WritePacketHeader(context, RecordedPacketType.Disconnect); - WriteClient(context, client, false); - context.Writer.Write(reason); - WriteLength(context); - - await WriteAsync(context.Stream); - } - finally - { - _pool.Return(context); - } - } - - public async Task WriteMessageAsync(ClientRecorder client, IMessageReader reader, MessageType messageType) - { - _logger.LogTrace("Writing Message."); - - var context = _pool.Get(); - - try - { - WritePacketHeader(context, RecordedPacketType.Message); - WriteClient(context, client, false); - WritePacket(context, reader, messageType); - WriteLength(context); - - await WriteAsync(context.Stream); - } - finally - { - _pool.Return(context); - } - } - - public async Task WriteGameCreatedAsync(ClientRecorder client, GameCode gameCode) - { - _logger.LogTrace("Writing GameCreated {0}.", gameCode); - - var context = _pool.Get(); - - try - { - WritePacketHeader(context, RecordedPacketType.GameCreated); - WriteClient(context, client, false); - WriteGameCode(context, gameCode); - WriteLength(context); - - await WriteAsync(context.Stream); - } - finally - { - _pool.Return(context); - } - } - private async Task WriteFileHeaderAsync() { var context = _pool.Get(); @@ -163,7 +163,7 @@ namespace Impostor.Server.Recorder context.Writer.Write(_startTime.ToUnixTimeMilliseconds()); context.Writer.Write(DotnetUtils.GetVersion()); - await WriteAsync(context.Stream); + await WriteAsync(context.Stream!); } finally { @@ -182,7 +182,7 @@ namespace Impostor.Server.Recorder context.Writer.Write((byte)type); } - private static void WriteClient(PacketSerializationContext context, ClientBase client, bool full) + private void WriteClient(PacketSerializationContext context, ClientBase client, bool full) { var address = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 12345); var addressBytes = address.Address.GetAddressBytes(); @@ -199,7 +199,7 @@ namespace Impostor.Server.Recorder } } - private static void WritePacket(PacketSerializationContext context, IMessageReader reader, MessageType messageType) + private void WritePacket(PacketSerializationContext context, IMessageReader reader, MessageType messageType) { context.Writer.Write((byte)messageType); context.Writer.Write((byte)reader.Tag); @@ -207,12 +207,12 @@ namespace Impostor.Server.Recorder context.Writer.Write(reader.Buffer, reader.Offset, reader.Length); } - private static void WriteGameCode(PacketSerializationContext context, in GameCode gameCode) + private void WriteGameCode(PacketSerializationContext context, in GameCode gameCode) { context.Writer.Write(gameCode.Code); } - private static void WriteLength(PacketSerializationContext context) + private void WriteLength(PacketSerializationContext context) { var length = context.Stream.Position; diff --git a/src/Impostor.Server/Recorder/PacketSerializationContext.cs b/src/Impostor.Server/Recorder/PacketSerializationContext.cs index 07755f6b..2290bcb4 100644 --- a/src/Impostor.Server/Recorder/PacketSerializationContext.cs +++ b/src/Impostor.Server/Recorder/PacketSerializationContext.cs @@ -1,4 +1,5 @@ -using System.IO; +using System.Diagnostics.CodeAnalysis; +using System.IO; using System.Text; namespace Impostor.Server.Recorder @@ -8,33 +9,25 @@ namespace Impostor.Server.Recorder private const int InitialStreamSize = 0x100; private const int MaximumStreamSize = 0x100000; - private MemoryStream _memory; - private BinaryWriter _writer; + private MemoryStream? _memory; + private BinaryWriter? _writer; + [AllowNull] public MemoryStream Stream { get { - if (_memory == null) - { - _memory = new MemoryStream(InitialStreamSize); - } - - return _memory; + return _memory ??= new MemoryStream(InitialStreamSize); } private set => _memory = value; } + [AllowNull] public BinaryWriter Writer { get { - if (_writer == null) - { - _writer = new BinaryWriter(Stream, Encoding.UTF8, true); - } - - return _writer; + return _writer ??= new BinaryWriter(Stream, Encoding.UTF8, true); } private set => _writer = value; } @@ -53,4 +46,4 @@ namespace Impostor.Server.Recorder } } } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Recorder/PacketSerializationContextPooledObjectPolicy.cs b/src/Impostor.Server/Recorder/PacketSerializationContextPooledObjectPolicy.cs index 17b355f5..e45948e8 100644 --- a/src/Impostor.Server/Recorder/PacketSerializationContextPooledObjectPolicy.cs +++ b/src/Impostor.Server/Recorder/PacketSerializationContextPooledObjectPolicy.cs @@ -15,4 +15,4 @@ namespace Impostor.Server.Recorder return true; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Recorder/RecordedPacketType.cs b/src/Impostor.Server/Recorder/RecordedPacketType.cs index a8a20bca..336cd57e 100644 --- a/src/Impostor.Server/Recorder/RecordedPacketType.cs +++ b/src/Impostor.Server/Recorder/RecordedPacketType.cs @@ -5,6 +5,6 @@ Connect = 1, Disconnect = 2, Message = 3, - GameCreated = 4 + GameCreated = 4, } -} \ No newline at end of file +} diff --git a/src/Impostor.Server/Recorder/ServerReplayVersion.cs b/src/Impostor.Server/Recorder/ServerReplayVersion.cs index 648205b5..ce77e3c7 100644 --- a/src/Impostor.Server/Recorder/ServerReplayVersion.cs +++ b/src/Impostor.Server/Recorder/ServerReplayVersion.cs @@ -1,17 +1,17 @@ namespace Impostor.Server.Recorder { /// - /// Version of the server replay data format. + /// Version of the server replay data format. /// public enum ServerReplayVersion { /// - /// Initial version + /// Initial version. /// Initial = 1, /// - /// Latest version + /// Latest version. /// Latest = Initial, } diff --git a/src/Impostor.Tests/Events/EventManagerTests.cs b/src/Impostor.Tests/Events/EventManagerTests.cs index d222d79b..a510803a 100644 --- a/src/Impostor.Tests/Events/EventManagerTests.cs +++ b/src/Impostor.Tests/Events/EventManagerTests.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Net.Sockets; using System.Threading.Tasks; using Impostor.Api.Events; using Impostor.Api.Events.Managers; @@ -11,10 +10,10 @@ namespace Impostor.Tests.Events { public class EventManagerTests { - public static readonly IEnumerable TestModes = new [] + public static readonly IEnumerable TestModes = new[] { new object[] { TestMode.Service }, - new object[] { TestMode.Temporary } + new object[] { TestMode.Temporary }, }; [Theory] @@ -38,14 +37,14 @@ namespace Impostor.Tests.Events await eventManager.CallAsync(new SetValueEvent(1)); - Assert.Equal(new [] + Assert.Equal(new[] { EventPriority.Monitor, EventPriority.Highest, EventPriority.High, EventPriority.Normal, EventPriority.Low, - EventPriority.Lowest + EventPriority.Lowest, }, listener.Priorities); } @@ -78,10 +77,10 @@ namespace Impostor.Tests.Events await eventManager.CallAsync(new SetValueEvent(1)); - Assert.Equal(new [] + Assert.Equal(new[] { EventPriority.Monitor, - EventPriority.Highest + EventPriority.Highest, }, listener.Priorities); } @@ -115,7 +114,7 @@ namespace Impostor.Tests.Events public enum TestMode { Service, - Temporary + Temporary, } public interface ISetValueEvent : IEventCancelable diff --git a/src/Impostor.Tests/GameCodeTests.cs b/src/Impostor.Tests/GameCodeTests.cs index de981235..6f0c23b4 100644 --- a/src/Impostor.Tests/GameCodeTests.cs +++ b/src/Impostor.Tests/GameCodeTests.cs @@ -1,5 +1,4 @@ using Impostor.Api.Innersloth; - using Xunit; namespace Impostor.Tests @@ -26,4 +25,4 @@ namespace Impostor.Tests Assert.Equal(codeInt, GameCodeParser.GameNameToInt(code)); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Tests/Hazel/MessageReaderTests.cs b/src/Impostor.Tests/Hazel/MessageReaderTests.cs index e7fa0dff..c0ecbdd7 100644 --- a/src/Impostor.Tests/Hazel/MessageReaderTests.cs +++ b/src/Impostor.Tests/Hazel/MessageReaderTests.cs @@ -72,7 +72,7 @@ namespace Impostor.Tests.Hazel public void ReadProperString() { const string Test1 = "Hello"; - string Test2 = new string(' ', 1024); + var Test2 = new string(' ', 1024); var msg = new MessageWriter(2048); msg.StartMessage(1); msg.Write(Test1); @@ -128,18 +128,18 @@ namespace Impostor.Tests.Hazel var msg = new MessageWriter(2048); msg.StartMessage(1); - msg.StartMessage(2); - msg.Write(Test1); - msg.Write(Test2); - msg.StartMessage(2); - msg.Write(Test1); - msg.Write(Test2); - msg.StartMessage(2); - msg.Write(Test1); - msg.Write(Test2); - msg.EndMessage(); - msg.EndMessage(); - msg.EndMessage(); + msg.StartMessage(2); + msg.Write(Test1); + msg.Write(Test2); + msg.StartMessage(2); + msg.Write(Test1); + msg.Write(Test2); + msg.StartMessage(2); + msg.Write(Test1); + msg.Write(Test2); + msg.EndMessage(); + msg.EndMessage(); + msg.EndMessage(); msg.EndMessage(); // Read message. @@ -217,7 +217,7 @@ namespace Impostor.Tests.Hazel 0x20, 0x6C, 0x6F, 0x6E, 0x67, 0x20, 0x70, 0x61, 0x63, 0x6B, 0x65, 0x74, 0x20, 0x74, 0x6F, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x63, 0x6F, 0x70, - 0x79, 0x69, 0x6E, 0x67, 0x2E + 0x79, 0x69, 0x6E, 0x67, 0x2E, }; var readerPool = CreateReaderPool(); @@ -301,15 +301,15 @@ namespace Impostor.Tests.Hazel var messageWriter = new MessageWriter(1024); messageWriter.StartMessage(0); - messageWriter.StartMessage(1); - messageWriter.Write("HiTest1"); - messageWriter.StartMessage(2); - messageWriter.Write("RemoveMe!"); - messageWriter.EndMessage(); - messageWriter.EndMessage(); - messageWriter.StartMessage(2); - messageWriter.Write("HiTest2"); - messageWriter.EndMessage(); + messageWriter.StartMessage(1); + messageWriter.Write("HiTest1"); + messageWriter.StartMessage(2); + messageWriter.Write("RemoveMe!"); + messageWriter.EndMessage(); + messageWriter.EndMessage(); + messageWriter.StartMessage(2); + messageWriter.Write("HiTest2"); + messageWriter.EndMessage(); messageWriter.EndMessage(); // Copy buffer. diff --git a/src/Impostor.Tests/Hazel/MessageWriterTests.cs b/src/Impostor.Tests/Hazel/MessageWriterTests.cs index 83d67da9..f1581911 100644 --- a/src/Impostor.Tests/Hazel/MessageWriterTests.cs +++ b/src/Impostor.Tests/Hazel/MessageWriterTests.cs @@ -35,4 +35,4 @@ namespace Impostor.Tests.Hazel } } } -} \ No newline at end of file +} diff --git a/src/Impostor.Tests/Impostor.Tests.csproj b/src/Impostor.Tests/Impostor.Tests.csproj index 3f96bf6b..a4ccd6bf 100644 --- a/src/Impostor.Tests/Impostor.Tests.csproj +++ b/src/Impostor.Tests/Impostor.Tests.csproj @@ -1,20 +1,23 @@ - - net5.0 - false - + + net5.0 + false + - - - - - - - + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + - - - + + + diff --git a/src/Impostor.Tools.Proxy/HexUtils.cs b/src/Impostor.Tools.Proxy/HexUtils.cs index 79517b4d..f04e226b 100644 --- a/src/Impostor.Tools.Proxy/HexUtils.cs +++ b/src/Impostor.Tools.Proxy/HexUtils.cs @@ -8,28 +8,28 @@ namespace Impostor.Tools.Proxy public static string HexDump(byte[] bytes, int bytesPerLine = 16) { if (bytes == null) return ""; - int bytesLength = bytes.Length; + var bytesLength = bytes.Length; - char[] HexChars = "0123456789ABCDEF".ToCharArray(); + var HexChars = "0123456789ABCDEF".ToCharArray(); - int firstHexColumn = - 8 // 8 characters for the address - + 3; // 3 spaces + var firstHexColumn = + 8 // 8 characters for the address + + 3; // 3 spaces - int firstCharColumn = firstHexColumn - + bytesPerLine * 3 // - 2 digit for the hexadecimal value and 1 space - + (bytesPerLine - 1) / 8 // - 1 extra space every 8 characters from the 9th - + 2; // 2 spaces + var firstCharColumn = firstHexColumn + + bytesPerLine * 3 // - 2 digit for the hexadecimal value and 1 space + + (bytesPerLine - 1) / 8 // - 1 extra space every 8 characters from the 9th + + 2; // 2 spaces - int lineLength = firstCharColumn - + bytesPerLine // - characters to show the ascii value - + Environment.NewLine.Length; // Carriage return and line feed (should normally be 2) + var lineLength = firstCharColumn + + bytesPerLine // - characters to show the ascii value + + Environment.NewLine.Length; // Carriage return and line feed (should normally be 2) - char[] line = (new String(' ', lineLength - Environment.NewLine.Length) + Environment.NewLine).ToCharArray(); - int expectedLines = (bytesLength + bytesPerLine - 1) / bytesPerLine; - StringBuilder result = new StringBuilder(expectedLines * lineLength); + var line = (new string(' ', lineLength - Environment.NewLine.Length) + Environment.NewLine).ToCharArray(); + var expectedLines = (bytesLength + bytesPerLine - 1) / bytesPerLine; + var result = new StringBuilder(expectedLines * lineLength); - for (int i = 0; i < bytesLength; i += bytesPerLine) + for (var i = 0; i < bytesLength; i += bytesPerLine) { line[0] = HexChars[(i >> 28) & 0xF]; line[1] = HexChars[(i >> 24) & 0xF]; @@ -40,10 +40,10 @@ namespace Impostor.Tools.Proxy line[6] = HexChars[(i >> 4) & 0xF]; line[7] = HexChars[(i >> 0) & 0xF]; - int hexColumn = firstHexColumn; - int charColumn = firstCharColumn; + var hexColumn = firstHexColumn; + var charColumn = firstCharColumn; - for (int j = 0; j < bytesPerLine; j++) + for (var j = 0; j < bytesPerLine; j++) { if (j > 0 && (j & 7) == 0) hexColumn++; if (i + j >= bytesLength) @@ -54,17 +54,20 @@ namespace Impostor.Tools.Proxy } else { - byte b = bytes[i + j]; + var b = bytes[i + j]; line[hexColumn] = HexChars[(b >> 4) & 0xF]; line[hexColumn + 1] = HexChars[b & 0xF]; line[charColumn] = (b < 32 ? '·' : (char)b); } + hexColumn += 3; charColumn++; } + result.Append(line); } + return result.ToString(); } } -} \ No newline at end of file +} diff --git a/src/Impostor.Tools.Proxy/Impostor.Tools.Proxy.csproj b/src/Impostor.Tools.Proxy/Impostor.Tools.Proxy.csproj index 8f523dc3..571d7b94 100644 --- a/src/Impostor.Tools.Proxy/Impostor.Tools.Proxy.csproj +++ b/src/Impostor.Tools.Proxy/Impostor.Tools.Proxy.csproj @@ -1,17 +1,19 @@ - - Exe - net5.0 - + + Exe + net5.0 + - - - - + + + + NU1701 + + + + + + - - - - diff --git a/src/Impostor.Tools.Proxy/Program.cs b/src/Impostor.Tools.Proxy/Program.cs index 468cdd15..c7f9cfac 100644 --- a/src/Impostor.Tools.Proxy/Program.cs +++ b/src/Impostor.Tools.Proxy/Program.cs @@ -18,22 +18,22 @@ namespace Impostor.Tools.Proxy private static readonly Dictionary TagMap = new Dictionary { - {0, "HostGame"}, - {1, "JoinGame"}, - {2, "StartGame"}, - {3, "RemoveGame"}, - {4, "RemovePlayer"}, - {5, "GameData"}, - {6, "GameDataTo"}, - {7, "JoinedGame"}, - {8, "EndGame"}, - {9, "GetGameList"}, - {10, "AlterGame"}, - {11, "KickPlayer"}, - {12, "WaitForHost"}, - {13, "Redirect"}, - {14, "ReselectServer"}, - {16, "GetGameListV2"} + { 0, "HostGame" }, + { 1, "JoinGame" }, + { 2, "StartGame" }, + { 3, "RemoveGame" }, + { 4, "RemovePlayer" }, + { 5, "GameData" }, + { 6, "GameDataTo" }, + { 7, "JoinedGame" }, + { 8, "EndGame" }, + { 9, "GetGameList" }, + { 10, "AlterGame" }, + { 11, "KickPlayer" }, + { 12, "WaitForHost" }, + { 13, "Redirect" }, + { 14, "ReselectServer" }, + { 16, "GetGameListV2" }, }; private static IServiceProvider _serviceProvider; @@ -46,7 +46,7 @@ namespace Impostor.Tools.Proxy _serviceProvider = services.BuildServiceProvider(); _readerPool = _serviceProvider.GetRequiredService>(); - + var devices = LivePacketDevice.AllLocalMachine; if (devices.Count == 0) { @@ -77,7 +77,7 @@ namespace Impostor.Tools.Proxy var ip = packet.Ethernet.IpV4; var ipSrc = ip.Source.ToString(); var udp = ip.Udp; - + // True if this is our own packet. using (var stream = udp.Payload.ToMemoryStream()) { @@ -86,14 +86,14 @@ namespace Impostor.Tools.Proxy reader.Update(stream.ToArray()); var option = reader.Buffer[0]; - if (option == (byte) MessageType.Reliable) + if (option == (byte)MessageType.Reliable) { reader.Seek(reader.Position + 3); } - else if (option == (byte) UdpSendOption.Acknowledgement || - option == (byte) UdpSendOption.Ping || - option == (byte) UdpSendOption.Hello || - option == (byte) UdpSendOption.Disconnect) + else if (option == (byte)UdpSendOption.Acknowledgement || + option == (byte)UdpSendOption.Ping || + option == (byte)UdpSendOption.Hello || + option == (byte)UdpSendOption.Disconnect) { return; } @@ -101,9 +101,9 @@ namespace Impostor.Tools.Proxy { reader.Seek(reader.Position + 1); } - + var isSent = ipSrc.StartsWith("192."); - + while (true) { if (reader.Position >= reader.Length) @@ -120,7 +120,7 @@ namespace Impostor.Tools.Proxy { HandleToClient(ipSrc, message); } - + if (message.Position < message.Length) { Console.ForegroundColor = ConsoleColor.Red; @@ -160,6 +160,7 @@ namespace Impostor.Tools.Proxy { Console.WriteLine("- PlayerId " + packet.ReadPackedInt32()); } + break; case 10: Console.WriteLine("- GameCode " + packet.ReadInt32()); diff --git a/src/Impostor.Tools.ServerReplay/Impostor.Tools.ServerReplay.csproj b/src/Impostor.Tools.ServerReplay/Impostor.Tools.ServerReplay.csproj index 98fa689f..3b46f3f8 100644 --- a/src/Impostor.Tools.ServerReplay/Impostor.Tools.ServerReplay.csproj +++ b/src/Impostor.Tools.ServerReplay/Impostor.Tools.ServerReplay.csproj @@ -6,11 +6,11 @@ - + - + diff --git a/src/Impostor.Tools.ServerReplay/Mocks/MockGameCodeFactory.cs b/src/Impostor.Tools.ServerReplay/Mocks/MockGameCodeFactory.cs index 1111b7e7..7dc9196f 100644 --- a/src/Impostor.Tools.ServerReplay/Mocks/MockGameCodeFactory.cs +++ b/src/Impostor.Tools.ServerReplay/Mocks/MockGameCodeFactory.cs @@ -11,4 +11,4 @@ namespace Impostor.Tools.ServerReplay.Mocks return Result; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Tools.ServerReplay/Mocks/MockHazelConnection.cs b/src/Impostor.Tools.ServerReplay/Mocks/MockHazelConnection.cs index 43f0257b..327296f1 100644 --- a/src/Impostor.Tools.ServerReplay/Mocks/MockHazelConnection.cs +++ b/src/Impostor.Tools.ServerReplay/Mocks/MockHazelConnection.cs @@ -16,7 +16,7 @@ namespace Impostor.Tools.ServerReplay.Mocks public IPEndPoint EndPoint { get; } public bool IsConnected { get; } - public IClient? Client { get; set; } + public IClient Client { get; set; } public ValueTask SendAsync(IMessageWriter writer) { @@ -28,4 +28,4 @@ namespace Impostor.Tools.ServerReplay.Mocks return ValueTask.CompletedTask; } } -} \ No newline at end of file +} diff --git a/src/Impostor.Tools.ServerReplay/Program.cs b/src/Impostor.Tools.ServerReplay/Program.cs index 261d679b..65401efa 100644 --- a/src/Impostor.Tools.ServerReplay/Program.cs +++ b/src/Impostor.Tools.ServerReplay/Program.cs @@ -89,7 +89,7 @@ namespace Impostor.Tools.ServerReplay services.AddSingleton(new ServerEnvironment { - IsReplay = true + IsReplay = true, }); services.AddSingleton(); diff --git a/src/ProjectRules.ruleset b/src/ProjectRules.ruleset new file mode 100644 index 00000000..5484352e --- /dev/null +++ b/src/ProjectRules.ruleset @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/stylecop.json b/src/stylecop.json new file mode 100644 index 00000000..216b35a2 --- /dev/null +++ b/src/stylecop.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", + "settings": { + "orderingRules": { + "usingDirectivesPlacement": "preserve" + }, + "layoutRules": { + "newlineAtEndOfFile": "require" + } + } +}