Compare commits

..
96 Commits
Author SHA1 Message Date
js6pak 3e857ed555 Fix plugin host disposal 2021-06-13 21:35:04 +02:00
js6pak 9d31752bf0 Add PluginManager 2021-06-12 15:51:39 +02:00
ced530b83a Added player voted event (#181)
Co-authored-by: AeonLucid <aeonlucid@outlook.com>
Co-authored-by: js6pak <kubastaron@hotmail.com>
2021-06-11 12:33:38 +00:00
8f1cba8429 Using MapData for Tasks (#395)
Co-authored-by: John Tran <john.tran.84@live.com.au>
Co-authored-by: js6pak <kubastaron@hotmail.com>
2021-06-10 18:54:34 +00:00
js6pak 9009bac883 Merge pull request #417 from miniduikboot/fix/initialize-color 2021-06-10 18:38:17 +00:00
miniduikboot f3460f05bc Initialize Color to -1 instead of Red
This could lead to an AC disconnect if the host picked red and waited
for other players to rejoin before joining back himself. Before this
commit, the host would SetColor himself to Red, but this would be
flagged as all other players would have been set to Red as enums
initialize to 0 (= Red) by default.

After the host SetColor'd himself, the host will send over the color
array, which initializes player colors to -1. This commit follows AU by
also initializing the color to -1, preventing the AC from flagging the
duplicate colors.
2021-05-30 18:30:47 +02:00
miniduikboot a13fee108f Fix KeyNotFoundException for nonexistent vents (#413)
Some mods add extra vents that don't yet exist, this commit checks if a
given vent exists and if it doesn't, throw an AC violation instead of
disconnecting the player

One downside is that the Enter/ExitVent events are no longer called, but
this would require the vent in that event to become nullable
2021-05-17 17:13:54 +00:00
js6pak adc0e6fe9b Don't broadcast packets of kicked players 2021-05-12 18:49:20 +02:00
js6pak ce62815dc5 Add custom message support (#404) 2021-05-10 11:08:26 +00:00
js6pak b1a0adaa28 Merge pull request #389 from Impostor/plugin-info-from-csproj 2021-04-27 17:54:53 +00:00
js6pak fe697b1b63 Deprecate old ImpostorPluginAttribute constructor 2021-04-27 14:58:16 +02:00
js6pak 55e6d38f9f Merge pull request #400 from HarmHoog/skin-hat-types 2021-04-26 12:48:16 +00:00
cchudant b73a46ff56 [skip ci] Rename dev branch in Running-the-server.md (#402) 2021-04-26 12:47:03 +00:00
js6pak 901deeff59 Remove ownership check from InnerVoteBanSystem 2021-04-21 22:01:01 +02:00
Harm Hoogeveen f2126fd4c6 Add new skin types 2021-04-20 14:24:06 +02:00
Harm Hoogeveen 9aa6109b3a Add new hat types 2021-04-20 14:23:02 +02:00
js6pak e1a6fdda98 Make it possible to read plugin information from csproj attributes 2021-04-13 23:13:52 +02:00
Harm Hoogeveenandjs6pak 283f59b51f Allow plugins to set dependencies, softdependencies and loadbefores to determine the load order of plugins (#385)
Co-authored-by: js6pak <kubastaron@hotmail.com>
2021-04-13 20:28:24 +00:00
Minorusamaandjs6pak d47343df08 BeforeGameCreatedEvent (#266)
Co-authored-by: js6pak <kubastaron@hotmail.com>
2021-04-13 16:29:44 +00:00
js6pak 0bb5442a3a Merge pull request #387 from Impostor/murder-check-ping
Add simple ping toleration to murder player check
2021-04-13 15:17:20 +00:00
js6pak 7ac6c32b5d Set configuration's BasePath to CurrentDirectory 2021-04-13 11:29:08 +02:00
112batman fbd9f12f9e Add GameHostChange event (#277) 2021-04-12 20:53:14 +00:00
js6pak f43577b745 Add simple ping toleration to murder player check 2021-04-11 16:05:08 +02:00
js6pak a56eed2680 Use actual disconnect message in ClientBase#DisconnectAsync 2021-04-11 14:57:29 +02:00
js6pak f0434f071c Merge pull request #377 from Impostor/airship 2021-04-11 12:04:31 +00:00
js6pak 8d27016cb7 Fix xmldoc warnings 2021-04-10 23:00:34 +02:00
js6pak e941796a4c Bump version 2021-04-10 22:55:40 +02:00
js6pak 1d66f07906 Make vent data initialization much cleaner 2021-04-10 17:14:17 +02:00
js6pak 7764987f91 Specify enum values for Platforms 2021-04-09 23:51:50 +02:00
js6pak bfba4385fd Make PlayerVentEvent an actual PlayerVentEvent 2021-04-06 21:10:53 +02:00
js6pak f03e72206e Update example plugin 2021-04-06 20:51:06 +02:00
js6pak 304b4bb7bf Rework vent api 2021-04-06 20:51:06 +02:00
970f826dc8 Allow Android Versions (#375)
Co-authored-by: js6pak <kubastaron@hotmail.com>
Co-authored-by: John Tran <john.tran.84@live.com.au>
2021-04-06 18:50:50 +00:00
js6pak 0a30fe5a3e Bring back tar.gz for unix builds 2021-04-05 15:27:25 +02:00
js6pak 4866a350f8 Implement airship spawning, closes #376 2021-04-04 23:27:39 +02:00
js6pak 13bddeb7bd Split ShipStatus to multiple classes, implement new door types 2021-04-04 23:27:39 +02:00
js6pak 225b56e71f Fix cheatcontext in ValidateImpostor calls 2021-04-04 23:27:39 +02:00
js6pak 60bf6b5f58 Fix namespaces 2021-04-04 23:27:39 +02:00
b5cee48242 Airship Vent Enums (#373)
Co-authored-by: miniduikboot <5243971+miniduikboot@users.noreply.github.com>
Co-authored-by: John Tran <john.tran.84@live.com.au>
2021-04-04 10:31:28 +00:00
js6pak c750c65481 Merge pull request #372 from miniduikboot/2021.3.31 2021-04-04 10:26:07 +00:00
miniduikboot d801a36af8 Rename things for 6pak 2021-04-04 10:35:00 +02:00
miniduikboot 441d9c300c Move PlayerVentEvent call to applicable RPC's 2021-04-03 00:46:34 +02:00
miniduikboot 7fd68e31e6 Fix Docker container build 2021-04-03 00:37:12 +02:00
miniduikboot 47aebe7b7b Fix InnerShipStatus deserializing
3.31 now distributes them as multiple messages

This also explains the two weird bytes in HeliSabotage, so these can be
removed too
2021-04-03 00:29:05 +02:00
miniduikboot 66c2434320 Implement HeliSabotageSystemType
It works, although I'm not completely sure why.
2021-04-03 00:29:05 +02:00
miniduikboot c01062ed65 implement rpc 32: use platform 2021-04-03 00:29:05 +02:00
miniduikboot d5ae007d1c implement rpc 31: climb ladder 2021-04-03 00:29:05 +02:00
miniduikboot 16a2b0aac6 I counted the doors on Airship
and I hope I counted correctly
2021-04-03 00:29:05 +02:00
miniduikboot 4c1bd4a578 editorconfig: Don't indent blocks in case contents
This is more in line with the existing codebase
2021-04-03 00:29:05 +02:00
miniduikboot d311150967 API: update enums for airship 2021-04-03 00:29:05 +02:00
miniduikboot 92e3506f51 First attempt at getting some airship stuff online 2021-04-03 00:29:05 +02:00
miniduikboot a63fc40099 Gamedata packets are now have initial state false
I managed to get into a lobby with this
2021-04-03 00:29:05 +02:00
js6pak 4f53d3f4e6 Hopefully fix the submodule 2021-04-03 00:14:33 +02:00
js6pak a39fae3325 Initial auth implementation 2021-04-03 00:12:15 +02:00
js6pak 7c34836d50 Remove reactor stuff 2021-04-03 00:12:15 +02:00
js6pak 989b06d04c Use BitConverter.Int32BitsToSingle in SpanReaderExtensions 2021-04-03 00:12:15 +02:00
js6pak 11e87e51db Update airship constants 2021-04-03 00:12:15 +02:00
js6pak b90e5b2c88 Switch back hazel to submodule 2021-04-03 00:11:55 +02:00
js6pak a0627bbc87 Always hook control with playerInfo 2021-03-28 20:46:31 +02:00
js6pak 40a41f3573 Fix a bug causing InnerPlayerInfo.Controller to be always null 2021-03-28 19:27:49 +02:00
js6pak 8621f09761 Merge pull request #333 from Impostor/fix/style-warnings
Fix warnings
2021-03-25 20:37:47 +00:00
js6pak 3321e3049f Make configs actually work with dependency injection 2021-03-24 20:05:26 +01:00
js6pak a90bbebab9 Update appveyor.yml for the ultimate yellow-less experience 2021-03-24 20:04:40 +01:00
js6pak f4dc0cd403 Revert hazel changes for easier merging with its upstream 2021-03-24 19:53:01 +01:00
js6pak fbed06bf81 Add icon to nuspec 2021-03-24 19:08:23 +01:00
js6pak ef5320c820 Update cake 2021-03-24 19:04:11 +01:00
js6pak bc85ef6810 Fix xmldoc warnings 2021-03-24 17:55:15 +01:00
js6pak e90ba734ab Code cleanup 2021-03-24 16:57:11 +01:00
js6pak 0f6bfb3597 Fix warnings 2021-03-24 16:38:23 +01:00
js6pak dc759b1d57 Fix FloatRange ranges 2021-03-23 21:21:11 +01:00
Minorusama be332e21d1 Add IInnerPlayerControl#ExileAsync (#271) 2021-03-23 20:12:39 +00:00
js6pak fe7a641bad Set VERSIONSUFFIX to docker by default 2021-03-16 22:12:56 +01:00
js6pak e0041e89d8 Update docker CI 2021-03-16 21:40:54 +01:00
js6pak f04bacf0de Update Server-configuration.md 2021-03-14 22:30:01 +00:00
js6pak 7e16b5595a Include AntiCheat.Enabled in default config.json 2021-03-14 23:25:56 +01:00
js6pak a1c59363a1 Merge remote-tracking branch 'origin/2021.3.5' 2021-03-14 23:19:35 +01:00
js6pak ea1085406a Fix typo in README.md 2021-03-14 21:23:10 +00:00
js6pak e359f0a15d Update README.md 2021-03-14 22:19:48 +01:00
js6pak 72f1e81c5f Merge branch '2021.3.5' 2021-03-14 22:04:44 +01:00
js6pak 443168ef71 Add DateTime to server replays (#349) 2021-03-14 20:50:55 +00:00
Galster-dev 20d5284a7a minor README.md changes (#342) 2021-03-10 23:06:12 +01:00
js6pak 9915f8b0cf Expose IsCancelled to IPlayerChatEvent 2021-03-07 16:49:57 +01:00
js6pak 0901be56f5 Implement GameData 205 2021-03-07 16:41:19 +01:00
miniduikboot 3090cea768 Remove fake player joining (#341) 2021-03-07 16:36:37 +01:00
js6pak 1059a4da16 Add debug logs in AnnouncementsService 2021-03-06 18:13:16 +01:00
js6pak acd2a56898 Simplify Message01JoinGameC2S 2021-03-06 17:20:36 +01:00
js6pak 575ad25fb6 New GameDataTags 2021-03-06 17:15:12 +01:00
AeonLucid 781ba34e1b Fix Impostor.Tools.ServerReplay compilation 2021-03-06 17:07:35 +01:00
js6pak 9bd43b4629 2021.3.5 2021-03-06 00:45:46 +01:00
js6pak e769b874c8 Add create game api (#241) 2021-03-04 09:11:50 +00:00
miniduikboot be19b1524b Warn if plugin loader paths don't exist (#330) 2021-03-03 14:36:17 +00:00
112batman 020a1b6447 Implement IInnerNetObject in IInnerMeetingHud (#256) 2021-03-03 09:23:38 +00:00
js6pak bbbf368a6f Bump version 2021-03-03 10:15:48 +01:00
js6pak d4bffd20ad [skip ci] Update Building-from-source.md 2021-03-03 09:05:33 +00:00
87a062c1b3 Sync Impostor with 6pak fork (#327)
Co-authored-by: DatGuy1 <datguysteam@gmail.com>
Co-authored-by: miniduikboot <5243971+miniduikboot@users.noreply.github.com>
2021-03-03 08:53:53 +00:00
js6pak f2d6531063 Add CheckName/SetName/CheckColor/SetColor anticheat checks (#278)
* Add CheckName/SetName/CheckColor/SetColor anticheat checks

* Disable expected checks for the host
2021-01-08 18:42:41 +01:00
420 changed files with 7461 additions and 7152 deletions

No files matched your search

+1 -1
View File
@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"cake.tool": {
"version": "0.38.5",
"version": "1.1.0",
"commands": [
"dotnet-cake"
]
-17
View File
@@ -1,17 +0,0 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- pinned
- security
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false
+9 -5
View File
@@ -2,7 +2,7 @@ name: Docker
on:
push:
branches: dev
branches: master
paths:
- 'src/Impostor.Server/**'
- 'src/Impostor.Shared/**'
@@ -33,15 +33,16 @@ jobs:
run: |
DOCKER_IMAGE=aeonlucid/impostor
VERSION=noop
VERSIONSUFFIX=docker
if [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
VERSIONSUFFIX=none
elif [[ $GITHUB_REF == refs/heads/* ]]; then
VERSION=$(echo ${GITHUB_REF#refs/heads/} | sed -r 's#/+#-#g')
if [ "${{ github.event.repository.default_branch }}" = "dev" ]; then
VERSION=nightly
fi
VERSION=nightly
VERSIONSUFFIX=docker.${{ github.run_number }}
elif [[ $GITHUB_REF == refs/pull/* ]]; then
VERSION=pr-${{ github.event.number }}
VERSIONSUFFIX=pr.${{ github.event.number }}
fi
TAGS="${DOCKER_IMAGE}:${VERSION}"
if [[ $VERSION =~ ^v[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
@@ -49,6 +50,7 @@ jobs:
fi
echo ::set-output name=version::${VERSION}
echo ::set-output name=tags::${TAGS}
echo ::set-output name=versionsuffix::${VERSIONSUFFIX}
echo ::set-output name=created::$(date -u +'%Y-%m-%dT%H:%M:%SZ')
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
@@ -68,3 +70,5 @@ jobs:
platforms: linux/amd64,linux/arm/v7,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.prep.outputs.tags }}
build-args: |
VERSIONSUFFIX=${{ steps.prep.outputs.versionsuffix }}
+3
View File
@@ -0,0 +1,3 @@
[submodule "src/Impostor.Hazel"]
path = src/Impostor.Hazel
url = https://github.com/Impostor/Impostor.Hazel
+6 -3
View File
@@ -4,12 +4,14 @@ FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:5.0 AS build
# https://github.com/containerd/containerd/blob/master/platforms/platforms.go#L17
ARG TARGETARCH
ARG VERSIONSUFFIX="docker"
WORKDIR /source
# Copy csproj and restore.
COPY src/Impostor.Server/Impostor.Server.csproj ./src/Impostor.Server/Impostor.Server.csproj
COPY src/Impostor.Api/Impostor.Api.csproj ./src/Impostor.Api/Impostor.Api.csproj
COPY src/Impostor.Hazel/Impostor.Hazel.csproj ./src/Impostor.Hazel/Impostor.Hazel.csproj
COPY src/Impostor.Hazel/Hazel/Hazel.csproj ./src/Impostor.Hazel/Hazel/Hazel.csproj
RUN case "$TARGETARCH" in \
amd64) NETCORE_PLATFORM='linux-x64';; \
@@ -19,7 +21,7 @@ RUN case "$TARGETARCH" in \
esac && \
dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Server/Impostor.Server.csproj && \
dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Api/Impostor.Api.csproj && \
dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Hazel/Impostor.Hazel.csproj
dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Hazel/Hazel/Hazel.csproj
# Copy everything else.
COPY src/. ./src/
@@ -29,7 +31,8 @@ RUN case "$TARGETARCH" in \
arm) NETCORE_PLATFORM='linux-arm';; \
*) echo "unsupported architecture"; exit 1 ;; \
esac && \
dotnet publish -c release -o /app -r "$NETCORE_PLATFORM" --no-restore ./src/Impostor.Server/Impostor.Server.csproj
[[ $VERSIONSUFFIX = "none" ]] && VERSIONSUFFIX=; \
dotnet publish -c release -o /app -r "$NETCORE_PLATFORM" -p:VersionSuffix="$VERSIONSUFFIX" --no-restore ./src/Impostor.Server/Impostor.Server.csproj
# Final image.
FROM --platform=$TARGETPLATFORM mcr.microsoft.com/dotnet/runtime:5.0
+6 -6
View File
@@ -1,16 +1,16 @@
# Impostor
[![Discord](https://img.shields.io/badge/Discord-chat-blue?style=flat-square)](https://discord.gg/Mk3w6Tb)
[![AppVeyor](https://img.shields.io/appveyor/build/Impostor/Impostor/dev?style=flat-square)](https://ci.appveyor.com/project/Impostor/Impostor/branch/dev)
[![AppVeyor](https://img.shields.io/appveyor/build/Impostor/Impostor/master?style=flat-square)](https://ci.appveyor.com/project/Impostor/Impostor/branch/master)
Impostor is one of the first **Among Us** private servers, written in C#.
We support Steam, Itch, Android and iOS. The latest version supported is `2020.9.22`, the `dev` build currently supports `2020.11.17`.
| Impostor version | Among Us version | Experimental | Download |
|-|-|-|-|
| 1.1.0 | 2020.09.07 - 2020.09.22 | No | [![Download](https://img.shields.io/badge/Download-v1.1.0-blue?style=flat-square)](https://github.com/Impostor/Impostor/releases/tag/v1.1.0) |
| 1.2.2 | 2020.09.22 - 2020.11.17 | Yes | [![Download](https://img.shields.io/badge/Download-v1.2.2-blue?style=flat-square)](https://ci.appveyor.com/project/Impostor/Impostor/branch/dev/artifacts) |
| 1.2.2 | 2020.09.22 - 2020.11.17 | No | [![Download](https://img.shields.io/badge/Download-v1.2.2-blue?style=flat-square)](https://github.com/Impostor/Impostor/releases/tag/v1.2.2) |
| 1.3.0 | 2021.3.5 | No | [![Download](https://img.shields.io/badge/Download-v1.3.0-blue?style=flat-square)](https://github.com/Impostor/Impostor/releases/tag/v1.3.0) |
| 1.4.0 | 2021.3.31 - 2021.4.2 | Yes | [![Download](https://img.shields.io/badge/Download-master-blue?style=flat-square)](https://ci.appveyor.com/project/Impostor/Impostor/branch/master/artifacts) |
## Features
@@ -27,9 +27,9 @@ If you just want to play on a server hosted by someone else, you need to follow
#### Windows
1. Find the [latest release](https://github.com/AeonLucid/Impostor/releases/latest).
2. Download `Impostor-Client-win-x64.zip`.
2. Download `Impostor-Patcher-win-x64.zip`.
3. Extract the zip.
4. Run `Impostor.Client.exe`.
4. Run `Impostor.Patcher.exe`.
5. Follow the instructions inside the application.
![Client](docs/images/client.jpg)
+2 -3
View File
@@ -1,12 +1,11 @@
version: '{build}'
environment:
IMPOSTOR_VERSION: '1.2.2'
DOTNET_CLI_TELEMETRY_OPTOUT: 1
branches:
except:
- gh-pages
- gh-pages
pull_requests:
do_not_increment_build_number: true
@@ -17,7 +16,7 @@ assembly_info:
dotnet_csproj:
patch: false
image: Visual Studio 2019 Preview
image: Ubuntu2004
install:
- git submodule update --init --recursive
+39 -56
View File
@@ -1,20 +1,25 @@
#addin "nuget:?package=SharpZipLib&Version=1.3.0"
#addin "nuget:?package=Cake.Compression&Version=0.2.4"
#addin "nuget:?package=Cake.FileHelpers&Version=3.3.0"
#addin "nuget:?package=SharpZipLib&Version=1.3.1"
#addin "nuget:?package=Cake.Compression&Version=0.2.6"
#addin "nuget:?package=Cake.FileHelpers&Version=4.0.1"
var buildId = EnvironmentVariable("APPVEYOR_BUILD_VERSION") ?? "0";
var buildVersion = EnvironmentVariable("IMPOSTOR_VERSION") ?? "1.0.0";
var buildBranch = EnvironmentVariable("APPVEYOR_REPO_BRANCH") ?? "dev";
var buildId = EnvironmentVariable("GITHUB_RUN_NUMBER") ?? EnvironmentVariable("APPVEYOR_BUILD_VERSION");
var buildRelease = EnvironmentVariable("APPVEYOR_REPO_TAG") == "true";
var buildVersion = FindRegexMatchGroupInFile("./src/Directory.Build.props", @"\<VersionPrefix\>(.*?)\<\/VersionPrefix\>", 1, System.Text.RegularExpressions.RegexOptions.None).Value;
var buildDir = MakeAbsolute(Directory("./build"));
var prNumber = EnvironmentVariable("APPVEYOR_PULL_REQUEST_NUMBER");
var target = Argument("target", "Deploy");
var configuration = Argument("configuration", "Release");
// On any branch that is not master, we need to tag the version as prerelease.
if (buildBranch != "master") {
buildVersion = buildVersion + "-ci." + buildId;
var msbuildSettings = new DotNetCoreMSBuildSettings();
if (buildRelease)
{
msbuildSettings.Properties["Version"] = new[] { buildVersion };
}
else if (buildId != null)
{
msbuildSettings.Properties["VersionSuffix"] = new[] { "ci." + buildId };
buildVersion += "-ci." + buildId;
}
//////////////////////////////////////////////////////////////////////
@@ -34,7 +39,8 @@ private void ImpostorPublish(string name, string project, string runtime, bool i
SelfContained = false,
PublishSingleFile = true,
PublishTrimmed = false,
OutputDirectory = projBuildDir
OutputDirectory = projBuildDir,
MSBuildSettings = msbuildSettings
});
if (isServer) {
@@ -62,7 +68,8 @@ private void ImpostorPublishNF(string name, string project) {
Configuration = configuration,
NoRestore = true,
Framework = "net472",
OutputDirectory = projBuildDir
OutputDirectory = projBuildDir,
MSBuildSettings = msbuildSettings
});
Zip(projBuildDir, projBuildZip);
@@ -86,13 +93,6 @@ Task("Restore")
DotNetCoreRestore("./src/Impostor.sln");
});
Task("Patch")
.WithCriteria(BuildSystem.AppVeyor.IsRunningOnAppVeyor)
.Does(() => {
ReplaceRegexInFiles("./src/**/*.csproj", @"<Version>.*?<\/Version>", "<Version>" + buildVersion + "</Version>");
ReplaceRegexInFiles("./src/**/*.props", @"<Version>.*?<\/Version>", "<Version>" + buildVersion + "</Version>");
});
Task("Replay")
.Does(() => {
// D:\Projects\GitHub\Impostor\Impostor\src\Impostor.Tools.ServerReplay\sessions
@@ -107,7 +107,6 @@ Task("Replay")
Task("Build")
.IsDependentOn("Clean")
.IsDependentOn("Patch")
.IsDependentOn("Restore")
.IsDependentOn("Replay")
.Does(() => {
@@ -116,44 +115,28 @@ Task("Build")
Configuration = configuration,
});
// Only build artifacts if;
// - buildBranch is master/dev
// - it is not a pull request
if ((buildBranch == "master" || buildBranch == "dev") && string.IsNullOrEmpty(prNumber)) {
// Client.
ImpostorPublishNF("Impostor-Patcher", "./src/Impostor.Patcher/Impostor.Patcher.WinForms/Impostor.Patcher.WinForms.csproj");
// Client.
ImpostorPublishNF("Impostor-Patcher", "./src/Impostor.Patcher/Impostor.Patcher.WinForms/Impostor.Patcher.WinForms.csproj");
ImpostorPublish("Impostor-Patcher-Cli", "./src/Impostor.Patcher/Impostor.Patcher.Cli/Impostor.Patcher.Cli.csproj", "win-x64");
ImpostorPublish("Impostor-Patcher-Cli", "./src/Impostor.Patcher/Impostor.Patcher.Cli/Impostor.Patcher.Cli.csproj", "osx-x64");
ImpostorPublish("Impostor-Patcher-Cli", "./src/Impostor.Patcher/Impostor.Patcher.Cli/Impostor.Patcher.Cli.csproj", "linux-x64");
ImpostorPublish("Impostor-Patcher-Cli", "./src/Impostor.Patcher/Impostor.Patcher.Cli/Impostor.Patcher.Cli.csproj", "win-x64");
ImpostorPublish("Impostor-Patcher-Cli", "./src/Impostor.Patcher/Impostor.Patcher.Cli/Impostor.Patcher.Cli.csproj", "osx-x64");
ImpostorPublish("Impostor-Patcher-Cli", "./src/Impostor.Patcher/Impostor.Patcher.Cli/Impostor.Patcher.Cli.csproj", "linux-x64");
// Server.
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "win-x64", true);
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "osx-x64", true);
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "linux-x64", true);
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "linux-arm", true);
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "linux-arm64", true);
// Server.
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "win-x64", true);
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "osx-x64", true);
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "linux-x64", true);
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "linux-arm", true);
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "linux-arm64", true);
// API.
DotNetCorePack("./src/Impostor.Api/Impostor.Api.csproj", new DotNetCorePackSettings {
Configuration = configuration,
OutputDirectory = buildDir,
IncludeSource = true,
IncludeSymbols = true
});
} else {
DotNetCoreBuild("./src/Impostor.Patcher/Impostor.Patcher.WinForms/Impostor.Patcher.WinForms.csproj", new DotNetCoreBuildSettings {
Configuration = configuration,
NoRestore = true,
Framework = "net472"
});
DotNetCoreBuild("./src/Impostor.Server/Impostor.Server.csproj", new DotNetCoreBuildSettings {
Configuration = configuration,
NoRestore = true,
Framework = "net5.0"
});
}
// API.
DotNetCorePack("./src/Impostor.Api/Impostor.Api.csproj", new DotNetCorePackSettings {
Configuration = configuration,
OutputDirectory = buildDir,
IncludeSource = true,
IncludeSymbols = true,
MSBuildSettings = msbuildSettings
});
});
Task("Test")
+8 -17
View File
@@ -1,29 +1,20 @@
# Building from source
The solution contains two main projects, the Impostor client and server. The client is built using [.NET Framework 4.7.2](https://dotnet.microsoft.com/download/dotnet-framework/net472) and the server with [.NET 5](https://dotnet.microsoft.com/download/dotnet/5.0).
Currently .NET 5 is not yet officially released, so in order to build using Visual Studio, you should have Visual Studio 2019 **Preview** installed.
This documentation will go over building both the [Server](#building-the-server) and the [Client](#building-the-client) and their requirements.
The solution contains two main projects, the Impostor server and patcher. The server is built using [.NET 5](https://dotnet.microsoft.com/download/dotnet/5.0) and the winforms patcher is with [.NET Framework 4.7.2](https://dotnet.microsoft.com/download/dotnet-framework/net472).
## Cloning Impostor
You need to clone Impostor with all submodules.
You need to clone Impostor using git.
```bash
git clone --recursive https://github.com/AeonLucid/Impostor.git
```
If you already have cloned Impostor but have errors related to Hazel, run the following.
```bash
git submodule update --init
git clone https://github.com/AeonLucid/Impostor.git
```
## Building the server
### Dependencies
- [.NET 5 SDK](https://dotnet.microsoft.com/download/dotnet/5.0)
- [Visual Studio Preview](https://visualstudio.microsoft.com/vs/preview/) (Optional, only if you want the full IDE experience)
- [Rider](https://www.jetbrains.com/rider/) or [Visual Studio](https://visualstudio.microsoft.com/vs/) (Optional, only if you want the full IDE experience)
### Build using the CLI
@@ -33,13 +24,13 @@ dotnet build
```
To setup the server, please look at [Running the server](Running-the-server.md).
## Building the client
## Building the winforms patcher
### Dependencies
* [.NET Framework 4.7.2 Developer Pack](https://dotnet.microsoft.com/download/dotnet-framework/thank-you/net472-developer-pack-offline-installer)
* [.NET Framework 4.7.2 Developer Pack](https://dotnet.microsoft.com/download/dotnet-framework/thank-you/net472-developer-pack-offline-installer) or [Mono](https://www.mono-project.com/download/)
### Build using the CLI
```bash
cd src/Impostor.Client/Impostor.Client.WinForms
cd src/Impostor.Patcher/Impostor.Patcher.WinForms
dotnet build
```
```
+1 -1
View File
@@ -9,7 +9,7 @@ There are currently two modes to run the Impostor server in. The first way is th
- [Windows x64](https://dotnet.microsoft.com/download/dotnet/thank-you/runtime-5.0.0-windows-x64-installer)
- [Linux x64](https://docs.microsoft.com/en-us/dotnet/core/install/linux)
- [macOS x64](https://dotnet.microsoft.com/download/dotnet/thank-you/runtime-5.0.0-macos-x64-installer)
2. Find the [latest dev release](https://ci.appveyor.com/project/Impostor/Impostor/branch/dev/artifacts).
2. Find the [latest master release](https://ci.appveyor.com/project/Impostor/Impostor/branch/master/artifacts).
3. Download either the Windows or the Linux version.
4. Extract the zip.
5. Modify `config.json` to your liking. Documentation can be found [here](Server-configuration.md) *(this step is mandatory if you want to expose this server to other devices)*
+3
View File
@@ -17,6 +17,7 @@ Some information about all the possible configurations. Click [here](https://git
| Key | Default | Value |
|-|-|-|
| **Enabled** | `true` | Whether the anticheat should be enabled. |
| **BanIpFromGame** | `true` | When a player is caught hacking, they will be kicked from the server. If this value is set to `true`, the player will be banned instead and will not be able to rejoin that specific game. **(Setting this to false does not disable the anti-cheat!)** |
### ServerRedirector
@@ -45,6 +46,7 @@ Server:PublicIp=127.0.0.1
Server:PublicPort=22023
Server:ListenIp=0.0.0.0
Server:ListenPort=22023
AntiCheat:Enabled=true
AntiCheat:BanIpFromGame=true
ServerRedirector:Enabled=false
ServerRedirector:Master=true
@@ -65,6 +67,7 @@ IMPOSTOR_Server__PublicIp=127.0.0.1
IMPOSTOR_Server__PublicPort=22023
IMPOSTOR_Server__ListenIp=0.0.0.0
IMPOSTOR_Server__ListenPort=22023
IMPOSTOR_AntiCheat__Enabled=true
IMPOSTOR_AntiCheat__BanIpFromGame=true
IMPOSTOR_ServerRedirector__Enabled=false
IMPOSTOR_ServerRedirector__Master=true
+7 -4
View File
@@ -4,8 +4,8 @@ root = true
# Don't use tabs for indentation.
[*]
charset = utf-8
end_of_line = crlf
insert_final_newline = false
end_of_line = lf
insert_final_newline = true
indent_style = space
# Code files
@@ -163,7 +163,7 @@ csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_object_initializers = true
# csharp_new_line_before_members_in_object_initializers = true TODO seems like Rider/ReSharper has the value inverted, uncomment when its fixed
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_between_query_expression_clauses = true
@@ -171,7 +171,7 @@ csharp_new_line_between_query_expression_clauses = true
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_case_contents_when_block = false
csharp_indent_switch_labels = true
csharp_indent_labels = flush_left
@@ -228,3 +228,6 @@ csharp_preserve_single_line_statements = true
# warning RS0037: PublicAPI.txt is missing '#nullable enable'
dotnet_diagnostic.RS0037.severity = none
# ReSharper properties
resharper_trailing_comma_in_multiline_lists = true
-149
View File
@@ -26,21 +26,6 @@ bld/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
@@ -72,32 +57,12 @@ artifacts/
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
@@ -112,72 +77,11 @@ _TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
#*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
@@ -197,13 +101,6 @@ ClientBin/
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
@@ -212,52 +109,6 @@ Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
+11
View File
@@ -0,0 +1,11 @@
<Project>
<PropertyGroup>
<VersionPrefix>1.4.0</VersionPrefix>
<VersionSuffix>dev</VersionSuffix>
</PropertyGroup>
<ItemGroup>
<AdditionalFiles Include="$(MSBuildThisFileDirectory)stylecop.json" />
</ItemGroup>
</Project>
+20
View File
@@ -0,0 +1,20 @@
using Impostor.Api.Net.Inner;
namespace Impostor.Api
{
public class CheatContext
{
public CheatContext(string name)
{
Name = name;
}
public static CheatContext Deserialize { get; } = new CheatContext(nameof(Deserialize));
public static CheatContext Serialize { get; } = new CheatContext(nameof(Serialize));
public string Name { get; }
public static implicit operator CheatContext(RpcCalls rpcCalls) => new CheatContext(rpcCalls.ToString());
}
}
@@ -0,0 +1,43 @@
using Impostor.Api.Innersloth;
namespace Impostor.Api.Events.Announcements
{
/// <summary>
/// Event fired after client requests a announcement.
/// </summary>
public interface IAnnouncementRequestEvent : IEvent
{
public interface IResponse
{
/// <summary>
/// Gets or sets FreeWeekendState, currently unused by the client.
/// </summary>
public FreeWeekendState FreeWeekendState { get; set; }
/// <summary>
/// Gets or sets a value indicating whether announcement should be loaded from client's cache, can save some bytes.
/// </summary>
public bool UseCached { get; set; }
/// <summary>
/// Gets or sets announcement, should be null when <see cref="UseCached" /> is set to true.
/// </summary>
public Announcement? Announcement { get; set; }
}
/// <summary>
/// Gets client's last announcement id.
/// </summary>
public int Id { get; }
/// <summary>
/// Gets client's language.
/// </summary>
public Language Language { get; }
/// <summary>
/// Gets or sets plugin made response.
/// </summary>
public IResponse Response { get; set; }
}
}
@@ -17,18 +17,18 @@ namespace Impostor.Api.Events
}
/// <summary>
/// The priority of the event listener.
/// Gets or sets the priority of the event listener.
/// </summary>
public EventPriority Priority { get; set; }
/// <summary>
/// The events that the listener is listening to.
/// Gets or sets the event that the listener is listening to.
/// </summary>
public Type? Event { get; set; }
/// <summary>
/// If set to true, the listener will be called regardless of the <see cref="IEventCancelable.IsCancelled"/>.
/// Gets or sets a value indicating whether the listener will be called regardless of the <see cref="IEventCancelable.IsCancelled" />.
/// </summary>
public bool IgnoreCancelled { get; set; }
}
}
}
@@ -0,0 +1,12 @@
using Impostor.Api.Net;
namespace Impostor.Api.Events.Client
{
/// <summary>
/// Called just after a <see cref="IClient"/> is created and connected.
/// </summary>
public interface IClientConnectedEvent : IClientEvent
{
IClient Client { get; }
}
}
@@ -0,0 +1,13 @@
using Impostor.Api.Net;
using Impostor.Api.Net.Messages;
namespace Impostor.Api.Events.Client
{
/// <summary>
/// Called just before a <see cref="IHazelConnection"/> is registered.
/// </summary>
public interface IClientConnectionEvent : IClientEvent
{
IMessageReader HandshakeData { get; }
}
}
@@ -0,0 +1,9 @@
using Impostor.Api.Net;
namespace Impostor.Api.Events.Client
{
public interface IClientEvent : IEvent
{
IHazelConnection Connection { get; }
}
}
@@ -3,7 +3,7 @@
namespace Impostor.Api.Events
{
/// <summary>
/// Called whenever a new <see cref="IGame"/> is created.
/// Called whenever a new <see cref="IGame" /> is created.
/// </summary>
public interface IGameCreatedEvent : IGameEvent
{
@@ -0,0 +1,25 @@
using Impostor.Api.Games;
using Impostor.Api.Net;
namespace Impostor.Api.Events
{
/// <summary>
/// Called just before a new <see cref="IGame"/> is created.
/// </summary>
public interface IGameCreationEvent : IEventCancelable
{
/// <summary>
/// Gets the client that requested creation of the game.
/// </summary>
/// <remarks>
/// Will be null if game creation was requested by a plugin.
/// </remarks>
IClient? Client { get; }
/// <summary>
/// Gets or sets the desired <see cref="Games.GameCode"/>.
/// </summary>
/// <exception cref="ImpostorException">If the GameCode is invalid or already used in another game.</exception>
GameCode? GameCode { get; set; }
}
}
@@ -3,7 +3,7 @@
namespace Impostor.Api.Events
{
/// <summary>
/// Called whenever a new <see cref="IGame"/> is destroyed.
/// Called whenever a new <see cref="IGame" /> is destroyed.
/// </summary>
public interface IGameDestroyedEvent : IGameEvent
{
+1 -1
View File
@@ -5,7 +5,7 @@ namespace Impostor.Api.Events
public interface IGameEvent : IEvent
{
/// <summary>
/// Gets the <see cref="IGame"/> this event belongs to.
/// Gets the <see cref="IGame" /> this event belongs to.
/// </summary>
IGame Game { get; }
}
@@ -0,0 +1,11 @@
using Impostor.Api.Net;
namespace Impostor.Api.Events
{
public interface IGameHostChangedEvent : IGameEvent
{
IClientPlayer PreviousHost { get; }
IClientPlayer? NewHost { get; }
}
}
@@ -1,6 +1,9 @@
namespace Impostor.Api.Events
using Impostor.Api.Net;
namespace Impostor.Api.Events
{
public interface IGamePlayerJoinedEvent : IGameEvent
{
IClientPlayer Player { get; }
}
}
@@ -0,0 +1,15 @@
using Impostor.Api.Games;
using Impostor.Api.Net;
namespace Impostor.Api.Events
{
/// <summary>
/// Called just before a <see cref="IClientPlayer"/> joins a game.
/// </summary>
public interface IGamePlayerJoiningEvent : IGameEvent
{
IClientPlayer Player { get; }
GameJoinResult? JoinResult { get; set; }
}
}
@@ -1,6 +1,11 @@
namespace Impostor.Api.Events
using Impostor.Api.Net;
namespace Impostor.Api.Events
{
public interface IGamePlayerLeftEvent : IGameEvent
{
IClientPlayer Player { get; }
bool IsBan { get; }
}
}
@@ -3,7 +3,7 @@
/// <summary>
/// Called when the game is going to start.
/// When this is called, not all players are initialized properly yet.
/// If you want to get correct player states, use <see cref="IGameStartedEvent"/>.
/// If you want to get correct player states, use <see cref="IGameStartedEvent" />.
/// </summary>
public interface IGameStartingEvent : IGameEvent
{
@@ -1,6 +1,17 @@
namespace Impostor.Api.Events.Meeting
using Impostor.Api.Net.Inner.Objects;
namespace Impostor.Api.Events.Meeting
{
public interface IMeetingEndedEvent : IMeetingEvent
{
/// <summary>
/// Gets the exiled player.
/// </summary>
IInnerPlayerControl? Exiled { get; }
/// <summary>
/// Gets a value indicating whether meeting result is a tie.
/// </summary>
bool IsTie { get; }
}
}
@@ -1,6 +1,6 @@
namespace Impostor.Api.Events.Player
{
public interface IPlayerChatEvent : IPlayerEvent
public interface IPlayerChatEvent : IPlayerEvent, IEventCancelable
{
/// <summary>
/// Gets the message sent by the player.
@@ -1,5 +1,4 @@
using Impostor.Api.Innersloth;
using Impostor.Api.Net.Inner.Objects;
using Impostor.Api.Net.Inner.Objects;
namespace Impostor.Api.Events.Player
{
@@ -0,0 +1,15 @@
using Impostor.Api.Innersloth;
namespace Impostor.Api.Events.Player
{
/// <summary>
/// Called whenever a player enters a vent.
/// </summary>
public interface IPlayerEnterVentEvent : IPlayerEvent
{
/// <summary>
/// Gets the entered vent.
/// </summary>
public IVent Vent { get; }
}
}
@@ -6,14 +6,14 @@ namespace Impostor.Api.Events.Player
public interface IPlayerEvent : IGameEvent
{
/// <summary>
/// Gets the <see cref="IClientPlayer"/> that triggered this <see cref="IPlayerEvent"/>.
/// Gets the <see cref="IClientPlayer" /> that triggered this <see cref="IPlayerEvent" />.
/// </summary>
IClientPlayer ClientPlayer { get; }
/// <summary>
/// Gets the networked <see cref="IInnerPlayerControl"/> that triggered this <see cref="IPlayerEvent"/>.
/// This <see cref="IInnerPlayerControl"/> belongs to the <see cref="IClientPlayer"/>.
/// Gets the networked <see cref="IInnerPlayerControl" /> that triggered this <see cref="IPlayerEvent" />.
/// This <see cref="IInnerPlayerControl" /> belongs to the <see cref="IClientPlayer" />.
/// </summary>
IInnerPlayerControl PlayerControl { get; }
}
}
}
@@ -0,0 +1,15 @@
using Impostor.Api.Innersloth;
namespace Impostor.Api.Events.Player
{
/// <summary>
/// Called whenever a player exits a vent.
/// </summary>
public interface IPlayerExitVentEvent : IPlayerEvent
{
/// <summary>
/// Gets the exited vent.
/// </summary>
public IVent Vent { get; }
}
}
@@ -0,0 +1,6 @@
namespace Impostor.Api.Events.Player
{
public interface IPlayerMovementEvent : IPlayerEvent
{
}
}
@@ -5,7 +5,7 @@ namespace Impostor.Api.Events.Player
public interface IPlayerStartMeetingEvent : IPlayerEvent
{
/// <summary>
/// Gets the player who's body got reported. Is null when the meeting started by Emergency call button
/// Gets the player who's body got reported. Is null when the meeting started by Emergency call button.
/// </summary>
IInnerPlayerControl? Body { get; }
}
@@ -2,16 +2,14 @@ using Impostor.Api.Innersloth;
namespace Impostor.Api.Events.Player
{
/// <summary>
/// Called whenever a player moves to another vent.
/// </summary>
public interface IPlayerVentEvent : IPlayerEvent
{
/// <summary>
/// Gets get the id of the used vent.
/// Gets the vent player moved to.
/// </summary>
public VentLocation VentId { get; }
/// <summary>
/// Gets a value indicating whether the vent was entered or exited.
/// </summary>
public bool VentEnter { get; }
public IVent NewVent { get; }
}
}
@@ -0,0 +1,24 @@
using Impostor.Api.Net.Inner.Objects;
namespace Impostor.Api.Events.Player
{
public enum VoteType : sbyte
{
ForceSkip = -2,
Skip = -1,
Player = 0,
}
public interface IPlayerVotedEvent : IPlayerEvent
{
/// <summary>
/// Gets the player he voted for.
/// </summary>
IInnerPlayerControl? VotedFor { get; }
/// <summary>
/// Gets the Vote type.
/// </summary>
VoteType VoteType { get; }
}
}
+1 -1
View File
@@ -3,4 +3,4 @@
public interface IEvent
{
}
}
}
+2 -2
View File
@@ -3,8 +3,8 @@
public interface IEventCancelable : IEvent
{
/// <summary>
/// True if the event was cancelled.
/// Gets or sets a value indicating whether the event was cancelled.
/// </summary>
bool IsCancelled { get; set; }
}
}
}
+1 -1
View File
@@ -3,4 +3,4 @@
public interface IEventListener
{
}
}
}
@@ -4,10 +4,10 @@ namespace Impostor.Api.Events
{
public interface IManualEventListener : IEventListener
{
EventPriority Priority { get; set; }
public bool CanExecute<T>();
public ValueTask Execute(IEvent @event);
EventPriority Priority { get; set; }
}
}
}
@@ -16,20 +16,20 @@ namespace Impostor.Api.Events.Managers
where TListener : IEventListener;
/// <summary>
/// Returns true if an event with the type <see cref="TEvent"/> is registered.
/// Returns true if an event with the type <typeparamref name="TEvent" /> is registered.
/// </summary>
/// <returns>True if the <see cref="TEvent"/> is registered.</returns>
/// <returns>True if the <typeparamref name="TEvent" /> is registered.</returns>
/// <typeparam name="TEvent">Type of the event.</typeparam>
bool IsRegistered<TEvent>()
where TEvent : IEvent;
/// <summary>
/// Call all the event listeners for the type <see cref="TEvent"/>.
/// Call all the event listeners for the type <typeparamref name="TEvent" />.
/// </summary>
/// <param name="event">The event argument.</param>
/// <typeparam name="TEvent">Type of the event.</typeparam>
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
ValueTask CallAsync<TEvent>(TEvent @event)
where TEvent : IEvent;
}
}
}
@@ -1,12 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Impostor.Server.Events
namespace Impostor.Api.Events
{
/// <summary>
/// Disposes multiple <see cref="IDisposable"/>.
/// Disposes multiple <see cref="IDisposable" />.
/// </summary>
internal class MultiDisposable : IDisposable
public class MultiDisposable : IDisposable
{
private readonly IEnumerable<IDisposable> _disposables;
@@ -15,6 +16,10 @@ namespace Impostor.Server.Events
_disposables = disposables;
}
public MultiDisposable(params IDisposable[] disposables) : this(disposables.AsEnumerable())
{
}
public void Dispose()
{
foreach (var disposable in _disposables)
@@ -1,24 +0,0 @@
using System;
using System.Runtime.Serialization;
namespace Impostor.Api
{
public class ImpostorCheatException : ImpostorException
{
public ImpostorCheatException()
{
}
protected ImpostorCheatException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
public ImpostorCheatException(string? message) : base(message)
{
}
public ImpostorCheatException(string? message, Exception? innerException) : base(message, innerException)
{
}
}
}
@@ -9,10 +9,6 @@ namespace Impostor.Api
{
}
protected ImpostorConfigException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
public ImpostorConfigException(string? message) : base(message)
{
}
@@ -20,5 +16,9 @@ namespace Impostor.Api
public ImpostorConfigException(string? message, Exception? innerException) : base(message, innerException)
{
}
protected ImpostorConfigException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}
@@ -9,10 +9,6 @@ namespace Impostor.Api
{
}
protected ImpostorException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
public ImpostorException(string? message) : base(message)
{
}
@@ -20,5 +16,9 @@ namespace Impostor.Api
public ImpostorException(string? message, Exception? innerException) : base(message, innerException)
{
}
protected ImpostorException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}
}
@@ -9,10 +9,6 @@ namespace Impostor.Api
{
}
protected ImpostorProtocolException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
public ImpostorProtocolException(string? message) : base(message)
{
}
@@ -20,5 +16,9 @@ namespace Impostor.Api
public ImpostorProtocolException(string? message, Exception? innerException) : base(message, innerException)
{
}
protected ImpostorProtocolException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}
@@ -0,0 +1,19 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace Impostor.Api
{
public static class DictionaryExtensions
{
/// <summary>Returns a read-only <see cref="ReadOnlyDictionary{TKey,TValue}" /> wrapper for the dictionary.</summary>
/// <param name="dictionary">An <see cref="IDictionary{TKey,TValue}" /> to create a <see cref="ReadOnlyDictionary{TKey,TValue}" /> from.</param>
/// <typeparam name="TKey">The type of the keys of <paramref name="dictionary" />.</typeparam>
/// <typeparam name="TValue">The type of the values of <paramref name="dictionary" />.</typeparam>
/// <returns>An object that acts as a read-only wrapper around the <see cref="IDictionary{TKey,TValue}" />.</returns>
public static ReadOnlyDictionary<TKey, TValue> AsReadOnly<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
where TKey : notnull
{
return new ReadOnlyDictionary<TKey, TValue>(dictionary);
}
}
}
@@ -5,7 +5,7 @@ using System.Runtime.CompilerServices;
namespace Impostor.Api
{
/// <summary>
/// Priovides a StreamReader-like api throught extensions
/// Priovides a StreamReader-like api throught extensions.
/// </summary>
public static class SpanReaderExtensions
{
@@ -35,9 +35,7 @@ namespace Impostor.Api
{
var original = Advance<float>(ref input);
// BitConverter.Int32BitsToSingle
// Doesn't exist in net 2.0 for some reason
return Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(original));
return BitConverter.Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(original));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -46,18 +44,12 @@ namespace Impostor.Api
return input.ReadByte() != 0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe float Int32BitsToSingle(int value)
{
return *((float*)&value);
}
/// <summary>
/// Advances the position of <see cref="input"/> by the size of <see cref="T"/>.
/// Advances the position of <paramref name="input" /> by the size of <typeparamref name="T" />.
/// </summary>
/// <typeparam name="T">Type that will be read.</typeparam>
/// <param name="input">input "stream"/span.</param>
/// <returns>The original input</returns>
/// <returns>The original input.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe ReadOnlySpan<byte> Advance<T>(ref ReadOnlySpan<byte> input)
where T : unmanaged
@@ -67,4 +59,4 @@ namespace Impostor.Api
return original;
}
}
}
}
@@ -9,4 +9,4 @@ namespace Impostor.Api
return SystemTypeHelpers.Names[(int)type];
}
}
}
}
@@ -39,4 +39,4 @@ namespace Impostor.Api.Games
return game.SendToAsync(writer, player.Client);
}
}
}
}
@@ -8,7 +8,7 @@ namespace Impostor.Api.Games
{
public static int GetGameCount(this IGameManager manager, MapFlags map)
{
return manager.Games.Count(game => map.HasFlag((MapFlags)(1 << game.Options.MapId)));
return manager.Games.Count(game => map.HasFlag((MapFlags)(1 << (byte)game.Options.Map)));
}
}
}
}
+8 -6
View File
@@ -1,4 +1,4 @@
using System;
using System;
using Impostor.Api.Innersloth;
namespace Impostor.Api.Games
@@ -14,13 +14,15 @@ namespace Impostor.Api.Games
public GameCode(string code)
{
Value = GameCodeParser.GameNameToInt(code);
Code = code;
Code = code.ToUpperInvariant();
}
public string Code { get; }
public int Value { get; }
public bool IsInvalid => Value == -1;
public static implicit operator string(GameCode code) => code.Code;
public static implicit operator int(GameCode code) => code.Value;
@@ -48,19 +50,19 @@ namespace Impostor.Api.Games
public static GameCode From(string value) => new GameCode(value);
/// <inheritdoc/>
/// <inheritdoc />
public bool Equals(GameCode other)
{
return Code == other.Code && Value == other.Value;
}
/// <inheritdoc/>
/// <inheritdoc />
public override bool Equals(object? obj)
{
return obj is GameCode other && Equals(other);
}
/// <inheritdoc/>
/// <inheritdoc />
public override int GetHashCode()
{
return HashCode.Combine(Code, Value);
@@ -71,4 +73,4 @@ namespace Impostor.Api.Games
return Code;
}
}
}
}
+2 -2
View File
@@ -41,8 +41,8 @@
/// Custom error by a plugin.
/// </summary>
/// <remarks>
/// A custom message can be set in <see cref="GameJoinResult.Message"/>.
/// A custom message can be set in <see cref="GameJoinResult.Message" />.
/// </remarks>
Custom,
}
}
}
+1 -1
View File
@@ -45,4 +45,4 @@ namespace Impostor.Api.Games
return new GameJoinResult(error);
}
}
}
}
+42 -17
View File
@@ -4,7 +4,6 @@ using System.Threading.Tasks;
using Impostor.Api.Innersloth;
using Impostor.Api.Net;
using Impostor.Api.Net.Inner;
using Impostor.Api.Net.Inner.Objects;
using Impostor.Api.Net.Messages;
namespace Impostor.Api.Games
@@ -25,47 +24,54 @@ namespace Impostor.Api.Games
int PlayerCount { get; }
IClientPlayer Host { get; }
IClientPlayer? Host { get; }
bool IsPublic { get; }
/// <summary>
/// Gets or sets display name on game list.
/// </summary>
string? DisplayName { get; set; }
IDictionary<object, object> Items { get; }
int HostId { get; }
IClientPlayer GetClientPlayer(int clientId);
IClientPlayer? GetClientPlayer(int clientId);
T? FindObjectByNetId<T>(uint netId)
where T : IInnerNetObject;
/// <summary>
/// Adds an <see cref="IPAddress"/> to the ban list of this game.
/// Prevents all future joins from this <see cref="IPAddress"/>.
///
/// This does not kick the player with that <see cref="IPAddress"/> from the lobby.
/// Adds an <see cref="IPAddress" /> to the ban list of this game.
/// Prevents all future joins from this <see cref="IPAddress" />.
/// This does not kick the player with that <see cref="IPAddress" /> from the lobby.
/// </summary>
/// <param name="ipAddress">
/// The <see cref="IPAddress"/> to ban.
/// The <see cref="IPAddress" /> to ban.
/// </param>
void BanIp(IPAddress ipAddress);
/// <summary>
/// Syncs the internal <see cref="GameOptionsData"/> to all players.
/// Syncs the internal <see cref="GameOptionsData" /> to all players.
/// Necessary to do if you modified it, otherwise it won't be used.
/// </summary>
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
ValueTask SyncSettingsAsync();
/// <summary>
/// Sets the specified list as Impostor on all connected players.
/// Sets game's privacy.
/// </summary>
/// <param name="players">List of players to be Impostor.</param>
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
ValueTask SetInfectedAsync(IEnumerable<IInnerPlayerControl> players);
/// <param name="isPublic">Privacy to set.</param>
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
ValueTask SetPrivacyAsync(bool isPublic);
/// <summary>
/// Send the message to all players.
/// </summary>
/// <param name="writer">Message to send.</param>
/// <param name="states">Required limbo state of the player.</param>
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
ValueTask SendToAllAsync(IMessageWriter writer, LimboStates states = LimboStates.NotLimbo);
/// <summary>
@@ -74,7 +80,7 @@ namespace Impostor.Api.Games
/// <param name="writer">Message to send.</param>
/// <param name="senderId">The player to exclude from sending the message.</param>
/// <param name="states">Required limbo state of the player.</param>
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
ValueTask SendToAllExceptAsync(IMessageWriter writer, int senderId, LimboStates states = LimboStates.NotLimbo);
/// <summary>
@@ -82,7 +88,26 @@ namespace Impostor.Api.Games
/// </summary>
/// <param name="writer">Message to send.</param>
/// <param name="id">ID of the client.</param>
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
ValueTask SendToAsync(IMessageWriter writer, int id);
/// <summary>
/// Creates a MessageWriter with GameData header.
/// </summary>
/// <remarks>Use with caution, recommended only for advanced developers.</remarks>
/// <param name="targetNetId">Net id of the InnerNetObject.</param>
/// <param name="callId">Rpc id of the message.</param>
/// <param name="targetClientId">Client id of GameDataTo's target.</param>
/// <param name="type">Message type of the message.</param>
/// <returns>A <see cref="IMessageWriter" /> that you can fill with rpc data and send using <see cref="FinishRpcAsync"/>.</returns>
IMessageWriter StartRpc(uint targetNetId, RpcCalls callId, int? targetClientId, MessageType type = MessageType.Reliable);
/// <summary>
/// Finishes rpc message and sends it to the target.
/// </summary>
/// <param name="writer">Message writer of the rpc.</param>
/// <param name="targetClientId">Id of the receiving client.</param>
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
ValueTask FinishRpcAsync(IMessageWriter writer, int? targetClientId = null);
}
}
+1 -1
View File
@@ -4,4 +4,4 @@
{
GameCode Create();
}
}
}
@@ -1,4 +1,6 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Impostor.Api.Innersloth;
namespace Impostor.Api.Games.Managers
{
@@ -7,5 +9,13 @@ namespace Impostor.Api.Games.Managers
IEnumerable<IGame> Games { get; }
IGame? Find(GameCode code);
/// <summary>
/// Creates a new game.
/// </summary>
/// <param name="options">Game options.</param>
/// <returns>Created game or null if creation was cancelled by a plugin.</returns>
/// <exception cref="ImpostorException">Thrown when game creation failed.</exception>
ValueTask<IGame?> CreateAsync(GameOptionsData options);
}
}
}
+9 -5
View File
@@ -1,12 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<CodeAnalysisRuleSet>ProjectRules.ruleset</CodeAnalysisRuleSet>
<TargetFramework>netstandard2.1</TargetFramework>
<CodeAnalysisRuleSet>../ProjectRules.ruleset</CodeAnalysisRuleSet>
<LangVersion>9</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Nullable>enable</Nullable>
<Version>1.0.0</Version>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<AssemblyName>Impostor.Api</AssemblyName>
@@ -16,13 +15,18 @@
<PackageId>Impostor.Api</PackageId>
<PackageTags>Among Us;Impostor;Impostor Plugin</PackageTags>
<PackageIconUrl>https://raw.githubusercontent.com/Impostor/Impostor/dev/docs/images/logo_64.png</PackageIconUrl>
<PackageIcon>logo_64.png</PackageIcon>
<PackageProjectUrl>https://github.com/Impostor/Impostor</PackageProjectUrl>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/Impostor/Impostor</RepositoryUrl>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Bcl.HashCode" Version="1.1.0" />
<None Include="../../docs/images/logo_64.png" Pack="true" PackagePath="\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0" />
<PackageReference Include="Nullable" Version="1.3.0">
@@ -35,4 +39,4 @@
</PackageReference>
</ItemGroup>
</Project>
</Project>
+1 -1
View File
@@ -4,4 +4,4 @@
{
ChangePrivacy = 1,
}
}
}
@@ -0,0 +1,14 @@
namespace Impostor.Api.Innersloth
{
public readonly struct Announcement
{
public readonly int Id;
public readonly string Message;
public Announcement(int id, string message)
{
Id = id;
Message = message;
}
}
}
+1 -1
View File
@@ -4,4 +4,4 @@
{
DidVote = 0,
}
}
}
@@ -1,6 +1,6 @@
namespace Impostor.Api.Innersloth.Customization
{
public enum ColorType : byte
public enum ColorType
{
Red = 0,
Blue = 1,
@@ -1,6 +1,6 @@
namespace Impostor.Api.Innersloth.Customization
{
public enum HatType
public enum HatType : uint
{
NoHat = 0,
Astronaut = 1,
@@ -45,8 +45,8 @@
ThirdEyeHat = 40,
ToiletPaperHat = 41,
Toppat = 42,
Fedora = 43,
Goggles2 = 44,
BlackFedora = 43,
SkiGoggles = 44,
Headphones = 45,
MaskHat = 46,
PaperMask = 47,
@@ -58,7 +58,7 @@
Cheese = 53,
Cherry = 54,
Egg = 55,
Fedora2 = 56,
GreenFedora = 56,
Flamingo = 57,
FlowerPin = 58,
Helmet = 59,
@@ -95,6 +95,27 @@
MiniCrewmate = 90,
NinjaMask = 91,
RamHorns = 92,
Snowman2 = 93,
SnowCrewmate = 93,
GeoffHat = 94,
DaveCap = 95,
EllieRose = 96,
SvenHat = 97,
BurtHat = 98,
EllryMohawk = 99,
ThomasMonoc = 100,
Wizard = 101,
Fredrick = 102,
MrMacbeth = 103,
ToppatHenry = 104,
ToppatEllie = 105,
GeoffreyPlumb = 106,
AngryEyebrows = 107,
ChocolateIce = 108,
HeartPin = 109,
Ponytail = 110,
RubberGlove = 111,
UnicornHorn = 112,
Zipper = 113,
RightHandMan = 114,
}
}
@@ -1,6 +1,6 @@
namespace Impostor.Api.Innersloth.Customization
{
public enum PetType
public enum PetType : uint
{
NoPet = 0,
Alien = 1,
@@ -1,6 +1,6 @@
namespace Impostor.Api.Innersloth.Customization
{
public enum SkinType : byte
public enum SkinType : uint
{
None = 0,
Astro = 1,
@@ -18,5 +18,8 @@
Miner = 13,
Winter = 14,
Archae = 15,
Prisoner = 16,
CCC = 17,
RightHandMan = 18,
}
}
+1 -1
View File
@@ -6,4 +6,4 @@
Kill = 1,
Disconnect = 2,
}
}
}
+27 -13
View File
@@ -3,52 +3,66 @@
public enum DisconnectReason
{
ExitGame = 0,
Destroy = 16,
// The game you tried to join is full.
// Check with the host to see if you can join next round.
GameFull = 1,
// The game you tried to join already started.
// Check with the host to see if you can join next round.
GameStarted = 2,
// Could not find the game you're looking for.
// Could not find the game you're looking for..
GameMissing = 3,
IncorrectGame = 18,
// For these a message can be given, specifying an empty message shows
// For this a message can be given, specifying an empty message shows
// "An unknown error disconnected you from the server."
CustomMessage1 = 4,
// 4, 12, 13, 14, 15 also count as Custom
Custom = 8,
// CustomMessage3 = 11,
// CustomMessage4 = 12,
// CustomMessage5 = 13,
// CustomMessage6 = 14,
// CustomMessage7 = 15,
// You are running an older version of the game.
// Please update to play with others.
IncorrectVersion = 5,
// You were banned from { GameCode ?? "the room" }
// You cannot rejoin that room.
// You were banned
Banned = 6,
// You can rejoin if the room hasn't started
// You were kicked
// You were kicked from { GameCode ?? "the room" }
// You can rejoin if the room hasn't started.
Kicked = 7,
// You were banned for hacking.
// Please stop.
Hacking = 10,
Destroy = 16,
// GameModes.LocalGame:
// You disconnected from the host.
// If this happens often, check your WiFi strength.
//
// GameModes.OnlineGame:
// You disconnected from the server.
// If this happens often, check your network strength.
// This may also be a server issue.
Error = 17,
// The server stopped this game. Possibly due to inactivity.
ServerRequest = 19,
// The Among Us servers are overloaded.
// Sorry! Please try again later!
ServerFull = 20,
FocusLostBackground = 207,
// You may not join another game for another { BanMinutesLeft } minutes after intentionally disconnecting.
IntentionalLeaving = 208,
// You were disconnected because Among Us was suspended by another app.
FocusLost = 209,
NewConnection = 210,
}
}
}
-22
View File
@@ -1,22 +0,0 @@
using Impostor.Api.Unity;
namespace Impostor.Api.Innersloth
{
public class FloatRange
{
private readonly float _min;
private readonly float _max;
public FloatRange(float min, float max)
{
_min = min;
_max = max;
}
public float Width => _max - _min;
public float Lerp(float v) => Mathf.Lerp(_min, _max, v);
public float ReverseLerp(float t) => Mathf.Clamp((t - _min) / Width, 0.0f, 1f);
}
}
@@ -0,0 +1,12 @@
using System;
namespace Impostor.Api.Innersloth
{
[Flags]
public enum FreeWeekendState : byte
{
NotFree,
FreeMIRA,
FreePolus,
}
}
+40 -65
View File
@@ -9,36 +9,11 @@ namespace Impostor.Api.Innersloth
public static class GameCodeParser
{
private const string V2 = "QWXRTYLPESDFGHUJKZOCVBINMA";
private static readonly int[] V2Map = {
25,
21,
19,
10,
8,
11,
12,
13,
22,
15,
16,
6,
24,
23,
18,
7,
0,
3,
9,
4,
14,
20,
1,
2,
5,
17
};
private static readonly int[] V2Map = Enumerable.Range(65, 26).Select(v => V2.IndexOf((char)v)).ToArray();
private static readonly RNGCryptoServiceProvider Random = new RNGCryptoServiceProvider();
public static string IntToGameName(int input)
{
// V2.
@@ -57,22 +32,6 @@ namespace Impostor.Api.Innersloth
#endif
}
private static string IntToGameNameV2(int input)
{
var a = input & 0x3FF;
var b = (input >> 10) & 0xFFFFF;
return new string(new []
{
V2[a % 26],
V2[a / 26],
V2[b % 26],
V2[b / 26 % 26],
V2[b / (26 * 26) % 26],
V2[b / (26 * 26 * 26) % 26]
});
}
public static int GameNameToInt(string code)
{
var upper = code.ToUpperInvariant();
@@ -80,7 +39,7 @@ namespace Impostor.Api.Innersloth
{
return -1;
}
var len = code.Length;
if (len == 6)
{
@@ -91,24 +50,9 @@ namespace Impostor.Api.Innersloth
{
return code[0] | ((code[1] | ((code[2] | (code[3] << 8)) << 8)) << 8);
}
return -1;
}
private static int GameNameToIntV2(string code)
{
var a = V2Map[code[0] - 65];
var b = V2Map[code[1] - 65];
var c = V2Map[code[2] - 65];
var d = V2Map[code[3] - 65];
var e = V2Map[code[4] - 65];
var f = V2Map[code[5] - 65];
var one = (a + 26 * b) & 0x3FF;
var two = (c + 26 * (d + 26 * (e + 26 * f)));
return (int) (one | ((two << 10) & 0x3FFFFC00) | 0x80000000);
}
public static int GenerateCode(int len)
{
@@ -116,7 +60,7 @@ namespace Impostor.Api.Innersloth
{
throw new ArgumentException("should be 4 or 6", nameof(len));
}
// Generate random bytes.
#if NETSTANDARD2_0
var data = new byte[len];
@@ -124,7 +68,7 @@ namespace Impostor.Api.Innersloth
Span<byte> data = stackalloc byte[len];
#endif
Random.GetBytes(data);
// Convert to their char representation.
Span<char> dataChar = stackalloc char[len];
for (var i = 0; i < len; i++)
@@ -138,5 +82,36 @@ namespace Impostor.Api.Innersloth
return GameNameToInt(new string(dataChar));
#endif
}
private static string IntToGameNameV2(int input)
{
var a = input & 0x3FF;
var b = (input >> 10) & 0xFFFFF;
return new string(new[]
{
V2[a % 26],
V2[a / 26],
V2[b % 26],
V2[(b / 26) % 26],
V2[(b / (26 * 26)) % 26],
V2[(b / (26 * 26 * 26)) % 26],
});
}
private static int GameNameToIntV2(string code)
{
var a = V2Map[code[0] - 65];
var b = V2Map[code[1] - 65];
var c = V2Map[code[2] - 65];
var d = V2Map[code[3] - 65];
var e = V2Map[code[4] - 65];
var f = V2Map[code[5] - 65];
var one = (a + (26 * b)) & 0x3FF;
var two = c + (26 * (d + (26 * (e + (26 * f)))));
return (int)(one | ((two << 10) & 0x3FFFFC00) | 0x80000000);
}
}
}
}
+1 -1
View File
@@ -16,4 +16,4 @@ namespace Impostor.Api.Innersloth
Polish = 128,
English = 256,
}
}
}
+109 -116
View File
@@ -7,145 +7,130 @@ namespace Impostor.Api.Innersloth
public class GameOptionsData
{
/// <summary>
/// The latest major version of the game client.
/// The latest major version of the game client.
/// </summary>
public const int LatestVersion = 4;
/// <summary>
/// Gets or sets host's version of the game.
/// Gets or sets host's version of the game.
/// </summary>
public byte Version { get; set; }
public byte Version { get; set; } = LatestVersion;
/// <summary>
/// Gets or sets the maximum amount of players for this lobby.
/// Gets or sets the maximum amount of players for this lobby.
/// </summary>
public byte MaxPlayers { get; set; }
public byte MaxPlayers { get; set; } = 10;
/// <summary>
/// Gets or sets the language of the lobby as per <see cref="GameKeywords"/> enum.
/// Gets or sets the language of the lobby as per <see cref="GameKeywords" /> enum.
/// </summary>
public GameKeywords Keywords { get; set; }
public GameKeywords Keywords { get; set; } = GameKeywords.English;
/// <summary>
/// Gets or sets the MapId selected for this lobby
/// Gets or sets the Map selected for this lobby.
/// </summary>
public MapTypes Map { get; set; } = MapTypes.Skeld;
/// <summary>
/// Gets or sets the Player speed modifier.
/// </summary>
public float PlayerSpeedMod { get; set; } = 1f;
/// <summary>
/// Gets or sets the Light modifier for the players that are members of the crew as a multiplier value.
/// </summary>
public float CrewLightMod { get; set; } = 1f;
/// <summary>
/// Gets or sets the Light modifier for the players that are Impostors as a multiplier value.
/// </summary>
public float ImpostorLightMod { get; set; } = 1f;
/// <summary>
/// Gets or sets the Impostor cooldown to kill in seconds.
/// </summary>
public float KillCooldown { get; set; } = 15f;
/// <summary>
/// Gets or sets the number of common tasks.
/// </summary>
public int NumCommonTasks { get; set; } = 1;
/// <summary>
/// Gets or sets the number of long tasks.
/// </summary>
public int NumLongTasks { get; set; } = 1;
/// <summary>
/// Gets or sets the number of short tasks.
/// </summary>
public int NumShortTasks { get; set; } = 2;
/// <summary>
/// Gets or sets the maximum amount of emergency meetings each player can call during the game in seconds.
/// </summary>
public int NumEmergencyMeetings { get; set; } = 1;
/// <summary>
/// Gets or sets the cooldown between each time any player can call an emergency meeting in seconds.
/// </summary>
public int EmergencyCooldown { get; set; } = 15;
/// <summary>
/// Gets or sets the number of impostors for this lobby.
/// </summary>
public int NumImpostors { get; set; } = 1;
/// <summary>
/// Gets or sets a value indicating whether ghosts (dead crew members) can do tasks.
/// </summary>
public bool GhostsDoTasks { get; set; } = true;
/// <summary>
/// Gets or sets the Kill as per values in <see cref="KillDistances" />.
/// </summary>
public KillDistances KillDistance { get; set; } = KillDistances.Normal;
/// <summary>
/// Gets or sets the time for discussion before voting time in seconds.
/// </summary>
public int DiscussionTime { get; set; } = 15;
/// <summary>
/// Gets or sets the time for voting in seconds.
/// </summary>
public int VotingTime { get; set; } = 120;
/// <summary>
/// Gets or sets a value indicating whether an ejected player is an impostor or not.
/// </summary>
public bool ConfirmImpostor { get; set; } = true;
/// <summary>
/// Gets or sets a value indicating whether players are able to see tasks being performed by other players.
/// </summary>
/// <remarks>
/// Skeld = 0, MiraHQ = 1, Polus = 2.
/// By being set to true, tasks such as Empty Garbage, Submit Scan, Clear asteroids, Prime shields execution will be visible to other players.
/// </remarks>
internal byte MapId { get; set; }
public bool VisualTasks { get; set; } = true;
/// <summary>
/// Gets or sets the map selected for this lobby
/// </summary>
public MapTypes Map
{
get => (MapTypes)MapId;
set => MapId = (byte)value;
}
/// <summary>
/// Gets or sets the Player speed modifier.
/// </summary>
public float PlayerSpeedMod { get; set; }
/// <summary>
/// Gets or sets the Light modifier for the players that are members of the crew as a multiplier value.
/// </summary>
public float CrewLightMod { get; set; }
/// <summary>
/// Gets or sets the Light modifier for the players that are Impostors as a multiplier value.
/// </summary>
public float ImpostorLightMod { get; set; }
/// <summary>
/// Gets or sets the Impostor cooldown to kill in seconds.
/// </summary>
public float KillCooldown { get; set; }
/// <summary>
/// Gets or sets the number of common tasks.
/// </summary>
public int NumCommonTasks { get; set; }
/// <summary>
/// Gets or sets the number of long tasks.
/// </summary>
public int NumLongTasks { get; set; }
/// <summary>
/// Gets or sets the number of short tasks.
/// </summary>
public int NumShortTasks { get; set; }
/// <summary>
/// Gets or sets the maximum amount of emergency meetings each player can call during the game in seconds.
/// </summary>
public int NumEmergencyMeetings { get; set; }
/// <summary>
/// Gets or sets the cooldown between each time any player can call an emergency meeting in seconds.
/// </summary>
public int EmergencyCooldown { get; set; }
/// <summary>
/// Gets or sets the number of impostors for this lobby.
/// </summary>
public int NumImpostors { get; set; }
/// <summary>
/// Gets or sets a value indicating whether ghosts (dead crew members) can do tasks.
/// </summary>
public bool GhostsDoTasks { get; set; }
/// <summary>
/// Gets or sets the Kill as per values in <see cref="KillDistances"/>.
/// </summary>
/// <remarks>
/// Short = 0, Normal = 1, Long = 2.
/// </remarks>
public KillDistances KillDistance { get; set; }
/// <summary>
/// Gets or sets the time for discussion before voting time in seconds.
/// </summary>
public int DiscussionTime { get; set; }
/// <summary>
/// Gets or sets the time for voting in seconds.
/// </summary>
public int VotingTime { get; set; }
/// <summary>
/// Gets or sets a value indicating whether an ejected player is an impostor or not.
/// </summary>
public bool ConfirmImpostor { get; set; }
/// <summary>
/// Gets or sets a value indicating whether players are able to see tasks being performed by other players.
/// </summary>
/// <remarks>
/// By being set to true, tasks such as Empty Garbage, Submit Scan, Clear asteroids, Prime shields execution will be visible to other players.
/// </remarks>
public bool VisualTasks { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the vote is anonymous.
/// Gets or sets a value indicating whether the vote is anonymous.
/// </summary>
public bool AnonymousVotes { get; set; }
/// <summary>
/// Gets or sets the task bar update mode as per values in <see cref="Innersloth.TaskBarUpdate"/>.
/// Gets or sets the task bar update mode as per values in <see cref="Innersloth.TaskBarUpdate" />.
/// </summary>
public TaskBarUpdate TaskBarUpdate { get; set; }
public TaskBarUpdate TaskBarUpdate { get; set; } = TaskBarUpdate.Always;
/// <summary>
/// Gets or sets a value indicating whether the GameOptions are the default ones.
/// Gets or sets a value indicating whether the GameOptions are the default ones.
/// </summary>
public bool IsDefaults { get; set; }
public bool IsDefaults { get; set; } = true;
/// <summary>
/// Deserialize a packet/message to a new GameOptionsData object.
/// Deserialize a packet/message to a new GameOptionsData object.
/// </summary>
/// <param name="reader">Message reader object containing the raw message.</param>
/// <returns>GameOptionsData object.</returns>
@@ -157,16 +142,16 @@ namespace Impostor.Api.Innersloth
}
/// <summary>
/// Serializes this instance of GameOptionsData object to a specified BinaryWriter.
/// Serializes this instance of GameOptionsData object to a specified BinaryWriter.
/// </summary>
/// <param name="writer">The stream to write the message to.</param>
/// <param name="version">The version of the game.</param>
public void Serialize(BinaryWriter writer, byte version)
public void Serialize(BinaryWriter writer, byte version = LatestVersion)
{
writer.Write((byte)version);
writer.Write((byte)MaxPlayers);
writer.Write((uint)Keywords);
writer.Write((byte)MapId);
writer.Write((byte)Map);
writer.Write((float)PlayerSpeedMod);
writer.Write((float)CrewLightMod);
writer.Write((float)ImpostorLightMod);
@@ -204,8 +189,16 @@ namespace Impostor.Api.Innersloth
}
}
public void Serialize(IMessageWriter writer)
{
using var memory = new MemoryStream();
using var writerBin = new BinaryWriter(memory);
Serialize(writerBin);
writer.WriteBytesAndSize(memory.ToArray());
}
/// <summary>
/// Deserialize a ReadOnlyMemory object to this instance of the GameOptionsData object.
/// Deserialize a ReadOnlyMemory object to this instance of the GameOptionsData object.
/// </summary>
/// <param name="memory">Memory containing the message/packet.</param>
public void Deserialize(ReadOnlyMemory<byte> memory)
@@ -215,7 +208,7 @@ namespace Impostor.Api.Innersloth
Version = bytes.ReadByte();
MaxPlayers = bytes.ReadByte();
Keywords = (GameKeywords)bytes.ReadUInt32();
MapId = bytes.ReadByte();
Map = (MapTypes)bytes.ReadByte();
PlayerSpeedMod = bytes.ReadSingle();
CrewLightMod = bytes.ReadSingle();
@@ -7,9 +7,7 @@
ImpostorByVote = 2,
ImpostorByKill = 3,
ImpostorBySabotage = 4,
// Unused (?)
ImpostorDisconnect = 5,
HumansDisconnect = 6,
}
}
}
+1 -1
View File
@@ -8,4 +8,4 @@
Ended = 3,
Destroyed = 4,
}
}
}
+1 -1
View File
@@ -7,4 +7,4 @@ namespace Impostor.Api.Innersloth
return (year * 25000) + (month * 1800) + (day * 50) + rev;
}
}
}
}
+15
View File
@@ -0,0 +1,15 @@
namespace Impostor.Api.Innersloth
{
public interface ITask
{
int Id { get; }
string Name { get; }
TaskTypes Type { get; }
TaskCategories Category { get; }
bool IsVisual { get; }
}
}
+19
View File
@@ -0,0 +1,19 @@
using System.Numerics;
namespace Impostor.Api.Innersloth
{
public interface IVent
{
int Id { get; }
string Name { get; }
Vector2 Position { get; }
IVent? Left { get; }
IVent? Center { get; }
IVent? Right { get; }
}
}
+11
View File
@@ -0,0 +1,11 @@
namespace Impostor.Api.Innersloth
{
public enum Language
{
English,
Spanish,
Portuguese,
Korean,
Russian,
}
}
+1 -1
View File
@@ -9,4 +9,4 @@ namespace Impostor.Api.Innersloth
MiraHQ = 2,
Polus = 4,
}
}
}
+3 -2
View File
@@ -1,9 +1,10 @@
namespace Impostor.Api.Innersloth
{
public enum MapTypes
public enum MapTypes : byte
{
Skeld = 0,
MiraHQ = 1,
Polus = 2,
Airship = 4,
}
}
}
@@ -0,0 +1,91 @@
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Impostor.Api.Innersloth.Maps.Tasks;
using Impostor.Api.Innersloth.Maps.Vents;
namespace Impostor.Api.Innersloth.Maps
{
public class AirshipData : IMapData
{
private readonly IReadOnlyDictionary<int, IVent> _vents;
private readonly IReadOnlyDictionary<int, ITask> _tasks;
internal AirshipData()
{
var vents = new[]
{
new AirshipVent(this, AirshipVent.Ids.Vault, new Vector2(-12.6322f, 8.4735f), left: AirshipVent.Ids.Cockpit),
new AirshipVent(this, AirshipVent.Ids.Cockpit, new Vector2(-22.099f, -1.512f), left: AirshipVent.Ids.Vault, right: AirshipVent.Ids.ViewingDeck),
new AirshipVent(this, AirshipVent.Ids.ViewingDeck, new Vector2(-15.659f, -11.6991f), left: AirshipVent.Ids.Cockpit),
new AirshipVent(this, AirshipVent.Ids.EngineRoom, new Vector2(0.203f, -2.5361f), left: AirshipVent.Ids.Kitchen, right: AirshipVent.Ids.MainHallBottom),
new AirshipVent(this, AirshipVent.Ids.Kitchen, new Vector2(-2.6019f, -9.338f), left: AirshipVent.Ids.EngineRoom, right: AirshipVent.Ids.MainHallBottom),
new AirshipVent(this, AirshipVent.Ids.MainHallBottom, new Vector2(7.021f, -3.730999f), left: AirshipVent.Ids.EngineRoom, right: AirshipVent.Ids.Kitchen),
new AirshipVent(this, AirshipVent.Ids.GapRight, new Vector2(9.814f, 3.206f), left: AirshipVent.Ids.MainHallTop, right: AirshipVent.Ids.GapLeft),
new AirshipVent(this, AirshipVent.Ids.GapLeft, new Vector2(12.663f, 5.922f), left: AirshipVent.Ids.MainHallTop, right: AirshipVent.Ids.GapRight),
new AirshipVent(this, AirshipVent.Ids.MainHallTop, new Vector2(3.605f, 6.923f), left: AirshipVent.Ids.GapLeft, right: AirshipVent.Ids.GapRight),
new AirshipVent(this, AirshipVent.Ids.Showers, new Vector2(23.9869f, -1.386f), left: AirshipVent.Ids.Records, right: AirshipVent.Ids.CargoBay),
new AirshipVent(this, AirshipVent.Ids.Records, new Vector2(23.2799f, 8.259998f), left: AirshipVent.Ids.Showers, right: AirshipVent.Ids.CargoBay),
new AirshipVent(this, AirshipVent.Ids.CargoBay, new Vector2(30.4409f, -3.577f), left: AirshipVent.Ids.Showers, right: AirshipVent.Ids.Records),
};
Vents = vents.ToDictionary(x => x.Id, x => x).AsReadOnly();
_vents = vents.ToDictionary(x => (int)x.Id, x => (IVent)x).AsReadOnly();
var tasks = new[]
{
new AirshipTask(AirshipTask.Ids.ElectricalFixWiring, TaskTypes.FixWiring, TaskCategories.CommonTask),
new AirshipTask(AirshipTask.Ids.MeetingRoomEnterIDCode, TaskTypes.EnterIdCode, TaskCategories.CommonTask),
new AirshipTask(AirshipTask.Ids.ElectricalResetBreakers, TaskTypes.ResetBreakers, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.VaultRoomDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.BrigDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.CargoBayDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.GapRoomDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.RecordsDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.CargoBayUnlockSafe, TaskTypes.UnlockSafe, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.VentilationStartFans, TaskTypes.StartFans, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.MainHallEmptyGarbage, TaskTypes.EmptyGarbage, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.MedicalEmptyGarbage, TaskTypes.EmptyGarbage, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.KitchenEmptyGarbage, TaskTypes.EmptyGarbage, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.MainHallDevelopPhotos, TaskTypes.DevelopPhotos, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.CargoBayFuelEngines, TaskTypes.FuelEngines, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.SecurityRewindTapes, TaskTypes.RewindTapes, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.VaultRoomPolishRuby, TaskTypes.PolishRuby, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ElectricalCalibrateDistributor, TaskTypes.CalibrateDistributor, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.CockpitStabilizeSteering, TaskTypes.StabilizeSteering, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ArmoryDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.CockpitDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.CommsDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.MedicalDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.ViewingDeckDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.ElectricalDivertPowerToArmory, TaskTypes.DivertPower, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ElectricalDivertPowerToCockpit, TaskTypes.DivertPower, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ElectricalDivertPowerToGapRoom, TaskTypes.DivertPower, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ElectricalDivertPowerToMainHall, TaskTypes.DivertPower, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ElectricalDivertPowerToMeetingRoom, TaskTypes.DivertPower, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ElectricalDivertPowerToShowers, TaskTypes.DivertPower, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ElectricalDivertPowerToEngine, TaskTypes.DivertPower, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ShowersPickUpTowels, TaskTypes.PickUpTowels, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.LoungeCleanToilet, TaskTypes.CleanToilet, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.VaultRoomDressMannequin, TaskTypes.DressMannequin, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.RecordsSortRecords, TaskTypes.SortRecords, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ArmoryPutAwayPistols, TaskTypes.PutAwayPistols, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ArmoryPutAwayRifles, TaskTypes.PutAwayRifles, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.MainHallDecontaminate, TaskTypes.Decontaminate, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.KitchenMakeBurger, TaskTypes.MakeBurger, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ShowersFixShower, TaskTypes.FixShower, TaskCategories.ShortTask),
};
Tasks = tasks.ToDictionary(x => x.Id, x => x).AsReadOnly();
_tasks = tasks.ToDictionary(x => (int)x.Id, x => (ITask)x).AsReadOnly();
}
public IReadOnlyDictionary<AirshipVent.Ids, AirshipVent> Vents { get; }
IReadOnlyDictionary<int, IVent> IMapData.Vents => _vents;
public IReadOnlyDictionary<AirshipTask.Ids, AirshipTask> Tasks { get; }
IReadOnlyDictionary<int, ITask> IMapData.Tasks => _tasks;
}
}
@@ -0,0 +1,19 @@
using System.Collections.Generic;
namespace Impostor.Api.Innersloth.Maps
{
public interface IMapData
{
public static IReadOnlyDictionary<MapTypes, IMapData> Maps { get; } = new Dictionary<MapTypes, IMapData>
{
[MapTypes.Skeld] = new SkeldData(),
[MapTypes.MiraHQ] = new MiraData(),
[MapTypes.Polus] = new PolusData(),
[MapTypes.Airship] = new AirshipData(),
}.AsReadOnly();
IReadOnlyDictionary<int, IVent> Vents { get; }
IReadOnlyDictionary<int, ITask> Tasks { get; }
}
}
@@ -0,0 +1,76 @@
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Impostor.Api.Innersloth.Maps.Tasks;
using Impostor.Api.Innersloth.Maps.Vents;
namespace Impostor.Api.Innersloth.Maps
{
public class MiraData : IMapData
{
private readonly IReadOnlyDictionary<int, IVent> _vents;
private readonly IReadOnlyDictionary<int, ITask> _tasks;
internal MiraData()
{
var vents = new[]
{
new MiraVent(this, MiraVent.Ids.Balcony, new Vector2(23.77f, -1.94f), left: MiraVent.Ids.Medbay, right: MiraVent.Ids.Cafeteria),
new MiraVent(this, MiraVent.Ids.Cafeteria, new Vector2(23.9f, 7.18f), left: MiraVent.Ids.Admin, right: MiraVent.Ids.Balcony),
new MiraVent(this, MiraVent.Ids.Reactor, new Vector2(0.4800001f, 10.697f), left: MiraVent.Ids.Laboratory, center: MiraVent.Ids.Decontamination, right: MiraVent.Ids.Launchpad),
new MiraVent(this, MiraVent.Ids.Laboratory, new Vector2(11.606f, 13.816f), left: MiraVent.Ids.Reactor, center: MiraVent.Ids.Decontamination, right: MiraVent.Ids.Office),
new MiraVent(this, MiraVent.Ids.Office, new Vector2(13.28f, 20.13f), left: MiraVent.Ids.Laboratory, center: MiraVent.Ids.Admin, right: MiraVent.Ids.Greenhouse),
new MiraVent(this, MiraVent.Ids.Admin, new Vector2(22.39f, 17.23f), left: MiraVent.Ids.Greenhouse, center: MiraVent.Ids.Cafeteria, right: MiraVent.Ids.Office),
new MiraVent(this, MiraVent.Ids.Greenhouse, new Vector2(17.85f, 25.23f), left: MiraVent.Ids.Admin, right: MiraVent.Ids.Office),
new MiraVent(this, MiraVent.Ids.Medbay, new Vector2(15.41f, -1.82f), left: MiraVent.Ids.Balcony, right: MiraVent.Ids.LockerRoom),
new MiraVent(this, MiraVent.Ids.Decontamination, new Vector2(6.83f, 3.145f), left: MiraVent.Ids.Reactor, center: MiraVent.Ids.LockerRoom, right: MiraVent.Ids.Laboratory),
new MiraVent(this, MiraVent.Ids.LockerRoom, new Vector2(4.29f, 0.5299997f), left: MiraVent.Ids.Medbay, center: MiraVent.Ids.Launchpad, right: MiraVent.Ids.Decontamination),
new MiraVent(this, MiraVent.Ids.Launchpad, new Vector2(-6.18f, 3.56f), left: MiraVent.Ids.Reactor, right: MiraVent.Ids.LockerRoom),
};
Vents = vents.ToDictionary(x => x.Id, x => x).AsReadOnly();
_vents = vents.ToDictionary(x => (int)x.Id, x => (IVent)x).AsReadOnly();
var tasks = new[]
{
new MiraTask(MiraTask.Ids.HallwayFixWiring, TaskTypes.FixWiring, TaskCategories.CommonTask),
new MiraTask(MiraTask.Ids.AdminEnterIDCode, TaskTypes.EnterIdCode, TaskCategories.CommonTask),
new MiraTask(MiraTask.Ids.MedbaySubmitScan, TaskTypes.SubmitScan, TaskCategories.LongTask, true),
new MiraTask(MiraTask.Ids.BalconyClearAsteroids, TaskTypes.ClearAsteroids, TaskCategories.LongTask),
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToAdmin, TaskTypes.DivertPower, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToCafeteria, TaskTypes.DivertPower, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToCommunications, TaskTypes.DivertPower, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToLaunchpad, TaskTypes.DivertPower, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToMedbay, TaskTypes.DivertPower, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToOffice, TaskTypes.DivertPower, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.StorageWaterPlants, TaskTypes.WaterPlants, TaskCategories.LongTask),
new MiraTask(MiraTask.Ids.ReactorStartReactor, TaskTypes.StartReactor, TaskCategories.LongTask),
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToGreenhouse, TaskTypes.DivertPower, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.AdminChartCourse, TaskTypes.ChartCourse, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.GreenhouseCleanO2Filter, TaskTypes.Filter, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.LaunchpadFuelEngines, TaskTypes.FuelEngines, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.LaboratoryAssembleArtifact, TaskTypes.AssembleArtifact, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.LaboratorySortSamples, TaskTypes.SortSamples, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.AdminPrimeShields, TaskTypes.PrimeShields, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.CafeteriaEmptyGarbage, TaskTypes.EmptyGarbage, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.BalconyMeasureWeather, TaskTypes.MeasureWeather, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToLaboratory, TaskTypes.DivertPower, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.CafeteriaBuyBeverage, TaskTypes.BuyBeverage, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.OfficeProcessData, TaskTypes.ProcessData, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.LaunchpadRunDiagnostics, TaskTypes.RunDiagnostics, TaskCategories.LongTask),
new MiraTask(MiraTask.Ids.ReactorUnlockManifolds, TaskTypes.UnlockManifolds, TaskCategories.ShortTask),
};
Tasks = tasks.ToDictionary(x => x.Id, x => x).AsReadOnly();
_tasks = tasks.ToDictionary(x => (int)x.Id, x => (ITask)x).AsReadOnly();
}
public IReadOnlyDictionary<MiraVent.Ids, MiraVent> Vents { get; }
IReadOnlyDictionary<int, IVent> IMapData.Vents => _vents;
public IReadOnlyDictionary<MiraTask.Ids, MiraTask> Tasks { get; }
IReadOnlyDictionary<int, ITask> IMapData.Tasks => _tasks;
}
}
@@ -0,0 +1,84 @@
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Impostor.Api.Innersloth.Maps.Tasks;
using Impostor.Api.Innersloth.Maps.Vents;
namespace Impostor.Api.Innersloth.Maps
{
public class PolusData : IMapData
{
private readonly IReadOnlyDictionary<int, IVent> _vents;
private readonly IReadOnlyDictionary<int, ITask> _tasks;
internal PolusData()
{
var vents = new[]
{
new PolusVent(this, PolusVent.Ids.Security, new Vector2(1.929f, -9.558001f), left: PolusVent.Ids.O2, right: PolusVent.Ids.Electrical),
new PolusVent(this, PolusVent.Ids.Electrical, new Vector2(6.9f, -14.41f), left: PolusVent.Ids.O2, right: PolusVent.Ids.Security),
new PolusVent(this, PolusVent.Ids.O2, new Vector2(3.51f, -16.58f), left: PolusVent.Ids.Electrical, right: PolusVent.Ids.Security),
new PolusVent(this, PolusVent.Ids.Communications, new Vector2(12.304f, -18.898f), left: PolusVent.Ids.Storage, right: PolusVent.Ids.Office),
new PolusVent(this, PolusVent.Ids.Office, new Vector2(16.379f, -19.599f), left: PolusVent.Ids.Communications, right: PolusVent.Ids.Storage),
new PolusVent(this, PolusVent.Ids.Admin, new Vector2(20.089f, -25.517f), left: PolusVent.Ids.OutsideAdmin, right: PolusVent.Ids.Lava),
new PolusVent(this, PolusVent.Ids.Laboratory, new Vector2(32.963f, -9.526f), right: PolusVent.Ids.Lava),
new PolusVent(this, PolusVent.Ids.Lava, new Vector2(30.907f, -11.86f), left: PolusVent.Ids.Laboratory, right: PolusVent.Ids.Admin),
new PolusVent(this, PolusVent.Ids.Storage, new Vector2(22f, -12.19f), left: PolusVent.Ids.Communications, right: PolusVent.Ids.Office),
new PolusVent(this, PolusVent.Ids.RightStabilizer, new Vector2(24.02f, -8.39f), left: PolusVent.Ids.LeftStabilizer),
new PolusVent(this, PolusVent.Ids.LeftStabilizer, new Vector2(9.64f, -7.72f), left: PolusVent.Ids.RightStabilizer),
new PolusVent(this, PolusVent.Ids.OutsideAdmin, new Vector2(18.93f, -24.85f), right: PolusVent.Ids.Admin),
};
Vents = vents.ToDictionary(x => x.Id, x => x).AsReadOnly();
_vents = vents.ToDictionary(x => (int)x.Id, x => (IVent)x).AsReadOnly();
var tasks = new[]
{
new PolusTask(PolusTask.Ids.OfficeSwipeCard, TaskTypes.SwipeCard, TaskCategories.CommonTask),
new PolusTask(PolusTask.Ids.DropshipInsertKeys, TaskTypes.InsertKeys, TaskCategories.CommonTask),
new PolusTask(PolusTask.Ids.OfficeScanBoardingPass, TaskTypes.ScanBoardingPass, TaskCategories.CommonTask),
new PolusTask(PolusTask.Ids.ElectricalFixWiring, TaskTypes.FixWiring, TaskCategories.CommonTask),
new PolusTask(PolusTask.Ids.WeaponsDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.OfficeDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.ElectricalDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.SpecimenRoomDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.O2DownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.SpecimenRoomStartReactor, TaskTypes.StartReactor, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.StorageFuelEngines, TaskTypes.FuelEngines, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.BoilerRoomOpenWaterways, TaskTypes.OpenWaterways, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.MedbayInspectSample, TaskTypes.InspectSample, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.BoilerRoomReplaceWaterJug, TaskTypes.ReplaceWaterJug, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.OutsideFixWeatherNodeNode_GI, TaskTypes.ActivateWeatherNodes, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.OutsideFixWeatherNodeNode_IRO, TaskTypes.ActivateWeatherNodes, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.OutsideFixWeatherNodeNode_PD, TaskTypes.ActivateWeatherNodes, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.OutsideFixWeatherNodeNode_TB, TaskTypes.ActivateWeatherNodes, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.CommunicationsRebootWiFi, TaskTypes.RebootWifi, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.O2MonitorTree, TaskTypes.MonitorOxygen, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.SpecimenRoomUnlockManifolds, TaskTypes.UnlockManifolds, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.SpecimenRoomStoreArtifacts, TaskTypes.StoreArtifact, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.O2FillCanisters, TaskTypes.FillCanisters, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.O2EmptyGarbage, TaskTypes.EmptyGarbage, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.DropshipChartCourse, TaskTypes.ChartCourse, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.MedbaySubmitScan, TaskTypes.SubmitScan, TaskCategories.ShortTask, true),
new PolusTask(PolusTask.Ids.WeaponsClearAsteroids, TaskTypes.ClearAsteroids, TaskCategories.ShortTask, true),
new PolusTask(PolusTask.Ids.OutsideFixWeatherNodeNode_CA, TaskTypes.ActivateWeatherNodes, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.OutsideFixWeatherNodeNode_MLG, TaskTypes.ActivateWeatherNodes, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.LaboratoryAlignTelescope, TaskTypes.AlignTelescope, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.LaboratoryRepairDrill, TaskTypes.RepairDrill, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.LaboratoryRecordTemperature, TaskTypes.RecordTemperature, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.OutsideRecordTemperature, TaskTypes.RecordTemperature, TaskCategories.ShortTask),
};
Tasks = tasks.ToDictionary(x => x.Id, x => x).AsReadOnly();
_tasks = tasks.ToDictionary(x => (int)x.Id, x => (ITask)x).AsReadOnly();
}
public IReadOnlyDictionary<PolusVent.Ids, PolusVent> Vents { get; }
IReadOnlyDictionary<int, IVent> IMapData.Vents => _vents;
public IReadOnlyDictionary<PolusTask.Ids, PolusTask> Tasks { get; }
IReadOnlyDictionary<int, ITask> IMapData.Tasks => _tasks;
}
}
@@ -0,0 +1,82 @@
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Impostor.Api.Innersloth.Maps.Tasks;
using Impostor.Api.Innersloth.Maps.Vents;
namespace Impostor.Api.Innersloth.Maps
{
public class SkeldData : IMapData
{
private readonly IReadOnlyDictionary<int, IVent> _vents;
private readonly IReadOnlyDictionary<int, ITask> _tasks;
internal SkeldData()
{
var vents = new[]
{
new SkeldVent(this, SkeldVent.Ids.Admin, new Vector2(2.544f, -9.955201f), left: SkeldVent.Ids.Cafeteria, right: SkeldVent.Ids.RightHallway),
new SkeldVent(this, SkeldVent.Ids.RightHallway, new Vector2(9.384f, -6.438f), left: SkeldVent.Ids.Admin, right: SkeldVent.Ids.Cafeteria),
new SkeldVent(this, SkeldVent.Ids.Cafeteria, new Vector2(4.2588f, -0.276f), left: SkeldVent.Ids.Admin, right: SkeldVent.Ids.RightHallway),
new SkeldVent(this, SkeldVent.Ids.Electrical, new Vector2(-9.7764f, -8.034f), left: SkeldVent.Ids.Security, right: SkeldVent.Ids.Medbay),
new SkeldVent(this, SkeldVent.Ids.UpperEngine, new Vector2(-15.288f, 2.52f), left: SkeldVent.Ids.UpperReactor),
new SkeldVent(this, SkeldVent.Ids.Security, new Vector2(-12.534f, -6.9492f), left: SkeldVent.Ids.Medbay, right: SkeldVent.Ids.Electrical),
new SkeldVent(this, SkeldVent.Ids.Medbay, new Vector2(-10.608f, -4.176f), left: SkeldVent.Ids.Security, right: SkeldVent.Ids.Electrical),
new SkeldVent(this, SkeldVent.Ids.Weapons, new Vector2(8.820001f, 3.324f), right: SkeldVent.Ids.UpperNavigation),
new SkeldVent(this, SkeldVent.Ids.LowerReactor, new Vector2(-20.796f, -6.9528f), left: SkeldVent.Ids.LowerEngine),
new SkeldVent(this, SkeldVent.Ids.LowerEngine, new Vector2(-15.2508f, -13.656f), left: SkeldVent.Ids.LowerReactor),
new SkeldVent(this, SkeldVent.Ids.Shields, new Vector2(9.5232f, -14.3376f), left: SkeldVent.Ids.LowerNavigation),
new SkeldVent(this, SkeldVent.Ids.UpperReactor, new Vector2(-21.876f, -3.0516f), left: SkeldVent.Ids.UpperEngine),
new SkeldVent(this, SkeldVent.Ids.UpperNavigation, new Vector2(16.008f, -3.168f), right: SkeldVent.Ids.Weapons),
new SkeldVent(this, SkeldVent.Ids.LowerNavigation, new Vector2(16.008f, -6.384f), right: SkeldVent.Ids.Shields),
};
Vents = vents.ToDictionary(x => x.Id, x => x).AsReadOnly();
_vents = vents.ToDictionary(x => (int)x.Id, x => (IVent)x).AsReadOnly();
var tasks = new[]
{
new SkeldTask(SkeldTask.Ids.AdminSwipeCard, TaskTypes.SwipeCard, TaskCategories.CommonTask),
new SkeldTask(SkeldTask.Ids.ElectricalFixWiring, TaskTypes.FixWiring, TaskCategories.CommonTask),
new SkeldTask(SkeldTask.Ids.WeaponsClearAsteroids, TaskTypes.ClearAsteroids, TaskCategories.LongTask, true),
new SkeldTask(SkeldTask.Ids.EnginesAlignEngineOutput, TaskTypes.AlignEngineOutput, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.MedbaySubmitScan, TaskTypes.SubmitScan, TaskCategories.LongTask, true),
new SkeldTask(SkeldTask.Ids.MedbayInspectSample, TaskTypes.InspectSample, TaskCategories.LongTask),
new SkeldTask(SkeldTask.Ids.StorageFuelEngines, TaskTypes.FuelEngines, TaskCategories.LongTask),
new SkeldTask(SkeldTask.Ids.ReactorStartReactor, TaskTypes.StartReactor, TaskCategories.LongTask),
new SkeldTask(SkeldTask.Ids.O2EmptyChute, TaskTypes.EmptyChute, TaskCategories.LongTask, true),
new SkeldTask(SkeldTask.Ids.CafeteriaEmptyGarbage, TaskTypes.EmptyGarbage, TaskCategories.LongTask, true),
new SkeldTask(SkeldTask.Ids.CommunicationsDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ElectricalCalibrateDistributor, TaskTypes.CalibrateDistributor, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.NavigationChartCourse, TaskTypes.ChartCourse, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.O2CleanO2Filter, TaskTypes.Filter, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ReactorUnlockManifolds, TaskTypes.UnlockManifolds, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ElectricalDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.NavigationStabilizeSteering, TaskTypes.StabilizeSteering, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.WeaponsDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ShieldsPrimeShields, TaskTypes.PrimeShields, TaskCategories.ShortTask, true),
new SkeldTask(SkeldTask.Ids.CafeteriaDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.NavigationDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToShields, TaskTypes.DivertPower, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToWeapons, TaskTypes.DivertPower, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToCommunications, TaskTypes.DivertPower, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToUpperEngine, TaskTypes.DivertPower, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToO2, TaskTypes.DivertPower, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToNavigation, TaskTypes.DivertPower, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToLowerEngine, TaskTypes.DivertPower, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToSecurity, TaskTypes.DivertPower, TaskCategories.ShortTask),
};
Tasks = tasks.ToDictionary(x => x.Id, x => x).AsReadOnly();
_tasks = tasks.ToDictionary(x => (int)x.Id, x => (ITask)x).AsReadOnly();
}
public IReadOnlyDictionary<SkeldVent.Ids, SkeldVent> Vents { get; }
IReadOnlyDictionary<int, IVent> IMapData.Vents => _vents;
public IReadOnlyDictionary<SkeldTask.Ids, SkeldTask> Tasks { get; }
IReadOnlyDictionary<int, ITask> IMapData.Tasks => _tasks;
}
}
@@ -0,0 +1,70 @@
namespace Impostor.Api.Innersloth.Maps.Tasks
{
public class AirshipTask : ITask
{
internal AirshipTask(Ids id, TaskTypes type, TaskCategories category, bool isVisual = false)
{
Id = id;
Name = id.ToString();
Type = type;
Category = category;
IsVisual = isVisual;
}
public enum Ids
{
ElectricalFixWiring = 0,
MeetingRoomEnterIDCode = 1,
ElectricalResetBreakers = 2,
VaultRoomDownloadData = 3,
BrigDownloadData = 4,
CargoBayDownloadData = 5,
GapRoomDownloadData = 6,
RecordsDownloadData = 7,
CargoBayUnlockSafe = 8,
VentilationStartFans = 9,
MainHallEmptyGarbage = 10,
MedicalEmptyGarbage = 11,
KitchenEmptyGarbage = 12,
MainHallDevelopPhotos = 13,
CargoBayFuelEngines = 14,
SecurityRewindTapes = 15,
VaultRoomPolishRuby = 16,
ElectricalCalibrateDistributor = 17,
CockpitStabilizeSteering = 18,
ArmoryDownloadData = 19,
CockpitDownloadData = 20,
CommsDownloadData = 21,
MedicalDownloadData = 22,
ViewingDeckDownloadData = 23,
ElectricalDivertPowerToArmory = 24,
ElectricalDivertPowerToCockpit = 25,
ElectricalDivertPowerToGapRoom = 26,
ElectricalDivertPowerToMainHall = 27,
ElectricalDivertPowerToMeetingRoom = 28,
ElectricalDivertPowerToShowers = 29,
ElectricalDivertPowerToEngine = 30,
ShowersPickUpTowels = 31,
LoungeCleanToilet = 32,
VaultRoomDressMannequin = 33,
RecordsSortRecords = 34,
ArmoryPutAwayPistols = 35,
ArmoryPutAwayRifles = 36,
MainHallDecontaminate = 37,
KitchenMakeBurger = 38,
ShowersFixShower = 39,
}
public Ids Id { get; }
int ITask.Id => (int)Id;
public string Name { get; }
public TaskTypes Type { get; }
public TaskCategories Category { get; }
public bool IsVisual { get; }
}
}
@@ -0,0 +1,56 @@
namespace Impostor.Api.Innersloth.Maps.Tasks
{
public class MiraTask : ITask
{
internal MiraTask(Ids id, TaskTypes type, TaskCategories category, bool isVisual = false)
{
Id = id;
Name = id.ToString();
Type = type;
Category = category;
IsVisual = isVisual;
}
public enum Ids
{
HallwayFixWiring = 0,
AdminEnterIDCode = 1,
MedbaySubmitScan = 2,
BalconyClearAsteroids = 3,
ElectricalDivertPowerToAdmin = 4,
ElectricalDivertPowerToCafeteria = 5,
ElectricalDivertPowerToCommunications = 6,
ElectricalDivertPowerToLaunchpad = 7,
ElectricalDivertPowerToMedbay = 8,
ElectricalDivertPowerToOffice = 9,
StorageWaterPlants = 10,
ReactorStartReactor = 11,
ElectricalDivertPowerToGreenhouse = 12,
AdminChartCourse = 13,
GreenhouseCleanO2Filter = 14,
LaunchpadFuelEngines = 15,
LaboratoryAssembleArtifact = 16,
LaboratorySortSamples = 17,
AdminPrimeShields = 18,
CafeteriaEmptyGarbage = 19,
BalconyMeasureWeather = 20,
ElectricalDivertPowerToLaboratory = 21,
CafeteriaBuyBeverage = 22,
OfficeProcessData = 23,
LaunchpadRunDiagnostics = 24,
ReactorUnlockManifolds = 25,
}
public Ids Id { get; }
int ITask.Id => (int)Id;
public string Name { get; }
public TaskTypes Type { get; }
public TaskCategories Category { get; }
public bool IsVisual { get; }
}
}
@@ -0,0 +1,63 @@
namespace Impostor.Api.Innersloth.Maps.Tasks
{
public class PolusTask : ITask
{
internal PolusTask(Ids id, TaskTypes type, TaskCategories category, bool isVisual = false)
{
Id = id;
Name = id.ToString();
Type = type;
Category = category;
IsVisual = isVisual;
}
public enum Ids
{
OfficeSwipeCard = 0,
DropshipInsertKeys = 1,
OfficeScanBoardingPass = 2,
ElectricalFixWiring = 3,
WeaponsDownloadData = 4,
OfficeDownloadData = 5,
ElectricalDownloadData = 6,
SpecimenRoomDownloadData = 7,
O2DownloadData = 8,
SpecimenRoomStartReactor = 9,
StorageFuelEngines = 10,
BoilerRoomOpenWaterways = 11,
MedbayInspectSample = 12,
BoilerRoomReplaceWaterJug = 13,
OutsideFixWeatherNodeNode_GI = 14,
OutsideFixWeatherNodeNode_IRO = 15,
OutsideFixWeatherNodeNode_PD = 16,
OutsideFixWeatherNodeNode_TB = 17,
CommunicationsRebootWiFi = 18,
O2MonitorTree = 19,
SpecimenRoomUnlockManifolds = 20,
SpecimenRoomStoreArtifacts = 21,
O2FillCanisters = 22,
O2EmptyGarbage = 23,
DropshipChartCourse = 24,
MedbaySubmitScan = 25,
WeaponsClearAsteroids = 26,
OutsideFixWeatherNodeNode_CA = 27,
OutsideFixWeatherNodeNode_MLG = 28,
LaboratoryAlignTelescope = 29,
LaboratoryRepairDrill = 30,
LaboratoryRecordTemperature = 31,
OutsideRecordTemperature = 32,
}
public Ids Id { get; }
int ITask.Id => (int)Id;
public string Name { get; }
public TaskTypes Type { get; }
public TaskCategories Category { get; }
public bool IsVisual { get; }
}
}
@@ -0,0 +1,59 @@
namespace Impostor.Api.Innersloth.Maps.Tasks
{
public class SkeldTask : ITask
{
internal SkeldTask(Ids id, TaskTypes type, TaskCategories category, bool isVisual = false)
{
Id = id;
Name = id.ToString();
Type = type;
Category = category;
IsVisual = isVisual;
}
public enum Ids
{
AdminSwipeCard = 0,
ElectricalFixWiring = 1,
WeaponsClearAsteroids = 2,
EnginesAlignEngineOutput = 3,
MedbaySubmitScan = 4,
MedbayInspectSample = 5,
StorageFuelEngines = 6,
ReactorStartReactor = 7,
O2EmptyChute = 8,
CafeteriaEmptyGarbage = 9,
CommunicationsDownloadData = 10,
ElectricalCalibrateDistributor = 11,
NavigationChartCourse = 12,
O2CleanO2Filter = 13,
ReactorUnlockManifolds = 14,
ElectricalDownloadData = 15,
NavigationStabilizeSteering = 16,
WeaponsDownloadData = 17,
ShieldsPrimeShields = 18,
CafeteriaDownloadData = 19,
NavigationDownloadData = 20,
ElectricalDivertPowerToShields = 21,
ElectricalDivertPowerToWeapons = 22,
ElectricalDivertPowerToCommunications = 23,
ElectricalDivertPowerToUpperEngine = 24,
ElectricalDivertPowerToO2 = 25,
ElectricalDivertPowerToNavigation = 26,
ElectricalDivertPowerToLowerEngine = 27,
ElectricalDivertPowerToSecurity = 28,
}
public Ids Id { get; }
int ITask.Id => (int)Id;
public string Name { get; }
public TaskTypes Type { get; }
public TaskCategories Category { get; }
public bool IsVisual { get; }
}
}
@@ -0,0 +1,61 @@
using System;
using System.Numerics;
namespace Impostor.Api.Innersloth.Maps.Vents
{
public class AirshipVent : IVent
{
private readonly Lazy<AirshipVent>? _left;
private readonly Lazy<AirshipVent>? _center;
private readonly Lazy<AirshipVent>? _right;
internal AirshipVent(AirshipData data, Ids id, Vector2 position, Ids? left = null, Ids? center = null, Ids? right = null)
{
Id = id;
Name = id.ToString();
Position = position;
_left = left == null ? null : new Lazy<AirshipVent>(() => data.Vents[left.Value]);
_center = center == null ? null : new Lazy<AirshipVent>(() => data.Vents[center.Value]);
_right = right == null ? null : new Lazy<AirshipVent>(() => data.Vents[right.Value]);
}
public enum Ids
{
Vault = 0,
Cockpit = 1,
ViewingDeck = 2,
EngineRoom = 3,
Kitchen = 4,
MainHallBottom = 5,
GapRight = 6,
GapLeft = 7,
MainHallTop = 8,
Showers = 9,
Records = 10,
CargoBay = 11,
}
public Ids Id { get; }
int IVent.Id => (int)Id;
public string Name { get; }
public Vector2 Position { get; }
public AirshipVent? Left => _left?.Value;
IVent? IVent.Left => Left;
public AirshipVent? Center => _center?.Value;
IVent? IVent.Center => Center;
public AirshipVent? Right => _right?.Value;
IVent? IVent.Right => Right;
}
}
@@ -0,0 +1,60 @@
using System;
using System.Numerics;
namespace Impostor.Api.Innersloth.Maps.Vents
{
public class MiraVent : IVent
{
private readonly Lazy<MiraVent>? _left;
private readonly Lazy<MiraVent>? _center;
private readonly Lazy<MiraVent>? _right;
internal MiraVent(MiraData data, Ids id, Vector2 position, Ids? left = null, Ids? center = null, Ids? right = null)
{
Id = id;
Name = id.ToString();
Position = position;
_left = left == null ? null : new Lazy<MiraVent>(() => data.Vents[left.Value]);
_center = center == null ? null : new Lazy<MiraVent>(() => data.Vents[center.Value]);
_right = right == null ? null : new Lazy<MiraVent>(() => data.Vents[right.Value]);
}
public enum Ids
{
Balcony = 1,
Cafeteria = 2,
Reactor = 3,
Laboratory = 4,
Office = 5,
Admin = 6,
Greenhouse = 7,
Medbay = 8,
Decontamination = 9,
LockerRoom = 10,
Launchpad = 11,
}
public Ids Id { get; }
int IVent.Id => (int)Id;
public string Name { get; }
public Vector2 Position { get; }
public MiraVent? Left => _left?.Value;
IVent? IVent.Left => Left;
public MiraVent? Center => _center?.Value;
IVent? IVent.Center => Center;
public MiraVent? Right => _right?.Value;
IVent? IVent.Right => Right;
}
}
@@ -0,0 +1,61 @@
using System;
using System.Numerics;
namespace Impostor.Api.Innersloth.Maps.Vents
{
public class PolusVent : IVent
{
private readonly Lazy<PolusVent>? _left;
private readonly Lazy<PolusVent>? _center;
private readonly Lazy<PolusVent>? _right;
internal PolusVent(PolusData data, Ids id, Vector2 position, Ids? left = null, Ids? center = null, Ids? right = null)
{
Id = id;
Name = id.ToString();
Position = position;
_left = left == null ? null : new Lazy<PolusVent>(() => data.Vents[left.Value]);
_center = center == null ? null : new Lazy<PolusVent>(() => data.Vents[center.Value]);
_right = right == null ? null : new Lazy<PolusVent>(() => data.Vents[right.Value]);
}
public enum Ids
{
Security = 0,
Electrical = 1,
O2 = 2,
Communications = 3,
Office = 4,
Admin = 5,
Laboratory = 6,
Lava = 7,
Storage = 8,
RightStabilizer = 9,
LeftStabilizer = 10,
OutsideAdmin = 11,
}
public Ids Id { get; }
int IVent.Id => (int)Id;
public string Name { get; }
public Vector2 Position { get; }
public PolusVent? Left => _left?.Value;
IVent? IVent.Left => Left;
public PolusVent? Center => _center?.Value;
IVent? IVent.Center => Center;
public PolusVent? Right => _right?.Value;
IVent? IVent.Right => Right;
}
}
@@ -0,0 +1,63 @@
using System;
using System.Numerics;
namespace Impostor.Api.Innersloth.Maps.Vents
{
public class SkeldVent : IVent
{
private readonly Lazy<SkeldVent>? _left;
private readonly Lazy<SkeldVent>? _center;
private readonly Lazy<SkeldVent>? _right;
internal SkeldVent(SkeldData data, Ids id, Vector2 position, Ids? left = null, Ids? center = null, Ids? right = null)
{
Id = id;
Name = id.ToString();
Position = position;
_left = left == null ? null : new Lazy<SkeldVent>(() => data.Vents[left.Value]);
_center = center == null ? null : new Lazy<SkeldVent>(() => data.Vents[center.Value]);
_right = right == null ? null : new Lazy<SkeldVent>(() => data.Vents[right.Value]);
}
public enum Ids
{
Admin = 0,
RightHallway = 1,
Cafeteria = 2,
Electrical = 3,
UpperEngine = 4,
Security = 5,
Medbay = 6,
Weapons = 7,
LowerReactor = 8,
LowerEngine = 9,
Shields = 10,
UpperReactor = 11,
UpperNavigation = 12,
LowerNavigation = 13,
}
public Ids Id { get; }
int IVent.Id => (int)Id;
public string Name { get; }
public Vector2 Position { get; }
public SkeldVent? Left => _left?.Value;
IVent? IVent.Left => Left;
public SkeldVent? Center => _center?.Value;
IVent? IVent.Center => Center;
public SkeldVent? Right => _right?.Value;
IVent? IVent.Right => Right;
}
}
+15
View File
@@ -0,0 +1,15 @@
namespace Impostor.Api.Innersloth
{
public enum Platforms
{
Unknown = 0,
StandaloneEpicPC = 1,
StandaloneSteamPC = 2,
StandaloneMac = 3,
StandaloneWin10 = 4,
StandaloneItch = 5,
IPhone = 6,
Android = 7,
Switch = 8,
}
}
@@ -0,0 +1,8 @@
namespace Impostor.Api.Innersloth
{
public enum QuickChatModes
{
FreeChatOrQuickChat = 1,
QuickChatOnly = 2,
}
}
+16 -14
View File
@@ -13,22 +13,11 @@ namespace Impostor.Api.Innersloth
}
public string Name { get; }
public string Ping { get; }
public IReadOnlyList<ServerInfo> Servers { get; }
public void Serialize(BinaryWriter writer)
{
writer.Write(0);
writer.Write(Name);
writer.Write(Ping);
writer.Write(Servers.Count);
foreach (var server in Servers)
{
server.Serialize(writer);
}
}
public static RegionInfo Deserialize(BinaryReader reader)
{
var unknown = reader.ReadInt32();
@@ -44,5 +33,18 @@ namespace Impostor.Api.Innersloth
return new RegionInfo(name, ping, servers);
}
public void Serialize(BinaryWriter writer)
{
writer.Write(0);
writer.Write(Name);
writer.Write(Ping);
writer.Write(Servers.Count);
foreach (var server in Servers)
{
server.Serialize(writer);
}
}
}
}
}
+16 -14
View File
@@ -5,24 +5,18 @@ namespace Impostor.Api.Innersloth
{
public class ServerInfo
{
public string Name { get; }
public string Ip { get; }
public ushort Port { get; }
public ServerInfo(string name, string ip, ushort port)
{
Name = name;
Ip = ip;
Port = port;
}
public void Serialize(BinaryWriter writer)
{
writer.Write(Name);
writer.Write(IPAddress.Parse(Ip).GetAddressBytes());
writer.Write(Port);
writer.Write(0);
}
public string Name { get; }
public string Ip { get; }
public ushort Port { get; }
public static ServerInfo Deserialize(BinaryReader reader)
{
@@ -30,8 +24,16 @@ namespace Impostor.Api.Innersloth
var ip = new IPAddress(reader.ReadBytes(4)).ToString();
var port = reader.ReadUInt16();
var unknown = reader.ReadInt32();
return new ServerInfo(name, ip, port);
}
public void Serialize(BinaryWriter writer)
{
writer.Write(Name);
writer.Write(IPAddress.Parse(Ip).GetAddressBytes());
writer.Write(Port);
writer.Write(0);
}
}
}
}
Loaded 100 of 420 files, more files were not shown because too many files have changed in this diff. Show more