├── src ├── Impostor.Benchmarks │ ├── .gitignore │ ├── Impostor.Benchmarks.csproj │ ├── Data │ │ ├── Span │ │ │ ├── MessageReaderOwner.cs │ │ │ └── MessageReader_Span.cs │ │ └── Pool │ │ │ └── MessageReader_Bytes_Pooled_ImprovedPolicy.cs │ ├── Program.cs │ └── Extensions │ │ └── SpanExtensions.cs ├── .gitignore ├── Impostor.Server │ ├── icon.ico │ ├── Net │ │ ├── Inner │ │ │ ├── Objects │ │ │ │ ├── Systems │ │ │ │ │ ├── IActivatable.cs │ │ │ │ │ ├── ISystemType.cs │ │ │ │ │ └── ShipStatus │ │ │ │ │ │ ├── SecurityCameraSystemType.cs │ │ │ │ │ │ ├── HudOverrideSystemType.cs │ │ │ │ │ │ ├── SabotageSystemType.cs │ │ │ │ │ │ ├── SwitchSystem.cs │ │ │ │ │ │ ├── MedScanSystem.cs │ │ │ │ │ │ ├── ReactorSystemType.cs │ │ │ │ │ │ └── LifeSuppSystemType.cs │ │ │ │ ├── InnerMeetingHud.Api.cs │ │ │ │ ├── Components │ │ │ │ │ ├── InnerPlayerPhysics.Api.cs │ │ │ │ │ └── InnerCustomNetworkTransform.Api.cs │ │ │ │ ├── InnerPlayerInfo.Api.cs │ │ │ │ ├── InnerGameData.TaskInfo.cs │ │ │ │ └── InnerLobbyBehaviour.cs │ │ │ ├── SpawnFlags.cs │ │ │ ├── RpcInfo.cs │ │ │ ├── GameDataTag.cs │ │ │ └── GameObject.cs │ │ ├── Redirector │ │ │ ├── INodeProvider.cs │ │ │ ├── INodeLocator.cs │ │ │ ├── NodeLocatorNoOp.cs │ │ │ ├── NodeProviderConfig.cs │ │ │ └── NodeLocatorRedis.cs │ │ ├── GameCodeFactory.cs │ │ ├── Manager │ │ │ └── ClientManager.Api.cs │ │ ├── Factories │ │ │ ├── IClientFactory.cs │ │ │ └── ClientFactory.cs │ │ ├── Messages │ │ │ └── MessageWriterProvider.cs │ │ └── State │ │ │ ├── ClientPlayer.Api.cs │ │ │ ├── GameNet.Api.cs │ │ │ └── GameNet.cs │ ├── Constants.cs │ ├── Config │ │ ├── ServerRedirectorNode.cs │ │ ├── DebugConfig.cs │ │ ├── AntiCheatConfig.cs │ │ ├── AnnouncementsServerConfig.cs │ │ ├── ServerRedirectorConfig.cs │ │ ├── ServerConfig.cs │ │ └── DisconnectMessages.cs │ ├── config.json │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Recorder │ │ ├── RecordedPacketType.cs │ │ ├── PacketSerializationContextPooledObjectPolicy.cs │ │ └── PacketSerializationContext.cs │ ├── Plugins │ │ ├── PluginConfig.cs │ │ ├── IAssemblyInformation.cs │ │ ├── LoadedAssemblyInformation.cs │ │ ├── PluginLoaderException.cs │ │ ├── AssemblyInformation.cs │ │ └── PluginInformation.cs │ ├── Events │ │ ├── Game │ │ │ ├── GameCreatedEvent.cs │ │ │ ├── GameStartedEvent.cs │ │ │ ├── GameStartingEvent.cs │ │ │ ├── GameDestroyedEvent.cs │ │ │ ├── GameAlterEvent.cs │ │ │ ├── GamePlayerJoinedEvent.cs │ │ │ ├── GameEndedEvent.cs │ │ │ ├── Meeting │ │ │ │ ├── MeetingEndedEvent.cs │ │ │ │ └── MeetingStartedEvent.cs │ │ │ ├── GamePlayerLeftEvent.cs │ │ │ └── Player │ │ │ │ ├── PlayerExileEvent.cs │ │ │ │ ├── PlayerSpawnedEvent.cs │ │ │ │ ├── PlayerDestroyedEvent.cs │ │ │ │ ├── PlayerCompletedTaskEvent.cs │ │ │ │ ├── PlayerMurderEvent.cs │ │ │ │ ├── PlayerStartMeetingEvent.cs │ │ │ │ ├── PlayerSetStartCounterEvent.cs │ │ │ │ ├── PlayerChatEvent.cs │ │ │ │ ├── PlayerVentEvent.cs │ │ │ │ └── PlayerMovementEvent.cs │ │ ├── Register │ │ │ ├── IRegisteredEventListener.cs │ │ │ ├── WrappedRegisteredEventListener.cs │ │ │ ├── ManualRegisteredEventListener.cs │ │ │ └── InvokedRegisteredEventListener.cs │ │ ├── EventHandler.cs │ │ ├── MultiDisposable.cs │ │ └── Announcements │ │ │ └── AnnouncementRequestEvent.cs │ ├── Extensions │ │ ├── NodeLocatorExtensions.cs │ │ └── ServiceProviderExtensions.cs │ ├── Impostor.Server.csproj.DotSettings │ ├── Utils │ │ ├── DotnetUtils.cs │ │ └── IpUtils.cs │ ├── config-full.json │ └── ProjectRules.ruleset ├── Impostor.Api │ ├── Events │ │ ├── IEvent.cs │ │ ├── IEventListener.cs │ │ ├── Game │ │ │ ├── IGamePlayerLeftEvent.cs │ │ │ ├── IGamePlayerJoinedEvent.cs │ │ │ ├── Meeting │ │ │ │ ├── IMeetingEndedEvent.cs │ │ │ │ ├── IMeetingStartedEvent.cs │ │ │ │ └── IMeetingEvent.cs │ │ │ ├── Player │ │ │ │ ├── IPlayerMovementEvent.cs │ │ │ │ ├── IPlayerSpawnedEvent.cs │ │ │ │ ├── IPlayerDestroyedEvent.cs │ │ │ │ ├── IPlayerExileEvent.cs │ │ │ │ ├── IPlayerCompletedTaskEvent.cs │ │ │ │ ├── IPlayerChatEvent.cs │ │ │ │ ├── IPlayerSetStartCounterEvent.cs │ │ │ │ ├── IPlayerMurderEvent.cs │ │ │ │ ├── IPlayerStartMeetingEvent.cs │ │ │ │ ├── IPlayerVentEvent.cs │ │ │ │ └── IPlayerEvent.cs │ │ │ ├── IGameAlterEvent.cs │ │ │ ├── IGameEndedEvent.cs │ │ │ ├── IGameStartedEvent.cs │ │ │ ├── IGameCreatedEvent.cs │ │ │ ├── IGameDestroyedEvent.cs │ │ │ ├── IGameEvent.cs │ │ │ └── IGameStartingEvent.cs │ │ ├── EventPriority.cs │ │ ├── IEventCancelable.cs │ │ ├── IManualEventListener.cs │ │ ├── Announcements │ │ │ └── IAnnouncementRequestEvent.cs │ │ └── Attributes │ │ │ └── EventListenerAttribute.cs │ ├── Net │ │ ├── IConnection.cs │ │ ├── Inner │ │ │ ├── Objects │ │ │ │ ├── IInnerMeetingHud.cs │ │ │ │ ├── IInnerGameData.cs │ │ │ │ ├── IInnerShipStatus.cs │ │ │ │ ├── IInnerVoteBanSystem.cs │ │ │ │ ├── IInnerLobbyBehaviour.cs │ │ │ │ ├── Components │ │ │ │ │ ├── IInnerPlayerPhysics.cs │ │ │ │ │ └── IInnerCustomNetworkTransform.cs │ │ │ │ └── ITaskInfo.cs │ │ │ ├── IInnerNetObject.cs │ │ │ ├── IGameNet.cs │ │ │ └── RpcCalls.cs │ │ ├── Manager │ │ │ └── IClientManager.cs │ │ ├── LimboStates.cs │ │ ├── Messages │ │ │ ├── AnnouncementsMessageFlags.cs │ │ │ ├── Rpcs │ │ │ │ ├── Rpc04Exiled.cs │ │ │ │ ├── Rpc22Close.cs │ │ │ │ ├── Rpc25ClearVote.cs │ │ │ │ ├── Rpc06SetName.cs │ │ │ │ ├── Rpc05CheckName.cs │ │ │ │ ├── Rpc13SendChat.cs │ │ │ │ ├── Rpc19EnterVent.cs │ │ │ │ ├── Rpc20ExitVent.cs │ │ │ │ ├── Rpc14StartMeeting.cs │ │ │ │ ├── Rpc01CompleteTask.cs │ │ │ │ ├── Rpc11ReportDeadBody.cs │ │ │ │ ├── Rpc00PlayAnimation.cs │ │ │ │ ├── Rpc08SetColor.cs │ │ │ │ ├── Rpc09SetHat.cs │ │ │ │ ├── Rpc17SetPet.cs │ │ │ │ ├── Rpc07CheckColor.cs │ │ │ │ ├── Rpc10SetSkin.cs │ │ │ │ ├── Rpc03SetInfected.cs │ │ │ │ ├── Rpc30UpdateGameData.cs │ │ │ │ ├── Rpc27CloseDoorsOfType.cs │ │ │ │ ├── Rpc02SyncSettings.cs │ │ │ │ ├── Rpc15SetScanner.cs │ │ │ │ ├── Rpc26AddVote.cs │ │ │ │ ├── Rpc12MurderPlayer.cs │ │ │ │ ├── Rpc24CastVote.cs │ │ │ │ ├── Rpc21SnapTo.cs │ │ │ │ ├── Rpc18SetStartCounter.cs │ │ │ │ ├── Rpc29SetTasks.cs │ │ │ │ ├── Rpc16SendChatNote.cs │ │ │ │ ├── Rpc23VotingComplete.cs │ │ │ │ └── Rpc28RepairSystem.cs │ │ │ ├── Announcements │ │ │ │ ├── Message00UseCache.cs │ │ │ │ ├── MessageHello.cs │ │ │ │ ├── Message02SetFreeWeekend.cs │ │ │ │ └── Message01Update.cs │ │ │ ├── C2S │ │ │ │ ├── Message04RemovePlayerC2S.cs │ │ │ │ ├── Message11KickPlayerC2S.cs │ │ │ │ ├── Message08EndGameC2S.cs │ │ │ │ ├── Message16GetGameListC2S.cs │ │ │ │ ├── Message01JoinGameC2S.cs │ │ │ │ ├── Message00HostGameC2S.cs │ │ │ │ └── Message10AlterGameC2S.cs │ │ │ ├── S2C │ │ │ │ ├── Message00HostGameS2C.cs │ │ │ │ ├── Message12WaitForHostS2C.cs │ │ │ │ ├── Message13RedirectS2C.cs │ │ │ │ ├── Message11KickPlayerS2C.cs │ │ │ │ ├── Message10AlterGameS2C.cs │ │ │ │ ├── Message07JoinedGameS2C.cs │ │ │ │ ├── Message04RemovePlayerS2C.cs │ │ │ │ └── Message01JoinGameS2C.cs │ │ │ ├── IMessageWriterProvider.cs │ │ │ ├── MessageFlags.cs │ │ │ └── MessageType.cs │ │ ├── IHazelConnection.cs │ │ └── IClientPlayer.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Innersloth │ │ ├── ChatNoteType.cs │ │ ├── AlterGameTags.cs │ │ ├── MapTypes.cs │ │ ├── DeathReason.cs │ │ ├── TaskBarUpdate.cs │ │ ├── Language.cs │ │ ├── MapFlags.cs │ │ ├── KillDistances.cs │ │ ├── FreeWeekendState.cs │ │ ├── GameStates.cs │ │ ├── GameVersion.cs │ │ ├── Announcement.cs │ │ ├── GameOverReason.cs │ │ ├── TextBox.cs │ │ ├── GameKeywords.cs │ │ ├── Customization │ │ │ ├── ColorType.cs │ │ │ ├── PetType.cs │ │ │ └── SkinType.cs │ │ ├── SystemTypeHelpers.cs │ │ ├── ServerInfo.cs │ │ ├── SystemTypes.cs │ │ ├── VentLocation.cs │ │ ├── TaskTypes.cs │ │ └── RegionInfo.cs │ ├── Games │ │ ├── IGameCodeFactory.cs │ │ ├── Managers │ │ │ └── IGameManager.cs │ │ ├── Extensions │ │ │ ├── GameManagerExtensions.cs │ │ │ └── GameExtensions.cs │ │ └── GameJoinError.cs │ ├── Plugins │ │ ├── IPlugin.cs │ │ ├── IPluginStartup.cs │ │ ├── PluginBase.cs │ │ └── ImpostorPluginAttribute.cs │ ├── Extensions │ │ └── SystemTypesExtensions.cs │ ├── Reactor │ │ ├── ModdedHandshakeS2C.cs │ │ ├── Mod.cs │ │ ├── PluginSide.cs │ │ ├── ModdedHandshakeC2S.cs │ │ └── ModList.cs │ ├── CheatContext.cs │ ├── Exceptions │ │ ├── ImpostorException.cs │ │ ├── ImpostorConfigException.cs │ │ └── ImpostorProtocolException.cs │ ├── ProjectRules.ruleset │ └── Impostor.Api.csproj.DotSettings ├── Impostor.Plugins.Debugger │ ├── Shared │ │ └── MainLayout.razor │ ├── DebugPlugin.cs │ ├── _Imports.razor │ ├── App.razor │ ├── Impostor.Plugins.Debugger.csproj │ ├── Pages │ │ └── _Host.cshtml │ └── DebugPluginStartup.cs ├── Impostor.Patcher │ ├── Impostor.Patcher.WinForms │ │ ├── icon.ico │ │ ├── App.config │ │ ├── Properties │ │ │ ├── Settings.settings │ │ │ └── Settings.Designer.cs │ │ ├── Program.cs │ │ └── Impostor.Patcher.WinForms.csproj │ ├── Directory.Build.props │ ├── Impostor.Patcher.Shared │ │ ├── Events │ │ │ ├── ErrorEventArgs.cs │ │ │ └── SavedEventArgs.cs │ │ ├── Impostor.Patcher.Shared.csproj │ │ └── Innersloth │ │ │ ├── ServerInfo.cs │ │ │ └── RegionInfo.cs │ └── Impostor.Patcher.Cli │ │ └── Impostor.Patcher.Cli.csproj ├── Impostor.Tools.ServerReplay │ ├── sessions │ │ └── session_1604255331821_dead_player_exception.dat │ ├── Mocks │ │ ├── MockGameCodeFactory.cs │ │ └── MockHazelConnection.cs │ └── Impostor.Tools.ServerReplay.csproj ├── Impostor.Plugins.Example │ ├── Impostor.Plugins.Example.csproj │ ├── Handlers │ │ ├── MeetingEventListener.cs │ │ └── AnnouncementsListener.cs │ ├── ExamplePluginStartup.cs │ └── ExamplePlugin.cs ├── Impostor.Client │ └── Impostor.Client.csproj ├── Impostor.Client.App │ └── Impostor.Client.App.csproj ├── Impostor.Hazel │ ├── HazelException.cs │ ├── Impostor.Hazel.csproj │ ├── ConnectionState.cs │ ├── DataReceivedEventArgs.cs │ ├── NewConnectionEventArgs.cs │ ├── NetworkConnectionListener.cs │ ├── MessageReaderPolicy.cs │ ├── DisconnectedEventArgs.cs │ ├── Extensions │ │ └── ServiceProviderExtensions.cs │ ├── Udp │ │ └── SendOptionInternal.cs │ ├── IPMode.cs │ └── IRecyclable.cs ├── Impostor.Tools.Proxy │ └── Impostor.Tools.Proxy.csproj └── Impostor.Tests │ ├── Impostor.Tests.csproj │ ├── GameCodeTests.cs │ └── Hazel │ └── MessageWriterTests.cs ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── 6--api-other.md │ ├── 3--api-suggestion.md │ ├── 5--api-unavailable-data.md │ ├── 2--feature-request.md │ ├── 4--api-invalid-data.md │ └── 1--bug-reporting.md ├── PULL_REQUEST_TEMPLATE.md ├── workflows │ └── main.yml └── stale.yml ├── docs ├── images │ ├── client.jpg │ ├── logo_458.png │ └── logo_64.png ├── README.md └── FAQ.md ├── .dockerignore ├── .gitignore ├── .config └── dotnet-tools.json ├── appveyor.yml └── CONTRIBUTING.md /src/Impostor.Benchmarks/.gitignore: -------------------------------------------------------------------------------- 1 | BenchmarkDotNet.Artifacts -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | /packages/ 4 | riderModule.iml 5 | /_ReSharper.Caches/ 6 | .idea -------------------------------------------------------------------------------- /docs/images/client.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NuclearPowered/Impostor/HEAD/docs/images/client.jpg -------------------------------------------------------------------------------- /docs/images/logo_458.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NuclearPowered/Impostor/HEAD/docs/images/logo_458.png -------------------------------------------------------------------------------- /docs/images/logo_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NuclearPowered/Impostor/HEAD/docs/images/logo_64.png -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .dockerignore 2 | .env 3 | .gitignore 4 | .vs 5 | .vscode 6 | **/.git 7 | **/.idea 8 | **/bin 9 | **/obj -------------------------------------------------------------------------------- /src/Impostor.Server/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NuclearPowered/Impostor/HEAD/src/Impostor.Server/icon.ico -------------------------------------------------------------------------------- /src/Impostor.Api/Events/IEvent.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Events 2 | { 3 | public interface IEvent 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.vscode 2 | /build 3 | /.vs 4 | /src/Impostor.Plugins.Debugger/Properties/launchSettings.json 5 | /tools 6 | 7 | .local/ 8 | -------------------------------------------------------------------------------- /src/Impostor.Plugins.Debugger/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 |
4 | @Body 5 |
-------------------------------------------------------------------------------- /src/Impostor.Api/Events/IEventListener.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Events 2 | { 3 | public interface IEventListener 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/IConnection.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net 2 | { 3 | public interface IConnection 4 | { 5 | 6 | } 7 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [assembly:InternalsVisibleTo("Impostor.Server")] -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/ChatNoteType.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Innersloth 2 | { 3 | public enum ChatNoteType : byte 4 | { 5 | DidVote = 0, 6 | } 7 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Inner/Objects/IInnerMeetingHud.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Inner.Objects 2 | { 3 | public interface IInnerMeetingHud 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/Impostor.Patcher/Impostor.Patcher.WinForms/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NuclearPowered/Impostor/HEAD/src/Impostor.Patcher/Impostor.Patcher.WinForms/icon.ico -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/IGamePlayerLeftEvent.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Events 2 | { 3 | public interface IGamePlayerLeftEvent : IGameEvent 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/Impostor.Api/Games/IGameCodeFactory.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Games 2 | { 3 | public interface IGameCodeFactory 4 | { 5 | GameCode Create(); 6 | } 7 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/IGamePlayerJoinedEvent.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Events 2 | { 3 | public interface IGamePlayerJoinedEvent : IGameEvent 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/AlterGameTags.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Innersloth 2 | { 3 | public enum AlterGameTags : byte 4 | { 5 | ChangePrivacy = 1, 6 | } 7 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Inner/Objects/IInnerGameData.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Inner.Objects 2 | { 3 | public interface IInnerGameData : IInnerNetObject 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/Meeting/IMeetingEndedEvent.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Events.Meeting 2 | { 3 | public interface IMeetingEndedEvent : IMeetingEvent 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/Player/IPlayerMovementEvent.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Events.Player 2 | { 3 | public interface IPlayerMovementEvent : IPlayerEvent 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/Player/IPlayerSpawnedEvent.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Events.Player 2 | { 3 | public interface IPlayerSpawnedEvent : IPlayerEvent 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Inner/Objects/IInnerShipStatus.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Inner.Objects 2 | { 3 | public interface IInnerShipStatus : IInnerNetObject 4 | { 5 | 6 | } 7 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/Meeting/IMeetingStartedEvent.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Events.Meeting 2 | { 3 | public interface IMeetingStartedEvent : IMeetingEvent 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/Player/IPlayerDestroyedEvent.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Events.Player 2 | { 3 | public interface IPlayerDestroyedEvent : IPlayerEvent 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Inner/Objects/IInnerVoteBanSystem.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Inner.Objects 2 | { 3 | public interface IInnerVoteBanSystem : IInnerNetObject 4 | { 5 | 6 | } 7 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/IGameAlterEvent.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Events 2 | { 3 | public interface IGameAlterEvent : IGameEvent 4 | { 5 | bool IsPublic { get; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/MapTypes.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Innersloth 2 | { 3 | public enum MapTypes 4 | { 5 | Skeld = 0, 6 | MiraHQ = 1, 7 | Polus = 2, 8 | } 9 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Inner/Objects/IInnerLobbyBehaviour.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Inner.Objects 2 | { 3 | public interface IInnerLobbyBehaviour : IInnerNetObject 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/DeathReason.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Innersloth 2 | { 3 | public enum DeathReason 4 | { 5 | Exile = 0, 6 | Kill = 1, 7 | Disconnect = 2, 8 | } 9 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Inner/Objects/Systems/IActivatable.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Server.Net.Inner.Objects.Systems 2 | { 3 | public interface IActivatable 4 | { 5 | bool IsActive { get; } 6 | } 7 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/TaskBarUpdate.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Innersloth 2 | { 3 | public enum TaskBarUpdate : byte 4 | { 5 | Always = 0, 6 | Meetings = 1, 7 | Never = 2 8 | } 9 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Inner/Objects/Components/IInnerPlayerPhysics.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Inner.Objects.Components 2 | { 3 | public interface IInnerPlayerPhysics : IInnerNetObject 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Redirector/INodeProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | 3 | namespace Impostor.Server.Net.Redirector 4 | { 5 | internal interface INodeProvider 6 | { 7 | IPEndPoint Get(); 8 | } 9 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/6--api-other.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 6. Api other 3 | about: For anything about the api that does not fit in the other issues 4 | title: '' 5 | labels: api 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "cake.tool": { 6 | "version": "0.38.5", 7 | "commands": [ 8 | "dotnet-cake" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Inner/IInnerNetObject.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Inner 2 | { 3 | public interface IInnerNetObject 4 | { 5 | public uint NetId { get; } 6 | 7 | public int OwnerId { get; } 8 | } 9 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Constants.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Server 2 | { 3 | internal static class Constants 4 | { 5 | public const int SpawnTimeout = 2500; 6 | public const int ConnectionTimeout = 2500; 7 | } 8 | } -------------------------------------------------------------------------------- /src/Impostor.Tools.ServerReplay/sessions/session_1604255331821_dead_player_exception.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NuclearPowered/Impostor/HEAD/src/Impostor.Tools.ServerReplay/sessions/session_1604255331821_dead_player_exception.dat -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Manager/IClientManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Impostor.Api.Net.Manager 4 | { 5 | public interface IClientManager 6 | { 7 | IEnumerable Clients { get; } 8 | } 9 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Config/ServerRedirectorNode.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Server.Config 2 | { 3 | public class ServerRedirectorNode 4 | { 5 | public string Ip { get; set; } 6 | 7 | public ushort Port { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Inner/Objects/InnerMeetingHud.Api.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Net.Inner.Objects; 2 | 3 | namespace Impostor.Server.Net.Inner.Objects 4 | { 5 | internal partial class InnerMeetingHud : IInnerMeetingHud 6 | { 7 | 8 | } 9 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/Language.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Innersloth 2 | { 3 | public enum Language 4 | { 5 | English, 6 | Spanish, 7 | Portuguese, 8 | Korean, 9 | Russian, 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/MapFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Impostor.Api.Innersloth 4 | { 5 | [Flags] 6 | public enum MapFlags 7 | { 8 | Skeld = 1, 9 | MiraHQ = 2, 10 | Polus = 4, 11 | } 12 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Inner/SpawnFlags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Impostor.Server.Net.Inner 4 | { 5 | [Flags] 6 | public enum SpawnFlags : byte 7 | { 8 | None = 0, 9 | IsClientCharacter = 1, 10 | } 11 | } -------------------------------------------------------------------------------- /src/Impostor.Server/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "Server": { 3 | "PublicIp": "127.0.0.1", 4 | "PublicPort": 22023, 5 | "ListenIp": "0.0.0.0", 6 | "ListenPort": 22023 7 | }, 8 | "AntiCheat": { 9 | "BanIpFromGame": true 10 | } 11 | } -------------------------------------------------------------------------------- /src/Impostor.Patcher/Impostor.Patcher.WinForms/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/Impostor.Server/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | [assembly:InternalsVisibleTo("Impostor.Benchmarks")] 4 | [assembly:InternalsVisibleTo("Impostor.Tests")] 5 | [assembly:InternalsVisibleTo("Impostor.Tools.ServerReplay")] 6 | -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/IGameEndedEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth; 2 | 3 | namespace Impostor.Api.Events 4 | { 5 | public interface IGameEndedEvent : IGameEvent 6 | { 7 | public GameOverReason GameOverReason { get; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/KillDistances.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Impostor.Api.Innersloth 4 | { 5 | [Flags] 6 | public enum KillDistances : byte 7 | { 8 | Short = 0, 9 | Normal = 1, 10 | Long = 2, 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/FreeWeekendState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Impostor.Api.Innersloth 4 | { 5 | [Flags] 6 | public enum FreeWeekendState : byte 7 | { 8 | NotFree, 9 | FreeMIRA, 10 | FreePolus, 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Impostor.Server/Recorder/RecordedPacketType.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Server.Recorder 2 | { 3 | internal enum RecordedPacketType : byte 4 | { 5 | Connect = 1, 6 | Disconnect = 2, 7 | Message = 3, 8 | GameCreated = 4 9 | } 10 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/Meeting/IMeetingEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Net.Inner.Objects; 2 | 3 | namespace Impostor.Api.Events.Meeting 4 | { 5 | public interface IMeetingEvent : IGameEvent 6 | { 7 | IInnerMeetingHud MeetingHud { get; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/GameStates.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Innersloth 2 | { 3 | public enum GameStates : byte 4 | { 5 | NotStarted = 0, 6 | Starting = 1, 7 | Started = 2, 8 | Ended = 3, 9 | Destroyed = 4, 10 | } 11 | } -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Impostor Documentation 2 | 3 | 1. [Running the server](Running-the-server.md) 4 | 2. [Server configuration](Server-configuration.md) 5 | 3. [Building from source](Building-from-source.md) 6 | 4. [Writing a plugin](Writing-a-plugin.md) 7 | 5. [Frequently answered questions](FAQ.md) -------------------------------------------------------------------------------- /src/Impostor.Api/Events/EventPriority.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Events 2 | { 3 | public enum EventPriority 4 | { 5 | Lowest = 0, 6 | Low = 1, 7 | Normal = 2, 8 | High = 3, 9 | Highest = 4, 10 | Monitor = 5, 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Inner/Objects/Components/InnerPlayerPhysics.Api.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Net.Inner.Objects.Components; 2 | 3 | namespace Impostor.Server.Net.Inner.Objects.Components 4 | { 5 | internal partial class InnerPlayerPhysics : IInnerPlayerPhysics 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/IGameStartedEvent.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Events 2 | { 3 | /// 4 | /// The game is started here and players have been initialized. 5 | /// 6 | public interface IGameStartedEvent : IGameEvent 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Impostor.Api/Games/Managers/IGameManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Impostor.Api.Games.Managers 4 | { 5 | public interface IGameManager 6 | { 7 | IEnumerable Games { get; } 8 | 9 | IGame? Find(GameCode code); 10 | } 11 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/Player/IPlayerExileEvent.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Events.Player 2 | { 3 | /// 4 | /// Called whenever a player gets exiled (voted out). 5 | /// 6 | public interface IPlayerExileEvent : IPlayerEvent 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Impostor.Patcher/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | Impostor 4 | Impostor 5 | Copyright © AeonLucid 2020 6 | 1.0.0 7 | 8 | -------------------------------------------------------------------------------- /src/Impostor.Server/Net/GameCodeFactory.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Games; 2 | 3 | namespace Impostor.Server.Net 4 | { 5 | public class GameCodeFactory : IGameCodeFactory 6 | { 7 | public GameCode Create() 8 | { 9 | return GameCode.Create(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Events/IEventCancelable.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Events 2 | { 3 | public interface IEventCancelable : IEvent 4 | { 5 | /// 6 | /// True if the event was cancelled. 7 | /// 8 | bool IsCancelled { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/LimboStates.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Impostor.Api.Net 4 | { 5 | [Flags] 6 | public enum LimboStates 7 | { 8 | PreSpawn = 1, 9 | NotLimbo = 2, 10 | WaitingForHost = 4, 11 | All = PreSpawn | NotLimbo | WaitingForHost, 12 | } 13 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/AnnouncementsMessageFlags.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages 2 | { 3 | public class AnnouncementsMessageFlags 4 | { 5 | public const byte UseCache = 0; 6 | public const byte SetUpdate = 1; 7 | public const byte SetFreeWeekend = 2; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Impostor.Server/Config/DebugConfig.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Server.Config 2 | { 3 | public class DebugConfig 4 | { 5 | public const string Section = "Debug"; 6 | 7 | public bool GameRecorderEnabled { get; set; } 8 | 9 | public string GameRecorderPath { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/IGameCreatedEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Games; 2 | 3 | namespace Impostor.Api.Events 4 | { 5 | /// 6 | /// Called whenever a new is created. 7 | /// 8 | public interface IGameCreatedEvent : IGameEvent 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/Player/IPlayerCompletedTaskEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth; 2 | using Impostor.Api.Net.Inner.Objects; 3 | 4 | namespace Impostor.Api.Events.Player 5 | { 6 | public interface IPlayerCompletedTaskEvent : IPlayerEvent 7 | { 8 | ITaskInfo Task { get; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/GameVersion.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Innersloth 2 | { 3 | public class GameVersion 4 | { 5 | public static int GetVersion(int year, int month, int day, int rev = 0) 6 | { 7 | return (year * 25000) + (month * 1800) + (day * 50) + rev; 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/IGameDestroyedEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Games; 2 | 3 | namespace Impostor.Api.Events 4 | { 5 | /// 6 | /// Called whenever a new is destroyed. 7 | /// 8 | public interface IGameDestroyedEvent : IGameEvent 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/Player/IPlayerChatEvent.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Events.Player 2 | { 3 | public interface IPlayerChatEvent : IPlayerEvent 4 | { 5 | /// 6 | /// Gets the message sent by the player. 7 | /// 8 | string Message { get; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Impostor.Patcher/Impostor.Patcher.WinForms/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Impostor.Server/Config/AntiCheatConfig.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Server.Config 2 | { 3 | public class AntiCheatConfig 4 | { 5 | public const string Section = "AntiCheat"; 6 | 7 | public bool Enabled { get; set; } = true; 8 | 9 | public bool BanIpFromGame { get; set; } = true; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Impostor.Api/Plugins/IPlugin.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Impostor.Api.Events; 3 | 4 | namespace Impostor.Api.Plugins 5 | { 6 | public interface IPlugin : IEventListener 7 | { 8 | ValueTask EnableAsync(); 9 | 10 | ValueTask DisableAsync(); 11 | 12 | ValueTask ReloadAsync(); 13 | } 14 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/IGameEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Games; 2 | 3 | namespace Impostor.Api.Events 4 | { 5 | public interface IGameEvent : IEvent 6 | { 7 | /// 8 | /// Gets the this event belongs to. 9 | /// 10 | IGame Game { get; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Impostor.Plugins.Example/Impostor.Plugins.Example.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/Impostor.Server/Plugins/PluginConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Impostor.Server.Plugins 4 | { 5 | public class PluginConfig 6 | { 7 | public List Paths { get; set; } = new List(); 8 | 9 | public List LibraryPaths { get; set; } = new List(); 10 | } 11 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Inner/Objects/ITaskInfo.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth; 2 | using Impostor.Api.Net.Messages; 3 | 4 | namespace Impostor.Api.Net.Inner.Objects 5 | { 6 | public interface ITaskInfo 7 | { 8 | uint Id { get; } 9 | 10 | TaskTypes Type { get; } 11 | 12 | bool Complete { get; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Impostor.Api/Extensions/SystemTypesExtensions.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth; 2 | 3 | namespace Impostor.Api 4 | { 5 | public static class SystemTypesExtensions 6 | { 7 | public static string GetFriendlyName(this SystemTypes type) 8 | { 9 | return SystemTypeHelpers.Names[(int)type]; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/Impostor.Plugins.Debugger/DebugPlugin.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Plugins; 2 | 3 | namespace Impostor.Plugins.Debugger 4 | { 5 | [ImpostorPlugin( 6 | package: "gg.impostor.debugger", 7 | name: "Debugger", 8 | author: "Gerard", 9 | version: "1.0.0")] 10 | public class DebugPlugin : PluginBase 11 | { 12 | } 13 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/Player/IPlayerSetStartCounterEvent.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Events.Player 2 | { 3 | public interface IPlayerSetStartCounterEvent : IPlayerEvent 4 | { 5 | /// 6 | /// Gets the current time of the start counter. 7 | /// 8 | byte SecondsLeft { get; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc04Exiled.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages.Rpcs 2 | { 3 | public static class Rpc04Exiled 4 | { 5 | public static void Serialize(IMessageWriter writer) 6 | { 7 | } 8 | 9 | public static void Deserialize(IMessageReader reader) 10 | { 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc22Close.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages.Rpcs 2 | { 3 | public static class Rpc22Close 4 | { 5 | public static void Serialize(IMessageWriter writer) 6 | { 7 | } 8 | 9 | public static void Deserialize(IMessageReader reader) 10 | { 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Inner/Objects/InnerPlayerInfo.Api.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Impostor.Api.Net.Inner.Objects; 3 | 4 | namespace Impostor.Server.Net.Inner.Objects 5 | { 6 | internal partial class InnerPlayerInfo : IInnerPlayerInfo 7 | { 8 | IEnumerable IInnerPlayerInfo.Tasks => Tasks; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Impostor.Api/Events/IManualEventListener.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace Impostor.Api.Events 4 | { 5 | public interface IManualEventListener : IEventListener 6 | { 7 | public bool CanExecute(); 8 | 9 | public ValueTask Execute(IEvent @event); 10 | 11 | EventPriority Priority { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc25ClearVote.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages.Rpcs 2 | { 3 | public static class Rpc25ClearVote 4 | { 5 | public static void Serialize(IMessageWriter writer) 6 | { 7 | } 8 | 9 | public static void Deserialize(IMessageReader reader) 10 | { 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Impostor.Api/Plugins/IPluginStartup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using Microsoft.Extensions.Hosting; 3 | 4 | namespace Impostor.Api.Plugins 5 | { 6 | public interface IPluginStartup 7 | { 8 | void ConfigureHost(IHostBuilder host); 9 | 10 | void ConfigureServices(IServiceCollection services); 11 | } 12 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Manager/ClientManager.Api.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Impostor.Api.Net; 3 | using Impostor.Api.Net.Manager; 4 | 5 | namespace Impostor.Server.Net.Manager 6 | { 7 | internal partial class ClientManager : IClientManager 8 | { 9 | IEnumerable IClientManager.Clients => _clients.Values; 10 | } 11 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Inner/Objects/Systems/ISystemType.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Net.Messages; 2 | 3 | namespace Impostor.Server.Net.Inner.Objects.Systems 4 | { 5 | public interface ISystemType 6 | { 7 | void Serialize(IMessageWriter writer, bool initialState); 8 | 9 | void Deserialize(IMessageReader reader, bool initialState); 10 | } 11 | } -------------------------------------------------------------------------------- /src/Impostor.Patcher/Impostor.Patcher.Shared/Events/ErrorEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Impostor.Patcher.Shared.Events 4 | { 5 | public class ErrorEventArgs : EventArgs 6 | { 7 | public ErrorEventArgs(string message) 8 | { 9 | Message = message; 10 | } 11 | 12 | public string Message { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Factories/IClientFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Impostor.Api.Net; 3 | using Impostor.Api.Reactor; 4 | 5 | namespace Impostor.Server.Net.Factories 6 | { 7 | internal interface IClientFactory 8 | { 9 | ClientBase Create(IHazelConnection connection, string name, int clientVersion, ISet mods); 10 | } 11 | } -------------------------------------------------------------------------------- /src/Impostor.Plugins.Debugger/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using Microsoft.AspNetCore.Authorization 3 | @using Microsoft.AspNetCore.Components.Authorization 4 | @using Microsoft.AspNetCore.Components.Forms 5 | @using Microsoft.AspNetCore.Components.Routing 6 | @using Microsoft.AspNetCore.Components.Web 7 | @using Microsoft.JSInterop 8 | @using Impostor.Plugins.Debugger.Shared -------------------------------------------------------------------------------- /src/Impostor.Server/Plugins/IAssemblyInformation.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.Loader; 3 | 4 | namespace Impostor.Server.Plugins 5 | { 6 | public interface IAssemblyInformation 7 | { 8 | AssemblyName AssemblyName { get; } 9 | 10 | bool IsPlugin { get; } 11 | 12 | Assembly Load(AssemblyLoadContext context); 13 | } 14 | } -------------------------------------------------------------------------------- /src/Impostor.Tools.ServerReplay/Mocks/MockGameCodeFactory.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Games; 2 | 3 | namespace Impostor.Tools.ServerReplay.Mocks 4 | { 5 | public class MockGameCodeFactory : IGameCodeFactory 6 | { 7 | public GameCode Result { get; set; } 8 | 9 | public GameCode Create() 10 | { 11 | return Result; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/Announcement.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Innersloth 2 | { 3 | public readonly struct Announcement 4 | { 5 | public readonly int Id; 6 | public readonly string Message; 7 | 8 | public Announcement(int id, string message) 9 | { 10 | Id = id; 11 | Message = message; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/3--api-suggestion.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 3. Api suggestion 3 | about: To make suggestions for the plugin api 4 | title: '' 5 | labels: api 6 | assignees: '' 7 | 8 | --- 9 | 10 | # Api Suggestion 11 | 12 | ## Suggestion 13 | 16 | 17 | ## Use case 18 | 21 | -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/Player/IPlayerMurderEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Net.Inner.Objects; 2 | 3 | namespace Impostor.Api.Events.Player 4 | { 5 | public interface IPlayerMurderEvent : IPlayerEvent 6 | { 7 | /// 8 | /// Gets the player who got murdered. 9 | /// 10 | IInnerPlayerControl Victim { get; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Game/GameCreatedEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events; 2 | using Impostor.Api.Games; 3 | 4 | namespace Impostor.Server.Events 5 | { 6 | public class GameCreatedEvent : IGameCreatedEvent 7 | { 8 | public GameCreatedEvent(IGame game) 9 | { 10 | Game = game; 11 | } 12 | 13 | public IGame Game { get; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Game/GameStartedEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events; 2 | using Impostor.Api.Games; 3 | 4 | namespace Impostor.Server.Events 5 | { 6 | public class GameStartedEvent : IGameStartedEvent 7 | { 8 | public GameStartedEvent(IGame game) 9 | { 10 | Game = game; 11 | } 12 | 13 | public IGame Game { get; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Game/GameStartingEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events; 2 | using Impostor.Api.Games; 3 | 4 | namespace Impostor.Server.Events 5 | { 6 | public class GameStartingEvent : IGameStartingEvent 7 | { 8 | public GameStartingEvent(IGame game) 9 | { 10 | Game = game; 11 | } 12 | 13 | public IGame Game { get; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Game/GameDestroyedEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events; 2 | using Impostor.Api.Games; 3 | 4 | namespace Impostor.Server.Events 5 | { 6 | public class GameDestroyedEvent : IGameDestroyedEvent 7 | { 8 | public GameDestroyedEvent(IGame game) 9 | { 10 | Game = game; 11 | } 12 | 13 | public IGame Game { get; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Impostor.Client/Impostor.Client.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Redirector/INodeLocator.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using System.Threading.Tasks; 3 | 4 | namespace Impostor.Server.Net.Redirector 5 | { 6 | public interface INodeLocator 7 | { 8 | ValueTask FindAsync(string gameCode); 9 | 10 | ValueTask SaveAsync(string gameCode, IPEndPoint endPoint); 11 | 12 | ValueTask RemoveAsync(string gameCode); 13 | } 14 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/GameOverReason.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Innersloth 2 | { 3 | public enum GameOverReason : byte 4 | { 5 | HumansByVote = 0, 6 | HumansByTask = 1, 7 | ImpostorByVote = 2, 8 | ImpostorByKill = 3, 9 | ImpostorBySabotage = 4, 10 | 11 | // Unused (?) 12 | ImpostorDisconnect = 5, 13 | HumansDisconnect = 6, 14 | } 15 | } -------------------------------------------------------------------------------- /src/Impostor.Patcher/Impostor.Patcher.Shared/Impostor.Patcher.Shared.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0;netstandard2.1 5 | 1.0.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Impostor.Plugins.Debugger/App.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

Sorry, there's nothing at this address.

8 |
9 |
10 |
-------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/TextBox.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Innersloth 2 | { 3 | public static class TextBox 4 | { 5 | public static bool IsCharAllowed(char i) 6 | { 7 | return i == ' ' || (i >= 'A' && i <= 'Z') || (i >= 'a' && i <= 'z') || (i >= '0' && i <= '9') || (i >= 'À' && i <= 'ÿ') || (i >= 'Ѐ' && i <= 'џ') || (i >= 'ㄱ' && i <= 'ㆎ') || (i >= '가' && i <= '힣'); 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/5--api-unavailable-data.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 5. Api unavailable data 3 | about: To let us know about unavailable data from the api that you would like to use 4 | title: '' 5 | labels: api 6 | assignees: '' 7 | 8 | --- 9 | 10 | # Api missing data 11 | 12 | ## Data 13 | 16 | 17 | ## Use-case 18 | 21 | -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Messages/MessageWriterProvider.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Net.Messages; 2 | using Impostor.Hazel; 3 | 4 | namespace Impostor.Server.Net.Messages 5 | { 6 | public class MessageWriterProvider : IMessageWriterProvider 7 | { 8 | public IMessageWriter Get(MessageType sendOption = MessageType.Unreliable) 9 | { 10 | return MessageWriter.Get(sendOption); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/GameKeywords.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Impostor.Api.Innersloth 4 | { 5 | [Flags] 6 | public enum GameKeywords : uint 7 | { 8 | All = 0, 9 | Other = 1, 10 | Spanish = 2, 11 | Korean = 4, 12 | Russian = 8, 13 | Portuguese = 16, 14 | Arabic = 32, 15 | Filipone = 64, 16 | Polish = 128, 17 | English = 256, 18 | } 19 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Reactor/ModdedHandshakeS2C.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Net.Messages; 2 | 3 | namespace Impostor.Api.Reactor 4 | { 5 | public static class ModdedHandshakeS2C 6 | { 7 | public static void Serialize(IMessageWriter writer, string serverBrand) 8 | { 9 | writer.StartMessage(byte.MaxValue); 10 | writer.Write(serverBrand); 11 | writer.EndMessage(); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Impostor.Server/Extensions/NodeLocatorExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Impostor.Server.Net.Redirector; 3 | 4 | namespace Impostor.Server 5 | { 6 | public static class NodeLocatorExtensions 7 | { 8 | public static async ValueTask ExistsAsync(this INodeLocator nodeLocator, string gameCode) 9 | { 10 | return await nodeLocator.FindAsync(gameCode) != null; 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/IGameStartingEvent.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Events 2 | { 3 | /// 4 | /// Called when the game is going to start. 5 | /// When this is called, not all players are initialized properly yet. 6 | /// If you want to get correct player states, use . 7 | /// 8 | public interface IGameStartingEvent : IGameEvent 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/Customization/ColorType.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Innersloth.Customization 2 | { 3 | public enum ColorType : byte 4 | { 5 | Red = 0, 6 | Blue = 1, 7 | Green = 2, 8 | Pink = 3, 9 | Orange = 4, 10 | Yellow = 5, 11 | Black = 6, 12 | White = 7, 13 | Purple = 8, 14 | Brown = 9, 15 | Cyan = 10, 16 | Lime = 11, 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/Customization/PetType.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Innersloth.Customization 2 | { 3 | public enum PetType : uint 4 | { 5 | NoPet = 0, 6 | Alien = 1, 7 | Crewmate = 2, 8 | Doggy = 3, 9 | Stickmin = 4, 10 | Hamster = 5, 11 | Robot = 6, 12 | Ufo = 7, 13 | Ellie = 8, 14 | Squig = 9, 15 | Bedcrab = 10, 16 | Glitch = 11, 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/Player/IPlayerStartMeetingEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Net.Inner.Objects; 2 | 3 | namespace Impostor.Api.Events.Player 4 | { 5 | public interface IPlayerStartMeetingEvent : IPlayerEvent 6 | { 7 | /// 8 | /// Gets the player who's body got reported. Is null when the meeting started by Emergency call button 9 | /// 10 | IInnerPlayerControl? Body { get; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Impostor.Patcher/Impostor.Patcher.Shared/Events/SavedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Impostor.Patcher.Shared.Events 4 | { 5 | public class SavedEventArgs : EventArgs 6 | { 7 | public SavedEventArgs(string ipAddress, ushort port) 8 | { 9 | IpAddress = ipAddress; 10 | Port = port; 11 | } 12 | 13 | public string IpAddress { get; } 14 | public ushort Port { get; } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Register/IRegisteredEventListener.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Impostor.Api.Events; 4 | 5 | namespace Impostor.Server.Events.Register 6 | { 7 | internal interface IRegisteredEventListener 8 | { 9 | Type EventType { get; } 10 | 11 | EventPriority Priority { get; } 12 | 13 | ValueTask InvokeAsync(object eventHandler, object @event, IServiceProvider provider); 14 | } 15 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Inner/RpcInfo.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Server.Net.Inner 2 | { 3 | public class RpcInfo 4 | { 5 | public RpcTargetType TargetType { get; init; } 6 | 7 | public bool CheckOwnership { get; init; } = true; 8 | 9 | public bool RequireHost { get; init; } 10 | } 11 | 12 | public enum RpcTargetType 13 | { 14 | Broadcast, 15 | Target, 16 | Both, 17 | Cmd 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc06SetName.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages.Rpcs 2 | { 3 | public static class Rpc06SetName 4 | { 5 | public static void Serialize(IMessageWriter writer, string name) 6 | { 7 | writer.Write(name); 8 | } 9 | 10 | public static void Deserialize(IMessageReader reader, out string name) 11 | { 12 | name = reader.ReadString(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc05CheckName.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages.Rpcs 2 | { 3 | public static class Rpc05CheckName 4 | { 5 | public static void Serialize(IMessageWriter writer, string name) 6 | { 7 | writer.Write(name); 8 | } 9 | 10 | public static void Deserialize(IMessageReader reader, out string name) 11 | { 12 | name = reader.ReadString(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Inner/GameDataTag.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Server.Net.Inner 2 | { 3 | public static class GameDataTag 4 | { 5 | public const byte DataFlag = 1; 6 | public const byte RpcFlag = 2; 7 | public const byte SpawnFlag = 4; 8 | public const byte DespawnFlag = 5; 9 | public const byte SceneChangeFlag = 6; 10 | public const byte ReadyFlag = 7; 11 | public const byte ChangeSettingsFlag = 8; 12 | } 13 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Games/Extensions/GameManagerExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Impostor.Api.Games.Managers; 3 | using Impostor.Api.Innersloth; 4 | 5 | namespace Impostor.Api.Games 6 | { 7 | public static class GameManagerExtensions 8 | { 9 | public static int GetGameCount(this IGameManager manager, MapFlags map) 10 | { 11 | return manager.Games.Count(game => map.HasFlag((MapFlags)(1 << game.Options.MapId))); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc13SendChat.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages.Rpcs 2 | { 3 | public static class Rpc13SendChat 4 | { 5 | public static void Serialize(IMessageWriter writer, string message) 6 | { 7 | writer.Write(message); 8 | } 9 | 10 | public static void Deserialize(IMessageReader reader, out string message) 11 | { 12 | message = reader.ReadString(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc19EnterVent.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages.Rpcs 2 | { 3 | public static class Rpc19EnterVent 4 | { 5 | public static void Serialize(IMessageWriter writer, int ventId) 6 | { 7 | writer.WritePacked(ventId); 8 | } 9 | 10 | public static void Deserialize(IMessageReader reader, out int ventId) 11 | { 12 | ventId = reader.ReadPackedInt32(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc20ExitVent.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages.Rpcs 2 | { 3 | public static class Rpc20ExitVent 4 | { 5 | public static void Serialize(IMessageWriter writer, int ventId) 6 | { 7 | writer.WritePacked(ventId); 8 | } 9 | 10 | public static void Deserialize(IMessageReader reader, out int ventId) 11 | { 12 | ventId = reader.ReadPackedInt32(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Impostor.Plugins.Debugger/Impostor.Plugins.Debugger.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | Library 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Game/GameAlterEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events; 2 | using Impostor.Api.Games; 3 | 4 | namespace Impostor.Server.Events 5 | { 6 | public class GameAlterEvent : IGameAlterEvent 7 | { 8 | public GameAlterEvent(IGame game, bool isPublic) 9 | { 10 | Game = game; 11 | IsPublic = isPublic; 12 | } 13 | 14 | public IGame Game { get; } 15 | 16 | public bool IsPublic { get; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc14StartMeeting.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages.Rpcs 2 | { 3 | public static class Rpc14StartMeeting 4 | { 5 | public static void Serialize(IMessageWriter writer, byte targetId) 6 | { 7 | writer.Write(targetId); 8 | } 9 | 10 | public static void Deserialize(IMessageReader reader, out byte targetId) 11 | { 12 | targetId = reader.ReadByte(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Description 2 | 3 | 4 | 13 | 14 | ### Closes issues 15 | 16 | - closes # 17 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Announcements/Message00UseCache.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages.Announcements 2 | { 3 | public static class Message00UseCache 4 | { 5 | public static void Serialize(IMessageWriter writer) 6 | { 7 | writer.StartMessage(AnnouncementsMessageFlags.UseCache); 8 | writer.EndMessage(); 9 | } 10 | 11 | public static void Deserialize(IMessageReader reader) 12 | { 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc01CompleteTask.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages.Rpcs 2 | { 3 | public static class Rpc01CompleteTask 4 | { 5 | public static void Serialize(IMessageWriter writer, uint taskId) 6 | { 7 | writer.WritePacked(taskId); 8 | } 9 | 10 | public static void Deserialize(IMessageReader reader, out uint taskId) 11 | { 12 | taskId = reader.ReadPackedUInt32(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc11ReportDeadBody.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages.Rpcs 2 | { 3 | public static class Rpc11ReportDeadBody 4 | { 5 | public static void Serialize(IMessageWriter writer, byte targetId) 6 | { 7 | writer.Write(targetId); 8 | } 9 | 10 | public static void Deserialize(IMessageReader reader, out byte targetId) 11 | { 12 | targetId = reader.ReadByte(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Impostor.Tools.ServerReplay/Impostor.Tools.ServerReplay.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net5.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/2--feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 2. Feature request 3 | about: To ask and request new features with Impostor 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | # Feature Request 11 | 12 | ## Feature Information: 13 | 17 | 18 | ## I confirm: 19 | - [ ] that I have searched for an existing feature request matching the description. 20 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/4--api-invalid-data.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 4. Api invalid data 3 | about: To let us know about invalid data in the api 4 | title: '' 5 | labels: api 6 | assignees: '' 7 | 8 | --- 9 | 10 | # Api missing data 11 | 12 | ## Data 13 | 16 | 17 | ## Expectations 18 | 21 | 22 | ## Reproduce 23 | 26 | -------------------------------------------------------------------------------- /src/Impostor.Client.App/Impostor.Client.App.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net5.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/Impostor.Hazel/HazelException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Impostor.Hazel 4 | { 5 | /// 6 | /// Wrapper for exceptions thrown from Hazel. 7 | /// 8 | [Serializable] 9 | public class HazelException : Exception 10 | { 11 | internal HazelException(string msg) : base (msg) 12 | { 13 | 14 | } 15 | 16 | internal HazelException(string msg, Exception e) : base (msg, e) 17 | { 18 | 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Impostor.Patcher/Impostor.Patcher.WinForms/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using Impostor.Patcher.WinForms.Forms; 4 | 5 | namespace Impostor.Patcher.WinForms 6 | { 7 | internal static class Program 8 | { 9 | [STAThread] 10 | private static void Main() 11 | { 12 | Application.EnableVisualStyles(); 13 | Application.SetCompatibleTextRenderingDefault(false); 14 | Application.Run(new FrmMain()); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Plugins/PluginBase.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace Impostor.Api.Plugins 4 | { 5 | public class PluginBase : IPlugin 6 | { 7 | public virtual ValueTask EnableAsync() 8 | { 9 | return default; 10 | } 11 | 12 | public virtual ValueTask DisableAsync() 13 | { 14 | return default; 15 | } 16 | 17 | public virtual ValueTask ReloadAsync() 18 | { 19 | return default; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/Impostor.Benchmarks/Impostor.Benchmarks.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net5.0 6 | true 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Inner/IGameNet.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Net.Inner.Objects; 2 | 3 | namespace Impostor.Api.Net.Inner 4 | { 5 | /// 6 | /// Holds all data that is serialized over the network through GameData packets. 7 | /// 8 | public interface IGameNet 9 | { 10 | IInnerLobbyBehaviour LobbyBehaviour { get; } 11 | 12 | IInnerGameData GameData { get; } 13 | 14 | IInnerVoteBanSystem VoteBan { get; } 15 | 16 | IInnerShipStatus ShipStatus { get; } 17 | } 18 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc00PlayAnimation.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth; 2 | 3 | namespace Impostor.Api.Net.Messages.Rpcs 4 | { 5 | public static class Rpc00PlayAnimation 6 | { 7 | public static void Serialize(IMessageWriter writer, TaskTypes task) 8 | { 9 | writer.Write((byte)task); 10 | } 11 | 12 | public static void Deserialize(IMessageReader reader, out TaskTypes task) 13 | { 14 | task = (TaskTypes)reader.ReadByte(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Impostor.Server/Net/State/ClientPlayer.Api.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Games; 2 | using Impostor.Api.Net; 3 | using Impostor.Api.Net.Inner.Objects; 4 | 5 | namespace Impostor.Server.Net.State 6 | { 7 | internal partial class ClientPlayer 8 | { 9 | /// 10 | IClient IClientPlayer.Client => Client; 11 | 12 | /// 13 | IGame IClientPlayer.Game => Game; 14 | 15 | /// 16 | IInnerPlayerControl? IClientPlayer.Character => Character; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Impostor.Server/Net/State/GameNet.Api.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Net.Inner; 2 | using Impostor.Api.Net.Inner.Objects; 3 | 4 | namespace Impostor.Server.Net.State 5 | { 6 | /// 7 | internal partial class GameNet : IGameNet 8 | { 9 | IInnerLobbyBehaviour IGameNet.LobbyBehaviour => LobbyBehaviour; 10 | 11 | IInnerGameData IGameNet.GameData => GameData; 12 | 13 | IInnerVoteBanSystem IGameNet.VoteBan => VoteBan; 14 | 15 | IInnerShipStatus IGameNet.ShipStatus => ShipStatus; 16 | } 17 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Net/State/GameNet.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Server.Net.Inner.Objects; 2 | using Impostor.Server.Net.Inner.Objects.Components; 3 | 4 | namespace Impostor.Server.Net.State 5 | { 6 | internal partial class GameNet 7 | { 8 | public InnerLobbyBehaviour LobbyBehaviour { get; internal set; } 9 | 10 | public InnerGameData GameData { get; internal set; } 11 | 12 | public InnerVoteBanSystem VoteBan { get; internal set; } 13 | 14 | public InnerShipStatus ShipStatus { get; internal set; } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc08SetColor.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth.Customization; 2 | 3 | namespace Impostor.Api.Net.Messages.Rpcs 4 | { 5 | public static class Rpc08SetColor 6 | { 7 | public static void Serialize(IMessageWriter writer, ColorType color) 8 | { 9 | writer.Write((byte)color); 10 | } 11 | 12 | public static void Deserialize(IMessageReader reader, out ColorType color) 13 | { 14 | color = (ColorType)reader.ReadByte(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc09SetHat.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth.Customization; 2 | 3 | namespace Impostor.Api.Net.Messages.Rpcs 4 | { 5 | public static class Rpc09SetHat 6 | { 7 | public static void Serialize(IMessageWriter writer, HatType hat) 8 | { 9 | writer.WritePacked((uint)hat); 10 | } 11 | 12 | public static void Deserialize(IMessageReader reader, out HatType hat) 13 | { 14 | hat = (HatType)reader.ReadPackedUInt32(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc17SetPet.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth.Customization; 2 | 3 | namespace Impostor.Api.Net.Messages.Rpcs 4 | { 5 | public static class Rpc17SetPet 6 | { 7 | public static void Serialize(IMessageWriter writer, PetType pet) 8 | { 9 | writer.WritePacked((uint)pet); 10 | } 11 | 12 | public static void Deserialize(IMessageReader reader, out PetType pet) 13 | { 14 | pet = (PetType)reader.ReadPackedUInt32(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Redirector/NodeLocatorNoOp.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using System.Threading.Tasks; 3 | 4 | namespace Impostor.Server.Net.Redirector 5 | { 6 | public class NodeLocatorNoOp : INodeLocator 7 | { 8 | public ValueTask FindAsync(string gameCode) => ValueTask.FromResult(default(IPEndPoint)); 9 | 10 | public ValueTask SaveAsync(string gameCode, IPEndPoint endPoint) => ValueTask.CompletedTask; 11 | 12 | public ValueTask RemoveAsync(string gameCode) => ValueTask.CompletedTask; 13 | } 14 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc07CheckColor.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth.Customization; 2 | 3 | namespace Impostor.Api.Net.Messages.Rpcs 4 | { 5 | public static class Rpc07CheckColor 6 | { 7 | public static void Serialize(IMessageWriter writer, ColorType color) 8 | { 9 | writer.Write((byte)color); 10 | } 11 | 12 | public static void Deserialize(IMessageReader reader, out ColorType color) 13 | { 14 | color = (ColorType)reader.ReadByte(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc10SetSkin.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth.Customization; 2 | 3 | namespace Impostor.Api.Net.Messages.Rpcs 4 | { 5 | public static class Rpc10SetSkin 6 | { 7 | public static void Serialize(IMessageWriter writer, SkinType skin) 8 | { 9 | writer.WritePacked((uint)skin); 10 | } 11 | 12 | public static void Deserialize(IMessageReader reader, out SkinType skin) 13 | { 14 | skin = (SkinType)reader.ReadPackedUInt32(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Game/GamePlayerJoinedEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events; 2 | using Impostor.Api.Games; 3 | using Impostor.Api.Net; 4 | 5 | namespace Impostor.Server.Events 6 | { 7 | public class GamePlayerJoinedEvent : IGamePlayerJoinedEvent 8 | { 9 | public GamePlayerJoinedEvent(IGame game, IClientPlayer player) 10 | { 11 | Game = game; 12 | Player = player; 13 | } 14 | 15 | public IGame Game { get; } 16 | 17 | public IClientPlayer Player { get; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/C2S/Message04RemovePlayerC2S.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages.C2S 2 | { 3 | public class Message04RemovePlayerC2S 4 | { 5 | public static void Serialize(IMessageWriter writer) 6 | { 7 | throw new System.NotImplementedException(); 8 | } 9 | 10 | public static void Deserialize(IMessageReader reader, out int playerId, out byte reason) 11 | { 12 | playerId = reader.ReadPackedInt32(); 13 | reason = reader.ReadByte(); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/C2S/Message11KickPlayerC2S.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages.C2S 2 | { 3 | public class Message11KickPlayerC2S 4 | { 5 | public static void Serialize(IMessageWriter writer) 6 | { 7 | throw new System.NotImplementedException(); 8 | } 9 | 10 | public static void Deserialize(IMessageReader reader, out int playerId, out bool isBan) 11 | { 12 | playerId = reader.ReadPackedInt32(); 13 | isBan = reader.ReadBoolean(); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc03SetInfected.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Impostor.Api.Net.Messages.Rpcs 4 | { 5 | public static class Rpc03SetInfected 6 | { 7 | public static void Serialize(IMessageWriter writer, byte[] infectedIds) 8 | { 9 | writer.WriteBytesAndSize(infectedIds); 10 | } 11 | 12 | public static void Deserialize(IMessageReader reader, out ReadOnlyMemory infectedIds) 13 | { 14 | infectedIds = reader.ReadBytesAndSize(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/Player/IPlayerVentEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth; 2 | 3 | namespace Impostor.Api.Events.Player 4 | { 5 | public interface IPlayerVentEvent : IPlayerEvent 6 | { 7 | /// 8 | /// Gets get the id of the used vent. 9 | /// 10 | public VentLocation VentId { get; } 11 | 12 | /// 13 | /// Gets a value indicating whether the vent was entered or exited. 14 | /// 15 | public bool VentEnter { get; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/Customization/SkinType.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Innersloth.Customization 2 | { 3 | public enum SkinType : uint 4 | { 5 | None = 0, 6 | Astro = 1, 7 | Capt = 2, 8 | Mech = 3, 9 | Military = 4, 10 | Police = 5, 11 | Science = 6, 12 | SuitB = 7, 13 | SuitW = 8, 14 | Wall = 9, 15 | Hazmat = 10, 16 | Security = 11, 17 | Tarmac = 12, 18 | Miner = 13, 19 | Winter = 14, 20 | Archae = 15, 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc30UpdateGameData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Impostor.Api.Net.Inner.Objects; 3 | 4 | namespace Impostor.Api.Net.Messages.Rpcs 5 | { 6 | public static class Rpc30UpdateGameData 7 | { 8 | public static void Serialize(IMessageWriter writer) 9 | { 10 | throw new NotImplementedException(); 11 | } 12 | 13 | public static void Deserialize(IMessageReader reader, IInnerGameData gameData) 14 | { 15 | throw new NotImplementedException(); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Game/GameEndedEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events; 2 | using Impostor.Api.Games; 3 | using Impostor.Api.Innersloth; 4 | 5 | namespace Impostor.Server.Events 6 | { 7 | public class GameEndedEvent : IGameEndedEvent 8 | { 9 | public GameEndedEvent(IGame game, GameOverReason gameOverReason) 10 | { 11 | Game = game; 12 | GameOverReason = gameOverReason; 13 | } 14 | 15 | public IGame Game { get; } 16 | 17 | public GameOverReason GameOverReason { get; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc27CloseDoorsOfType.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth; 2 | 3 | namespace Impostor.Api.Net.Messages.Rpcs 4 | { 5 | public static class Rpc27CloseDoorsOfType 6 | { 7 | public static void Serialize(IMessageWriter writer, SystemTypes systemType) 8 | { 9 | writer.Write((byte)systemType); 10 | } 11 | 12 | public static void Deserialize(IMessageReader reader, out SystemTypes systemType) 13 | { 14 | systemType = (SystemTypes)reader.ReadByte(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Impostor.Api/Reactor/Mod.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Reactor 2 | { 3 | public readonly struct Mod 4 | { 5 | public readonly string Id; 6 | public readonly string Version; 7 | public readonly PluginSide Side; 8 | 9 | public Mod(string id, string version, PluginSide side) 10 | { 11 | Id = id; 12 | Version = version; 13 | Side = side; 14 | } 15 | 16 | public override string ToString() 17 | { 18 | return $"{Id} ({Version})"; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc02SyncSettings.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth; 2 | 3 | namespace Impostor.Api.Net.Messages.Rpcs 4 | { 5 | public static class Rpc02SyncSettings 6 | { 7 | public static void Serialize(IMessageWriter writer, GameOptionsData gameOptionsData) 8 | { 9 | gameOptionsData.Serialize(writer); 10 | } 11 | 12 | public static void Deserialize(IMessageReader reader, GameOptionsData gameOptionsData) 13 | { 14 | gameOptionsData.Deserialize(reader.ReadBytesAndSize()); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc15SetScanner.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages.Rpcs 2 | { 3 | public static class Rpc15SetScanner 4 | { 5 | public static void Serialize(IMessageWriter writer, bool on, byte scannerCount) 6 | { 7 | writer.Write(on); 8 | writer.Write(scannerCount); 9 | } 10 | 11 | public static void Deserialize(IMessageReader reader, out bool on, out byte scannerCount) 12 | { 13 | on = reader.ReadBoolean(); 14 | scannerCount = reader.ReadByte(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Game/Meeting/MeetingEndedEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events.Meeting; 2 | using Impostor.Api.Games; 3 | using Impostor.Api.Net.Inner.Objects; 4 | 5 | namespace Impostor.Server.Events.Meeting 6 | { 7 | public class MeetingEndedEvent : IMeetingEndedEvent 8 | { 9 | public MeetingEndedEvent(IGame game, IInnerMeetingHud meetingHud) 10 | { 11 | Game = game; 12 | MeetingHud = meetingHud; 13 | } 14 | 15 | public IGame Game { get; } 16 | 17 | public IInnerMeetingHud MeetingHud { get; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Impostor.Server/Recorder/PacketSerializationContextPooledObjectPolicy.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.ObjectPool; 2 | 3 | namespace Impostor.Server.Recorder 4 | { 5 | public class PacketSerializationContextPooledObjectPolicy : IPooledObjectPolicy 6 | { 7 | public PacketSerializationContext Create() 8 | { 9 | return new PacketSerializationContext(); 10 | } 11 | 12 | public bool Return(PacketSerializationContext obj) 13 | { 14 | obj.Reset(); 15 | return true; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Game/Meeting/MeetingStartedEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events.Meeting; 2 | using Impostor.Api.Games; 3 | using Impostor.Api.Net.Inner.Objects; 4 | 5 | namespace Impostor.Server.Events.Meeting 6 | { 7 | public class MeetingStartedEvent : IMeetingStartedEvent 8 | { 9 | public MeetingStartedEvent(IGame game, IInnerMeetingHud meetingHud) 10 | { 11 | Game = game; 12 | MeetingHud = meetingHud; 13 | } 14 | 15 | public IGame Game { get; } 16 | 17 | public IInnerMeetingHud MeetingHud { get; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/C2S/Message08EndGameC2S.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth; 2 | 3 | namespace Impostor.Api.Net.Messages.C2S 4 | { 5 | public class Message08EndGameC2S 6 | { 7 | public static void Serialize(IMessageWriter writer) 8 | { 9 | throw new System.NotImplementedException(); 10 | } 11 | 12 | public static void Deserialize(IMessageReader reader, out GameOverReason gameOverReason) 13 | { 14 | gameOverReason = (GameOverReason)reader.ReadByte(); 15 | reader.ReadBoolean(); // showAd 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/Impostor.Tools.Proxy/Impostor.Tools.Proxy.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net5.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Impostor.Server/Impostor.Server.csproj.DotSettings: -------------------------------------------------------------------------------- 1 | 2 | True 3 | True -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/C2S/Message16GetGameListC2S.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth; 2 | 3 | namespace Impostor.Api.Net.Messages.C2S 4 | { 5 | public class Message16GetGameListC2S 6 | { 7 | public static void Serialize(IMessageWriter writer) 8 | { 9 | throw new System.NotImplementedException(); 10 | } 11 | 12 | public static void Deserialize(IMessageReader reader, out GameOptionsData options) 13 | { 14 | reader.ReadPackedInt32(); // Hardcoded 0. 15 | options = GameOptionsData.DeserializeCreate(reader); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc26AddVote.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages.Rpcs 2 | { 3 | public static class Rpc26AddVote 4 | { 5 | public static void Serialize(IMessageWriter writer, int clientId, int targetClientId) 6 | { 7 | writer.Write(clientId); 8 | writer.Write(targetClientId); 9 | } 10 | 11 | public static void Deserialize(IMessageReader reader, out int clientId, out int targetClientId) 12 | { 13 | clientId = reader.ReadInt32(); 14 | targetClientId = reader.ReadInt32(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Announcements/MessageHello.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth; 2 | 3 | namespace Impostor.Api.Net.Messages.Announcements 4 | { 5 | public class MessageHello 6 | { 7 | public static void Deserialize(IMessageReader reader, out int announcementVersion, out int id, out Language language) 8 | { 9 | reader.ReadByte(); // SendOption header, probably added by accident 10 | announcementVersion = reader.ReadPackedInt32(); 11 | id = reader.ReadPackedInt32(); 12 | language = (Language)reader.ReadPackedInt32(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc12MurderPlayer.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Games; 2 | using Impostor.Api.Net.Inner.Objects; 3 | 4 | namespace Impostor.Api.Net.Messages.Rpcs 5 | { 6 | public static class Rpc12MurderPlayer 7 | { 8 | public static void Serialize(IMessageWriter writer, IInnerPlayerControl target) 9 | { 10 | writer.Write(target); 11 | } 12 | 13 | public static void Deserialize(IMessageReader reader, IGame game, out IInnerPlayerControl? target) 14 | { 15 | target = reader.ReadNetObject(game); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc24CastVote.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages.Rpcs 2 | { 3 | public static class Rpc24CastVote 4 | { 5 | public static void Serialize(IMessageWriter writer, byte playerId, sbyte suspectPlayerId) 6 | { 7 | writer.Write(playerId); 8 | writer.Write(suspectPlayerId); 9 | } 10 | 11 | public static void Deserialize(IMessageReader reader, out byte playerId, out sbyte suspectPlayerId) 12 | { 13 | playerId = reader.ReadByte(); 14 | suspectPlayerId = reader.ReadSByte(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Game/GamePlayerLeftEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events; 2 | using Impostor.Api.Games; 3 | using Impostor.Api.Net; 4 | 5 | namespace Impostor.Server.Events 6 | { 7 | public class GamePlayerLeftEvent : IGamePlayerLeftEvent 8 | { 9 | public GamePlayerLeftEvent(IGame game, IClientPlayer player, bool isBan) 10 | { 11 | Game = game; 12 | Player = player; 13 | IsBan = isBan; 14 | } 15 | 16 | public IGame Game { get; } 17 | 18 | public IClientPlayer Player { get; } 19 | 20 | public bool IsBan { get; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc21SnapTo.cs: -------------------------------------------------------------------------------- 1 | using System.Numerics; 2 | 3 | namespace Impostor.Api.Net.Messages.Rpcs 4 | { 5 | public static class Rpc21SnapTo 6 | { 7 | public static void Serialize(IMessageWriter writer, Vector2 position, ushort minSid) 8 | { 9 | writer.Write(position); 10 | writer.Write(minSid); 11 | } 12 | 13 | public static void Deserialize(IMessageReader reader, out Vector2 position, out ushort minSid) 14 | { 15 | position = reader.ReadVector2(); 16 | minSid = reader.ReadUInt16(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Impostor.Server/Utils/DotnetUtils.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace Impostor.Server.Utils 4 | { 5 | internal static class DotnetUtils 6 | { 7 | private const string DefaultUnknownBuild = "UNKNOWN"; 8 | 9 | public static string GetVersion() 10 | { 11 | var attribute = typeof(DotnetUtils).Assembly.GetCustomAttribute(); 12 | if (attribute != null) 13 | { 14 | return attribute.InformationalVersion; 15 | } 16 | 17 | return DefaultUnknownBuild; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/S2C/Message00HostGameS2C.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Impostor.Api.Innersloth; 3 | 4 | namespace Impostor.Api.Net.Messages.S2C 5 | { 6 | public static class Message00HostGameS2C 7 | { 8 | public static void Serialize(IMessageWriter writer, int gameCode) 9 | { 10 | writer.StartMessage(MessageFlags.HostGame); 11 | writer.Write(gameCode); 12 | writer.EndMessage(); 13 | } 14 | 15 | public static GameOptionsData Deserialize(IMessageReader reader) 16 | { 17 | throw new NotImplementedException(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Reactor/PluginSide.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Reactor 2 | { 3 | /// 4 | /// Plugin side used in modded handshake 5 | /// 6 | public enum PluginSide : byte 7 | { 8 | /// 9 | /// Required by both sides, reject connection if missing on the other side 10 | /// 11 | Both, 12 | 13 | /// 14 | /// Required only by client 15 | /// 16 | ClientOnly, 17 | 18 | /// 19 | /// Required only by server 20 | /// 21 | ServerOnly, 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Impostor.Api/CheatContext.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Server.Net.Inner; 2 | 3 | namespace Impostor.Api 4 | { 5 | public class CheatContext 6 | { 7 | public CheatContext(string name) 8 | { 9 | Name = name; 10 | } 11 | 12 | public static CheatContext Deserialize { get; } = new CheatContext(nameof(Deserialize)); 13 | 14 | public static CheatContext Serialize { get; } = new CheatContext(nameof(Serialize)); 15 | 16 | public string Name { get; } 17 | 18 | public static implicit operator CheatContext(RpcCalls rpcCalls) => new CheatContext(rpcCalls.ToString()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc18SetStartCounter.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages.Rpcs 2 | { 3 | public static class Rpc18SetStartCounter 4 | { 5 | public static void Serialize(IMessageWriter writer, int sequenceId, sbyte startCounter) 6 | { 7 | writer.Write(sequenceId); 8 | writer.Write(startCounter); 9 | } 10 | 11 | public static void Deserialize(IMessageReader reader, out int sequenceId, out sbyte startCounter) 12 | { 13 | sequenceId = reader.ReadPackedInt32(); 14 | startCounter = reader.ReadSByte(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Impostor.Plugins.Example/Handlers/MeetingEventListener.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Impostor.Api.Events; 3 | using Impostor.Api.Events.Meeting; 4 | 5 | namespace Impostor.Plugins.Example.Handlers 6 | { 7 | public class MeetingEventListener : IEventListener 8 | { 9 | [EventListener] 10 | public void OnMeetingStarted(IMeetingStartedEvent e) 11 | { 12 | Console.WriteLine("Meeting > started"); 13 | } 14 | 15 | [EventListener] 16 | public void OnMeetingEnded(IMeetingEndedEvent e) 17 | { 18 | Console.WriteLine("Meeting > ended"); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/1--bug-reporting.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 1. Bug reporting 3 | about: Bugs within Impostor 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | # Bug Report 11 | 12 | ## Base Information 13 | - Operating System 14 | - Impostor Version 15 | - Among Us Version 16 | 17 | ## I confirm: 18 | - [ ] that I have searched for an existing bug report for this issue. 19 | 20 | 21 | ## Symptoms 22 | 23 | 26 | 27 | Enter Symptoms on this line. 28 | 29 | ## Reproduction 30 | 31 | 34 | 35 | Enter reproductions steps here. 36 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | 6 | jobs: 7 | build: 8 | runs-on: ubuntu-20.04 9 | 10 | steps: 11 | - uses: actions/checkout@v2 12 | with: 13 | submodules: true 14 | 15 | - name: Setup .NET 16 | uses: actions/setup-dotnet@v1 17 | with: 18 | dotnet-version: 5.0.102 19 | 20 | - name: Cake Action 21 | run: | 22 | dotnet tool restore 23 | dotnet cake build.cake --bootstrap 24 | dotnet cake build.cake --pack 25 | 26 | - uses: actions/upload-artifact@v2 27 | with: 28 | path: ./build/*.zip 29 | -------------------------------------------------------------------------------- /src/Impostor.Benchmarks/Data/Span/MessageReaderOwner.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Impostor.Benchmarks.Data.Span 4 | { 5 | public class MessageReaderOwner 6 | { 7 | private readonly Memory _data; 8 | 9 | public MessageReaderOwner(Memory data) 10 | { 11 | _data = data; 12 | } 13 | 14 | public int Position { get; internal set; } 15 | public int Length => _data.Length; 16 | 17 | public MessageReader_Span CreateReader() 18 | { 19 | return new MessageReader_Span(this, byte.MaxValue, _data.Span.Slice(Position)); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/SecurityCameraSystemType.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Net.Messages; 2 | 3 | namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus 4 | { 5 | public class SecurityCameraSystemType : ISystemType 6 | { 7 | public byte InUse { get; internal set; } 8 | 9 | public void Serialize(IMessageWriter writer, bool initialState) 10 | { 11 | throw new System.NotImplementedException(); 12 | } 13 | 14 | public void Deserialize(IMessageReader reader, bool initialState) 15 | { 16 | InUse = reader.ReadByte(); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Announcements/IAnnouncementRequestEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth; 2 | 3 | namespace Impostor.Api.Events.Announcements 4 | { 5 | public interface IAnnouncementRequestEvent : IEvent 6 | { 7 | public interface IResponse 8 | { 9 | public FreeWeekendState FreeWeekendState { get; set; } 10 | 11 | public bool UseCached { get; set; } 12 | 13 | public Announcement? Announcement { get; set; } 14 | } 15 | 16 | public int Id { get; } 17 | 18 | public Language Language { get; } 19 | 20 | public IResponse Response { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/C2S/Message01JoinGameC2S.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Impostor.Api.Net.Messages.C2S 4 | { 5 | public static class Message01JoinGameC2S 6 | { 7 | public static void Serialize(IMessageWriter writer) 8 | { 9 | throw new System.NotImplementedException(); 10 | } 11 | 12 | public static void Deserialize(IMessageReader reader, out int gameCode, out byte unknown) 13 | { 14 | var slice = reader.ReadBytes(sizeof(Int32) + sizeof(byte)).Span; 15 | 16 | gameCode = slice.ReadInt32(); 17 | unknown = slice.ReadByte(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/C2S/Message00HostGameC2S.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth; 2 | 3 | namespace Impostor.Api.Net.Messages.C2S 4 | { 5 | public static class Message00HostGameC2S 6 | { 7 | public static void Serialize(IMessageWriter writer, GameOptionsData gameOptionsData) 8 | { 9 | writer.StartMessage(MessageFlags.HostGame); 10 | gameOptionsData.Serialize(writer); 11 | writer.EndMessage(); 12 | } 13 | 14 | public static GameOptionsData Deserialize(IMessageReader reader) 15 | { 16 | return GameOptionsData.DeserializeCreate(reader); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Impostor.Server/Config/AnnouncementsServerConfig.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Server.Utils; 2 | 3 | namespace Impostor.Server.Config 4 | { 5 | internal class AnnouncementsServerConfig 6 | { 7 | private string? _resolvedListenIp; 8 | 9 | public const string Section = "AnnouncementsServer"; 10 | 11 | public bool Enabled { get; set; } = true; 12 | 13 | public string ListenIp { get; set; } = "0.0.0.0"; 14 | 15 | public ushort ListenPort { get; set; } = 22024; 16 | 17 | public string ResolveListenIp() 18 | { 19 | return _resolvedListenIp ??= IpUtils.ResolveIp(ListenIp); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/HudOverrideSystemType.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Net.Messages; 2 | 3 | namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus 4 | { 5 | public class HudOverrideSystemType : ISystemType, IActivatable 6 | { 7 | public bool IsActive { get; private set; } 8 | 9 | public void Serialize(IMessageWriter writer, bool initialState) 10 | { 11 | throw new System.NotImplementedException(); 12 | } 13 | 14 | public void Deserialize(IMessageReader reader, bool initialState) 15 | { 16 | IsActive = reader.ReadBoolean(); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc29SetTasks.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Impostor.Api.Net.Messages.Rpcs 4 | { 5 | public static class Rpc29SetTasks 6 | { 7 | public static void Serialize(IMessageWriter writer, byte playerId, ReadOnlyMemory taskTypeIds) 8 | { 9 | writer.Write(playerId); 10 | writer.Write(taskTypeIds); 11 | } 12 | 13 | public static void Deserialize(IMessageReader reader, out byte playerId, out ReadOnlyMemory taskTypeIds) 14 | { 15 | playerId = reader.ReadByte(); 16 | taskTypeIds = reader.ReadBytesAndSize(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Impostor.Api/Exceptions/ImpostorException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace Impostor.Api 5 | { 6 | public class ImpostorException : Exception 7 | { 8 | public ImpostorException() 9 | { 10 | } 11 | 12 | protected ImpostorException(SerializationInfo info, StreamingContext context) : base(info, context) 13 | { 14 | } 15 | 16 | public ImpostorException(string? message) : base(message) 17 | { 18 | } 19 | 20 | public ImpostorException(string? message, Exception? innerException) : base(message, innerException) 21 | { 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/Impostor.Hazel/Impostor.Hazel.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | net5.0 6 | HAZEL_BAG 7 | 1.0.0 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/Impostor.Server/Config/ServerRedirectorConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Impostor.Server.Config 4 | { 5 | public class ServerRedirectorConfig 6 | { 7 | public const string Section = "ServerRedirector"; 8 | 9 | public bool Enabled { get; set; } 10 | 11 | public bool Master { get; set; } 12 | 13 | public NodeLocator Locator { get; set; } 14 | 15 | public List Nodes { get; set; } 16 | 17 | public class NodeLocator 18 | { 19 | public string Redis { get; set; } 20 | 21 | public string UdpMasterEndpoint { get; set; } 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Plugins/ImpostorPluginAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Impostor.Api.Plugins 4 | { 5 | [AttributeUsage(AttributeTargets.Class)] 6 | public class ImpostorPluginAttribute : Attribute 7 | { 8 | public ImpostorPluginAttribute(string package, string name, string author, string version) 9 | { 10 | Package = package; 11 | Name = name; 12 | Author = author; 13 | Version = version; 14 | } 15 | 16 | public string Package { get; } 17 | 18 | public string Name { get; } 19 | 20 | public string Author { get; } 21 | 22 | public string Version { get; } 23 | } 24 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/C2S/Message10AlterGameC2S.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth; 2 | 3 | namespace Impostor.Api.Net.Messages.C2S 4 | { 5 | public class Message10AlterGameC2S 6 | { 7 | public static void Serialize(IMessageWriter writer) 8 | { 9 | throw new System.NotImplementedException(); 10 | } 11 | 12 | public static void Deserialize(IMessageReader reader, out AlterGameTags gameTag, out bool isPublic) 13 | { 14 | var slice = reader.ReadBytes(sizeof(byte) + sizeof(byte)).Span; 15 | 16 | gameTag = (AlterGameTags)slice.ReadByte(); 17 | isPublic = slice.ReadBoolean(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc16SendChatNote.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth; 2 | 3 | namespace Impostor.Api.Net.Messages.Rpcs 4 | { 5 | public static class Rpc16SendChatNote 6 | { 7 | public static void Serialize(IMessageWriter writer, byte playerId, ChatNoteType chatNoteType) 8 | { 9 | writer.Write(playerId); 10 | writer.Write((byte)chatNoteType); 11 | } 12 | 13 | public static void Deserialize(IMessageReader reader, out byte playerId, out ChatNoteType chatNoteType) 14 | { 15 | playerId = reader.ReadByte(); 16 | chatNoteType = (ChatNoteType)reader.ReadByte(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Announcements/Message02SetFreeWeekend.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth; 2 | 3 | namespace Impostor.Api.Net.Messages.Announcements 4 | { 5 | public static class Message02SetFreeWeekend 6 | { 7 | public static void Serialize(IMessageWriter writer, FreeWeekendState state) 8 | { 9 | writer.StartMessage(AnnouncementsMessageFlags.SetFreeWeekend); 10 | writer.Write((byte)state); 11 | writer.EndMessage(); 12 | } 13 | 14 | public static void Deserialize(IMessageReader reader, out FreeWeekendState state) 15 | { 16 | state = (FreeWeekendState)reader.ReadByte(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Announcements/Message01Update.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages.Announcements 2 | { 3 | public static class Message01Update 4 | { 5 | public static void Serialize(IMessageWriter writer, int id, string message) 6 | { 7 | writer.StartMessage(AnnouncementsMessageFlags.SetUpdate); 8 | writer.WritePacked(id); 9 | writer.Write(message); 10 | writer.EndMessage(); 11 | } 12 | 13 | public static void Deserialize(IMessageReader reader, out int id, out string message) 14 | { 15 | id = reader.ReadPackedInt32(); 16 | message = reader.ReadString(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Impostor.Api/Exceptions/ImpostorConfigException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace Impostor.Api 5 | { 6 | public class ImpostorConfigException : ImpostorException 7 | { 8 | public ImpostorConfigException() 9 | { 10 | } 11 | 12 | protected ImpostorConfigException(SerializationInfo info, StreamingContext context) : base(info, context) 13 | { 14 | } 15 | 16 | public ImpostorConfigException(string? message) : base(message) 17 | { 18 | } 19 | 20 | public ImpostorConfigException(string? message, Exception? innerException) : base(message, innerException) 21 | { 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Impostor.Server/Events/EventHandler.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events; 2 | using Impostor.Server.Events.Register; 3 | 4 | namespace Impostor.Server.Events 5 | { 6 | internal readonly struct EventHandler 7 | { 8 | public EventHandler(IEventListener o, IRegisteredEventListener listener) 9 | { 10 | Object = o; 11 | Listener = listener; 12 | } 13 | 14 | public IEventListener Object { get; } 15 | 16 | public IRegisteredEventListener Listener { get; } 17 | 18 | public void Deconstruct(out IEventListener o, out IRegisteredEventListener listener) 19 | { 20 | o = Object; 21 | listener = Listener; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Reactor/ModdedHandshakeC2S.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Impostor.Api.Net.Messages; 3 | 4 | namespace Impostor.Api.Reactor 5 | { 6 | public static class ModdedHandshakeC2S 7 | { 8 | public static void Deserialize(IMessageReader reader, out int clientVersion, out string name, out ISet? mods) 9 | { 10 | clientVersion = reader.ReadInt32(); 11 | name = reader.ReadString(); 12 | 13 | if (reader.Length > reader.Position) 14 | { 15 | ModList.Deserialize(reader, out mods); 16 | } 17 | else 18 | { 19 | mods = null; 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Impostor.Server/Plugins/LoadedAssemblyInformation.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.Loader; 3 | 4 | namespace Impostor.Server.Plugins 5 | { 6 | public class LoadedAssemblyInformation : IAssemblyInformation 7 | { 8 | private readonly Assembly _assembly; 9 | 10 | public LoadedAssemblyInformation(Assembly assembly) 11 | { 12 | AssemblyName = assembly.GetName(); 13 | _assembly = assembly; 14 | } 15 | 16 | public AssemblyName AssemblyName { get; } 17 | 18 | public bool IsPlugin => false; 19 | 20 | public Assembly Load(AssemblyLoadContext context) 21 | { 22 | return _assembly; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Exceptions/ImpostorProtocolException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace Impostor.Api 5 | { 6 | public class ImpostorProtocolException : ImpostorException 7 | { 8 | public ImpostorProtocolException() 9 | { 10 | } 11 | 12 | protected ImpostorProtocolException(SerializationInfo info, StreamingContext context) : base(info, context) 13 | { 14 | } 15 | 16 | public ImpostorProtocolException(string? message) : base(message) 17 | { 18 | } 19 | 20 | public ImpostorProtocolException(string? message, Exception? innerException) : base(message, innerException) 21 | { 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Impostor.Server/Plugins/PluginLoaderException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | using Impostor.Api; 4 | 5 | namespace Impostor.Server.Plugins 6 | { 7 | public class PluginLoaderException : ImpostorException 8 | { 9 | public PluginLoaderException() 10 | { 11 | } 12 | 13 | protected PluginLoaderException(SerializationInfo info, StreamingContext context) : base(info, context) 14 | { 15 | } 16 | 17 | public PluginLoaderException(string? message) : base(message) 18 | { 19 | } 20 | 21 | public PluginLoaderException(string? message, Exception? innerException) : base(message, innerException) 22 | { 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/Impostor.Plugins.Example/Handlers/AnnouncementsListener.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events; 2 | using Impostor.Api.Events.Announcements; 3 | using Impostor.Api.Innersloth; 4 | 5 | namespace Impostor.Plugins.Example.Handlers 6 | { 7 | public class AnnouncementsListener : IEventListener 8 | { 9 | private const int Id = 50; 10 | 11 | [EventListener] 12 | public void OnAnnouncementRequestEvent(IAnnouncementRequestEvent e) 13 | { 14 | if (e.Id == Id) 15 | { 16 | e.Response.UseCached = true; 17 | } 18 | else 19 | { 20 | e.Response.Announcement = new Announcement(Id, "Hello!"); 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Inner/GameObject.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Impostor.Server.Net.Inner 4 | { 5 | internal class GameObject 6 | { 7 | public GameObject() 8 | { 9 | Components = new List(); 10 | } 11 | 12 | protected List Components { get; } 13 | 14 | public List GetComponentsInChildren() 15 | { 16 | var result = new List(); 17 | 18 | foreach (var component in Components) 19 | { 20 | if (component is T c) 21 | { 22 | result.Add(c); 23 | } 24 | } 25 | 26 | return result; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Impostor.Benchmarks/Program.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Configs; 2 | using BenchmarkDotNet.Diagnosers; 3 | using BenchmarkDotNet.Running; 4 | using Impostor.Benchmarks.Tests; 5 | 6 | namespace Impostor.Benchmarks 7 | { 8 | internal static class Program 9 | { 10 | private static void Main(string[] args) 11 | { 12 | // BenchmarkRunner.Run( 13 | // DefaultConfig.Instance 14 | // .AddDiagnoser(MemoryDiagnoser.Default) 15 | // ); 16 | 17 | BenchmarkRunner.Run( 18 | DefaultConfig.Instance 19 | .AddDiagnoser(MemoryDiagnoser.Default) 20 | ); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Impostor.Hazel/ConnectionState.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Hazel 2 | { 3 | /// 4 | /// Represents the state a is currently in. 5 | /// 6 | public enum ConnectionState 7 | { 8 | /// 9 | /// The Connection has either not been established yet or has been disconnected. 10 | /// 11 | NotConnected, 12 | 13 | /// 14 | /// The Connection is currently connecting to an endpoint. 15 | /// 16 | Connecting, 17 | 18 | /// 19 | /// The Connection is connected and data can be transfered. 20 | /// 21 | Connected, 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Impostor.Server/Events/MultiDisposable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Impostor.Server.Events 5 | { 6 | /// 7 | /// Disposes multiple . 8 | /// 9 | internal class MultiDisposable : IDisposable 10 | { 11 | private readonly IEnumerable _disposables; 12 | 13 | public MultiDisposable(IEnumerable disposables) 14 | { 15 | _disposables = disposables; 16 | } 17 | 18 | public void Dispose() 19 | { 20 | foreach (var disposable in _disposables) 21 | { 22 | disposable?.Dispose(); 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: stale 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: false 18 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc23VotingComplete.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Impostor.Api.Net.Messages.Rpcs 4 | { 5 | public static class Rpc23VotingComplete 6 | { 7 | public static void Serialize(IMessageWriter writer, byte[] states, byte playerId, bool tie) 8 | { 9 | writer.WriteBytesAndSize(states); 10 | writer.Write(playerId); 11 | writer.Write(tie); 12 | } 13 | 14 | public static void Deserialize(IMessageReader reader, out ReadOnlyMemory states, out byte playerId, out bool tie) 15 | { 16 | states = reader.ReadBytesAndSize(); 17 | playerId = reader.ReadByte(); 18 | tie = reader.ReadBoolean(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Game/Player/PlayerExileEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events.Player; 2 | using Impostor.Api.Games; 3 | using Impostor.Api.Net; 4 | using Impostor.Api.Net.Inner.Objects; 5 | 6 | namespace Impostor.Server.Events.Player 7 | { 8 | public class PlayerExileEvent : IPlayerExileEvent 9 | { 10 | public PlayerExileEvent(IGame game, IClientPlayer clientPlayer, IInnerPlayerControl playerControl) 11 | { 12 | Game = game; 13 | ClientPlayer = clientPlayer; 14 | PlayerControl = playerControl; 15 | } 16 | 17 | public IGame Game { get; } 18 | 19 | public IClientPlayer ClientPlayer { get; } 20 | 21 | public IInnerPlayerControl PlayerControl { get; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/S2C/Message12WaitForHostS2C.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages.S2C 2 | { 3 | public class Message12WaitForHostS2C 4 | { 5 | public static void Serialize(IMessageWriter writer, bool clear, int gameCode, int playerId) 6 | { 7 | if (clear) 8 | { 9 | writer.Clear(MessageType.Reliable); 10 | } 11 | 12 | writer.StartMessage(MessageFlags.WaitForHost); 13 | writer.Write(gameCode); 14 | writer.Write(playerId); 15 | writer.EndMessage(); 16 | } 17 | 18 | public static void Deserialize(IMessageReader reader) 19 | { 20 | throw new System.NotImplementedException(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Reactor/ModList.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Impostor.Api.Net.Messages; 3 | 4 | namespace Impostor.Api.Reactor 5 | { 6 | public static class ModList 7 | { 8 | public static void Deserialize(IMessageReader reader, out ISet mods) 9 | { 10 | var length = reader.ReadPackedInt32(); 11 | 12 | mods = new HashSet(length); 13 | 14 | for (var i = 0; i < length; i++) 15 | { 16 | var id = reader.ReadString(); 17 | var version = reader.ReadString(); 18 | var pluginSide = (PluginSide)reader.ReadByte(); 19 | 20 | mods.Add(new Mod(id, version, pluginSide)); 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Game/Player/PlayerSpawnedEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events.Player; 2 | using Impostor.Api.Games; 3 | using Impostor.Api.Net; 4 | using Impostor.Api.Net.Inner.Objects; 5 | 6 | namespace Impostor.Server.Events.Player 7 | { 8 | public class PlayerSpawnedEvent : IPlayerSpawnedEvent 9 | { 10 | public PlayerSpawnedEvent(IGame game, IClientPlayer clientPlayer, IInnerPlayerControl playerControl) 11 | { 12 | Game = game; 13 | ClientPlayer = clientPlayer; 14 | PlayerControl = playerControl; 15 | } 16 | 17 | public IGame Game { get; } 18 | 19 | public IClientPlayer ClientPlayer { get; } 20 | 21 | public IInnerPlayerControl PlayerControl { get; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Impostor.Plugins.Debugger/Pages/_Host.cshtml: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @namespace Impostor.Plugins.Debugger.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | 5 | 6 | 7 | 8 | 9 | 10 | Impostor Debugger 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Game/Player/IPlayerEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Net; 2 | using Impostor.Api.Net.Inner.Objects; 3 | 4 | namespace Impostor.Api.Events.Player 5 | { 6 | public interface IPlayerEvent : IGameEvent 7 | { 8 | /// 9 | /// Gets the that triggered this . 10 | /// 11 | IClientPlayer ClientPlayer { get; } 12 | 13 | /// 14 | /// Gets the networked that triggered this . 15 | /// This belongs to the . 16 | /// 17 | IInnerPlayerControl PlayerControl { get; } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Game/Player/PlayerDestroyedEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events.Player; 2 | using Impostor.Api.Games; 3 | using Impostor.Api.Net; 4 | using Impostor.Api.Net.Inner.Objects; 5 | 6 | namespace Impostor.Server.Events.Player 7 | { 8 | public class PlayerDestroyedEvent : IPlayerDestroyedEvent 9 | { 10 | public PlayerDestroyedEvent(IGame game, IClientPlayer clientPlayer, IInnerPlayerControl playerControl) 11 | { 12 | Game = game; 13 | ClientPlayer = clientPlayer; 14 | PlayerControl = playerControl; 15 | } 16 | 17 | public IGame Game { get; } 18 | 19 | public IClientPlayer ClientPlayer { get; } 20 | 21 | public IInnerPlayerControl PlayerControl { get; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Impostor.Patcher/Impostor.Patcher.Cli/Impostor.Patcher.Cli.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Impostor.Cli 5 | net5.0 6 | win-x64;linux-x64;linux-arm;linux-arm64;osx-x64 7 | Exe 8 | true 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Inner/Objects/Components/IInnerCustomNetworkTransform.cs: -------------------------------------------------------------------------------- 1 | using System.Numerics; 2 | using System.Threading.Tasks; 3 | 4 | namespace Impostor.Api.Net.Inner.Objects.Components 5 | { 6 | public interface IInnerCustomNetworkTransform : IInnerNetObject 7 | { 8 | /// 9 | /// Gets position where the object thinks it is (not interpolated). 10 | /// 11 | Vector2 Position { get; } 12 | 13 | /// 14 | /// Snaps the current to the given position . 15 | /// 16 | /// The target position. 17 | /// Task that must be awaited. 18 | ValueTask SnapToAsync(Vector2 position); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/S2C/Message13RedirectS2C.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | 3 | namespace Impostor.Api.Net.Messages.S2C 4 | { 5 | public class Message13RedirectS2C 6 | { 7 | public static void Serialize(IMessageWriter writer, bool clear, IPEndPoint ipEndPoint) 8 | { 9 | if (clear) 10 | { 11 | writer.Clear(MessageType.Reliable); 12 | } 13 | 14 | writer.StartMessage(MessageFlags.Redirect); 15 | writer.Write(ipEndPoint.Address); 16 | writer.Write((ushort)ipEndPoint.Port); 17 | writer.EndMessage(); 18 | } 19 | 20 | public static void Deserialize(IMessageReader reader) 21 | { 22 | throw new System.NotImplementedException(); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/Impostor.Tests/Impostor.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | false 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/S2C/Message11KickPlayerS2C.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages.S2C 2 | { 3 | public class Message11KickPlayerS2C 4 | { 5 | public static void Serialize(IMessageWriter writer, bool clear, int gameCode, int playerId, bool isBan) 6 | { 7 | if (clear) 8 | { 9 | writer.Clear(MessageType.Reliable); 10 | } 11 | 12 | writer.StartMessage(MessageFlags.KickPlayer); 13 | writer.Write(gameCode); 14 | writer.WritePacked(playerId); 15 | writer.Write(isBan); 16 | writer.EndMessage(); 17 | } 18 | 19 | public static void Deserialize(IMessageReader reader) 20 | { 21 | throw new System.NotImplementedException(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/Impostor.Hazel/DataReceivedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Net.Messages; 2 | 3 | namespace Impostor.Hazel 4 | { 5 | public struct DataReceivedEventArgs 6 | { 7 | public readonly Connection Sender; 8 | 9 | /// 10 | /// The bytes received from the client. 11 | /// 12 | public readonly IMessageReader Message; 13 | 14 | /// 15 | /// The the data was sent with. 16 | /// 17 | public readonly MessageType Type; 18 | 19 | public DataReceivedEventArgs(Connection sender, IMessageReader msg, MessageType type) 20 | { 21 | this.Sender = sender; 22 | this.Message = msg; 23 | this.Type = type; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Impostor.Server/config-full.json: -------------------------------------------------------------------------------- 1 | { 2 | "Server": { 3 | "PublicIp": "127.0.0.1", 4 | "PublicPort": 22023, 5 | "ListenIp": "0.0.0.0", 6 | "ListenPort": 22023 7 | }, 8 | "AnnouncementsServer": { 9 | "Enabled": true, 10 | "ListenIp": "0.0.0.0", 11 | "ListenPort": 22024 12 | }, 13 | "AntiCheat": { 14 | "Enabled": true, 15 | "BanIpFromGame": true 16 | }, 17 | "ServerRedirector": { 18 | "Enabled": false, 19 | "Master": true, 20 | "Locator": { 21 | "Redis": "127.0.0.1.6379", 22 | "UdpMasterEndpoint": "127.0.0.1:32320" 23 | }, 24 | "Nodes": [ 25 | { 26 | "Ip": "127.0.0.1", 27 | "Port": 22024 28 | } 29 | ] 30 | }, 31 | "Debug": { 32 | "GameRecorderEnabled": true, 33 | "GameRecorderPath": "" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Impostor.Hazel/NewConnectionEventArgs.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Net.Messages; 2 | 3 | namespace Impostor.Hazel 4 | { 5 | public struct NewConnectionEventArgs 6 | { 7 | /// 8 | /// The data received from the client in the handshake. 9 | /// This data is yours. Remember to recycle it. 10 | /// 11 | public readonly IMessageReader HandshakeData; 12 | 13 | /// 14 | /// The to the new client. 15 | /// 16 | public readonly Connection Connection; 17 | 18 | public NewConnectionEventArgs(IMessageReader handshakeData, Connection connection) 19 | { 20 | this.HandshakeData = handshakeData; 21 | this.Connection = connection; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/SabotageSystemType.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Net.Messages; 2 | 3 | namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus 4 | { 5 | public class SabotageSystemType : ISystemType 6 | { 7 | private readonly IActivatable[] _specials; 8 | 9 | public SabotageSystemType(IActivatable[] specials) 10 | { 11 | _specials = specials; 12 | } 13 | 14 | public float Timer { get; set; } 15 | 16 | public void Serialize(IMessageWriter writer, bool initialState) 17 | { 18 | throw new System.NotImplementedException(); 19 | } 20 | 21 | public void Deserialize(IMessageReader reader, bool initialState) 22 | { 23 | Timer = reader.ReadSingle(); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/Impostor.Hazel/NetworkConnectionListener.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | 3 | namespace Impostor.Hazel 4 | { 5 | /// 6 | /// Abstract base class for a for network based connections. 7 | /// 8 | /// 9 | public abstract class NetworkConnectionListener : ConnectionListener 10 | { 11 | /// 12 | /// The local end point the listener is listening for new clients on. 13 | /// 14 | public IPEndPoint EndPoint { get; protected set; } 15 | 16 | /// 17 | /// The IPMode the listener is listening for new clients on. 18 | /// 19 | public IPMode IPMode { get; protected set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Impostor.Benchmarks/Extensions/SpanExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Buffers.Binary; 3 | using System.Runtime.CompilerServices; 4 | 5 | namespace Impostor.Benchmarks.Extensions 6 | { 7 | public static class SpanExtensions 8 | { 9 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 10 | public static Span ReadMessage(this Span input) 11 | { 12 | var length = BinaryPrimitives.ReadUInt16LittleEndian(input); 13 | var tag = input[2]; 14 | 15 | return input.Slice(3, length); 16 | } 17 | 18 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 19 | public static int ReadUInt16(this ref ReadOnlySpan input) 20 | { 21 | return BinaryPrimitives.ReadUInt16LittleEndian(input); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Impostor.Hazel/MessageReaderPolicy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Extensions.DependencyInjection; 3 | using Microsoft.Extensions.ObjectPool; 4 | 5 | namespace Impostor.Hazel 6 | { 7 | public class MessageReaderPolicy : IPooledObjectPolicy 8 | { 9 | private readonly IServiceProvider _serviceProvider; 10 | 11 | public MessageReaderPolicy(IServiceProvider serviceProvider) 12 | { 13 | _serviceProvider = serviceProvider; 14 | } 15 | 16 | public MessageReader Create() 17 | { 18 | return new MessageReader(_serviceProvider.GetRequiredService>()); 19 | } 20 | 21 | public bool Return(MessageReader obj) 22 | { 23 | obj.Reset(); 24 | return true; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/IMessageWriterProvider.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages 2 | { 3 | public interface IMessageWriterProvider 4 | { 5 | /// 6 | /// Retrieves a from the internal pool. 7 | /// Make sure to call when you are done! 8 | /// 9 | /// 10 | /// Whether to send the message as or . 11 | /// Reliable packets will ensure delivery while unreliable packets may be lost. 12 | /// 13 | /// A from the pool. 14 | IMessageWriter Get(MessageType sendOption = MessageType.Unreliable); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Impostor.Tests/GameCodeTests.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth; 2 | 3 | using Xunit; 4 | 5 | namespace Impostor.Tests 6 | { 7 | public class GameCodeTests 8 | { 9 | [Fact] 10 | public void CodeV1() 11 | { 12 | const string code = "ABCD"; 13 | const int codeInt = 0x44434241; 14 | 15 | Assert.Equal(code, GameCodeParser.IntToGameName(codeInt)); 16 | Assert.Equal(codeInt, GameCodeParser.GameNameToInt(code)); 17 | } 18 | 19 | [Fact] 20 | public void CodeV2() 21 | { 22 | const string code = "ABCDEF"; 23 | const int codeInt = -1943683525; 24 | 25 | Assert.Equal(code, GameCodeParser.IntToGameName(codeInt)); 26 | Assert.Equal(codeInt, GameCodeParser.GameNameToInt(code)); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Impostor.Hazel/DisconnectedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Impostor.Api.Net.Messages; 3 | 4 | namespace Impostor.Hazel 5 | { 6 | public class DisconnectedEventArgs : EventArgs 7 | { 8 | /// 9 | /// Optional disconnect reason. May be null. 10 | /// 11 | public readonly string Reason; 12 | 13 | /// 14 | /// Optional data sent with a disconnect message. May be null. 15 | /// You must not recycle this. If you need the message outside of a callback, you should copy it. 16 | /// 17 | public readonly IMessageReader Message; 18 | 19 | public DisconnectedEventArgs(string reason, IMessageReader message) 20 | { 21 | this.Reason = reason; 22 | this.Message = message; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/S2C/Message10AlterGameS2C.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth; 2 | 3 | namespace Impostor.Api.Net.Messages.S2C 4 | { 5 | public static class Message10AlterGameS2C 6 | { 7 | public static void Serialize(IMessageWriter writer, bool clear, int gameCode, bool isPublic) 8 | { 9 | if (clear) 10 | { 11 | writer.Clear(MessageType.Reliable); 12 | } 13 | 14 | writer.StartMessage(MessageFlags.AlterGame); 15 | writer.Write(gameCode); 16 | writer.Write((byte)AlterGameTags.ChangePrivacy); 17 | writer.Write(isPublic); 18 | writer.EndMessage(); 19 | } 20 | 21 | public static void Deserialize(IMessageReader reader) 22 | { 23 | throw new System.NotImplementedException(); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/Impostor.Plugins.Example/ExamplePluginStartup.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events; 2 | using Impostor.Api.Plugins; 3 | using Impostor.Plugins.Example.Handlers; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Microsoft.Extensions.Hosting; 6 | 7 | namespace Impostor.Plugins.Example 8 | { 9 | public class ExamplePluginStartup : IPluginStartup 10 | { 11 | public void ConfigureHost(IHostBuilder host) 12 | { 13 | } 14 | 15 | public void ConfigureServices(IServiceCollection services) 16 | { 17 | services.AddSingleton(); 18 | services.AddSingleton(); 19 | services.AddSingleton(); 20 | services.AddSingleton(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/MessageFlags.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages 2 | { 3 | public static class MessageFlags 4 | { 5 | public const byte HostGame = 0; 6 | public const byte JoinGame = 1; 7 | public const byte StartGame = 2; 8 | public const byte RemoveGame = 3; 9 | public const byte RemovePlayer = 4; 10 | public const byte GameData = 5; 11 | public const byte GameDataTo = 6; 12 | public const byte JoinedGame = 7; 13 | public const byte EndGame = 8; 14 | public const byte AlterGame = 10; 15 | public const byte KickPlayer = 11; 16 | public const byte WaitForHost = 12; 17 | public const byte Redirect = 13; 18 | public const byte ReselectServer = 14; 19 | public const byte GetGameList = 9; 20 | public const byte GetGameListV2 = 16; 21 | } 22 | } -------------------------------------------------------------------------------- /src/Impostor.Hazel/Extensions/ServiceProviderExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using Microsoft.Extensions.DependencyInjection.Extensions; 3 | using Microsoft.Extensions.ObjectPool; 4 | 5 | namespace Impostor.Hazel.Extensions 6 | { 7 | public static class ServiceProviderExtensions 8 | { 9 | public static void AddHazel(this IServiceCollection services) 10 | { 11 | services.TryAddSingleton(new DefaultObjectPoolProvider()); 12 | 13 | services.AddSingleton(serviceProvider => 14 | { 15 | var provider = serviceProvider.GetRequiredService(); 16 | var policy = ActivatorUtilities.CreateInstance(serviceProvider); 17 | return provider.Create(policy); 18 | }); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Game/Player/PlayerCompletedTaskEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events.Player; 2 | using Impostor.Api.Games; 3 | using Impostor.Api.Net; 4 | using Impostor.Api.Net.Inner.Objects; 5 | 6 | namespace Impostor.Server.Events.Player 7 | { 8 | public class PlayerCompletedTaskEvent : IPlayerCompletedTaskEvent 9 | { 10 | public PlayerCompletedTaskEvent(IGame game, IClientPlayer clientPlayer, IInnerPlayerControl playerControl, ITaskInfo task) 11 | { 12 | Game = game; 13 | ClientPlayer = clientPlayer; 14 | PlayerControl = playerControl; 15 | Task = task; 16 | } 17 | 18 | public IGame Game { get; } 19 | 20 | public IClientPlayer ClientPlayer { get; } 21 | 22 | public IInnerPlayerControl PlayerControl { get; } 23 | 24 | public ITaskInfo Task { get; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Game/Player/PlayerMurderEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events.Player; 2 | using Impostor.Api.Games; 3 | using Impostor.Api.Net; 4 | using Impostor.Api.Net.Inner.Objects; 5 | 6 | namespace Impostor.Server.Events.Player 7 | { 8 | public class PlayerMurderEvent : IPlayerMurderEvent 9 | { 10 | public PlayerMurderEvent(IGame game, IClientPlayer clientPlayer, IInnerPlayerControl playerControl, IInnerPlayerControl victim) 11 | { 12 | Game = game; 13 | ClientPlayer = clientPlayer; 14 | PlayerControl = playerControl; 15 | Victim = victim; 16 | } 17 | 18 | public IGame Game { get; } 19 | 20 | public IClientPlayer ClientPlayer { get; } 21 | 22 | public IInnerPlayerControl PlayerControl { get; } 23 | 24 | public IInnerPlayerControl Victim { get; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Impostor.Server/Config/ServerConfig.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Server.Utils; 2 | 3 | namespace Impostor.Server.Config 4 | { 5 | internal class ServerConfig 6 | { 7 | private string? _resolvedPublicIp; 8 | private string? _resolvedListenIp; 9 | 10 | public const string Section = "Server"; 11 | 12 | public string PublicIp { get; set; } = "127.0.0.1"; 13 | 14 | public ushort PublicPort { get; set; } = 22023; 15 | 16 | public string ListenIp { get; set; } = "127.0.0.1"; 17 | 18 | public ushort ListenPort { get; set; } = 22023; 19 | 20 | public string ResolvePublicIp() 21 | { 22 | return _resolvedPublicIp ??= IpUtils.ResolveIp(PublicIp); 23 | } 24 | 25 | public string ResolveListenIp() 26 | { 27 | return _resolvedListenIp ??= IpUtils.ResolveIp(ListenIp); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Game/Player/PlayerStartMeetingEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events.Player; 2 | using Impostor.Api.Games; 3 | using Impostor.Api.Net; 4 | using Impostor.Api.Net.Inner.Objects; 5 | 6 | namespace Impostor.Server.Events.Player 7 | { 8 | public class PlayerStartMeetingEvent : IPlayerStartMeetingEvent 9 | { 10 | public PlayerStartMeetingEvent(IGame game, IClientPlayer clientPlayer, IInnerPlayerControl playerControl, IInnerPlayerControl? body) 11 | { 12 | Game = game; 13 | ClientPlayer = clientPlayer; 14 | PlayerControl = playerControl; 15 | Body = body; 16 | } 17 | 18 | public IGame Game { get; } 19 | 20 | public IClientPlayer ClientPlayer { get; } 21 | 22 | public IInnerPlayerControl PlayerControl { get; } 23 | 24 | public IInnerPlayerControl? Body { get; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Game/Player/PlayerSetStartCounterEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events.Player; 2 | using Impostor.Api.Games; 3 | using Impostor.Api.Net; 4 | using Impostor.Api.Net.Inner.Objects; 5 | 6 | namespace Impostor.Server.Events.Player 7 | { 8 | public class PlayerSetStartCounterEvent : IPlayerSetStartCounterEvent 9 | { 10 | public PlayerSetStartCounterEvent(IGame game, IClientPlayer clientPlayer, IInnerPlayerControl playerControl, byte secondsLeft) 11 | { 12 | Game = game; 13 | ClientPlayer = clientPlayer; 14 | PlayerControl = playerControl; 15 | SecondsLeft = secondsLeft; 16 | } 17 | 18 | public byte SecondsLeft { get; } 19 | 20 | public IClientPlayer ClientPlayer { get; } 21 | 22 | public IInnerPlayerControl PlayerControl { get; } 23 | 24 | public IGame Game { get; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/SwitchSystem.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Net.Messages; 2 | 3 | namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus 4 | { 5 | public class SwitchSystem : ISystemType, IActivatable 6 | { 7 | public byte ExpectedSwitches { get; set; } 8 | 9 | public byte ActualSwitches { get; set; } 10 | 11 | public byte Value { get; set; } = byte.MaxValue; 12 | 13 | public bool IsActive { get; } 14 | 15 | public void Serialize(IMessageWriter writer, bool initialState) 16 | { 17 | throw new System.NotImplementedException(); 18 | } 19 | 20 | public void Deserialize(IMessageReader reader, bool initialState) 21 | { 22 | ExpectedSwitches = reader.ReadByte(); 23 | ActualSwitches = reader.ReadByte(); 24 | Value = reader.ReadByte(); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/Rpcs/Rpc28RepairSystem.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Games; 2 | using Impostor.Api.Innersloth; 3 | using Impostor.Api.Net.Inner.Objects; 4 | 5 | namespace Impostor.Api.Net.Messages.Rpcs 6 | { 7 | public static class Rpc28RepairSystem 8 | { 9 | public static void Serialize(IMessageWriter writer, SystemTypes systemType, IInnerPlayerControl player, byte amount) 10 | { 11 | writer.Write((byte)systemType); 12 | writer.Write(player); 13 | writer.Write(amount); 14 | } 15 | 16 | public static void Deserialize(IMessageReader reader, IGame game, out SystemTypes systemType, out IInnerPlayerControl? player, out byte amount) 17 | { 18 | systemType = (SystemTypes)reader.ReadByte(); 19 | player = reader.ReadNetObject(game); 20 | amount = reader.ReadByte(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Factories/ClientFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Impostor.Api.Net; 4 | using Impostor.Api.Reactor; 5 | using Microsoft.Extensions.DependencyInjection; 6 | 7 | namespace Impostor.Server.Net.Factories 8 | { 9 | internal class ClientFactory : IClientFactory 10 | where TClient : ClientBase 11 | { 12 | private readonly IServiceProvider _serviceProvider; 13 | 14 | public ClientFactory(IServiceProvider serviceProvider) 15 | { 16 | _serviceProvider = serviceProvider; 17 | } 18 | 19 | public ClientBase Create(IHazelConnection connection, string name, int clientVersion, ISet mods) 20 | { 21 | var client = ActivatorUtilities.CreateInstance(_serviceProvider, name, connection, mods); 22 | connection.Client = client; 23 | return client; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/Impostor.Tools.ServerReplay/Mocks/MockHazelConnection.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using System.Threading.Tasks; 3 | using Impostor.Api.Net; 4 | using Impostor.Api.Net.Messages; 5 | 6 | namespace Impostor.Tools.ServerReplay.Mocks 7 | { 8 | public class MockHazelConnection : IHazelConnection 9 | { 10 | public MockHazelConnection(IPEndPoint endPoint) 11 | { 12 | EndPoint = endPoint; 13 | IsConnected = true; 14 | Client = null; 15 | } 16 | 17 | public IPEndPoint EndPoint { get; } 18 | public bool IsConnected { get; } 19 | public IClient? Client { get; set; } 20 | 21 | public ValueTask SendAsync(IMessageWriter writer) 22 | { 23 | return ValueTask.CompletedTask; 24 | } 25 | 26 | public ValueTask DisconnectAsync(string reason) 27 | { 28 | return ValueTask.CompletedTask; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Extensions/ServiceProviderExtensions.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Server.Events.Player; 2 | using Microsoft.Extensions.DependencyInjection; 3 | using Microsoft.Extensions.DependencyInjection.Extensions; 4 | using Microsoft.Extensions.ObjectPool; 5 | 6 | namespace Impostor.Server 7 | { 8 | public static class ServiceProviderExtensions 9 | { 10 | public static void AddEventPools(this IServiceCollection services) 11 | { 12 | services.TryAddSingleton(new DefaultObjectPoolProvider()); 13 | 14 | services.AddSingleton(serviceProvider => 15 | { 16 | var provider = serviceProvider.GetRequiredService(); 17 | var policy = ActivatorUtilities.CreateInstance(serviceProvider); 18 | return provider.Create(policy); 19 | }); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Game/Player/PlayerChatEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events; 2 | using Impostor.Api.Events.Player; 3 | using Impostor.Api.Games; 4 | using Impostor.Api.Net; 5 | using Impostor.Api.Net.Inner.Objects; 6 | 7 | namespace Impostor.Server.Events.Player 8 | { 9 | public class PlayerChatEvent : IPlayerChatEvent, IEventCancelable 10 | { 11 | public PlayerChatEvent(IGame game, IClientPlayer clientPlayer, IInnerPlayerControl playerControl, string message) 12 | { 13 | Game = game; 14 | ClientPlayer = clientPlayer; 15 | PlayerControl = playerControl; 16 | Message = message; 17 | } 18 | 19 | public IGame Game { get; } 20 | 21 | public IClientPlayer ClientPlayer { get; } 22 | 23 | public IInnerPlayerControl PlayerControl { get; } 24 | 25 | public string Message { get; } 26 | 27 | public bool IsCancelled { get; set; } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Inner/Objects/InnerGameData.TaskInfo.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth; 2 | using Impostor.Api.Net.Inner.Objects; 3 | using Impostor.Api.Net.Messages; 4 | 5 | namespace Impostor.Server.Net.Inner.Objects 6 | { 7 | internal partial class InnerGameData 8 | { 9 | public class TaskInfo : ITaskInfo 10 | { 11 | public uint Id { get; internal set; } 12 | 13 | public bool Complete { get; internal set; } 14 | 15 | public TaskTypes Type { get; internal set; } 16 | 17 | public void Serialize(IMessageWriter writer) 18 | { 19 | writer.WritePacked((uint)Id); 20 | writer.Write(Complete); 21 | } 22 | 23 | public void Deserialize(IMessageReader reader) 24 | { 25 | Id = reader.ReadPackedUInt32(); 26 | Complete = reader.ReadBoolean(); 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Register/WrappedRegisteredEventListener.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Impostor.Api.Events; 4 | 5 | namespace Impostor.Server.Events.Register 6 | { 7 | internal class WrappedRegisteredEventListener : IRegisteredEventListener 8 | { 9 | private readonly IRegisteredEventListener _innerObject; 10 | private readonly object _object; 11 | 12 | public WrappedRegisteredEventListener(IRegisteredEventListener innerObject, object o) 13 | { 14 | _innerObject = innerObject; 15 | _object = o; 16 | } 17 | 18 | public Type EventType => _innerObject.EventType; 19 | 20 | public EventPriority Priority => _innerObject.Priority; 21 | 22 | public ValueTask InvokeAsync(object eventHandler, object @event, IServiceProvider provider) 23 | { 24 | return _innerObject.InvokeAsync(_object, @event, provider); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/MedScanSystem.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Impostor.Api.Net.Messages; 3 | 4 | namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus 5 | { 6 | public class MedScanSystem : ISystemType 7 | { 8 | public MedScanSystem() 9 | { 10 | UsersList = new List(); 11 | } 12 | 13 | public List UsersList { get; } 14 | 15 | public void Serialize(IMessageWriter writer, bool initialState) 16 | { 17 | throw new System.NotImplementedException(); 18 | } 19 | 20 | public void Deserialize(IMessageReader reader, bool initialState) 21 | { 22 | UsersList.Clear(); 23 | 24 | var num = reader.ReadPackedInt32(); 25 | 26 | for (var i = 0; i < num; i++) 27 | { 28 | UsersList.Add(reader.ReadByte()); 29 | } 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/SystemTypeHelpers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | namespace Impostor.Api.Innersloth 5 | { 6 | internal class SystemTypeHelpers 7 | { 8 | public static readonly SystemTypes[] AllTypes; 9 | public static readonly string[] Names; 10 | 11 | static SystemTypeHelpers() 12 | { 13 | AllTypes = Enum.GetValues(typeof(SystemTypes)).Cast().ToArray(); 14 | Names = AllTypes.Select(x => 15 | { 16 | return x switch 17 | { 18 | SystemTypes.UpperEngine => "Upper Engine", 19 | SystemTypes.Nav => "Navigations", 20 | SystemTypes.LifeSupp => "O2", 21 | SystemTypes.LowerEngine => "Lower Engine", 22 | SystemTypes.LockerRoom => "Locker Room", 23 | _ => x.ToString() 24 | }; 25 | }).ToArray(); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Inner/Objects/Components/InnerCustomNetworkTransform.Api.cs: -------------------------------------------------------------------------------- 1 | using System.Numerics; 2 | using System.Threading.Tasks; 3 | using Impostor.Api.Net.Inner.Objects.Components; 4 | 5 | namespace Impostor.Server.Net.Inner.Objects.Components 6 | { 7 | internal partial class InnerCustomNetworkTransform : IInnerCustomNetworkTransform 8 | { 9 | public Vector2 Position => _targetSyncPosition; 10 | 11 | public async ValueTask SnapToAsync(Vector2 position) 12 | { 13 | var minSid = (ushort)(_lastSequenceId + 5U); 14 | 15 | // Snap in the server. 16 | SnapTo(position, minSid); 17 | 18 | // Broadcast to all clients. 19 | using (var writer = _game.StartRpc(NetId, RpcCalls.SnapTo)) 20 | { 21 | writer.Write(position); 22 | writer.Write(_lastSequenceId); 23 | await _game.FinishRpcAsync(writer); 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Impostor.Api/ProjectRules.ruleset: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Impostor.Plugins.Example/ExamplePlugin.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Impostor.Api.Plugins; 3 | using Microsoft.Extensions.Logging; 4 | 5 | namespace Impostor.Plugins.Example 6 | { 7 | [ImpostorPlugin( 8 | package: "gg.impostor.example", 9 | name: "Example", 10 | author: "AeonLucid", 11 | version: "1.0.0")] 12 | public class ExamplePlugin : PluginBase 13 | { 14 | private readonly ILogger _logger; 15 | 16 | public ExamplePlugin(ILogger logger) 17 | { 18 | _logger = logger; 19 | } 20 | 21 | public override ValueTask EnableAsync() 22 | { 23 | _logger.LogInformation("Example is being enabled."); 24 | return default; 25 | } 26 | 27 | public override ValueTask DisableAsync() 28 | { 29 | _logger.LogInformation("Example is being disabled."); 30 | return default; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Game/Player/PlayerVentEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events.Player; 2 | using Impostor.Api.Games; 3 | using Impostor.Api.Innersloth; 4 | using Impostor.Api.Net; 5 | using Impostor.Api.Net.Inner.Objects; 6 | 7 | namespace Impostor.Server.Events.Player 8 | { 9 | public class PlayerVentEvent : IPlayerVentEvent 10 | { 11 | public PlayerVentEvent(IGame game, IClientPlayer sender, IInnerPlayerControl innerPlayerPhysics, VentLocation ventId, bool ventEnter) 12 | { 13 | Game = game; 14 | ClientPlayer = sender; 15 | PlayerControl = innerPlayerPhysics; 16 | VentId = ventId; 17 | VentEnter = ventEnter; 18 | } 19 | 20 | public IGame Game { get; } 21 | 22 | public IClientPlayer ClientPlayer { get; } 23 | 24 | public IInnerPlayerControl PlayerControl { get; } 25 | 26 | public VentLocation VentId { get; } 27 | 28 | public bool VentEnter { get; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Impostor.Benchmarks/Data/Pool/MessageReader_Bytes_Pooled_ImprovedPolicy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Extensions.DependencyInjection; 3 | using Microsoft.Extensions.ObjectPool; 4 | 5 | namespace Impostor.Benchmarks.Data.Pool 6 | { 7 | public class MessageReader_Bytes_Pooled_ImprovedPolicy : IPooledObjectPolicy 8 | { 9 | private readonly IServiceProvider _serviceProvider; 10 | 11 | public MessageReader_Bytes_Pooled_ImprovedPolicy(IServiceProvider serviceProvider) 12 | { 13 | _serviceProvider = serviceProvider; 14 | } 15 | 16 | public MessageReader_Bytes_Pooled_Improved Create() 17 | { 18 | return new MessageReader_Bytes_Pooled_Improved(_serviceProvider.GetRequiredService>()); 19 | } 20 | 21 | public bool Return(MessageReader_Bytes_Pooled_Improved obj) 22 | { 23 | return true; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Impostor.Hazel/Udp/SendOptionInternal.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Hazel.Udp 2 | { 3 | /// 4 | /// Extra internal states for SendOption enumeration when using UDP. 5 | /// 6 | public enum UdpSendOption : byte 7 | { 8 | /// 9 | /// Hello message for initiating communication. 10 | /// 11 | Hello = 8, 12 | 13 | /// 14 | /// A single byte of continued existence 15 | /// 16 | Ping = 12, 17 | 18 | /// 19 | /// Message for discontinuing communication. 20 | /// 21 | Disconnect = 9, 22 | 23 | /// 24 | /// Message acknowledging the receipt of a message. 25 | /// 26 | Acknowledgement = 10, 27 | 28 | /// 29 | /// Message that is part of a larger, fragmented message. 30 | /// 31 | Fragment = 11, 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /docs/FAQ.md: -------------------------------------------------------------------------------- 1 | # Frequently Answered Questions 2 | 3 | ## What is this? 4 | The Impostor project is a reverse engineered and open sourced server for the game Among Us. The game itself is developed by [InnerSloth](http://www.innersloth.com/) while this project is maintained by the community. This project was built out of frustration for the lack of server availability in certain regions and the inability for the core developer, [AeonLucid](https://github.com/AeonLucid), to join a public game. As of this time, it has not been officially endorsed by the studio. 5 | 6 | ## Can this be used with the mobile version of the game? 7 | Yes, Impostor can be used with both the Android and iOS\* versions of the game. 8 | ###### \* In order to play on an Impostor server with iOS, you _must_ have a jailbroken device. 9 | 10 | ## How can I get started? 11 | See [Setting up your Server](Running-the-server.md) for more information on running the server and [Client Setup](https://impostor.github.io/Impostor/) for helping your friends join in! 12 | -------------------------------------------------------------------------------- /src/Impostor.Hazel/IPMode.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Hazel 2 | { 3 | /// 4 | /// Represents the IP version that a connection or listener will use. 5 | /// 6 | /// 7 | /// If you wand a client to connect or be able to connect using IPv6 then you should use , 8 | /// this sets the underlying sockets to use IPv6 but still allow IPv4 sockets to connect for backwards compatability 9 | /// and hence it is the default IPMode in most cases. 10 | /// 11 | public enum IPMode 12 | { 13 | /// 14 | /// Instruction to use IPv4 only, IPv6 connections will not be able to connect. 15 | /// 16 | IPv4, 17 | 18 | /// 19 | /// Instruction to use IPv6 only, IPv4 connections will not be able to connect. IPv4 addresses can be connected 20 | /// by converting to IPv6 addresses. 21 | /// 22 | IPv6 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Announcements/AnnouncementRequestEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events.Announcements; 2 | using Impostor.Api.Innersloth; 3 | 4 | namespace Impostor.Server.Events.Announcements 5 | { 6 | public class AnnouncementRequestEvent : IAnnouncementRequestEvent 7 | { 8 | public AnnouncementRequestEvent(int id, Language language) 9 | { 10 | Id = id; 11 | Language = language; 12 | } 13 | 14 | public int Id { get; } 15 | 16 | public Language Language { get; } 17 | 18 | public IAnnouncementRequestEvent.IResponse Response { get; set; } = new AnnouncementResponse(); 19 | 20 | public class AnnouncementResponse : IAnnouncementRequestEvent.IResponse 21 | { 22 | public FreeWeekendState FreeWeekendState { get; set; } = FreeWeekendState.NotFree; 23 | 24 | public bool UseCached { get; set; } = false; 25 | 26 | public Announcement? Announcement { get; set; } = null; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/S2C/Message07JoinedGameS2C.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Net.Messages.S2C 2 | { 3 | public static class Message07JoinedGameS2C 4 | { 5 | public static void Serialize(IMessageWriter writer, bool clear, int gameCode, int playerId, int hostId, int[] otherPlayerIds) 6 | { 7 | if (clear) 8 | { 9 | writer.Clear(MessageType.Reliable); 10 | } 11 | 12 | writer.StartMessage(MessageFlags.JoinedGame); 13 | writer.Write(gameCode); 14 | writer.Write(playerId); 15 | writer.Write(hostId); 16 | writer.WritePacked(otherPlayerIds.Length); 17 | 18 | foreach (var id in otherPlayerIds) 19 | { 20 | writer.WritePacked(id); 21 | } 22 | 23 | writer.EndMessage(); 24 | } 25 | 26 | public static void Deserialize(IMessageReader reader) 27 | { 28 | throw new System.NotImplementedException(); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/S2C/Message04RemovePlayerS2C.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Innersloth; 2 | 3 | namespace Impostor.Api.Net.Messages.S2C 4 | { 5 | public class Message04RemovePlayerS2C 6 | { 7 | public static void Serialize(IMessageWriter writer, bool clear, int gameCode, int playerId, int hostId, DisconnectReason reason) 8 | { 9 | // Only a subset of DisconnectReason shows an unique message. 10 | // ExitGame, Banned and Kicked. 11 | if (clear) 12 | { 13 | writer.Clear(MessageType.Reliable); 14 | } 15 | 16 | writer.StartMessage(MessageFlags.RemovePlayer); 17 | writer.Write(gameCode); 18 | writer.Write(playerId); 19 | writer.Write(hostId); 20 | writer.Write((byte)reason); 21 | writer.EndMessage(); 22 | } 23 | 24 | public static void Deserialize(IMessageReader reader) 25 | { 26 | throw new System.NotImplementedException(); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Register/ManualRegisteredEventListener.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Impostor.Api.Events; 4 | 5 | namespace Impostor.Server.Events.Register 6 | { 7 | internal class ManualRegisteredEventListener : IRegisteredEventListener 8 | { 9 | public Type EventType { get; } = typeof(object); 10 | 11 | private readonly IManualEventListener _manualEventListener; 12 | 13 | public ManualRegisteredEventListener(IManualEventListener manualEventListener) 14 | { 15 | _manualEventListener = manualEventListener; 16 | } 17 | 18 | public EventPriority Priority => _manualEventListener.Priority; 19 | 20 | public ValueTask InvokeAsync(object eventHandler, object @event, IServiceProvider provider) 21 | { 22 | if (@event is IEvent typedEvent) 23 | { 24 | return _manualEventListener.Execute(typedEvent); 25 | } 26 | 27 | return ValueTask.CompletedTask; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Impostor.Server/Config/DisconnectMessages.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Server.Config 2 | { 3 | public static class DisconnectMessages 4 | { 5 | public const string Error = "There was an internal server error. " + 6 | "Check the server console for more information. " + 7 | "Please report the issue on the AmongUsServer GitHub if it keeps happening."; 8 | 9 | public const string Destroyed = "The game you tried to join is being destroyed. " + 10 | "Please create a new game."; 11 | 12 | public const string NotImplemented = "Game listing has not been implemented in Impostor yet for servers " + 13 | "running in server redirection mode."; 14 | 15 | public const string UsernameLength = "Your username is too long, please make it shorter."; 16 | 17 | public const string UsernameIllegalCharacters = "Your username contains illegal characters, please remove them."; 18 | } 19 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Register/InvokedRegisteredEventListener.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Impostor.Api.Events; 4 | 5 | namespace Impostor.Server.Events.Register 6 | { 7 | internal class InvokedRegisteredEventListener : IRegisteredEventListener 8 | { 9 | private readonly IRegisteredEventListener _innerObject; 10 | private readonly Func, Task> _invoker; 11 | 12 | public InvokedRegisteredEventListener(IRegisteredEventListener innerObject, Func, Task> invoker) 13 | { 14 | _innerObject = innerObject; 15 | _invoker = invoker; 16 | } 17 | 18 | public Type EventType => _innerObject.EventType; 19 | 20 | public EventPriority Priority => _innerObject.Priority; 21 | 22 | public ValueTask InvokeAsync(object eventHandler, object @event, IServiceProvider provider) 23 | { 24 | return new ValueTask(_invoker(() => _innerObject.InvokeAsync(eventHandler, @event, provider).AsTask())); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Inner/RpcCalls.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Server.Net.Inner 2 | { 3 | public enum RpcCalls : byte 4 | { 5 | PlayAnimation = 0, 6 | CompleteTask = 1, 7 | SyncSettings = 2, 8 | SetInfected = 3, 9 | Exiled = 4, 10 | CheckName = 5, 11 | SetName = 6, 12 | CheckColor = 7, 13 | SetColor = 8, 14 | SetHat = 9, 15 | SetSkin = 10, 16 | ReportDeadBody = 11, 17 | MurderPlayer = 12, 18 | SendChat = 13, 19 | StartMeeting = 14, 20 | SetScanner = 15, 21 | SendChatNote = 16, 22 | SetPet = 17, 23 | SetStartCounter = 18, 24 | EnterVent = 19, 25 | ExitVent = 20, 26 | SnapTo = 21, 27 | Close = 22, 28 | VotingComplete = 23, 29 | CastVote = 24, 30 | ClearVote = 25, 31 | AddVote = 26, 32 | CloseDoorsOfType = 27, 33 | RepairSystem = 28, 34 | SetTasks = 29, 35 | UpdateGameData = 30, 36 | CustomRpc = byte.MaxValue 37 | } 38 | } -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: '{build}' 2 | 3 | environment: 4 | IMPOSTOR_VERSION: '1.2.2' 5 | DOTNET_CLI_TELEMETRY_OPTOUT: 1 6 | 7 | branches: 8 | except: 9 | - gh-pages 10 | 11 | pull_requests: 12 | do_not_increment_build_number: true 13 | 14 | assembly_info: 15 | patch: false 16 | 17 | dotnet_csproj: 18 | patch: false 19 | 20 | image: Visual Studio 2019 Preview 21 | 22 | install: 23 | - git submodule update --init --recursive 24 | - ps: dotnet tool restore 25 | 26 | build_script: 27 | - ps: dotnet cake build.cake --bootstrap 28 | - ps: dotnet cake build.cake --pack 29 | 30 | test: off 31 | 32 | artifacts: 33 | - path: ./build/*.zip 34 | - path: ./build/*.tar.gz 35 | - path: ./build/*.nupkg 36 | - path: ./build/*.snupkg 37 | 38 | # deploy: 39 | # - provider: NuGet 40 | # artifact: /.*(\.|\.s)nupkg/ 41 | # on: 42 | # branch: dev 43 | # api_key: 44 | # secure: 4OHXl+m1KVi60hB1j54MpdP8tVv0UNfkdF4rVP+2AhAjN4a2MVT+Bl90gJZ96xHF 45 | 46 | only_commits: 47 | files: 48 | - appveyor.yml 49 | - build.cake 50 | - src/**/* 51 | - .gitmodules 52 | -------------------------------------------------------------------------------- /src/Impostor.Hazel/IRecyclable.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Hazel 2 | { 3 | /// 4 | /// Interface for all items that can be returned to an object pool. 5 | /// 6 | /// 7 | public interface IRecyclable 8 | { 9 | /// 10 | /// Returns this object back to the object pool. 11 | /// 12 | /// 13 | /// 14 | /// Calling this when you are done with the object returns the object back to a pool in order to be reused. 15 | /// This can reduce the amount of work the GC has to do dramatically but it is optional to call this. 16 | /// 17 | /// 18 | /// Calling this indicates to Hazel that this can be reused and thus you should only call this when you are 19 | /// completely finished with the object as the contents can be overwritten at any point after. 20 | /// 21 | /// 22 | void Recycle(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Impostor.Server/Plugins/AssemblyInformation.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Reflection; 3 | using System.Runtime.Loader; 4 | 5 | namespace Impostor.Server.Plugins 6 | { 7 | public class AssemblyInformation : IAssemblyInformation 8 | { 9 | private Assembly _assembly; 10 | 11 | public AssemblyInformation(AssemblyName assemblyName, string path, bool isPlugin) 12 | { 13 | AssemblyName = assemblyName; 14 | Path = path; 15 | IsPlugin = isPlugin; 16 | } 17 | 18 | public string Path { get; } 19 | 20 | public bool IsPlugin { get; } 21 | 22 | public AssemblyName AssemblyName { get; } 23 | 24 | public Assembly Load(AssemblyLoadContext context) 25 | { 26 | if (_assembly != null) 27 | { 28 | return _assembly; 29 | } 30 | 31 | using var stream = File.Open(Path, FileMode.Open, FileAccess.Read, FileShare.Read); 32 | 33 | _assembly = context.LoadFromStream(stream); 34 | 35 | return _assembly; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Plugins/PluginInformation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using Impostor.Api.Plugins; 4 | 5 | namespace Impostor.Server.Plugins 6 | { 7 | public class PluginInformation 8 | { 9 | private readonly ImpostorPluginAttribute _attribute; 10 | 11 | public PluginInformation(IPluginStartup startup, Type pluginType) 12 | { 13 | _attribute = pluginType.GetCustomAttribute(); 14 | 15 | Startup = startup; 16 | PluginType = pluginType; 17 | } 18 | 19 | public string Package => _attribute.Package; 20 | 21 | public string Name => _attribute.Name; 22 | 23 | public string Author => _attribute.Author; 24 | 25 | public string Version => _attribute.Version; 26 | 27 | public IPluginStartup Startup { get; } 28 | 29 | public Type PluginType { get; } 30 | 31 | public IPlugin Instance { get; set; } 32 | 33 | public override string ToString() 34 | { 35 | return $"{Package} {Name} ({Version}) by {Author}"; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/Impostor.Patcher/Impostor.Patcher.WinForms/Impostor.Patcher.WinForms.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Impostor 5 | {804CF172-0C87-4423-9688-BD97D549891E} 6 | WinExe 7 | net472 8 | true 9 | Copyright © AeonLucid 2020 10 | icon.ico 11 | true 12 | true 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/ServerInfo.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Net; 3 | 4 | namespace Impostor.Api.Innersloth 5 | { 6 | public class ServerInfo 7 | { 8 | public string Name { get; } 9 | public string Ip { get; } 10 | public ushort Port { get; } 11 | 12 | public ServerInfo(string name, string ip, ushort port) 13 | { 14 | Name = name; 15 | Ip = ip; 16 | Port = port; 17 | } 18 | 19 | public void Serialize(BinaryWriter writer) 20 | { 21 | writer.Write(Name); 22 | writer.Write(IPAddress.Parse(Ip).GetAddressBytes()); 23 | writer.Write(Port); 24 | writer.Write(0); 25 | } 26 | 27 | public static ServerInfo Deserialize(BinaryReader reader) 28 | { 29 | var name = reader.ReadString(); 30 | var ip = new IPAddress(reader.ReadBytes(4)).ToString(); 31 | var port = reader.ReadUInt16(); 32 | var unknown = reader.ReadInt32(); 33 | 34 | return new ServerInfo(name, ip, port); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/Impostor.Tests/Hazel/MessageWriterTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Impostor.Hazel; 4 | using Xunit; 5 | 6 | namespace Impostor.Tests.Hazel 7 | { 8 | public class MessageWriterTests 9 | { 10 | [Fact] 11 | public void ReadOnlyMemoryWriteWorksTheSameAsArray() 12 | { 13 | var oldVer = new MessageWriter(1024); 14 | var newVer = new MessageWriter(1024); 15 | 16 | var data = Enumerable.Repeat 17 | ( 18 | Enumerable.Range(0, byte.MaxValue) 19 | .Select(x => (byte)x), 20 | 2 21 | ).SelectMany(x => x).ToArray(); 22 | 23 | WriteSomeData(oldVer); 24 | WriteSomeData(newVer); 25 | 26 | oldVer.Write(data); 27 | newVer.Write(data.AsMemory()); 28 | 29 | Assert.True(oldVer.Buffer.AsSpan().SequenceEqual(newVer.Buffer.AsSpan())); 30 | 31 | static void WriteSomeData(MessageWriter oldVer) 32 | { 33 | oldVer.WritePacked(99); 34 | oldVer.WritePacked(101); 35 | } 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/SystemTypes.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Innersloth 2 | { 3 | public enum SystemTypes : byte 4 | { 5 | Hallway = 0, 6 | Storage = 1, 7 | Cafeteria = 2, 8 | Reactor = 3, 9 | UpperEngine = 4, 10 | Nav = 5, 11 | Admin = 6, 12 | Electrical = 7, 13 | LifeSupp = 8, 14 | Shields = 9, 15 | MedBay = 10, 16 | Security = 11, 17 | Weapons = 12, 18 | LowerEngine = 13, 19 | Comms = 14, 20 | ShipTasks = 15, 21 | Doors = 16, 22 | Sabotage = 17, 23 | /// 24 | /// Decontam on Mira and bottom decontam on Polus 25 | /// 26 | Decontamination = 18, 27 | Launchpad = 19, 28 | LockerRoom = 20, 29 | Laboratory = 21, 30 | Balcony = 22, 31 | Office = 23, 32 | Greenhouse = 24, 33 | Dropship = 25, 34 | /// 35 | /// Top decontam on Polus 36 | /// 37 | Decontamination2 = 26, 38 | Outside = 27, 39 | Specimens = 28, 40 | BoilerRoom = 29 41 | } 42 | } -------------------------------------------------------------------------------- /src/Impostor.Plugins.Debugger/DebugPluginStartup.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Plugins; 2 | using Microsoft.AspNetCore.Builder; 3 | using Microsoft.AspNetCore.Hosting; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Microsoft.Extensions.Hosting; 6 | 7 | namespace Impostor.Plugins.Debugger 8 | { 9 | public class DebugPluginStartup : IPluginStartup 10 | { 11 | public void ConfigureServices(IServiceCollection services) 12 | { 13 | services.AddRazorPages(); 14 | services.AddServerSideBlazor(); 15 | } 16 | 17 | public void ConfigureHost(IHostBuilder host) 18 | { 19 | host.ConfigureWebHostDefaults(webBuilder => 20 | { 21 | webBuilder.Configure(app => 22 | { 23 | app.UseStaticFiles(); 24 | app.UseRouting(); 25 | 26 | app.UseEndpoints(endpoints => 27 | { 28 | endpoints.MapBlazorHub(); 29 | endpoints.MapFallbackToPage("/_Host"); 30 | }); 31 | }); 32 | }); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/Impostor.Patcher/Impostor.Patcher.Shared/Innersloth/ServerInfo.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Net; 3 | 4 | namespace Impostor.Patcher.Shared.Innersloth 5 | { 6 | public class ServerInfo 7 | { 8 | public string Name { get; } 9 | public string Ip { get; } 10 | public ushort Port { get; } 11 | 12 | public ServerInfo(string name, string ip, ushort port) 13 | { 14 | Name = name; 15 | Ip = ip; 16 | Port = port; 17 | } 18 | 19 | public void Serialize(BinaryWriter writer) 20 | { 21 | writer.Write(Name); 22 | writer.Write(IPAddress.Parse(Ip).GetAddressBytes()); 23 | writer.Write(Port); 24 | writer.Write(0); 25 | } 26 | 27 | public static ServerInfo Deserialize(BinaryReader reader) 28 | { 29 | var name = reader.ReadString(); 30 | var ip = new IPAddress(reader.ReadBytes(4)).ToString(); 31 | var port = reader.ReadUInt16(); 32 | var unknown = reader.ReadInt32(); 33 | 34 | return new ServerInfo(name, ip, port); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Events/Attributes/EventListenerAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Impostor.Api.Events 4 | { 5 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] 6 | public class EventListenerAttribute : Attribute 7 | { 8 | public EventListenerAttribute(EventPriority priority = EventPriority.Normal) 9 | { 10 | Priority = priority; 11 | } 12 | 13 | public EventListenerAttribute(Type @event, EventPriority priority = EventPriority.Normal) 14 | { 15 | Priority = priority; 16 | Event = @event; 17 | } 18 | 19 | /// 20 | /// The priority of the event listener. 21 | /// 22 | public EventPriority Priority { get; set; } 23 | 24 | /// 25 | /// The events that the listener is listening to. 26 | /// 27 | public Type? Event { get; set; } 28 | 29 | /// 30 | /// If set to true, the listener will be called regardless of the . 31 | /// 32 | public bool IgnoreCancelled { get; set; } 33 | } 34 | } -------------------------------------------------------------------------------- /src/Impostor.Server/ProjectRules.ruleset: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/Impostor.Patcher/Impostor.Patcher.WinForms/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Impostor.Patcher.Properties 12 | { 13 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 14 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute( 15 | "Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 17 | { 18 | private static Settings defaultInstance = 19 | ((Settings) (global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 20 | 21 | public static Settings Default 22 | { 23 | get { return defaultInstance; } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Inner/Objects/InnerLobbyBehaviour.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Impostor.Api.Games; 3 | using Impostor.Api.Net; 4 | using Impostor.Api.Net.Inner.Objects; 5 | using Impostor.Api.Net.Messages; 6 | using Impostor.Server.Net.State; 7 | 8 | namespace Impostor.Server.Net.Inner.Objects 9 | { 10 | internal class InnerLobbyBehaviour : InnerNetObject, IInnerLobbyBehaviour 11 | { 12 | private readonly IGame _game; 13 | 14 | public InnerLobbyBehaviour(IGame game) 15 | { 16 | _game = game; 17 | 18 | Components.Add(this); 19 | } 20 | 21 | public override ValueTask SerializeAsync(IMessageWriter writer, bool initialState) 22 | { 23 | throw new System.NotImplementedException(); 24 | } 25 | 26 | public override ValueTask DeserializeAsync(IClientPlayer sender, IClientPlayer? target, IMessageReader reader, bool initialState) 27 | { 28 | throw new System.NotImplementedException(); 29 | } 30 | 31 | public override ValueTask HandleRpc(ClientPlayer sender, ClientPlayer? target, RpcCalls call, IMessageReader reader) 32 | { 33 | throw new System.NotImplementedException(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribute guidelines 2 | 3 | We are always looking for people to help improve Impostor. 4 | 5 | ## Code 6 | 7 | - If you are implementing or fixing an issue, please comment on the issue so work is not duplicated. 8 | - If you want to implementing a new feature, create an issue first describing the issue so we know about it. We are always open for discussion or questions on [Discord](https://discord.gg/Mk3w6Tb). 9 | - Don't commit unnecessary changes to the codebase or debugging code. 10 | - Write meaningful commits or squash them. 11 | - Please try to follow the code style of the rest of the codebase. An `.editorconfig` file has been provided to keep consistency. 12 | 13 | ## Pull requests 14 | 15 | - Only make pull requests to the `dev` branch. 16 | - Only implement one feature per pull request to keep it easy to understand. 17 | - Expect comments or questions on your pull request from the project maintainers. We try to keep the code as consistent and maintainable as possible. 18 | - Each pull request should come from a new branch in your fork, it should have a meaningful name. 19 | - We try to respond to pull requests as fast as possible. If you think we might have missed it, let us know on [Discord](https://discord.gg/Mk3w6Tb). 20 | 21 | 22 | If you have any questions, let us know. -------------------------------------------------------------------------------- /src/Impostor.Api/Impostor.Api.csproj.DotSettings: -------------------------------------------------------------------------------- 1 | 2 | True 3 | True 4 | True 5 | True 6 | True 7 | True 8 | True -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/ReactorSystemType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Impostor.Api.Net.Messages; 4 | 5 | namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus 6 | { 7 | public class ReactorSystemType : ISystemType, IActivatable 8 | { 9 | public ReactorSystemType() 10 | { 11 | Countdown = 10000f; 12 | UserConsolePairs = new HashSet>(); 13 | } 14 | 15 | public float Countdown { get; private set; } 16 | 17 | public HashSet> UserConsolePairs { get; } 18 | 19 | public bool IsActive => Countdown < 10000.0; 20 | 21 | public void Serialize(IMessageWriter writer, bool initialState) 22 | { 23 | throw new System.NotImplementedException(); 24 | } 25 | 26 | public void Deserialize(IMessageReader reader, bool initialState) 27 | { 28 | Countdown = reader.ReadSingle(); 29 | UserConsolePairs.Clear(); // TODO: Thread safety 30 | 31 | var count = reader.ReadPackedInt32(); 32 | 33 | for (var i = 0; i < count; i++) 34 | { 35 | UserConsolePairs.Add(new Tuple(reader.ReadByte(), reader.ReadByte())); 36 | } 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Redirector/NodeProviderConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Net; 3 | using Impostor.Server.Config; 4 | using Microsoft.Extensions.Options; 5 | 6 | namespace Impostor.Server.Net.Redirector 7 | { 8 | internal class NodeProviderConfig : INodeProvider 9 | { 10 | private readonly List _nodes; 11 | private readonly object _lock; 12 | private int _currentIndex; 13 | 14 | public NodeProviderConfig(IOptions redirectorConfig) 15 | { 16 | _nodes = new List(); 17 | _lock = new object(); 18 | 19 | if (redirectorConfig.Value.Nodes != null) 20 | { 21 | foreach (var node in redirectorConfig.Value.Nodes) 22 | { 23 | _nodes.Add(new IPEndPoint(IPAddress.Parse(node.Ip), node.Port)); 24 | } 25 | } 26 | } 27 | 28 | public IPEndPoint Get() 29 | { 30 | lock (_lock) 31 | { 32 | var node = _nodes[_currentIndex++]; 33 | 34 | if (_currentIndex == _nodes.Count) 35 | { 36 | _currentIndex = 0; 37 | } 38 | 39 | return node; 40 | } 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Games/GameJoinError.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Games 2 | { 3 | public enum GameJoinError 4 | { 5 | /// 6 | /// No error occured while joining the game. 7 | /// 8 | None, 9 | 10 | /// 11 | /// The client is not registered in the client manager. 12 | /// 13 | InvalidClient, 14 | 15 | /// 16 | /// The client has been banned from the game. 17 | /// 18 | Banned, 19 | 20 | /// 21 | /// The game is full. 22 | /// 23 | GameFull, 24 | 25 | /// 26 | /// The limbo state of the player is incorrect. 27 | /// 28 | InvalidLimbo, 29 | 30 | /// 31 | /// The game is already started. 32 | /// 33 | GameStarted, 34 | 35 | /// 36 | /// The game has been destroyed. 37 | /// 38 | GameDestroyed, 39 | 40 | /// 41 | /// Custom error by a plugin. 42 | /// 43 | /// 44 | /// A custom message can be set in . 45 | /// 46 | Custom, 47 | } 48 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/IHazelConnection.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using System.Threading.Tasks; 3 | using Impostor.Api.Net.Messages; 4 | 5 | namespace Impostor.Api.Net 6 | { 7 | /// 8 | /// Represents the connection of the client. 9 | /// 10 | public interface IHazelConnection 11 | { 12 | /// 13 | /// Gets the IP endpoint of the client. 14 | /// 15 | IPEndPoint EndPoint { get; } 16 | 17 | /// 18 | /// Gets a value indicating whether the client is connected to the server. 19 | /// 20 | bool IsConnected { get; } 21 | 22 | /// 23 | /// Gets the client of the connection. 24 | /// 25 | IClient? Client { get; set; } 26 | 27 | /// 28 | /// Sends a message writer to the connection. 29 | /// 30 | /// The message. 31 | /// 32 | ValueTask SendAsync(IMessageWriter writer); 33 | 34 | /// 35 | /// Disconnects the client and invokes the disconnect handler. 36 | /// 37 | /// A reason. 38 | /// 39 | ValueTask DisconnectAsync(string? reason); 40 | } 41 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Inner/Objects/Systems/ShipStatus/LifeSuppSystemType.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Impostor.Api.Net.Messages; 3 | 4 | namespace Impostor.Server.Net.Inner.Objects.Systems.ShipStatus 5 | { 6 | public class LifeSuppSystemType : ISystemType, IActivatable 7 | { 8 | public LifeSuppSystemType() 9 | { 10 | Countdown = 10000f; 11 | CompletedConsoles = new HashSet(); 12 | } 13 | 14 | public float Countdown { get; private set; } 15 | 16 | public HashSet CompletedConsoles { get; } 17 | 18 | public bool IsActive => Countdown < 10000.0; 19 | 20 | public void Serialize(IMessageWriter writer, bool initialState) 21 | { 22 | throw new System.NotImplementedException(); 23 | } 24 | 25 | public void Deserialize(IMessageReader reader, bool initialState) 26 | { 27 | Countdown = reader.ReadSingle(); 28 | 29 | if (reader.Position >= reader.Length) 30 | { 31 | return; 32 | } 33 | 34 | CompletedConsoles.Clear(); // TODO: Thread safety 35 | 36 | var num = reader.ReadPackedInt32(); 37 | 38 | for (var i = 0; i < num; i++) 39 | { 40 | CompletedConsoles.Add(reader.ReadPackedInt32()); 41 | } 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/VentLocation.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Innersloth 2 | { 3 | public enum VentLocation : uint 4 | { 5 | // Skeld 6 | SkeldAdmin = 0, 7 | SkeldRightHallway = 1, 8 | SkeldCafeteria = 2, 9 | SkeldElectrical = 3, 10 | SkeldUpperEngine = 4, 11 | SkeldSecurity = 5, 12 | SkeldMedbay = 6, 13 | SkeldWeapons = 7, 14 | SkeldLowerReactor = 8, 15 | SkeldLowerEngine = 9, 16 | SkeldShields = 10, 17 | SkeldUpperReactor = 11, 18 | SkeldUpperNavigation = 12, 19 | SkeldLowerNavigation = 13, 20 | 21 | // Mira HQ 22 | MiraBalcony = 1, 23 | MiraCafeteria = 2, 24 | MiraReactor = 3, 25 | MiraLaboratory = 4, 26 | MiraOffice = 5, 27 | MiraAdmin = 6, 28 | MiraGreenhouse = 7, 29 | MiraMedbay = 8, 30 | MiraDecontamination = 9, 31 | MiraLockerRoom = 10, 32 | MiraLaunchpad = 11, 33 | 34 | // Polus 35 | PolusSecurity = 0, 36 | PolusElectrical = 1, 37 | PolusO2 = 2, 38 | PolusCommunications = 3, 39 | PolusOffice = 4, 40 | PolusAdmin = 5, 41 | PolusLaboratory = 6, 42 | PolusLava = 7, 43 | PolusStorage = 8, 44 | PolusRightStabilizer = 9, 45 | PolusLeftStabilizer = 10, 46 | PolusOutsideAdmin = 11, 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Impostor.Server/Net/Redirector/NodeLocatorRedis.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Threading.Tasks; 4 | using Microsoft.Extensions.Caching.Distributed; 5 | using Microsoft.Extensions.Logging; 6 | 7 | namespace Impostor.Server.Net.Redirector 8 | { 9 | public class NodeLocatorRedis : INodeLocator 10 | { 11 | private readonly IDistributedCache _cache; 12 | 13 | public NodeLocatorRedis(ILogger logger, IDistributedCache cache) 14 | { 15 | logger.LogWarning("Using the redis NodeLocator."); 16 | _cache = cache; 17 | } 18 | 19 | public async ValueTask FindAsync(string gameCode) 20 | { 21 | var entry = await _cache.GetStringAsync(gameCode); 22 | if (entry == null) 23 | { 24 | return null; 25 | } 26 | 27 | return IPEndPoint.Parse(entry); 28 | } 29 | 30 | public async ValueTask SaveAsync(string gameCode, IPEndPoint endPoint) 31 | { 32 | await _cache.SetStringAsync(gameCode, endPoint.ToString(), new DistributedCacheEntryOptions 33 | { 34 | SlidingExpiration = TimeSpan.FromHours(1), 35 | }); 36 | } 37 | 38 | public async ValueTask RemoveAsync(string gameCode) 39 | { 40 | await _cache.RemoveAsync(gameCode); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/IClientPlayer.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Impostor.Api.Games; 3 | using Impostor.Api.Net.Inner; 4 | using Impostor.Api.Net.Inner.Objects; 5 | 6 | namespace Impostor.Api.Net 7 | { 8 | /// 9 | /// Represents a player in . 10 | /// 11 | public interface IClientPlayer 12 | { 13 | /// 14 | /// Gets the client that belongs to the player. 15 | /// 16 | IClient Client { get; } 17 | 18 | /// 19 | /// Gets the game where the belongs to. 20 | /// 21 | IGame Game { get; } 22 | 23 | /// 24 | /// Gets or sets the current limbo state of the player. 25 | /// 26 | LimboStates Limbo { get; set; } 27 | 28 | IInnerPlayerControl? Character { get; } 29 | 30 | public bool IsHost { get; } 31 | 32 | /// 33 | /// Checks if the specified is owned by . 34 | /// 35 | /// The . 36 | /// Returns true if owned by . 37 | bool IsOwner(IInnerNetObject netObject); 38 | 39 | ValueTask KickAsync(); 40 | 41 | ValueTask BanAsync(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/TaskTypes.cs: -------------------------------------------------------------------------------- 1 | namespace Impostor.Api.Innersloth 2 | { 3 | public enum TaskTypes : uint 4 | { 5 | SubmitScan = 0, 6 | PrimeShields = 1, 7 | FuelEngines = 2, 8 | ChartCourse = 3, 9 | StartReactor = 4, 10 | SwipeCard = 5, 11 | ClearAsteroids = 6, 12 | UploadData = 7, 13 | InspectSample = 8, 14 | EmptyChute = 9, 15 | EmptyGarbage = 10, 16 | AlignEngineOutput = 11, 17 | FixWiring = 12, 18 | CalibrateDistributor = 13, 19 | DivertPower = 14, 20 | UnlockManifolds = 15, 21 | ResetReactor = 16, 22 | FixLights = 17, 23 | Filter = 18, 24 | FixComms = 19, 25 | RestoreOxy = 20, 26 | StabilizeSteering = 21, 27 | AssembleArtifact = 22, 28 | SortSamples = 23, 29 | MeasureWeather = 24, 30 | EnterIdCode = 25, 31 | BuyBeverage = 26, 32 | ProcessData = 27, 33 | RunDiagnostics = 28, 34 | WaterPlants = 29, 35 | MonitorOxygen = 30, 36 | StoreArtifact = 31, 37 | FillCanisters = 32, 38 | ActivateWeatherNodes = 33, 39 | InsertKeys = 34, 40 | ResetSeismic = 35, 41 | ScanBoardingPass = 36, 42 | OpenWaterways = 37, 43 | ReplaceWaterJug = 38, 44 | RepairDrill = 39, 45 | AlignTelescope = 40, 46 | RecordTemperature = 41, 47 | RebootWifi = 42, 48 | } 49 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Innersloth/RegionInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | 4 | namespace Impostor.Api.Innersloth 5 | { 6 | public class RegionInfo 7 | { 8 | public RegionInfo(string name, string ping, IReadOnlyList servers) 9 | { 10 | Name = name; 11 | Ping = ping; 12 | Servers = servers; 13 | } 14 | 15 | public string Name { get; } 16 | public string Ping { get; } 17 | public IReadOnlyList Servers { get; } 18 | 19 | public void Serialize(BinaryWriter writer) 20 | { 21 | writer.Write(0); 22 | writer.Write(Name); 23 | writer.Write(Ping); 24 | writer.Write(Servers.Count); 25 | 26 | foreach (var server in Servers) 27 | { 28 | server.Serialize(writer); 29 | } 30 | } 31 | 32 | public static RegionInfo Deserialize(BinaryReader reader) 33 | { 34 | var unknown = reader.ReadInt32(); 35 | var name = reader.ReadString(); 36 | var ping = reader.ReadString(); 37 | var servers = new List(); 38 | var serverCount = reader.ReadInt32(); 39 | 40 | for (var i = 0; i < serverCount; i++) 41 | { 42 | servers.Add(ServerInfo.Deserialize(reader)); 43 | } 44 | 45 | return new RegionInfo(name, ping, servers); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Games/Extensions/GameExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Impostor.Api.Net; 4 | using Impostor.Api.Net.Messages; 5 | 6 | namespace Impostor.Api.Games 7 | { 8 | public static class GameExtensions 9 | { 10 | public static ValueTask SendToAllExceptAsync(this IGame game, IMessageWriter writer, LimboStates states, int? id) 11 | { 12 | return id.HasValue 13 | ? game.SendToAllExceptAsync(writer, id.Value, states) 14 | : game.SendToAllAsync(writer, states); 15 | } 16 | 17 | public static ValueTask SendToAllExceptAsync(this IGame game, IMessageWriter writer, LimboStates states, IClient client) 18 | { 19 | if (client == null) 20 | { 21 | throw new ArgumentNullException(nameof(client)); 22 | } 23 | 24 | return game.SendToAllExceptAsync(writer, client.Id, states); 25 | } 26 | 27 | public static ValueTask SendToAsync(this IGame game, IMessageWriter writer, IClient client) 28 | { 29 | if (client == null) 30 | { 31 | throw new ArgumentNullException(nameof(client)); 32 | } 33 | 34 | return game.SendToAsync(writer, client.Id); 35 | } 36 | 37 | public static ValueTask SendToAsync(this IGame game, IMessageWriter writer, IClientPlayer player) 38 | { 39 | return game.SendToAsync(writer, player.Client); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/MessageType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Impostor.Api.Net.Messages 4 | { 5 | /// 6 | /// Specifies how a message should be sent between connections. 7 | /// 8 | [Flags] 9 | public enum MessageType : byte 10 | { 11 | /// 12 | /// Requests unreliable delivery with no fragmentation. 13 | /// 14 | /// 15 | /// Sending data using unreliable delivery means that data is not guaranteed to arrive at it's destination nor is 16 | /// it guaranteed to arrive only once. However, unreliable delivery can be faster than other methods and it 17 | /// typically requires a smaller number of protocol bytes than other methods. There is also typically less 18 | /// processing involved and less memory needed as packets are not stored once sent. 19 | /// 20 | Unreliable, 21 | 22 | /// 23 | /// Requests data be sent reliably but with no fragmentation. 24 | /// 25 | /// 26 | /// Sending data reliably means that data is guaranteed to arrive and to arrive only once. Reliable delivery 27 | /// typically requires more processing, more memory (as packets need to be stored in case they need resending), 28 | /// a larger number of protocol bytes and can be slower than unreliable delivery. 29 | /// 30 | Reliable, 31 | } 32 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Events/Game/Player/PlayerMovementEvent.cs: -------------------------------------------------------------------------------- 1 | using Impostor.Api.Events.Player; 2 | using Impostor.Api.Games; 3 | using Impostor.Api.Net; 4 | using Impostor.Api.Net.Inner.Objects; 5 | using Microsoft.Extensions.ObjectPool; 6 | 7 | namespace Impostor.Server.Events.Player 8 | { 9 | public class PlayerMovementEvent : IPlayerMovementEvent 10 | { 11 | #pragma warning disable 8766 12 | public IGame? Game { get; private set; } 13 | 14 | public IClientPlayer? ClientPlayer { get; private set; } 15 | 16 | public IInnerPlayerControl? PlayerControl { get; private set; } 17 | #pragma warning restore 8766 18 | 19 | public void Reset(IGame game, IClientPlayer clientPlayer, IInnerPlayerControl playerControl) 20 | { 21 | Game = game; 22 | ClientPlayer = clientPlayer; 23 | PlayerControl = playerControl; 24 | } 25 | 26 | public void Reset() 27 | { 28 | Game = null; 29 | ClientPlayer = null; 30 | PlayerControl = null; 31 | } 32 | 33 | public class PlayerMovementEventObjectPolicy : IPooledObjectPolicy 34 | { 35 | public PlayerMovementEvent Create() 36 | { 37 | return new PlayerMovementEvent(); 38 | } 39 | 40 | public bool Return(PlayerMovementEvent obj) 41 | { 42 | obj.Reset(); 43 | return true; 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Impostor.Patcher/Impostor.Patcher.Shared/Innersloth/RegionInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | 4 | namespace Impostor.Patcher.Shared.Innersloth 5 | { 6 | public class RegionInfo 7 | { 8 | public RegionInfo(string name, string ping, IReadOnlyList servers) 9 | { 10 | Name = name; 11 | Ping = ping; 12 | Servers = servers; 13 | } 14 | 15 | public string Name { get; } 16 | public string Ping { get; } 17 | public IReadOnlyList Servers { get; } 18 | 19 | public void Serialize(BinaryWriter writer) 20 | { 21 | writer.Write(0); 22 | writer.Write(Name); 23 | writer.Write(Ping); 24 | writer.Write(Servers.Count); 25 | 26 | foreach (var server in Servers) 27 | { 28 | server.Serialize(writer); 29 | } 30 | } 31 | 32 | public static RegionInfo Deserialize(BinaryReader reader) 33 | { 34 | var unknown = reader.ReadInt32(); 35 | var name = reader.ReadString(); 36 | var ping = reader.ReadString(); 37 | var servers = new List(); 38 | var serverCount = reader.ReadInt32(); 39 | 40 | for (var i = 0; i < serverCount; i++) 41 | { 42 | servers.Add(ServerInfo.Deserialize(reader)); 43 | } 44 | 45 | return new RegionInfo(name, ping, servers); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /src/Impostor.Server/Utils/IpUtils.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Net; 3 | using System.Net.Sockets; 4 | using Impostor.Api; 5 | 6 | namespace Impostor.Server.Utils 7 | { 8 | internal static class IpUtils 9 | { 10 | public static string ResolveIp(string ip) 11 | { 12 | // Check if valid ip was entered. 13 | if (!IPAddress.TryParse(ip, out var ipAddress)) 14 | { 15 | // Attempt to resolve DNS. 16 | try 17 | { 18 | var hostAddresses = Dns.GetHostAddresses(ip); 19 | if (hostAddresses.Length == 0) 20 | { 21 | throw new ImpostorConfigException($"Invalid IP Address entered '{ip}'."); 22 | } 23 | 24 | // Use first IPv4 result. 25 | ipAddress = hostAddresses.First(x => x.AddressFamily == AddressFamily.InterNetwork); 26 | } 27 | catch (SocketException) 28 | { 29 | throw new ImpostorConfigException($"Failed to resolve hostname '{ip}'."); 30 | } 31 | } 32 | 33 | // Only IPv4. 34 | if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6) 35 | { 36 | throw new ImpostorConfigException($"Invalid IP Address entered '{ipAddress}', only IPv4 is supported by Among Us."); 37 | } 38 | 39 | return ipAddress.ToString(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Impostor.Server/Recorder/PacketSerializationContext.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Text; 3 | 4 | namespace Impostor.Server.Recorder 5 | { 6 | public class PacketSerializationContext 7 | { 8 | private const int InitialStreamSize = 0x100; 9 | private const int MaximumStreamSize = 0x100000; 10 | 11 | private MemoryStream _memory; 12 | private BinaryWriter _writer; 13 | 14 | public MemoryStream Stream 15 | { 16 | get 17 | { 18 | if (_memory == null) 19 | { 20 | _memory = new MemoryStream(InitialStreamSize); 21 | } 22 | 23 | return _memory; 24 | } 25 | private set => _memory = value; 26 | } 27 | 28 | public BinaryWriter Writer 29 | { 30 | get 31 | { 32 | if (_writer == null) 33 | { 34 | _writer = new BinaryWriter(Stream, Encoding.UTF8, true); 35 | } 36 | 37 | return _writer; 38 | } 39 | private set => _writer = value; 40 | } 41 | 42 | public void Reset() 43 | { 44 | if (Stream.Capacity > MaximumStreamSize) 45 | { 46 | Stream = null; 47 | Writer = null; 48 | } 49 | else 50 | { 51 | Stream.Position = 0L; 52 | Stream.SetLength(0L); 53 | } 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /src/Impostor.Benchmarks/Data/Span/MessageReader_Span.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Buffers.Binary; 3 | using Impostor.Hazel; 4 | 5 | namespace Impostor.Benchmarks.Data.Span 6 | { 7 | public ref struct MessageReader_Span 8 | { 9 | private readonly MessageReaderOwner _owner; 10 | private readonly byte _tag; 11 | private readonly Span _data; 12 | 13 | public MessageReader_Span(MessageReaderOwner owner, byte tag, Span data) 14 | { 15 | _owner = owner; 16 | _tag = tag; 17 | _data = data; 18 | } 19 | 20 | public MessageReader_Span ReadMessage() 21 | { 22 | var length = ReadUInt16(); 23 | var tag = ReadByte(); 24 | var pos = _owner.Position; 25 | 26 | _owner.Position += length; 27 | 28 | return new MessageReader_Span(_owner, tag, _data.Slice(3, length)); 29 | } 30 | 31 | public byte ReadByte() 32 | { 33 | return _data[_owner.Position++]; 34 | } 35 | 36 | public ushort ReadUInt16() 37 | { 38 | var output = BinaryPrimitives.ReadUInt16LittleEndian(_data.Slice(_owner.Position)); 39 | _owner.Position += sizeof(ushort); 40 | return output; 41 | } 42 | 43 | public int ReadInt32() 44 | { 45 | var output = BinaryPrimitives.ReadInt32LittleEndian(_data.Slice(_owner.Position)); 46 | _owner.Position += sizeof(int); 47 | return output; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Impostor.Api/Net/Messages/S2C/Message01JoinGameS2C.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Impostor.Api.Innersloth; 3 | 4 | namespace Impostor.Api.Net.Messages.S2C 5 | { 6 | public class Message01JoinGameS2C 7 | { 8 | public static void SerializeJoin(IMessageWriter writer, bool clear, int gameCode, int playerId, int hostId) 9 | { 10 | if (clear) 11 | { 12 | writer.Clear(MessageType.Reliable); 13 | } 14 | 15 | writer.StartMessage(MessageFlags.JoinGame); 16 | writer.Write(gameCode); 17 | writer.Write(playerId); 18 | writer.Write(hostId); 19 | writer.EndMessage(); 20 | } 21 | 22 | public static void SerializeError(IMessageWriter writer, bool clear, DisconnectReason reason, string? message = null) 23 | { 24 | if (clear) 25 | { 26 | writer.Clear(MessageType.Reliable); 27 | } 28 | 29 | writer.StartMessage(MessageFlags.JoinGame); 30 | writer.Write((int)reason); 31 | 32 | if (reason == DisconnectReason.Custom) 33 | { 34 | if (message == null) 35 | { 36 | throw new ArgumentNullException(nameof(message)); 37 | } 38 | 39 | writer.Write(message); 40 | } 41 | 42 | writer.EndMessage(); 43 | } 44 | 45 | public static void Deserialize(IMessageReader reader) 46 | { 47 | throw new System.NotImplementedException(); 48 | } 49 | } 50 | } --------------------------------------------------------------------------------