mirror of
https://github.com/Impostor/Impostor.git
synced 2026-10-20 11:39:41 +00:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e857ed555 | ||
|
|
9d31752bf0 |
No files matched your search
@@ -3,7 +3,7 @@
|
|||||||
"isRoot": true,
|
"isRoot": true,
|
||||||
"tools": {
|
"tools": {
|
||||||
"cake.tool": {
|
"cake.tool": {
|
||||||
"version": "2.2.0",
|
"version": "1.1.0",
|
||||||
"commands": [
|
"commands": [
|
||||||
"dotnet-cake"
|
"dotnet-cake"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,53 +0,0 @@
|
|||||||
name: CI
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- '.github/workflows/ci.yml'
|
|
||||||
- 'src/**/**'
|
|
||||||
- 'build.cake'
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- '.github/workflows/ci.yml'
|
|
||||||
- 'src/**/**'
|
|
||||||
- 'build.cake'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: ~/.nuget/packages
|
|
||||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-nuget-
|
|
||||||
|
|
||||||
- name: Setup .NET
|
|
||||||
uses: actions/setup-dotnet@v2
|
|
||||||
with:
|
|
||||||
dotnet-version: 8.x
|
|
||||||
|
|
||||||
- name: Run the Cake script
|
|
||||||
uses: cake-build/cake-action@v1
|
|
||||||
with:
|
|
||||||
verbosity: Diagnostic
|
|
||||||
|
|
||||||
- uses: softprops/action-gh-release@v1
|
|
||||||
if: github.ref_type == 'tag'
|
|
||||||
with:
|
|
||||||
draft: true
|
|
||||||
files: |
|
|
||||||
./build/*.zip
|
|
||||||
./build/*.tar.gz
|
|
||||||
./build/*.nupkg
|
|
||||||
./build/*.snupkg
|
|
||||||
|
|
||||||
- name: Push NuGet package
|
|
||||||
if: github.ref_type == 'tag'
|
|
||||||
run: |
|
|
||||||
dotnet nuget push ./build/*.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_IMPOSTOR }}
|
|
||||||
@@ -6,6 +6,7 @@ on:
|
|||||||
paths:
|
paths:
|
||||||
- 'src/Impostor.Server/**'
|
- 'src/Impostor.Server/**'
|
||||||
- 'src/Impostor.Shared/**'
|
- 'src/Impostor.Shared/**'
|
||||||
|
- '.gitmodules'
|
||||||
- '.github/workflows/docker.yml'
|
- '.github/workflows/docker.yml'
|
||||||
- 'Dockerfile'
|
- 'Dockerfile'
|
||||||
tags:
|
tags:
|
||||||
@@ -14,6 +15,7 @@ on:
|
|||||||
paths:
|
paths:
|
||||||
- 'src/Impostor.Server/**'
|
- 'src/Impostor.Server/**'
|
||||||
- 'src/Impostor.Shared/**'
|
- 'src/Impostor.Shared/**'
|
||||||
|
- '.gitmodules'
|
||||||
- '.github/workflows/docker.yml'
|
- '.github/workflows/docker.yml'
|
||||||
- 'Dockerfile'
|
- 'Dockerfile'
|
||||||
|
|
||||||
@@ -23,7 +25,9 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
- name: Prepare
|
- name: Prepare
|
||||||
id: prep
|
id: prep
|
||||||
run: |
|
run: |
|
||||||
@@ -44,14 +48,14 @@ jobs:
|
|||||||
if [[ $VERSION =~ ^v[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
|
if [[ $VERSION =~ ^v[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
|
||||||
TAGS="$TAGS,${DOCKER_IMAGE}:latest"
|
TAGS="$TAGS,${DOCKER_IMAGE}:latest"
|
||||||
fi
|
fi
|
||||||
echo version=${VERSION} >> $GITHUB_OUTPUT
|
echo ::set-output name=version::${VERSION}
|
||||||
echo tags=${TAGS} >> $GITHUB_OUTPUT
|
echo ::set-output name=tags::${TAGS}
|
||||||
echo versionsuffix=${VERSIONSUFFIX} >> $GITHUB_OUTPUT
|
echo ::set-output name=versionsuffix::${VERSIONSUFFIX}
|
||||||
echo created=$(date -u +'%Y-%m-%dT%H:%M:%SZ') >> $GITHUB_OUTPUT
|
echo ::set-output name=created::$(date -u +'%Y-%m-%dT%H:%M:%SZ')
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v3
|
uses: docker/setup-qemu-action@v1
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v1
|
||||||
- name: Login to DockerHub
|
- name: Login to DockerHub
|
||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
uses: docker/login-action@v1
|
uses: docker/login-action@v1
|
||||||
@@ -59,7 +63,7 @@ jobs:
|
|||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
- name: Build and push
|
- name: Build and push
|
||||||
uses: docker/build-push-action@v5
|
uses: docker/build-push-action@v2
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./Dockerfile
|
file: ./Dockerfile
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "src/Impostor.Hazel"]
|
||||||
|
path = src/Impostor.Hazel
|
||||||
|
url = https://github.com/Impostor/Impostor.Hazel
|
||||||
+3
-3
@@ -9,14 +9,14 @@ We are always looking for people to help improve Impostor.
|
|||||||
- Don't commit unnecessary changes to the codebase or debugging code.
|
- Don't commit unnecessary changes to the codebase or debugging code.
|
||||||
- Write meaningful commits or squash them.
|
- Write meaningful commits or squash them.
|
||||||
- Please try to follow the code style of the rest of the codebase. An `.editorconfig` file has been provided to keep consistency.
|
- Please try to follow the code style of the rest of the codebase. An `.editorconfig` file has been provided to keep consistency.
|
||||||
- Stylecop is also enabled: please make sure your PR compiles without warnings.
|
|
||||||
|
|
||||||
## Pull requests
|
## Pull requests
|
||||||
|
|
||||||
- Only make pull requests to the `dev` branch.
|
- Only make pull requests to the `dev` branch.
|
||||||
- Only implement one feature per pull request to keep it easy to understand.
|
- Only implement one feature per pull request to keep it easy to understand.
|
||||||
- Expect comments or questions on your pull request from the project maintainers. We try to keep the code as consistent and maintainable as possible.
|
- Expect comments or questions on your pull request from the project maintainers. We try to keep the code as consistent and maintainable as possible.
|
||||||
- Each pull request should come from a new branch in your fork, it should have a meaningful name.
|
- Each pull request should come from a new branch in your fork, it should have a meaningful name.
|
||||||
- We try to respond to pull requests as fast as possible. If you think we might have missed it, let us know on [Discord](https://discord.gg/Mk3w6Tb).
|
- We try to respond to pull requests as fast as possible. If you think we might have missed it, let us know on [Discord](https://discord.gg/Mk3w6Tb).
|
||||||
|
|
||||||
If you have any questions, let us know.
|
|
||||||
|
If you have any questions, let us know.
|
||||||
+8
-13
@@ -1,4 +1,4 @@
|
|||||||
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build
|
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:5.0 AS build
|
||||||
|
|
||||||
# See for all possible platforms
|
# See for all possible platforms
|
||||||
# https://github.com/containerd/containerd/blob/master/platforms/platforms.go#L17
|
# https://github.com/containerd/containerd/blob/master/platforms/platforms.go#L17
|
||||||
@@ -10,9 +10,8 @@ WORKDIR /source
|
|||||||
|
|
||||||
# Copy csproj and restore.
|
# Copy csproj and restore.
|
||||||
COPY src/Impostor.Server/Impostor.Server.csproj ./src/Impostor.Server/Impostor.Server.csproj
|
COPY src/Impostor.Server/Impostor.Server.csproj ./src/Impostor.Server/Impostor.Server.csproj
|
||||||
COPY src/Impostor.Api.Innersloth.Generator/Impostor.Api.Innersloth.Generator.csproj ./src/Impostor.Api.Innersloth.Generator/Impostor.Api.Innersloth.Generator.csproj
|
|
||||||
COPY src/Impostor.Api/Impostor.Api.csproj ./src/Impostor.Api/Impostor.Api.csproj
|
COPY src/Impostor.Api/Impostor.Api.csproj ./src/Impostor.Api/Impostor.Api.csproj
|
||||||
COPY src/Directory.Build.props ./src/Directory.Build.props
|
COPY src/Impostor.Hazel/Hazel/Hazel.csproj ./src/Impostor.Hazel/Hazel/Hazel.csproj
|
||||||
|
|
||||||
RUN case "$TARGETARCH" in \
|
RUN case "$TARGETARCH" in \
|
||||||
amd64) NETCORE_PLATFORM='linux-x64';; \
|
amd64) NETCORE_PLATFORM='linux-x64';; \
|
||||||
@@ -21,8 +20,8 @@ RUN case "$TARGETARCH" in \
|
|||||||
*) echo "unsupported architecture"; exit 1 ;; \
|
*) echo "unsupported architecture"; exit 1 ;; \
|
||||||
esac && \
|
esac && \
|
||||||
dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Server/Impostor.Server.csproj && \
|
dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Server/Impostor.Server.csproj && \
|
||||||
dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Api.Innersloth.Generator/Impostor.Api.Innersloth.Generator.csproj && \
|
dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Api/Impostor.Api.csproj && \
|
||||||
dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Api/Impostor.Api.csproj
|
dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Hazel/Hazel/Hazel.csproj
|
||||||
|
|
||||||
# Copy everything else.
|
# Copy everything else.
|
||||||
COPY src/. ./src/
|
COPY src/. ./src/
|
||||||
@@ -32,16 +31,12 @@ RUN case "$TARGETARCH" in \
|
|||||||
arm) NETCORE_PLATFORM='linux-arm';; \
|
arm) NETCORE_PLATFORM='linux-arm';; \
|
||||||
*) echo "unsupported architecture"; exit 1 ;; \
|
*) echo "unsupported architecture"; exit 1 ;; \
|
||||||
esac && \
|
esac && \
|
||||||
[ $VERSIONSUFFIX = "none" ] && VERSIONSUFFIX=; \
|
[[ $VERSIONSUFFIX = "none" ]] && VERSIONSUFFIX=; \
|
||||||
dotnet publish -c release -o /app -r "$NETCORE_PLATFORM" -p:VersionSuffix="$VERSIONSUFFIX" --no-restore ./src/Impostor.Server/Impostor.Server.csproj
|
dotnet publish -c release -o /app -r "$NETCORE_PLATFORM" -p:VersionSuffix="$VERSIONSUFFIX" --no-restore ./src/Impostor.Server/Impostor.Server.csproj
|
||||||
|
|
||||||
# Final image.
|
# Final image.
|
||||||
FROM --platform=$TARGETPLATFORM mcr.microsoft.com/dotnet/aspnet:8.0
|
FROM --platform=$TARGETPLATFORM mcr.microsoft.com/dotnet/runtime:5.0
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=build /app ./
|
COPY --from=build /app ./
|
||||||
|
EXPOSE 22023/udp
|
||||||
# Override ASPNETCORE_URLS to stop warning.
|
ENTRYPOINT ["./Impostor.Server"]
|
||||||
ENV ASPNETCORE_URLS=
|
|
||||||
|
|
||||||
EXPOSE 22023/tcp 22023/udp
|
|
||||||
ENTRYPOINT ["./Impostor.Server"]
|
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
# Impostor
|
# Impostor
|
||||||
|
|
||||||
[](https://discord.gg/Mk3w6Tb)
|
[](https://discord.gg/Mk3w6Tb)
|
||||||
[](https://github.com/Impostor/Impostor/actions)
|
[](https://ci.appveyor.com/project/Impostor/Impostor/branch/master)
|
||||||
|
|
||||||
Impostor is the first working **Among Us** private server, written in C#.
|
Impostor is one of the first **Among Us** private servers, written in C#.
|
||||||
|
|
||||||
As Among Us is actively updated, you may want to use the latest build from the master branch if you want to play on the latest version of Among Us that supported by Impostor.
|
| Impostor version | Among Us version | Experimental | Download |
|
||||||
|
|-|-|-|-|
|
||||||
If you want to play on an older version of Among Us, you can download old releases from [here](https://github.com/Impostor/Impostor/releases/), however these versions are less supported.
|
| 1.1.0 | 2020.09.07 - 2020.09.22 | No | [](https://github.com/Impostor/Impostor/releases/tag/v1.1.0) |
|
||||||
|
| 1.2.2 | 2020.09.22 - 2020.11.17 | No | [](https://github.com/Impostor/Impostor/releases/tag/v1.2.2) |
|
||||||
|
| 1.3.0 | 2021.3.5 | No | [](https://github.com/Impostor/Impostor/releases/tag/v1.3.0) |
|
||||||
|
| 1.4.0 | 2021.3.31 - 2021.4.2 | Yes | [](https://ci.appveyor.com/project/Impostor/Impostor/branch/master/artifacts) |
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@@ -19,7 +22,34 @@ If you want to play on an older version of Among Us, you can download old releas
|
|||||||
|
|
||||||
### Client
|
### Client
|
||||||
|
|
||||||
If you just want to play on a server hosted by someone else, you need to configure your client to connect to an Impostor server. Please go to [this website](https://impostor.github.io/Impostor) to set up your client by following the instructions for your OS there.
|
If you just want to play on a server hosted by someone else, you need to follow these instructions.
|
||||||
|
|
||||||
|
#### Windows
|
||||||
|
|
||||||
|
1. Find the [latest release](https://github.com/AeonLucid/Impostor/releases/latest).
|
||||||
|
2. Download `Impostor-Patcher-win-x64.zip`.
|
||||||
|
3. Extract the zip.
|
||||||
|
4. Run `Impostor.Patcher.exe`.
|
||||||
|
5. Follow the instructions inside the application.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
If you do not wish to execute any programs. Follow the instructions in [this website](https://impostor.github.io/Impostor)
|
||||||
|
|
||||||
|
#### Android
|
||||||
|
|
||||||
|
##### Android 10 and below.
|
||||||
|
1. Go to [this website](https://impostor.github.io/Impostor) **(ON YOUR MOBILE DEVICE)**
|
||||||
|
2. Follow the instructions listed there.
|
||||||
|
|
||||||
|
##### Android 11.
|
||||||
|
1. Connect your phone to a computer. Go to [this website](https://impostor.github.io/Impostor) on the computer and follow the steps 1 and 2 to generate a `regionInfo.dat` file.
|
||||||
|
2. Instead of following the next steps, open the phone's internal storage on your computer and navigate to `/sdcard/Android/data/com.innersloth.spacemafia/files`.
|
||||||
|
3. Copy the generated `regionInfo.dat` file into the `files` folder you just navigated to.
|
||||||
|
|
||||||
|
#### iOS
|
||||||
|
|
||||||
|
iOS devices need to be jailbroken in order to connect to Impostor servers.
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
|
|
||||||
@@ -27,7 +57,7 @@ See the [docs](docs/Running-the-server.md) for instructions on how to set it up.
|
|||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
See [TROUBLESHOOTING](docs/TROUBLESHOOTING.md) to solve issues with the Impostor client or the server.
|
See [TROUBLESHOOTING](docs/TROUBLESHOOTING.md) to solve issues the Impostor client or the server.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
version: '{build}'
|
||||||
|
|
||||||
|
environment:
|
||||||
|
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||||
|
|
||||||
|
branches:
|
||||||
|
except:
|
||||||
|
- gh-pages
|
||||||
|
|
||||||
|
pull_requests:
|
||||||
|
do_not_increment_build_number: true
|
||||||
|
|
||||||
|
assembly_info:
|
||||||
|
patch: false
|
||||||
|
|
||||||
|
dotnet_csproj:
|
||||||
|
patch: false
|
||||||
|
|
||||||
|
image: Ubuntu2004
|
||||||
|
|
||||||
|
install:
|
||||||
|
- git submodule update --init --recursive
|
||||||
|
- ps: dotnet tool restore
|
||||||
|
|
||||||
|
build_script:
|
||||||
|
- ps: dotnet cake build.cake --bootstrap
|
||||||
|
- ps: dotnet cake build.cake --pack
|
||||||
|
|
||||||
|
test: off
|
||||||
|
|
||||||
|
artifacts:
|
||||||
|
- path: ./build/*.zip
|
||||||
|
- path: ./build/*.tar.gz
|
||||||
|
- path: ./build/*.nupkg
|
||||||
|
- path: ./build/*.snupkg
|
||||||
|
|
||||||
|
# deploy:
|
||||||
|
# - provider: NuGet
|
||||||
|
# artifact: /.*(\.|\.s)nupkg/
|
||||||
|
# on:
|
||||||
|
# branch: dev
|
||||||
|
# api_key:
|
||||||
|
# secure: 4OHXl+m1KVi60hB1j54MpdP8tVv0UNfkdF4rVP+2AhAjN4a2MVT+Bl90gJZ96xHF
|
||||||
|
|
||||||
|
only_commits:
|
||||||
|
files:
|
||||||
|
- appveyor.yml
|
||||||
|
- build.cake
|
||||||
|
- src/**/*
|
||||||
|
- .gitmodules
|
||||||
+35
-39
@@ -1,33 +1,25 @@
|
|||||||
#addin "nuget:?package=SharpZipLib&Version=1.3.3"
|
#addin "nuget:?package=SharpZipLib&Version=1.3.1"
|
||||||
#addin "nuget:?package=Cake.Compression&Version=0.3.0"
|
#addin "nuget:?package=Cake.Compression&Version=0.2.6"
|
||||||
#addin "nuget:?package=Cake.FileHelpers&Version=5.0.0"
|
#addin "nuget:?package=Cake.FileHelpers&Version=4.0.1"
|
||||||
|
|
||||||
var workflow = BuildSystem.GitHubActions.Environment.Workflow;
|
|
||||||
var buildId = workflow.RunNumber;
|
|
||||||
var tag = workflow.RefType == GitHubActionsRefType.Tag ? workflow.RefName : null;
|
|
||||||
|
|
||||||
|
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 buildVersion = FindRegexMatchGroupInFile("./src/Directory.Build.props", @"\<VersionPrefix\>(.*?)\<\/VersionPrefix\>", 1, System.Text.RegularExpressions.RegexOptions.None).Value;
|
||||||
var buildDir = MakeAbsolute(Directory("./build"));
|
var buildDir = MakeAbsolute(Directory("./build"));
|
||||||
|
|
||||||
var target = Argument("target", "Test");
|
var target = Argument("target", "Deploy");
|
||||||
var configuration = Argument("configuration", "Release");
|
var configuration = Argument("configuration", "Release");
|
||||||
|
|
||||||
var msbuildSettings = new DotNetMSBuildSettings();
|
var msbuildSettings = new DotNetCoreMSBuildSettings();
|
||||||
|
|
||||||
if (tag != null)
|
if (buildRelease)
|
||||||
{
|
{
|
||||||
if (tag[1..] != buildVersion) throw new Exception("Tag version has to be the same as VersionPrefix in Directory.Build.props");
|
msbuildSettings.Properties["Version"] = new[] { buildVersion };
|
||||||
msbuildSettings.Version = buildVersion;
|
|
||||||
}
|
}
|
||||||
else if (buildId != 0)
|
else if (buildId != null)
|
||||||
{
|
{
|
||||||
buildId += 500;
|
msbuildSettings.Properties["VersionSuffix"] = new[] { "ci." + buildId };
|
||||||
msbuildSettings.VersionSuffix = "ci." + buildId;
|
|
||||||
buildVersion += "-ci." + buildId;
|
buildVersion += "-ci." + buildId;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
buildVersion += "-dev";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@@ -39,9 +31,10 @@ private void ImpostorPublish(string name, string project, string runtime, bool i
|
|||||||
var projBuildDir = buildDir.Combine(name + "_" + runtime);
|
var projBuildDir = buildDir.Combine(name + "_" + runtime);
|
||||||
var projBuildName = name + "_" + buildVersion + "_" + runtime;
|
var projBuildName = name + "_" + buildVersion + "_" + runtime;
|
||||||
|
|
||||||
DotNetPublish(project, new DotNetPublishSettings {
|
DotNetCorePublish(project, new DotNetCorePublishSettings {
|
||||||
Configuration = configuration,
|
Configuration = configuration,
|
||||||
NoRestore = true,
|
NoRestore = true,
|
||||||
|
Framework = "net5.0",
|
||||||
Runtime = runtime,
|
Runtime = runtime,
|
||||||
SelfContained = false,
|
SelfContained = false,
|
||||||
PublishSingleFile = true,
|
PublishSingleFile = true,
|
||||||
@@ -64,10 +57,6 @@ private void ImpostorPublish(string name, string project, string runtime, bool i
|
|||||||
} else {
|
} else {
|
||||||
GZipCompress(projBuildDir, buildDir.CombineWithFilePath(projBuildName + ".tar.gz"));
|
GZipCompress(projBuildDir, buildDir.CombineWithFilePath(projBuildName + ".tar.gz"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BuildSystem.GitHubActions.IsRunningOnGitHubActions) {
|
|
||||||
BuildSystem.GitHubActions.Commands.UploadArtifact(projBuildDir, projBuildName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ImpostorPublishNF(string name, string project) {
|
private void ImpostorPublishNF(string name, string project) {
|
||||||
@@ -75,7 +64,7 @@ private void ImpostorPublishNF(string name, string project) {
|
|||||||
var projBuildDir = buildDir.Combine(name + "_" + runtime);
|
var projBuildDir = buildDir.Combine(name + "_" + runtime);
|
||||||
var projBuildZip = buildDir.CombineWithFilePath(name + "_" + buildVersion + "_" + runtime + ".zip");
|
var projBuildZip = buildDir.CombineWithFilePath(name + "_" + buildVersion + "_" + runtime + ".zip");
|
||||||
|
|
||||||
DotNetPublish(project, new DotNetPublishSettings {
|
DotNetCorePublish(project, new DotNetCorePublishSettings {
|
||||||
Configuration = configuration,
|
Configuration = configuration,
|
||||||
NoRestore = true,
|
NoRestore = true,
|
||||||
Framework = "net472",
|
Framework = "net472",
|
||||||
@@ -101,17 +90,18 @@ Task("Clean")
|
|||||||
|
|
||||||
Task("Restore")
|
Task("Restore")
|
||||||
.Does(() => {
|
.Does(() => {
|
||||||
DotNetRestore("./src/Impostor.sln");
|
DotNetCoreRestore("./src/Impostor.sln");
|
||||||
});
|
});
|
||||||
|
|
||||||
Task("Replay")
|
Task("Replay")
|
||||||
.Does(() => {
|
.Does(() => {
|
||||||
// D:\Projects\GitHub\Impostor\Impostor\src\Impostor.Tools.ServerReplay\sessions
|
// D:\Projects\GitHub\Impostor\Impostor\src\Impostor.Tools.ServerReplay\sessions
|
||||||
DotNetRun(
|
DotNetCoreRun(
|
||||||
"./src/Impostor.Tools.ServerReplay/Impostor.Tools.ServerReplay.csproj",
|
"./src/Impostor.Tools.ServerReplay/Impostor.Tools.ServerReplay.csproj",
|
||||||
"./src/Impostor.Tools.ServerReplay/sessions", new DotNetRunSettings {
|
"./src/Impostor.Tools.ServerReplay/sessions", new DotNetCoreRunSettings {
|
||||||
Configuration = configuration,
|
Configuration = configuration,
|
||||||
NoRestore = true,
|
NoRestore = true,
|
||||||
|
Framework = "net5.0"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -121,9 +111,16 @@ Task("Build")
|
|||||||
.IsDependentOn("Replay")
|
.IsDependentOn("Replay")
|
||||||
.Does(() => {
|
.Does(() => {
|
||||||
// Tests.
|
// Tests.
|
||||||
DotNetBuild("./src/Impostor.Tests/Impostor.Tests.csproj", new DotNetBuildSettings {
|
DotNetCoreBuild("./src/Impostor.Tests/Impostor.Tests.csproj", new DotNetCoreBuildSettings {
|
||||||
Configuration = configuration,
|
Configuration = configuration,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 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");
|
||||||
|
|
||||||
// Server.
|
// Server.
|
||||||
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "win-x64", true);
|
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "win-x64", true);
|
||||||
@@ -133,33 +130,32 @@ Task("Build")
|
|||||||
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "linux-arm64", true);
|
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "linux-arm64", true);
|
||||||
|
|
||||||
// API.
|
// API.
|
||||||
DotNetPack("./src/Impostor.Api/Impostor.Api.csproj", new DotNetPackSettings {
|
DotNetCorePack("./src/Impostor.Api/Impostor.Api.csproj", new DotNetCorePackSettings {
|
||||||
Configuration = configuration,
|
Configuration = configuration,
|
||||||
OutputDirectory = buildDir,
|
OutputDirectory = buildDir,
|
||||||
IncludeSource = true,
|
IncludeSource = true,
|
||||||
IncludeSymbols = true,
|
IncludeSymbols = true,
|
||||||
MSBuildSettings = msbuildSettings
|
MSBuildSettings = msbuildSettings
|
||||||
});
|
});
|
||||||
|
|
||||||
if (BuildSystem.GitHubActions.IsRunningOnGitHubActions) {
|
|
||||||
foreach (var file in GetFiles(buildDir + "/*.{nupkg,snupkg}"))
|
|
||||||
{
|
|
||||||
BuildSystem.GitHubActions.Commands.UploadArtifact(file, "Impostor.Api");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Task("Test")
|
Task("Test")
|
||||||
.IsDependentOn("Build")
|
.IsDependentOn("Build")
|
||||||
.Does(() => {
|
.Does(() => {
|
||||||
DotNetTest("./src/Impostor.Tests/Impostor.Tests.csproj", new DotNetTestSettings {
|
DotNetCoreTest("./src/Impostor.Tests/Impostor.Tests.csproj", new DotNetCoreTestSettings {
|
||||||
Configuration = configuration,
|
Configuration = configuration,
|
||||||
NoBuild = true
|
NoBuild = true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Task("Deploy")
|
||||||
|
.IsDependentOn("Test")
|
||||||
|
.Does(() => {
|
||||||
|
Information("Finished.");
|
||||||
|
});
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// EXECUTION
|
// EXECUTION
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
RunTarget(target);
|
RunTarget(target);
|
||||||
@@ -1,20 +1,19 @@
|
|||||||
# Building from source
|
# Building from source
|
||||||
|
|
||||||
The solution contains the Impostor server and its dependencies, like Hazel and the plugin API. The server is built using [.NET 8](https://dotnet.microsoft.com/download/dotnet/8.0).
|
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
|
## Cloning Impostor
|
||||||
|
|
||||||
You need to clone Impostor using git:
|
You need to clone Impostor using git.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/Impostor/Impostor.git
|
git clone https://github.com/AeonLucid/Impostor.git
|
||||||
```
|
```
|
||||||
|
|
||||||
## Building the server
|
## Building the server
|
||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
- [.NET 5 SDK](https://dotnet.microsoft.com/download/dotnet/5.0)
|
||||||
- [.NET 8 SDK](https://dotnet.microsoft.com/download/dotnet/8.0)
|
|
||||||
- [Rider](https://www.jetbrains.com/rider/) or [Visual Studio](https://visualstudio.microsoft.com/vs/) (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
|
### Build using the CLI
|
||||||
@@ -22,8 +21,16 @@ git clone https://github.com/Impostor/Impostor.git
|
|||||||
```bash
|
```bash
|
||||||
cd src/Impostor.Server/
|
cd src/Impostor.Server/
|
||||||
dotnet build
|
dotnet build
|
||||||
# Or if you want a single file, ready for production: (change linux-x64 to win-x64 if you use Windows)
|
|
||||||
dotnet publish -c Release -r linux-x64 -p:PublishSingleFile=true
|
|
||||||
```
|
```
|
||||||
|
|
||||||
To setup the server, please look at [Running the server](Running-the-server.md).
|
To setup the server, please look at [Running the server](Running-the-server.md).
|
||||||
|
|
||||||
|
## 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) or [Mono](https://www.mono-project.com/download/)
|
||||||
|
|
||||||
|
### Build using the CLI
|
||||||
|
```bash
|
||||||
|
cd src/Impostor.Patcher/Impostor.Patcher.WinForms
|
||||||
|
dotnet build
|
||||||
|
```
|
||||||
+3
-15
@@ -1,23 +1,11 @@
|
|||||||
# Frequently Answered Questions
|
# Frequently Answered Questions
|
||||||
|
|
||||||
## What is this?
|
## What is this?
|
||||||
|
The Impostor project is a reverse engineered and open sourced server for the game Among Us. The game itself is developed by [InnerSloth](http://www.innersloth.com/) while this project is maintained by the community. This project was built out of frustration for the lack of server availability in certain regions and the inability for the core developer, [AeonLucid](https://github.com/AeonLucid), to join a public game. As of this time, it has not been officially endorsed by the studio.
|
||||||
The Impostor project is a reverse engineered and open source server for the game Among Us. The game itself is developed by [Innersloth](http://www.innersloth.com/) while this project is maintained by the community. This project was built out of frustration for the lack of server availability in certain regions and the inability for the core developer, [AeonLucid](https://github.com/AeonLucid), to join a public game. As of this time, it has not been officially endorsed by the studio.
|
|
||||||
|
|
||||||
## Can this be used with the mobile version of the game?
|
## Can this be used with the mobile version of the game?
|
||||||
|
Yes, Impostor can be used with both the Android and iOS\* versions of the game.
|
||||||
Yes, Impostor can be used with both the Android and iOS versions of the game. You can add a custom server via a link, you can do this using the [site](https://impostor.github.io/Impostor)
|
###### \* In order to play on an Impostor server with iOS, you _must_ have a jailbroken device.
|
||||||
|
|
||||||
## Can this be used with the console version of the game?
|
|
||||||
|
|
||||||
Sadly not, as these don't allow adding custom servers.
|
|
||||||
|
|
||||||
## Can this be used with Among Us 3D/VR?
|
|
||||||
|
|
||||||
No, it's an entirely different game with a completely different network stack. So we'd need to develop another server completely from scratch. We're currently not interested in doing this.
|
|
||||||
|
|
||||||
## How can I get started?
|
## How can I get started?
|
||||||
|
|
||||||
See [Setting up your Server](Running-the-server.md) for more information on running the server and [Client Setup](https://impostor.github.io/Impostor/) for helping your friends join in!
|
See [Setting up your Server](Running-the-server.md) for more information on running the server and [Client Setup](https://impostor.github.io/Impostor/) for helping your friends join in!
|
||||||
|
|
||||||
If you're having issues with the server software, check the [Troubleshooting page](TROUBLESHOOTING.md).
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
# HTTP Server
|
|
||||||
|
|
||||||
Since Impostor 1.9.0 a HTTP service is included for matchmaking, which is required for clients to connect to the Impostor server.
|
|
||||||
|
|
||||||
Starting from Among Us 16.0.5, you need to set up HTTPS for players to connect to your server.
|
|
||||||
Unfortunately Impostor doesn't handle SSL certificates, so you need to set up a reverse proxy.
|
|
||||||
|
|
||||||
## Use a reverse proxy
|
|
||||||
|
|
||||||
A reverse proxy allows you to forward HTTP requests from users to multiple services. If you already have one, you should configure it to add Impostor.
|
|
||||||
|
|
||||||
If you have never set up a reverse proxy before, we recommend you to set up [Caddy](https://caddyserver.com/). It is easy to set up and comes with support for requesting SSL certificates out of the box.
|
|
||||||
|
|
||||||
To prevent people from connecting directly to Impostor, we recommend changing the "ListenIp" in the "HttpServer" section to "127.0.0.1". This makes sure people can't connect to your HTTP server other than via your reverse proxy. Keep the "ListenIp" in the "Server" section at "0.0.0.0" though, running the normal game traffic through a proxy is not supported.
|
|
||||||
|
|
||||||
### Caddy
|
|
||||||
|
|
||||||
To install Caddy, follow the [official installation guide](https://caddyserver.com/docs/install). Then use the following lines as your `Caddyfile` configuration file:
|
|
||||||
|
|
||||||
```
|
|
||||||
example.com # replace example.com with your domain name
|
|
||||||
|
|
||||||
reverse_proxy :22023
|
|
||||||
```
|
|
||||||
|
|
||||||
Now run `caddy run` in the folder with this Caddyfile and it should set up a server for you with a free SSL certificate.
|
|
||||||
If this works, you should set up [Caddy to run in the background](https://caddyserver.com/docs/running)
|
|
||||||
|
|
||||||
### Nginx
|
|
||||||
|
|
||||||
Nginx is an alternative to Caddy that is a bit harder to set up. If you already use Nginx, you can use our snippet to add Impostor:
|
|
||||||
|
|
||||||
<details><summary>Nginx configuration</summary>
|
|
||||||
|
|
||||||
```nginx
|
|
||||||
server {
|
|
||||||
listen 443 ssl http2;
|
|
||||||
server_name example.com; # replace example.com with your domain name
|
|
||||||
|
|
||||||
# Assuming you're using Certbot, replace example.com with your domain name
|
|
||||||
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
|
|
||||||
ssl_trusted_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://localhost:22023; # Change the port to your HttpServer's ListenPort
|
|
||||||
proxy_set_header X-Forwarded-For $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Redirect all traffic to HTTPS
|
|
||||||
server {
|
|
||||||
listen 80 default_server;
|
|
||||||
location / {
|
|
||||||
return 307 https://$host$request_uri;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
## Stop exposing Impostor's HTTP server to the internet directly
|
|
||||||
|
|
||||||
To only allow connections to Impostor's HTTP servers via the reverse proxy, we recommend to set the ListenIp of the HTTP server to 127.0.0.1:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
// NOTE: merge this snippet into the rest of your configuration
|
|
||||||
"HttpServer": {
|
|
||||||
"ListenIp": "127.0.0.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Or if you're configuring Impostor with environment variables:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
IMPOSTOR_HttpServer__ListenIp=127.0.0.1
|
|
||||||
```
|
|
||||||
|
|
||||||
For more information on server configuration, see [Server-configuration.md](Server Configuration).
|
|
||||||
+79
-45
@@ -1,53 +1,30 @@
|
|||||||
# Running the server
|
# Running the server
|
||||||
|
|
||||||
There are currently two install methods for Impostor: You can install it normally or inside of a Docker container. If you do not have a particular preference, we recommend the normal installation over the Docker container method.
|
There are currently two modes to run the Impostor server in. The first way is the simplest one and is the one you should probably use. The other way will distribute players across other servers and is a more advanced configuration.
|
||||||
|
|
||||||
## General remarks for both install methods
|
## Single server
|
||||||
|
|
||||||
This section applies to both the normal installation as well as the Docker (Compose) installation
|
### Without docker
|
||||||
|
1. Install the **.NET 5.0 runtime**.
|
||||||
|
- [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 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)*
|
||||||
|
6. Run `Impostor.Server.exe` (Windows) / `Impostor.Server` (Linux)
|
||||||
|
|
||||||
To connect to the server, you need to configure and install a region file on https://impostor.github.io/Impostor/
|
### Using docker
|
||||||
|
|
||||||
Among Us connects to the server using two network services: the (TCP) HTTP service points Among Us to the UDP service, then the UDP service hosts the actual game traffic. Because of this, Impostor uses port 22023 using **both** the TCP and UDP protocols.
|
[](https://hub.docker.com/repository/docker/aeonlucid/impostor)
|
||||||
|
[](https://hub.docker.com/repository/docker/aeonlucid/impostor)
|
||||||
To connect to your Among Us version from another PC, you need to set up a HTTP reverse proxy to support HTTPS. If you're just running a version of Impostor for testing Setup instructions for this are in the [Http Server documentation](Http-server.md).
|
|
||||||
|
|
||||||
If you want to test if your Among Us HTTP server is working, open `http://localhost:22023` (assuming you're using the default settings, change the IP and port respectively) in a browser
|
|
||||||
|
|
||||||
Depending on your host you may also need to port forward Impostor to the internet or pass Impostor traffic by your firewall. Port 22023 UDP needs to be accessible for everyone that wants to play on the server, then you also need to portforward your HTTP reverse proxy or port 22023 TCP if you don't use a reverse proxy. As port forwarding changes per host or router configuration, port forwarding is not covered by this guide.
|
|
||||||
|
|
||||||
## Normal installation
|
|
||||||
|
|
||||||
1. Install [.NET 8.0](https://dotnet.microsoft.com/download/dotnet/8.0). We recommend either the ASP.NET Core Runtime or the SDK. The SDK is necessary in case you want to develop Impostor or Impostor plugins.
|
|
||||||
2. Download the [latest release](https://github.com/Impostor/Impostor/releases) or the [latest CI build](https://nightly.link/Impostor/Impostor/workflows/ci/master). Note that Impostor is built for multiple CPU-architectures and operating systems, you most likely want the x64 version, unless you are running on a Raspberry Pi or another device/VPS with an Arm processor.
|
|
||||||
3. Extract the zip.
|
|
||||||
4. Modify `config.json` to your liking. Documentation can be found [here](Server-configuration.md). You need to at least change `PublicIp` to the address people will connect to your server to.
|
|
||||||
5. Run `Impostor.Server` (Linux/macOS) or `Impostor.Server.exe` (Windows)
|
|
||||||
6. Set up a reverse proxy to support HTTPS, so you can connect to your server from another device. See [reverse proxy configuration](Http-server.md)
|
|
||||||
7. (OPTIONAL - Linux) Configure a systemd definition file and enable the service to start on boot, see [systemd configuration](Server-configuration.md#systemd)
|
|
||||||
|
|
||||||
|
|
||||||
## Using Docker
|
|
||||||
|
|
||||||
[](https://hub.docker.com/r/aeonlucid/impostor)
|
|
||||||
[](https://hub.docker.com/r/aeonlucid/impostor)
|
|
||||||
|
|
||||||
Docker is a program that allows you to run programs like Impostor in a container.
|
|
||||||
|
|
||||||
After installing Docker, you can just start a Docker container with `docker run`:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
docker run -p 127.0.0.1:22023:22023/tcp -p 22023:22023/udp -e IMPOSTOR_Server__PublicIp=your.public.ip.here aeonlucid/impostor:nightly
|
docker run -p 22023:22023/udp aeonlucid/impostor:nightly
|
||||||
```
|
```
|
||||||
|
|
||||||
Please replace `your.public.ip.here` with the public IP address of your server. This is the address Among Us will try to reach your server at.
|
### Using docker-compose
|
||||||
|
|
||||||
To configure the docker container, either use environment variables or mount config.json in your container.
|
|
||||||
|
|
||||||
## Using Docker Compose
|
|
||||||
|
|
||||||
Docker Compose allows you to start a Docker container using a predefined configuration. This is an example configuration you can continue on:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
version: '3.4'
|
version: '3.4'
|
||||||
|
|
||||||
@@ -56,12 +33,69 @@ services:
|
|||||||
image: aeonlucid/impostor:nightly
|
image: aeonlucid/impostor:nightly
|
||||||
container_name: impostor
|
container_name: impostor
|
||||||
ports:
|
ports:
|
||||||
- 127.0.0.1:22023:22023/tcp # Set up your own reverse proxy to terminate HTTPS
|
|
||||||
- 22023:22023/udp
|
- 22023:22023/udp
|
||||||
environment: # Either configure Impostor using environment variables or mount config.json in your container
|
|
||||||
- IMPOSTOR_Server__PublicIp=your.public.ip.here
|
|
||||||
volumes:
|
volumes:
|
||||||
- /path/to/local/config.json:/app/config.json # Mount config.json
|
- /path/to/local/config.json:/app/config.json # For easy editing of the config
|
||||||
- /path/to/local/plugins:/app/plugins # Only needed if using plugins
|
- /path/to/local/plugins:/app/plugins # Only needed if using plugins
|
||||||
- /path/to/local/libraries:/app/libraries # Only needed if using external libraries (some plugins may need this)
|
- /path/to/local/libraries:/app/libraries # Only needed if using external libraries
|
||||||
|
```
|
||||||
|
|
||||||
|
## Multiple servers
|
||||||
|
|
||||||
|
Follow the steps from the single server on two or more servers.
|
||||||
|
|
||||||
|
### Master server
|
||||||
|
|
||||||
|
The master server will accept client connections and redirect them to the other servers listed in the configuration. It will not host any games itself.
|
||||||
|
|
||||||
|
Example configuration:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Server": {
|
||||||
|
"PublicIp": "127.0.0.1",
|
||||||
|
"PublicPort": 22023,
|
||||||
|
"ListenIp": "0.0.0.0",
|
||||||
|
"ListenPort": 22023
|
||||||
|
},
|
||||||
|
"ServerRedirector": {
|
||||||
|
"Enabled": true,
|
||||||
|
"Master": true,
|
||||||
|
"Locator": {
|
||||||
|
"Redis": "",
|
||||||
|
"UdpMasterEndpoint": "127.0.0.1:22024"
|
||||||
|
},
|
||||||
|
"Nodes": [
|
||||||
|
{
|
||||||
|
"Ip": "127.0.0.1",
|
||||||
|
"Port": 22025
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Node servers
|
||||||
|
|
||||||
|
The node server should have `ServerRedirector` enabled too, but `Master` **must be disabled**. Nodes do not need to be aware of each other.
|
||||||
|
|
||||||
|
Example configuration:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Server": {
|
||||||
|
"PublicIp": "127.0.0.1",
|
||||||
|
"PublicPort": 22025,
|
||||||
|
"ListenIp": "0.0.0.0",
|
||||||
|
"ListenPort": 22025
|
||||||
|
},
|
||||||
|
"ServerRedirector": {
|
||||||
|
"Enabled": true,
|
||||||
|
"Master": false,
|
||||||
|
"Locator": {
|
||||||
|
"Redis": "",
|
||||||
|
"UdpMasterEndpoint": "127.0.0.1:22024"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
+53
-158
@@ -1,113 +1,66 @@
|
|||||||
# Server configuration
|
# Server configuration
|
||||||
|
|
||||||
|
Some information about all the possible configurations. Click [here](https://github.com/AeonLucid/Impostor/blob/master/src/Impostor.Server/config.full.json) to see all the possible config options.
|
||||||
|
|
||||||
## Options
|
## Options
|
||||||
|
|
||||||
### Required Server Configuration
|
### Required Server Configuration
|
||||||
|
|
||||||
| Key | Default | Description |
|
| Key | Default | Description |
|
||||||
| -------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|-|-|-|
|
||||||
| **PublicIp** | `127.0.0.1` | This needs to the public IPv4 address of the server which you give to others to connect. You can find your IPv4 address [on this website](http://whatismyip.host/). Unless you are only planning to use Impostor privately, on your local network, you should change this to your public ip. It is also possible to use hostnames instead of IPv4 addresses, which will be resolved to IPv4 addresses. |
|
| **PublicIp** | `127.0.0.1` | This needs to the public IPv4 address of the server which you give to others to connect. You can find your IPv4 address [on this website](http://whatismyip.host/). Unless you are only planning to use Impostor privately, on your local network, you should change this to your public ip. It is also possible to use hostnames instead of IPv4 addresses, which will be resolved to IPv4 addresses. |
|
||||||
| **PublicPort** | `22023` | The public port of the server which you give to others to connect. (**This is the external port you configure on your router when port forwarding.**) Usually `22023`. |
|
| **PublicPort** | `22023` | The public port of the server which you give to others to connect. (**This is the external port you configure on your router when port forwarding.**) Usually `22023`. |
|
||||||
| **ListenIp** | `0.0.0.0` | The network interface to listen on. If you do not know what to put here, use `0.0.0.0`. Since 1.2.2 it is also possible to use hostnames instead of IPv4 addresses, these must resolve to a valid IPv4 address. |
|
| **ListenIp** | `0.0.0.0` | The network interface to listen on. If you do not know what to put here, use `0.0.0.0`. Since 1.2.2 it is also possible to use hostnames instead of IPv4 addresses, these must resolve to a valid IPv4 address. |
|
||||||
| **ListenPort** | `22023` | The listen port of the server, usually `22023`. For port forwarding purposes: this is an UDP port |
|
| **ListenPort** | `22023` | The listen port of the server, usually `22023`. |
|
||||||
|
|
||||||
### HttpServer
|
|
||||||
|
|
||||||
Impostor has an Http Server that is used by recent versions of Among Us to connect to. See [the Http Server page](Http-server.md) for more details on how to set this up.
|
|
||||||
|
|
||||||
| Key | Default | Description |
|
|
||||||
|----------------|-----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
||||||
| **Enabled** | `true` | Whether the http server should be enabled. |
|
|
||||||
| **ListenIp** | `0.0.0.0` | The network interface to listen on. Use `127.0.0.1` if you use a reverse proxy or just run locally. Use `0.0.0.0` if you are directly exposing this server to the internet |
|
|
||||||
| **ListenPort** | `22023` | The listen port of this server. For port forwarding purposes, this is an TCP port. |
|
|
||||||
|
|
||||||
### AntiCheat
|
### AntiCheat
|
||||||
|
|
||||||
Impostor has an Anticheat that makes it possible to kick cheaters from games automatically. Note that the anticheat is tuned on the vanilla version of the game, so client-side modifications could trigger the Anticheat if you're playing with them.
|
| 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!)** |
|
||||||
|
|
||||||
| Key | Default | Value |
|
### ServerRedirector
|
||||||
|-------------------------------|---------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
In a multi-node setup these need to be specified.
|
||||||
| **Enabled** | `true` | Whether the anticheat should be enabled. |
|
| Key | Default | Value |
|
||||||
| **BanIpFromGame** | `true` | When anticheat is enabled and 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. |
|
|-|-|-|
|
||||||
| **AllowCheatingHosts** | `"Never"` | Configure whether hosts are allowed to cheat. "Never" forbids it, "Always" allows it. "IfRequested" allows hosts to cheat if they connect with the DisableServerAuthorityFlag set. |
|
| **Enabled** | `false` | Whether the server runs in multi-node setup. If this is `false`, all other options in this section do not have any effect. |
|
||||||
| **AllowHostOnlyExtensions** | "IfRequested" | Configure whether [Host-Only extensions](https://github.com/Innersloth-LLC/AmongUsModdingInformation#host-only-mods) are allowed in all games ("Always"), +25 games only ("IfRequested") or by nobody ("Never") |
|
| **Master** | `false` | Whether the current server is a master. A master is responsible for redirecting clients to nodes |
|
||||||
| **EnableGameFlowChecks** | `true` | Enable checks that check if certain actions are done in the appropriate order or at the appropriate moment in the game. This includes changing cosmetics while in game or murdering too fast. |
|
| **Locator** | | Fill in either `Redis` or `UdpMasterEndpoint` to choose which method to use for locating other nodes. This must be the same across all servers. |
|
||||||
| **EnableInvalidObjectChecks** | `true` | Enables checks that check if network objects are spawned properly. Disabling this option also implies disabling EnableRoleChecks. |
|
| **>Redis** | | Format `127.0.0.1.6379`, you can also use a password like so: `127.0.0.1.6379,password=value`. |
|
||||||
| **EnableMustBeHostChecks** | `true` | Enables checks that check if players are the host before they can do actions that require them to be host of the game. This includes starting the game and spawning objects. |
|
| **>UdpMasterEndpoint** | | On the master, this value acts as a listen ip and port. On a node, this should be the public ip and port of the master. Format `127.0.0.1:32320`. |
|
||||||
| **EnableColorLimitChecks** | `true` | Enables checks that checks if players request colors that are already in use. |
|
| **Nodes** | | An array containing public ips and ports of nodes. Only needs to be set on the master. See above for an example. |
|
||||||
| **EnableNameLimitChecks** | `true` | Enables checks that checks if player names have a length that is possible to set using the user interface. |
|
|
||||||
| **EnableItemLimitChecks** | `true` | Enables checks for item counts that cannot be exceeded in the official clients. |
|
|
||||||
| **EnableOwnershipChecks** | `true` | Enables checks that check if players are allowed to perform a certain action on themself or another player. |
|
|
||||||
| **EnableRoleChecks** | `true` | Enables checks that check if players have the correct role when performing certain role abilities like venting or murdering. |
|
|
||||||
| **EnableTargetChecks** | `true` | Enables checks that check if certain packets to everyone that should only have been sent to certain players or vice versa. This includes sending votes or network objects. |
|
|
||||||
| **EnableIdentifierChecks** | `true` | Enables checks that verify if the friendcode and puid a host claims for a player in their PlayerInfo match the ones known for that player. |
|
|
||||||
| **ForbidProtocolExtensions** | `true` | If disabled allows players to send network packets that go beyond the network packets sent by the vanilla game. This is necessary for most mods that need all players to install it. |
|
|
||||||
| **EnablePacketSizeChecks** | `true` | Enables checks that verify if network messages exceed the maximum allowed size. |
|
|
||||||
| **PacketSizeLimit** | `1203` | The maximum allowed size (in bytes) for a network message. The official servers of Among Us requires that a Hazel packet is < 1204 bytes, excluding headers. |
|
|
||||||
|
|
||||||
### Compatibility
|
|
||||||
|
|
||||||
Impostor has some compatibility options which allow some extra flexibility but may not work properly. Enabling any of these options is not recommended. When contacting support, please mention which of these options are enabled.
|
|
||||||
|
|
||||||
| Key | Default | Value |
|
|
||||||
|-----------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
||||||
| **AllowFutureGameVersions** | `false` | Warning: Setting this option to `true` is unsupported and may cause issues when large updates to Among Us are released, but can be useful when a small patch is released. Allows future versions of Among Us to join your server. |
|
|
||||||
| **AllowHostAuthority** | `false` | Certain Among Us mods allow disabling some server-authoritative features, which also changes some code paths in the client. These code paths have not undergone as much testing and contain bugs, which can't be fixed from the Impostor side. Use with caution. |
|
|
||||||
| **AllowVersionMixing** | `false` | Allows players using different game versions to play in one lobby that have not been marked by the Impostor developers as compatible. |
|
|
||||||
|
|
||||||
### Debug
|
|
||||||
|
|
||||||
The Debug configuration is used to enable the game recorder. This is mostly useful when developing Impostor.
|
|
||||||
|
|
||||||
| Key | Default | Value |
|
|
||||||
| ----------------------- | ------- | -------------------------------------------- |
|
|
||||||
| **GameRecorderEnabled** | `false` | Enables the Game Recorder. |
|
|
||||||
| **GameRecorderPath** | _empty_ | Path where the recorded games will be saved. |
|
|
||||||
|
|
||||||
### Serilog (Logging)
|
|
||||||
|
|
||||||
Impostor's log framework, Serilog, can be configured in the config file. You can change its default log level and you can add additional sinks.
|
|
||||||
|
|
||||||
| Key | Default | Value |
|
|
||||||
| ---------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
||||||
| **MinimumLevel** | `Information` | Minimum log level for a message to be printed. If a log entry is as severe or more severe than this level, it will be printed. From most severe to least severe: `Fatal`,`Error`, `Warning`, `Information`, `Debug`, `Verbose` |
|
|
||||||
| **Using** | `[]` | List of additional Serilog Sinks assemblies to load. |
|
|
||||||
| **WriteTo** | `[]` | Additional logging sinks. See the Serilog documentation or the example in this section. Serilog |
|
|
||||||
|
|
||||||
For more information, check the [Serilog.Settings.Configuration](https://github.com/serilog/serilog-settings-configuration) documentation.
|
|
||||||
|
|
||||||
For example, to add logging to a file, you should add the following snippet to your configuration:
|
|
||||||
|
|
||||||
```json
|
|
||||||
"Serilog": {
|
|
||||||
"Using": [
|
|
||||||
"Serilog.Sinks.File"
|
|
||||||
],
|
|
||||||
"WriteTo": [
|
|
||||||
{
|
|
||||||
"Name": "File",
|
|
||||||
"Args": {
|
|
||||||
"path": "logs/log.txt",
|
|
||||||
"rollingInterval": "Day"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Next to that, you also need to copy over Serilog.Sinks.File.dll from [NuGet](https://www.nuget.org/packages/Serilog.Sinks.File/). See the [Serilog.Sinks.File documentation](https://github.com/serilog/serilog-sinks-file#json-appsettingsjson-configuration) for a list of parameters that can be configured.
|
|
||||||
|
|
||||||
Other Serilog sinks are also supported, but are out of scope for this documentation.
|
|
||||||
|
|
||||||
## Config providers
|
## Config providers
|
||||||
|
|
||||||
### File
|
### File
|
||||||
|
|
||||||
The `config.json` file contains all the configurable options.
|
The simplest option to configure is by using the `config.json` file next to the server executable. For all possible options see the [config-full.json](https://github.com/Impostor/Impostor/blob/dev/src/Impostor.Server/config-full.json) file.
|
||||||
|
|
||||||
|
### Command line arguments
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
```
|
||||||
|
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
|
||||||
|
ServerRedirector:Locator:Redis=127.0.0.1.6379
|
||||||
|
ServerRedirector:Locator:UdpMasterEndpoint=127.0.0.1:32320
|
||||||
|
ServerRedirector:Nodes:0:Ip=127.0.0.1
|
||||||
|
ServerRedirector:Nodes:0:Port=22024
|
||||||
|
ServerRedirector:Nodes:1:Ip=127.0.0.1
|
||||||
|
ServerRedirector:Nodes:1:Port=22025
|
||||||
|
```
|
||||||
|
|
||||||
### Environment variables
|
### Environment variables
|
||||||
|
|
||||||
If you're unable to edit the `config.json` file, you can instead set Environment variables to configure Impostor. The general pattern for each variable is `IMPOSTOR_SectionName__VariableName`. For example, to disable the anticheat, you can set the environment variable `IMPOSTOR_AntiCheat__Enabled=false`. Here are some more examples:
|
TODO
|
||||||
|
|
||||||
```
|
```
|
||||||
IMPOSTOR_Server__PublicIp=127.0.0.1
|
IMPOSTOR_Server__PublicIp=127.0.0.1
|
||||||
@@ -116,70 +69,12 @@ IMPOSTOR_Server__ListenIp=0.0.0.0
|
|||||||
IMPOSTOR_Server__ListenPort=22023
|
IMPOSTOR_Server__ListenPort=22023
|
||||||
IMPOSTOR_AntiCheat__Enabled=true
|
IMPOSTOR_AntiCheat__Enabled=true
|
||||||
IMPOSTOR_AntiCheat__BanIpFromGame=true
|
IMPOSTOR_AntiCheat__BanIpFromGame=true
|
||||||
```
|
IMPOSTOR_ServerRedirector__Enabled=false
|
||||||
|
IMPOSTOR_ServerRedirector__Master=true
|
||||||
# systemd
|
IMPOSTOR_ServerRedirector__Locator__Redis=127.0.0.1.6379
|
||||||
|
IMPOSTOR_ServerRedirector__Locator__UdpMasterEndpoint=127.0.0.1:32320
|
||||||
Linux users will likely want to create a systemd service definition to manage running the Impostor application. Benefits to using a systemd service include the following:
|
IMPOSTOR_ServerRedirector__Nodes__0__Ip=127.0.0.1
|
||||||
|
IMPOSTOR_ServerRedirector__Nodes__0__Port=22024
|
||||||
- The server process can automatically restart if the process dies
|
IMPOSTOR_ServerRedirector__Nodes__1__Ip=127.0.0.1
|
||||||
- Impostor can be set to start on boot (handy if you do system updates regularly)
|
IMPOSTOR_ServerRedirector__Nodes__1__Port=22025
|
||||||
- You can use systemd targets to ensure the process doesn't start until the system dependencies are met
|
|
||||||
|
|
||||||
Using your favorite text editor, create the following service file:
|
|
||||||
|
|
||||||
```
|
|
||||||
sudoedit /etc/systemd/system/impostor.service
|
|
||||||
```
|
|
||||||
|
|
||||||
Modify the following template to your needs and populate the service file.
|
|
||||||
|
|
||||||
```
|
|
||||||
[Unit]
|
|
||||||
Description=Impostor private Among Us server - https://github.com/Impostor/Impostor
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
# Directory where Impostor is installed
|
|
||||||
WorkingDirectory=/opt/impostor
|
|
||||||
# Path to Impostor binary
|
|
||||||
ExecStart=/opt/impostor/Impostor.Server
|
|
||||||
Restart=always
|
|
||||||
# Restart service after 10 seconds if the dotnet service crashes
|
|
||||||
RestartSec=10
|
|
||||||
KillSignal=SIGTERM
|
|
||||||
SyslogIdentifier=impostor
|
|
||||||
|
|
||||||
# User and group that will run the Impostor server process -- ensure that user is allowed to execute the binary
|
|
||||||
User=impostor
|
|
||||||
Group=impostor
|
|
||||||
TimeoutStopSec=10
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
# Wait until most system services have started before starting Impostor
|
|
||||||
After=multi-user.target
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
```
|
|
||||||
|
|
||||||
Reload all systemd unit files to source in the new file you've created.
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo systemctl daemon-reload
|
|
||||||
```
|
|
||||||
|
|
||||||
Start the service.
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo systemctl start impostor.service
|
|
||||||
```
|
|
||||||
|
|
||||||
Check the log for the service and verify it has started correctly -- Hint: Use the Q key to quit out of journalctl.
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo journalctl -u impostor.service
|
|
||||||
```
|
|
||||||
|
|
||||||
If everything has started correctly, ensure the service is set to start on boot.
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo systemctl enable impostor.service
|
|
||||||
```
|
```
|
||||||
+9
-44
@@ -1,63 +1,28 @@
|
|||||||
# Troubleshooting
|
# Troubleshooting
|
||||||
|
|
||||||
If you're reading this, something went wrong.
|
If you're reading this, something went wrong.
|
||||||
Don't worry though, as this is the most thorough guide to help you!
|
Don't worry though, as this is the most thorough guide to help you!
|
||||||
|
|
||||||
## `./Impostor.Server: line 1: ELF: not found` (plus other errors)
|
## `./Impostor.Server: line 1: ELF: not found` (plus other errors)
|
||||||
|
|
||||||
No idea where you got that system. But we clearly do **NOT** support it.
|
No idea where you got that system. But we clearly do **NOT** support it.
|
||||||
|
|
||||||
## `cannot execute binary file: Exec format error`
|
## `cannot execute binary file: Exec format error`
|
||||||
|
Please check that you have downloaded the right version of Impostor, as we mantain two CPU architectures (x64 and ARM).
|
||||||
Please check that you have downloaded the right version of Impostor, as we mantain two CPU architectures (x64 and ARM).
|
Unless you are running Impostor on a SBC (Single-Board Computer), like the Raspberry Pi, you most likely want to use the x64 version.
|
||||||
Unless you are running Impostor on a computer like the Raspberry Pi, you most likely want to use the x64 version.
|
|
||||||
|
|
||||||
## `./Impostor.Server: Permission denied`
|
## `./Impostor.Server: Permission denied`
|
||||||
|
|
||||||
This is an error related to Linux file permissions.
|
This is an error related to Linux file permissions.
|
||||||
Some files do not hold their executable bit (the permission that allows them to run) during a download.
|
Some files do not hold their executable bit (the permission that allows them to run) during a download.
|
||||||
You can solve this by doing: `chmod +x Impostor.Server`
|
You can solve this by doing: `chmod +x Impostor.Server`
|
||||||
|
|
||||||
## Disconnected with `Your client is too new, please update your Impostor to play`
|
## `You are using an older version of the game`
|
||||||
|
You are using an older version of Impostor. The game does not really check who is outdated and blames it on the user.
|
||||||
|
Make sure you got the latest working version of Impostor (probably in AppVeyor, not Github).
|
||||||
|
|
||||||
This happens when your game is too new for your copy of Impostor to support.
|
## `You disconnected from the server. Reliable Packet 1 ...`
|
||||||
|
Please double-check that you have followed the [Server Configuration](Server-configuration.md) correctly.
|
||||||
If you're using an Impostor release, check if there is a newer release available that supports your version. If this doesn't exist, you can try the [latest build from CI](https://nightly.link/Impostor/Impostor/workflows/ci/master).
|
**NOTE: Your public ip does not start with `127` nor `192`**
|
||||||
|
|
||||||
If even that build doesn't work, you can try looking through the Pull Requests to see if there is a pending pull request that aims to update it to the next version, but note these may be unstable and may contain malicious code, as they haven't been vetted by the Impostor development team yet.
|
|
||||||
|
|
||||||
## Disconnected with `Please update your game to play on this server`
|
|
||||||
|
|
||||||
This happens when you're using a version of Impostor that is too new for your game version. You can download an older version from [the GitHub release page](https://github.com/Impostor/Impostor/releases). We however don't support older versions of Impostor with new API's and bugfixes so we recommend to update your game instead.
|
|
||||||
|
|
||||||
## Disconnected with `You are using an older version of the game`
|
|
||||||
|
|
||||||
You are using a version of Impostor that is not designed for the version of the game you're playing. The game does not really check who is outdated and blames it on the user. Newer versions (v1.5.0+) do warn correctly and send the correct message.
|
|
||||||
|
|
||||||
Look at which version of the game you're playing, which you can see in the top left corner of the main menu, then download an Impostor version for that game. Every [release on the release page](https://github.com/Impostor/Impostor/releases) shows which version of the game it is compatible with. If your game version is newer than the latest release, check if the [latest build from CI works](https://nightly.link/Impostor/Impostor/workflows/ci/master).
|
|
||||||
|
|
||||||
## Disconnected with `You disconnected from the server. Reliable Packet 1 ...`
|
|
||||||
|
|
||||||
Please double-check that you have followed the [Server Configuration](Server-configuration.md) correctly.
|
|
||||||
**NOTE: Your public ip does not start with `10`, `127` or `192`**
|
|
||||||
Also check if the port Impostor (ListenPort) is listening on is correctly port-forwarded for UDP (or TCP/UDP).
|
Also check if the port Impostor (ListenPort) is listening on is correctly port-forwarded for UDP (or TCP/UDP).
|
||||||
|
|
||||||
## `Could not load file or assembly...`
|
## `Could not load file or assembly...`
|
||||||
|
Please check that you only have **working** plugins in the `plugins` folder.
|
||||||
Please check that you only have **working** plugins in the `plugins` folder.
|
|
||||||
This error can be caused by non-plugin files or plugins that are not working correctly.
|
This error can be caused by non-plugin files or plugins that are not working correctly.
|
||||||
|
|
||||||
## Disconnected with `You disconnected from the server. If this happens often, check your network strength. This may also be a server issue`
|
|
||||||
|
|
||||||
Usually this means that Among Us couldn't connect to Impostor's HTTP server.
|
|
||||||
|
|
||||||
Open the address of your server in a web browser, it should show you a small page confirming that Impostor is available.
|
|
||||||
|
|
||||||
## My question is not yet answered and I'm still having problems!
|
|
||||||
|
|
||||||
That's unfortunate. Join the [Impostor Discord](https://discord.gg/Mk3w6Tb), ask your question there and we'll try to help you out. Note that we're not always available, so it may take some time to get an answer. To make answering your question easier, please add the following details:
|
|
||||||
|
|
||||||
- Which version of Impostor are you using?
|
|
||||||
- Which version or Among Us are you using?
|
|
||||||
- Which operating system are you running Impostor on?
|
|
||||||
- If you have console logs, attaching these will also help.
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
# Upgrading Impostor
|
|
||||||
|
|
||||||
Sometimes we make incompatible changes to existing code. This document lists these changes and which changes you should make as a server administrator.
|
|
||||||
|
|
||||||
## Impostor 1.9.0
|
|
||||||
|
|
||||||
Previously we recommended using the Impostor.Http plugin for HTTP matchmaking. Because Among Us now relies on HTTP matchmaking, this plugin is now part of the default installation. As a result, you should change your server as follows:
|
|
||||||
|
|
||||||
- If you have Impostor.Http installed, you should remove that plugin. If you have changed the default settings, you need to move these changes to the [HttpServer section in config.json](Server-configuration.md#HttpServer).
|
|
||||||
- If you have plugins that required Impostor.Http's API (like Reactor.Impostor.Http), you should check that plugin for updates
|
|
||||||
- It is no longer necessary to add the ASP.NET Core folder to the PluginLoader's LibraryPaths
|
|
||||||
|
|
||||||
+21
-10
@@ -19,24 +19,31 @@ Impostor has support for plugins. This document will help you to setup a develop
|
|||||||
- [Impostor versions](#impostor-versions)
|
- [Impostor versions](#impostor-versions)
|
||||||
- [9. Missing/invalid data or want more functions?](#9-missinginvalid-data-or-want-more-functions)
|
- [9. Missing/invalid data or want more functions?](#9-missinginvalid-data-or-want-more-functions)
|
||||||
|
|
||||||
## 1. Install .NET SDK
|
## 1. Install .NET Core SDK
|
||||||
|
|
||||||
Download and install the latest .NET SDK.
|
Download and install the latest .NET Core SDK.
|
||||||
|
|
||||||
https://dotnet.microsoft.com/download
|
https://dotnet.microsoft.com/download
|
||||||
|
|
||||||
## 2. Create a C# project
|
## 2. Create a C# project
|
||||||
|
|
||||||
The first step is creating a new C# project, it must be a **Class Library (.NET Standard)**. The target framework can be any of those compatible with .NET 8, but we recommend sticking with **.NET 8.0**.
|
The first step is creating a new C# project, it must be a **Class Library (.NET Standard)**. The target framework can be any of those compatible with .NET 5, which includes:
|
||||||
|
|
||||||
|
- .NET Standard 2.0
|
||||||
|
- .NET Standard 2.1
|
||||||
|
- .NET Core 3.1
|
||||||
|
- .NET 5
|
||||||
|
|
||||||
For more information about compatibility, see https://docs.microsoft.com/en-us/dotnet/standard/net-standard.
|
For more information about compatibility, see https://docs.microsoft.com/en-us/dotnet/standard/net-standard.
|
||||||
|
|
||||||
|
> At the moment of writing this document, I recommend you to use **.NET Standard 2.1** until .NET 5 is released officially. This should give you enough functionality. If not, upgrade to .NET Core 3.1.
|
||||||
|
|
||||||
When the project has been created, you should have `Class.cs` and `Project.csproj` files. Your `Project.csproj` should look something like this.
|
When the project has been created, you should have `Class.cs` and `Project.csproj` files. Your `Project.csproj` should look something like this.
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
```
|
```
|
||||||
@@ -55,13 +62,16 @@ Make sure to get a prerelease if you are writing a plugin for a dev release of t
|
|||||||
1. Right click your project.
|
1. Right click your project.
|
||||||
2. Click `Manage NuGet Packages`.
|
2. Click `Manage NuGet Packages`.
|
||||||
3. Click `Browse`.
|
3. Click `Browse`.
|
||||||
4. Search for `Impostor.Api`.
|
4. Next to the search bar, enable `Include prerelease`.
|
||||||
5. Click the `Impostor.Api` result and press install on the right side.
|
5. Search for `Impostor.Api`.
|
||||||
|
6. Click the `Impostor.Api` result and press install on the right side.
|
||||||
|
|
||||||
### Dotnet CLI
|
### Dotnet CLI
|
||||||
|
|
||||||
|
> Make sure to grab the latest (pre-)release version from NuGet [here](https://www.nuget.org/packages/Impostor.Api).
|
||||||
|
|
||||||
1. Open your project folder in command prompt / bash.
|
1. Open your project folder in command prompt / bash.
|
||||||
2. Run `dotnet add package Impostor.Api`.
|
2. Run `dotnet add package Impostor.Api -v "1.2.0-ci.58"`.
|
||||||
|
|
||||||
## 4. The plugin class
|
## 4. The plugin class
|
||||||
|
|
||||||
@@ -262,7 +272,7 @@ Now your plugin is ready to be tested.
|
|||||||
|
|
||||||
1. Right click your project and press `Build`.
|
1. Right click your project and press `Build`.
|
||||||
2. Right click your project and press `Open Folder in File Explorer`.
|
2. Right click your project and press `Open Folder in File Explorer`.
|
||||||
3. Go to `bin/Debug/net8.0/`.
|
3. Go to `bin/Debug/netstandard2.1/`.
|
||||||
4. In this directory, you should find your plugin named `Project.dll`.
|
4. In this directory, you should find your plugin named `Project.dll`.
|
||||||
5. Copy the `Project.dll` to the `plugins` directory in your Impostor server directory.
|
5. Copy the `Project.dll` to the `plugins` directory in your Impostor server directory.
|
||||||
6. (Re)start your Impostor server.
|
6. (Re)start your Impostor server.
|
||||||
@@ -285,6 +295,7 @@ Some extra information that might be useful for those developing plugins.
|
|||||||
- `IEventManager`
|
- `IEventManager`
|
||||||
- `IClientManager`
|
- `IClientManager`
|
||||||
- `IOptions<ServerConfig>`
|
- `IOptions<ServerConfig>`
|
||||||
|
- `IOptions<ServerRedirectorConfig>`
|
||||||
- You can add your own classes and `EventListener` implementation to the `IServiceProvider` by creating a new class and implementing `IPluginStartup`. Make sure to register them as a singleton `services.AddSingleton<IEventListener, GameEventListener>();`.
|
- You can add your own classes and `EventListener` implementation to the `IServiceProvider` by creating a new class and implementing `IPluginStartup`. Make sure to register them as a singleton `services.AddSingleton<IEventListener, GameEventListener>();`.
|
||||||
|
|
||||||
### Server configuration
|
### Server configuration
|
||||||
@@ -301,7 +312,7 @@ Constantly copying the plugin dll to your server directory can be pretty annoyin
|
|||||||
},
|
},
|
||||||
"PluginLoader": {
|
"PluginLoader": {
|
||||||
"Paths": [
|
"Paths": [
|
||||||
"D:\\Projects\\Impostor\\src\\Impostor.Plugins.Example\\bin\\Debug\\net8.0"
|
"D:\\Projects\\Impostor\\src\\Impostor.Plugins.Example\\bin\\Debug\\netstandard2.1"
|
||||||
],
|
],
|
||||||
"LibraryPaths": []
|
"LibraryPaths": []
|
||||||
}
|
}
|
||||||
@@ -329,4 +340,4 @@ Create an issue:
|
|||||||
- [Suggest a function](https://github.com/Impostor/Impostor/issues/new?template=3--api-suggestion.md)
|
- [Suggest a function](https://github.com/Impostor/Impostor/issues/new?template=3--api-suggestion.md)
|
||||||
- [Data is invalid](https://github.com/Impostor/Impostor/issues/new?template=4--api-invalid.md)
|
- [Data is invalid](https://github.com/Impostor/Impostor/issues/new?template=4--api-invalid.md)
|
||||||
- [Data is unavailable](https://github.com/Impostor/Impostor/issues/new?template=5--api-missing.md)
|
- [Data is unavailable](https://github.com/Impostor/Impostor/issues/new?template=5--api-missing.md)
|
||||||
- [Other](https://github.com/Impostor/Impostor/issues/new?template=6--api-other.md)
|
- [Other](https://github.com/Impostor/Impostor/issues/new?template=6--api-other.md)
|
||||||
@@ -144,12 +144,6 @@ dotnet_naming_style.end_in_async.word_separator =
|
|||||||
# error RS2008: Enable analyzer release tracking for the analyzer project containing rule '{0}'
|
# error RS2008: Enable analyzer release tracking for the analyzer project containing rule '{0}'
|
||||||
dotnet_diagnostic.RS2008.severity = none
|
dotnet_diagnostic.RS2008.severity = none
|
||||||
|
|
||||||
# IDE0005: Remove unnecessary import
|
|
||||||
dotnet_diagnostic.IDE0005.severity = warning
|
|
||||||
|
|
||||||
# IDE0007: Use `var` instead of explicit type
|
|
||||||
dotnet_diagnostic.IDE0007.severity = warning
|
|
||||||
|
|
||||||
# IDE0035: Remove unreachable code
|
# IDE0035: Remove unreachable code
|
||||||
dotnet_diagnostic.IDE0035.severity = warning
|
dotnet_diagnostic.IDE0035.severity = warning
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<VersionPrefix>1.4.0</VersionPrefix>
|
||||||
<LangVersion>11</LangVersion>
|
|
||||||
<VersionPrefix>1.10.9</VersionPrefix>
|
|
||||||
<VersionSuffix>dev</VersionSuffix>
|
<VersionSuffix>dev</VersionSuffix>
|
||||||
<EnforceCodeStyleInBuild Condition="$(MSBuildProjectName)!='Hazel'">true</EnforceCodeStyleInBuild>
|
|
||||||
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Numerics;
|
|
||||||
|
|
||||||
namespace Impostor.Api.Innersloth.Generator;
|
|
||||||
|
|
||||||
internal static class Extensions
|
|
||||||
{
|
|
||||||
public static string NormalizePath(this string path)
|
|
||||||
{
|
|
||||||
return path.Replace("\\", "/");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool TryTrimStart(this string text, string value, [NotNullWhen(true)] out string? result)
|
|
||||||
{
|
|
||||||
if (text.StartsWith(value))
|
|
||||||
{
|
|
||||||
result = text[value.Length..];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = null;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string ToCSharpString(this Vector2 value)
|
|
||||||
{
|
|
||||||
return $"new Vector2({value.X.ToString(CultureInfo.InvariantCulture)}f, {value.Y.ToString(CultureInfo.InvariantCulture)}f)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
using System.Collections.Immutable;
|
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.CodeAnalysis;
|
|
||||||
|
|
||||||
namespace Impostor.Api.Innersloth.Generator.Generators;
|
|
||||||
|
|
||||||
public abstract class BaseGenerator
|
|
||||||
{
|
|
||||||
protected SourceProductionContext _sourceProductionContext;
|
|
||||||
protected ImmutableArray<(string RelativePath, string Content)> _files;
|
|
||||||
|
|
||||||
protected BaseGenerator(SourceProductionContext sourceProductionContext, ImmutableArray<(string RelativePath, string Content)> files)
|
|
||||||
{
|
|
||||||
_sourceProductionContext = sourceProductionContext;
|
|
||||||
_files = files;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected string GetFileContent(string path)
|
|
||||||
{
|
|
||||||
return _files.Single(x => x.RelativePath == path).Content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.Immutable;
|
|
||||||
using System.Text.Json;
|
|
||||||
using CSharpPoet;
|
|
||||||
using Microsoft.CodeAnalysis;
|
|
||||||
|
|
||||||
namespace Impostor.Api.Innersloth.Generator.Generators;
|
|
||||||
|
|
||||||
public sealed class EnumGenerator : BaseGenerator
|
|
||||||
{
|
|
||||||
public EnumGenerator(SourceProductionContext sourceProductionContext, ImmutableArray<(string RelativePath, string Content)> files) : base(sourceProductionContext, files)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Generate(string name, string? @namespace = null, string? sourceName = null, bool flags = false, CSharpEnumUnderlyingType underlyingType = CSharpEnumUnderlyingType.Int)
|
|
||||||
{
|
|
||||||
var dictionary = JsonSerializer.Deserialize<Dictionary<string, long>>(GetFileContent($"enums/{sourceName ?? name}.json"))!;
|
|
||||||
|
|
||||||
var @enum = new CSharpEnum(name, underlyingType);
|
|
||||||
|
|
||||||
foreach (var pair in dictionary)
|
|
||||||
{
|
|
||||||
var value = flags && pair.Value > 0
|
|
||||||
? $"1 << {Math.Log(pair.Value, 2)}"
|
|
||||||
: pair.Value.ToString();
|
|
||||||
|
|
||||||
@enum.Members.Add(new CSharpEnum.Member(pair.Key, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags)
|
|
||||||
{
|
|
||||||
@enum.Attributes.Add(new CSharpAttribute("System.FlagsAttribute"));
|
|
||||||
}
|
|
||||||
|
|
||||||
var source = new CSharpFile(@namespace ?? "Impostor.Api.Innersloth") { @enum }.ToString();
|
|
||||||
_sourceProductionContext.AddSource(name, source);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,210 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.Immutable;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Numerics;
|
|
||||||
using System.Text.Json;
|
|
||||||
using CSharpPoet;
|
|
||||||
using Microsoft.CodeAnalysis;
|
|
||||||
|
|
||||||
namespace Impostor.Api.Innersloth.Generator.Generators;
|
|
||||||
|
|
||||||
public sealed class MapDataGenerator : BaseGenerator
|
|
||||||
{
|
|
||||||
public MapDataGenerator(SourceProductionContext sourceProductionContext, ImmutableArray<(string RelativePath, string Content)> files) : base(sourceProductionContext, files)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private T? Deserialize<T>(string name, string fileName)
|
|
||||||
{
|
|
||||||
return JsonSerializer.Deserialize<T>(
|
|
||||||
GetFileContent($"maps/{name}/{fileName}.json"),
|
|
||||||
new JsonSerializerOptions
|
|
||||||
{
|
|
||||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
|
||||||
Converters =
|
|
||||||
{
|
|
||||||
new Vector2Converter(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Generate(string name)
|
|
||||||
{
|
|
||||||
var className = name + "Data";
|
|
||||||
|
|
||||||
var spawnInfo = Deserialize<SpawnInfo>(name, "spawn")!;
|
|
||||||
var tasks = Deserialize<Dictionary<int, TaskInfo>>(name, "tasks")!;
|
|
||||||
var vents = Deserialize<Dictionary<int, VentInfo>>(name, "vents")!;
|
|
||||||
var doors = Deserialize<Dictionary<int, DoorInfo>>(name, "doors")!;
|
|
||||||
|
|
||||||
var ventsData = new DictionaryData("VentData", "Vents", writer =>
|
|
||||||
{
|
|
||||||
foreach (var pair in vents)
|
|
||||||
{
|
|
||||||
var id = pair.Key;
|
|
||||||
var vent = pair.Value;
|
|
||||||
|
|
||||||
var connections = "";
|
|
||||||
if (vent.Left != null) connections += ", left: " + vent.Left.Value;
|
|
||||||
if (vent.Center != null) connections += ", center: " + vent.Center.Value;
|
|
||||||
if (vent.Right != null) connections += ", right: " + vent.Right.Value;
|
|
||||||
|
|
||||||
writer.WriteLine($"[{id}] = new(this, {id}, \"{vent.Name}\", {vent.Position.ToCSharpString()}{connections}),");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var tasksData = new DictionaryData("TaskData", "Tasks", writer =>
|
|
||||||
{
|
|
||||||
foreach (var pair in tasks)
|
|
||||||
{
|
|
||||||
var id = pair.Key;
|
|
||||||
var task = pair.Value;
|
|
||||||
|
|
||||||
writer.WriteLine($"[{id}] = new({id}, TaskTypes.{task.TaskType}, TaskCategories.{task.Length}Task),");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var doorsData = new DictionaryData("DoorData", "Doors", writer =>
|
|
||||||
{
|
|
||||||
foreach (var pair in doors)
|
|
||||||
{
|
|
||||||
var id = pair.Key;
|
|
||||||
var door = pair.Value;
|
|
||||||
|
|
||||||
writer.WriteLine($"[{id}] = new({id}, SystemTypes.{door.Room}, {door.Position.ToCSharpString()}),");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var constructor = new CSharpMethod(Visibility.Internal, className, ".ctor")
|
|
||||||
{
|
|
||||||
Body = writer =>
|
|
||||||
{
|
|
||||||
ventsData.WriteInitializer(writer);
|
|
||||||
writer.WriteLine();
|
|
||||||
tasksData.WriteInitializer(writer);
|
|
||||||
writer.WriteLine();
|
|
||||||
doorsData.WriteInitializer(writer);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
var @class = new CSharpClass(className)
|
|
||||||
{
|
|
||||||
IsSealed = true,
|
|
||||||
Extends = { "MapData" },
|
|
||||||
Members =
|
|
||||||
{
|
|
||||||
constructor,
|
|
||||||
|
|
||||||
ventsData.CreateProperty(),
|
|
||||||
tasksData.CreateProperty(),
|
|
||||||
doorsData.CreateProperty(),
|
|
||||||
|
|
||||||
new CSharpBlankLine(),
|
|
||||||
|
|
||||||
CreateSimpleProperty("float", "SpawnRadius", spawnInfo.SpawnRadius.ToString(CultureInfo.InvariantCulture) + "f"),
|
|
||||||
CreateSimpleProperty("Vector2", "InitialSpawnCenter", spawnInfo.InitialSpawnCenter.ToCSharpString()),
|
|
||||||
CreateSimpleProperty("Vector2", "MeetingSpawnCenter", spawnInfo.MeetingSpawnCenter.ToCSharpString()),
|
|
||||||
CreateSimpleProperty("Vector2", "MeetingSpawnCenter2", spawnInfo.MeetingSpawnCenter2.ToCSharpString()),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
var source = new CSharpFile("Impostor.Api.Innersloth.Maps")
|
|
||||||
{
|
|
||||||
Usings = { "System.Collections.Generic", "System.Numerics" },
|
|
||||||
Members = { @class },
|
|
||||||
}.ToString();
|
|
||||||
_sourceProductionContext.AddSource(className, source);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static CSharpProperty CreateSimpleProperty(string type, string name, string value)
|
|
||||||
{
|
|
||||||
return new CSharpProperty(type, name)
|
|
||||||
{
|
|
||||||
Getter = new CSharpProperty.Accessor { Body = writer => writer.Write(value + ";") },
|
|
||||||
IsOverride = true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private sealed class DictionaryData
|
|
||||||
{
|
|
||||||
private readonly string _keyType;
|
|
||||||
private readonly string _valueType;
|
|
||||||
private readonly string _name;
|
|
||||||
private readonly Action<CodeWriter> _body;
|
|
||||||
|
|
||||||
public DictionaryData(string keyType, string valueType, string name, Action<CodeWriter> body)
|
|
||||||
{
|
|
||||||
_keyType = keyType;
|
|
||||||
_valueType = valueType;
|
|
||||||
_name = name;
|
|
||||||
_body = body;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DictionaryData(string valueType, string name, Action<CodeWriter> body) : this("int", valueType, name, body)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void WriteInitializer(CodeWriter writer)
|
|
||||||
{
|
|
||||||
writer.WriteLine($"{_name} = new Dictionary<{_keyType}, {_valueType}>");
|
|
||||||
writer.WriteLine("{");
|
|
||||||
|
|
||||||
using (writer.Indent())
|
|
||||||
{
|
|
||||||
_body(writer);
|
|
||||||
}
|
|
||||||
|
|
||||||
writer.WriteLine("}.AsReadOnly();");
|
|
||||||
}
|
|
||||||
|
|
||||||
public CSharpProperty CreateProperty()
|
|
||||||
{
|
|
||||||
return new CSharpProperty($"IReadOnlyDictionary<{_keyType}, {_valueType}>", _name)
|
|
||||||
{
|
|
||||||
Getter = new CSharpProperty.Accessor(),
|
|
||||||
IsOverride = true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class SpawnInfo
|
|
||||||
{
|
|
||||||
public required Vector2 InitialSpawnCenter { get; init; }
|
|
||||||
public required Vector2 MeetingSpawnCenter { get; init; }
|
|
||||||
public required Vector2 MeetingSpawnCenter2 { get; init; }
|
|
||||||
public required float SpawnRadius { get; init; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class TaskInfo
|
|
||||||
{
|
|
||||||
public required string Type { get; init; }
|
|
||||||
public required string TaskType { get; init; }
|
|
||||||
public required string Length { get; init; }
|
|
||||||
public required TaskConsole[] Consoles { get; init; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class TaskConsole
|
|
||||||
{
|
|
||||||
public required int Id { get; init; }
|
|
||||||
public required string Room { get; init; }
|
|
||||||
public required Vector2 Position { get; init; }
|
|
||||||
public required float UsableDistance { get; init; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class VentInfo
|
|
||||||
{
|
|
||||||
public required string Name { get; init; }
|
|
||||||
public required Vector2 Position { get; init; }
|
|
||||||
public required int? Left { get; init; }
|
|
||||||
public required int? Center { get; init; }
|
|
||||||
public required int? Right { get; init; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class DoorInfo
|
|
||||||
{
|
|
||||||
public required string Room { get; init; }
|
|
||||||
public required Vector2 Position { get; init; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
|
||||||
<LangVersion>latest</LangVersion>
|
|
||||||
<DebugType>embedded</DebugType>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
|
|
||||||
<IsRoslynComponent>true</IsRoslynComponent>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" PrivateAssets="all" />
|
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" PrivateAssets="all" />
|
|
||||||
<PackageReference Include="PolySharp" Version="1.14.1" PrivateAssets="all" />
|
|
||||||
|
|
||||||
<PackageReference Include="System.Text.Json" Version="8.0.5" PrivateAssets="all" GeneratePathProperty="true" />
|
|
||||||
<PackageReference Include="System.Text.Encodings.Web" Version="8.0.0" PrivateAssets="all" GeneratePathProperty="true" />
|
|
||||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" PrivateAssets="all" GeneratePathProperty="true" />
|
|
||||||
|
|
||||||
<PackageReference Include="CSharpPoet" Version="0.3.0" PrivateAssets="all" GeneratePathProperty="true" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<GetTargetPathDependsOn>$(GetTargetPathDependsOn);GetDependencyTargetPaths</GetTargetPathDependsOn>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<Target Name="GetDependencyTargetPaths">
|
|
||||||
<ItemGroup>
|
|
||||||
<TargetPathWithTargetPlatformMoniker Include="$(PkgSystem_Text_Json)\lib\netstandard2.0\*.dll" IncludeRuntimeDependency="false" />
|
|
||||||
<TargetPathWithTargetPlatformMoniker Include="$(PkgSystem_Text_Encodings_Web)\lib\netstandard2.0\*.dll" IncludeRuntimeDependency="false" />
|
|
||||||
<TargetPathWithTargetPlatformMoniker Include="$(PKGMicrosoft_Bcl_AsyncInterfaces)\lib\netstandard2.0\*.dll" IncludeRuntimeDependency="false" />
|
|
||||||
|
|
||||||
<TargetPathWithTargetPlatformMoniker Include="$(PkgCSharpPoet)\lib\netstandard2.0\*.dll" IncludeRuntimeDependency="false" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://json.schemastore.org/launchsettings.json",
|
|
||||||
"profiles": {
|
|
||||||
"Generator": {
|
|
||||||
"commandName": "DebugRoslynComponent",
|
|
||||||
"targetProject": "../Impostor.Api/Impostor.Api.csproj"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using CSharpPoet;
|
|
||||||
using Impostor.Api.Innersloth.Generator.Generators;
|
|
||||||
using Microsoft.CodeAnalysis;
|
|
||||||
|
|
||||||
namespace Impostor.Api.Innersloth.Generator;
|
|
||||||
|
|
||||||
[Generator(LanguageNames.CSharp)]
|
|
||||||
public sealed class SourceGenerator : IIncrementalGenerator
|
|
||||||
{
|
|
||||||
private const string DataPath = "Innersloth/Data/";
|
|
||||||
|
|
||||||
private readonly record struct Options(string ProjectDirectory)
|
|
||||||
{
|
|
||||||
public bool TryGetRelativePath(string path, [NotNullWhen(true)] out string? relativePath)
|
|
||||||
{
|
|
||||||
if (
|
|
||||||
path.NormalizePath().TryTrimStart(ProjectDirectory, out relativePath) &&
|
|
||||||
relativePath.TryTrimStart(DataPath, out relativePath)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
relativePath = null;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
|
||||||
{
|
|
||||||
var optionsProvider = context.AnalyzerConfigOptionsProvider
|
|
||||||
.Select((analyzerConfigOptions, _) =>
|
|
||||||
{
|
|
||||||
if (!analyzerConfigOptions.GlobalOptions.TryGetValue("build_property.projectdir", out var projectDirectory))
|
|
||||||
{
|
|
||||||
throw new Exception("Couldn't get project directory");
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Options(projectDirectory.NormalizePath());
|
|
||||||
});
|
|
||||||
|
|
||||||
var filesProvider = context.AdditionalTextsProvider.Combine(optionsProvider)
|
|
||||||
.Where(static pair =>
|
|
||||||
{
|
|
||||||
var (file, options) = pair;
|
|
||||||
return options.TryGetRelativePath(file.Path, out var relativePath) && relativePath.EndsWith(".json");
|
|
||||||
})
|
|
||||||
.Select(static (pair, cancellationToken) =>
|
|
||||||
{
|
|
||||||
var (file, options) = pair;
|
|
||||||
|
|
||||||
if (!options.TryGetRelativePath(file.Path, out var relativePath))
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
RelativePath: relativePath,
|
|
||||||
Content: file.GetText(cancellationToken)!.ToString()
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.Collect();
|
|
||||||
|
|
||||||
context.RegisterSourceOutput(filesProvider, (spc, files) =>
|
|
||||||
{
|
|
||||||
if (files.IsEmpty)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException($"No json files found in Impostor.Api/{DataPath}");
|
|
||||||
}
|
|
||||||
|
|
||||||
var enumGenerator = new EnumGenerator(spc, files);
|
|
||||||
|
|
||||||
enumGenerator.Generate("ColorType", "Impostor.Api.Innersloth.Customization");
|
|
||||||
|
|
||||||
enumGenerator.Generate("DisconnectReason", sourceName: "DisconnectReasons");
|
|
||||||
enumGenerator.Generate("GameKeywords", flags: true, underlyingType: CSharpEnumUnderlyingType.UnsignedInt);
|
|
||||||
enumGenerator.Generate("GameOverReason", underlyingType: CSharpEnumUnderlyingType.Byte);
|
|
||||||
enumGenerator.Generate("Platforms");
|
|
||||||
enumGenerator.Generate("RoleTypes", underlyingType: CSharpEnumUnderlyingType.UnsignedShort);
|
|
||||||
enumGenerator.Generate("RulesPresets", underlyingType: CSharpEnumUnderlyingType.Byte);
|
|
||||||
enumGenerator.Generate("SpecialGameModes", underlyingType: CSharpEnumUnderlyingType.Byte);
|
|
||||||
enumGenerator.Generate("StringNames");
|
|
||||||
enumGenerator.Generate("SystemTypes", underlyingType: CSharpEnumUnderlyingType.Byte);
|
|
||||||
enumGenerator.Generate("Language", sourceName: "SupportedLangs");
|
|
||||||
enumGenerator.Generate("TaskTypes");
|
|
||||||
enumGenerator.Generate("BoolOptionNames", "Impostor.Api.Innersloth.GameFilters");
|
|
||||||
enumGenerator.Generate("ByteOptionNames", "Impostor.Api.Innersloth.GameFilters");
|
|
||||||
enumGenerator.Generate("CategorizedOptionNames", "Impostor.Api.Innersloth.GameFilters");
|
|
||||||
enumGenerator.Generate("FloatArrayOptionNames", "Impostor.Api.Innersloth.GameFilters");
|
|
||||||
enumGenerator.Generate("FloatOptionNames", "Impostor.Api.Innersloth.GameFilters");
|
|
||||||
enumGenerator.Generate("Int32ArrayOptionNames", "Impostor.Api.Innersloth.GameFilters");
|
|
||||||
enumGenerator.Generate("Int32OptionNames", "Impostor.Api.Innersloth.GameFilters");
|
|
||||||
enumGenerator.Generate("UInt32OptionNames", "Impostor.Api.Innersloth.GameFilters");
|
|
||||||
|
|
||||||
enumGenerator.Generate("RpcCalls", "Impostor.Api.Net.Inner", underlyingType: CSharpEnumUnderlyingType.Byte);
|
|
||||||
|
|
||||||
var mapDataGenerator = new MapDataGenerator(spc, files);
|
|
||||||
|
|
||||||
var mapNames = new[] { "Skeld", "Mira", "April", "Polus", "Airship", "Fungle" };
|
|
||||||
foreach (var mapName in mapNames)
|
|
||||||
{
|
|
||||||
mapDataGenerator.Generate(mapName);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Numerics;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace Impostor.Api.Innersloth.Generator;
|
|
||||||
|
|
||||||
public class Vector2Converter : JsonConverter<Vector2>
|
|
||||||
{
|
|
||||||
public override Vector2 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
|
||||||
{
|
|
||||||
if (reader.TokenType != JsonTokenType.StartObject) throw new JsonException();
|
|
||||||
|
|
||||||
float x = 0;
|
|
||||||
float y = 0;
|
|
||||||
|
|
||||||
while (reader.Read())
|
|
||||||
{
|
|
||||||
if (reader.TokenType == JsonTokenType.EndObject) break;
|
|
||||||
|
|
||||||
switch (reader.GetString())
|
|
||||||
{
|
|
||||||
case "x":
|
|
||||||
reader.Read();
|
|
||||||
x = reader.GetSingle();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "y":
|
|
||||||
reader.Read();
|
|
||||||
y = reader.GetSingle();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Vector2(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Write(Utf8JsonWriter writer, Vector2 value, JsonSerializerOptions options)
|
|
||||||
{
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,157 +0,0 @@
|
|||||||
{
|
|
||||||
"version": 1,
|
|
||||||
"dependencies": {
|
|
||||||
".NETStandard,Version=v2.0": {
|
|
||||||
"CSharpPoet": {
|
|
||||||
"type": "Direct",
|
|
||||||
"requested": "[0.3.0, )",
|
|
||||||
"resolved": "0.3.0",
|
|
||||||
"contentHash": "3QDh9rMuiNhMtNWOLj0FItiZruON7lj3zD0CXC9IHq4JWpF5OjbaZ2s1X0u6gftE73KCoTezXIgKvxacps78Fw=="
|
|
||||||
},
|
|
||||||
"Microsoft.Bcl.AsyncInterfaces": {
|
|
||||||
"type": "Direct",
|
|
||||||
"requested": "[8.0.0, )",
|
|
||||||
"resolved": "8.0.0",
|
|
||||||
"contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==",
|
|
||||||
"dependencies": {
|
|
||||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Microsoft.CodeAnalysis.Analyzers": {
|
|
||||||
"type": "Direct",
|
|
||||||
"requested": "[3.3.4, )",
|
|
||||||
"resolved": "3.3.4",
|
|
||||||
"contentHash": "AxkxcPR+rheX0SmvpLVIGLhOUXAKG56a64kV9VQZ4y9gR9ZmPXnqZvHJnmwLSwzrEP6junUF11vuc+aqo5r68g=="
|
|
||||||
},
|
|
||||||
"Microsoft.CodeAnalysis.CSharp": {
|
|
||||||
"type": "Direct",
|
|
||||||
"requested": "[4.7.0, )",
|
|
||||||
"resolved": "4.7.0",
|
|
||||||
"contentHash": "JHCP2L6lB0oJ3tQoHkC67SFZxW+KbJVOnAo+6L01K5r/NlBlSUhTk5nUAldWhTVwGdzqNeHqGtnEqpsCmGSwQA==",
|
|
||||||
"dependencies": {
|
|
||||||
"Microsoft.CodeAnalysis.Common": "[4.7.0]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"NETStandard.Library": {
|
|
||||||
"type": "Direct",
|
|
||||||
"requested": "[2.0.3, )",
|
|
||||||
"resolved": "2.0.3",
|
|
||||||
"contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
|
|
||||||
"dependencies": {
|
|
||||||
"Microsoft.NETCore.Platforms": "1.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"PolySharp": {
|
|
||||||
"type": "Direct",
|
|
||||||
"requested": "[1.14.1, )",
|
|
||||||
"resolved": "1.14.1",
|
|
||||||
"contentHash": "mOOmFYwad3MIOL14VCjj02LljyF1GNw1wP0YVlxtcPvqdxjGGMNdNJJxHptlry3MOd8b40Flm8RPOM8JOlN2sQ=="
|
|
||||||
},
|
|
||||||
"System.Text.Encodings.Web": {
|
|
||||||
"type": "Direct",
|
|
||||||
"requested": "[8.0.0, )",
|
|
||||||
"resolved": "8.0.0",
|
|
||||||
"contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"System.Buffers": "4.5.1",
|
|
||||||
"System.Memory": "4.5.5",
|
|
||||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"System.Text.Json": {
|
|
||||||
"type": "Direct",
|
|
||||||
"requested": "[8.0.5, )",
|
|
||||||
"resolved": "8.0.5",
|
|
||||||
"contentHash": "0f1B50Ss7rqxXiaBJyzUu9bWFOO2/zSlifZ/UNMdiIpDYe4cY4LQQicP4nirK1OS31I43rn062UIJ1Q9bpmHpg==",
|
|
||||||
"dependencies": {
|
|
||||||
"Microsoft.Bcl.AsyncInterfaces": "8.0.0",
|
|
||||||
"System.Buffers": "4.5.1",
|
|
||||||
"System.Memory": "4.5.5",
|
|
||||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0",
|
|
||||||
"System.Text.Encodings.Web": "8.0.0",
|
|
||||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Microsoft.CodeAnalysis.Common": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.7.0",
|
|
||||||
"contentHash": "pD5S14xMUebSGYe75kt0q/aaS/ftvktSo/pEv7aX7hNPHfdZS+SZeXvkvcffGxWkunYOyRF9m1oN7zzSdYj9dQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"Microsoft.CodeAnalysis.Analyzers": "3.3.4",
|
|
||||||
"System.Collections.Immutable": "7.0.0",
|
|
||||||
"System.Memory": "4.5.5",
|
|
||||||
"System.Reflection.Metadata": "7.0.0",
|
|
||||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0",
|
|
||||||
"System.Text.Encoding.CodePages": "7.0.0",
|
|
||||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Microsoft.NETCore.Platforms": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "1.1.0",
|
|
||||||
"contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A=="
|
|
||||||
},
|
|
||||||
"System.Buffers": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.5.1",
|
|
||||||
"contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg=="
|
|
||||||
},
|
|
||||||
"System.Collections.Immutable": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "7.0.0",
|
|
||||||
"contentHash": "dQPcs0U1IKnBdRDBkrCTi1FoajSTBzLcVTpjO4MBCMC7f4pDOIPzgBoX8JjG7X6uZRJ8EBxsi8+DR1JuwjnzOQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"System.Memory": "4.5.5",
|
|
||||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"System.Memory": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.5.5",
|
|
||||||
"contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
|
|
||||||
"dependencies": {
|
|
||||||
"System.Buffers": "4.5.1",
|
|
||||||
"System.Numerics.Vectors": "4.4.0",
|
|
||||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"System.Numerics.Vectors": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.4.0",
|
|
||||||
"contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ=="
|
|
||||||
},
|
|
||||||
"System.Reflection.Metadata": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "7.0.0",
|
|
||||||
"contentHash": "MclTG61lsD9sYdpNz9xsKBzjsmsfCtcMZYXz/IUr2zlhaTaABonlr1ESeompTgM+Xk+IwtGYU7/voh3YWB/fWw==",
|
|
||||||
"dependencies": {
|
|
||||||
"System.Collections.Immutable": "7.0.0",
|
|
||||||
"System.Memory": "4.5.5"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"System.Runtime.CompilerServices.Unsafe": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "6.0.0",
|
|
||||||
"contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
|
|
||||||
},
|
|
||||||
"System.Text.Encoding.CodePages": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "7.0.0",
|
|
||||||
"contentHash": "LSyCblMpvOe0N3E+8e0skHcrIhgV2huaNcjUUEa8hRtgEAm36aGkRoC8Jxlb6Ra6GSfF29ftduPNywin8XolzQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"System.Memory": "4.5.5",
|
|
||||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"System.Threading.Tasks.Extensions": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.5.4",
|
|
||||||
"contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==",
|
|
||||||
"dependencies": {
|
|
||||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
".NETStandard,Version=v2.0/win-x64": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
namespace Impostor.Api;
|
|
||||||
|
|
||||||
// NOTE: when adding items to this enum, add them to the bottom for API stability
|
|
||||||
public enum CheatCategory
|
|
||||||
{
|
|
||||||
/// <summary>A packet used a part of the network protocol that is unknown to Impostor, like a custom RPC.</summary>
|
|
||||||
ProtocolExtension,
|
|
||||||
|
|
||||||
/// <summary>A host-only mod extension is used outside of host-authoritive mode.</summary>
|
|
||||||
HostOnlyExtension,
|
|
||||||
|
|
||||||
/// <summary>A packet was sent at an inappropriate moment.</summary>
|
|
||||||
GameFlow,
|
|
||||||
|
|
||||||
/// <summary>A packet was sent by a non-host player that should normally only be sent by the host.</summary>
|
|
||||||
MustBeHost,
|
|
||||||
|
|
||||||
/// <summary>A packet was sent that violated limits on the selection of player colors.</summary>
|
|
||||||
ColorLimits,
|
|
||||||
|
|
||||||
/// <summary>A packet was sent that exceeded the limits of possible nicknames to enter ingame.</summary>
|
|
||||||
NameLimits,
|
|
||||||
|
|
||||||
/// <summary>A packet was sent on behalf of another player.</summary>
|
|
||||||
Ownership,
|
|
||||||
|
|
||||||
/// <summary>An ability was used that the current role cannot access.</summary>
|
|
||||||
Role,
|
|
||||||
|
|
||||||
/// <summary>A packet was sent to a player that should be broadcasted, or vice versa.</summary>
|
|
||||||
Target,
|
|
||||||
|
|
||||||
/// <summary>A packet was sent on an invalid network object, like a PlayerControl without PlayerInfo.</summary>
|
|
||||||
InvalidObject,
|
|
||||||
|
|
||||||
/// <summary>A packet was sent that exceeded the maximum allowed RPC size.</summary>
|
|
||||||
PacketSize,
|
|
||||||
|
|
||||||
/// <summary>Legacy category for unsorted anticheat checks.</summary>
|
|
||||||
Other,
|
|
||||||
|
|
||||||
/// <summary>A packet was sent with more items than possible in the game.</summary>
|
|
||||||
ItemLimits,
|
|
||||||
|
|
||||||
/// <summary>A packet contained an identifier (friendcode or puid) that does not match the one known for that player.</summary>
|
|
||||||
Identifiers,
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
namespace Impostor.Api.Config
|
|
||||||
{
|
|
||||||
public class AntiCheatConfig
|
|
||||||
{
|
|
||||||
public const string Section = "AntiCheat";
|
|
||||||
|
|
||||||
public bool Enabled { get; set; } = true;
|
|
||||||
|
|
||||||
public bool BanIpFromGame { get; set; } = true;
|
|
||||||
|
|
||||||
public CheatingHostMode AllowCheatingHosts { get; set; } = CheatingHostMode.Never;
|
|
||||||
|
|
||||||
public CheatingHostMode AllowHostOnlyExtensions { get; set; } = CheatingHostMode.IfRequested;
|
|
||||||
|
|
||||||
public bool EnableGameFlowChecks { get; set; } = true;
|
|
||||||
|
|
||||||
public bool EnableMustBeHostChecks { get; set; } = true;
|
|
||||||
|
|
||||||
public bool EnableInvalidObjectChecks { get; set; } = true;
|
|
||||||
|
|
||||||
public bool EnableColorLimitChecks { get; set; } = true;
|
|
||||||
|
|
||||||
public bool EnableNameLimitChecks { get; set; } = true;
|
|
||||||
|
|
||||||
public bool EnableItemLimitChecks { get; set; } = true;
|
|
||||||
|
|
||||||
public bool EnableOwnershipChecks { get; set; } = true;
|
|
||||||
|
|
||||||
public bool EnableRoleChecks { get; set; } = true;
|
|
||||||
|
|
||||||
public bool EnableTargetChecks { get; set; } = true;
|
|
||||||
|
|
||||||
public bool EnableIdentifierChecks { get; set; } = true;
|
|
||||||
|
|
||||||
public bool ForbidProtocolExtensions { get; set; } = true;
|
|
||||||
|
|
||||||
public bool EnablePacketSizeChecks { get; set; } = true;
|
|
||||||
|
|
||||||
public int PacketSizeLimit { get; set; } = 1203;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
namespace Impostor.Api.Config
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Details if exceptions are made for hosts that are cheating.
|
|
||||||
/// </summary>
|
|
||||||
public enum CheatingHostMode
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Hosts follow the same policies as other players.
|
|
||||||
/// </summary>
|
|
||||||
Never,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Hosts are allowed to cheat if they request HostAuthority. If they
|
|
||||||
/// do not request this, the same policies as for other players applies.
|
|
||||||
/// </summary>
|
|
||||||
/// <para>
|
|
||||||
/// HostAuthority can be requested by hosts by adding 25 to their patch
|
|
||||||
/// version when connecting. This flag is used by a lot of (host-only)
|
|
||||||
/// mods and also disable server authority over MurderPlayer packets.
|
|
||||||
/// </para>
|
|
||||||
IfRequested,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Hosts are always allowed to cheat.
|
|
||||||
/// </summary>
|
|
||||||
Always,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
namespace Impostor.Api.Config
|
|
||||||
{
|
|
||||||
public class CompatibilityConfig
|
|
||||||
{
|
|
||||||
public const string Section = "Compatibility";
|
|
||||||
|
|
||||||
public bool AllowFutureGameVersions { get; set; } = false;
|
|
||||||
|
|
||||||
public bool AllowHostAuthority { get; set; } = false;
|
|
||||||
|
|
||||||
public bool AllowVersionMixing { get; set; } = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
namespace Impostor.Api.Config
|
|
||||||
{
|
|
||||||
public static class DisconnectMessages
|
|
||||||
{
|
|
||||||
public const string Error = "There was an internal server error. " +
|
|
||||||
"Check the server console for more information. " +
|
|
||||||
"Please report the issue on the Impostor GitHub if it keeps happening.";
|
|
||||||
|
|
||||||
public const string ClientOutdated = "Please update your game to play in this lobby.";
|
|
||||||
|
|
||||||
public const string ClientTooNew = "Your game version is too new for this lobby. " +
|
|
||||||
"If you want to join this lobby you need to downgrade your client.";
|
|
||||||
|
|
||||||
public const string Destroyed = "The game you tried to join is being destroyed. " +
|
|
||||||
"Please create a new game.";
|
|
||||||
|
|
||||||
public const string UsernameLength = "Your username is too long, please make it shorter.";
|
|
||||||
|
|
||||||
public const string UsernameIllegalCharacters = "Your username contains illegal characters, please remove them.";
|
|
||||||
|
|
||||||
public const string VersionClientTooOld = "Please update your game to play on this server.";
|
|
||||||
|
|
||||||
public const string VersionServerTooOld = "Your client is too new, please update your Impostor server to play.";
|
|
||||||
|
|
||||||
public const string VersionUnsupported = "Your client version is unsupported, please update your Game and/or Impostor server.";
|
|
||||||
|
|
||||||
private const string UpgradingDocsLink = "https://github.com/Impostor/Impostor/blob/master/docs/Upgrading.md";
|
|
||||||
|
|
||||||
public const string UdpMatchmakingUnsupported = $"""
|
|
||||||
Sorry, UDP Matchmaking is no longer supported.
|
|
||||||
See <link={UpgradingDocsLink}#impostor-190>Impostor documentation</link> on how to migrate to HTTP Matchmaking
|
|
||||||
""";
|
|
||||||
|
|
||||||
public const string HostAuthorityUnsupported = "Your client is requesting host authority, which is not enabled on this Impostor server.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
namespace Impostor.Api.Config;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Configuration for HttpServer.
|
|
||||||
/// </summary>
|
|
||||||
public class HttpServerConfig
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the name of this config section.
|
|
||||||
/// </summary>
|
|
||||||
public const string Section = "HttpServer";
|
|
||||||
|
|
||||||
public bool Enabled { get; set; } = true;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the IP address the HTTP Matchmaking server will listen on.
|
|
||||||
/// </summary>
|
|
||||||
/// Use "127.0.0.1" if you are running behind a reverse proxy or just testing locally.
|
|
||||||
/// Use "0.0.0.0" if you are directly exposing this server to the internet.
|
|
||||||
public string ListenIp { get; set; } = "0.0.0.0";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the port the HTTP Matchmaking server will listen on.
|
|
||||||
/// </summary>
|
|
||||||
/// For port forwarding purposes, this is a TCP port.
|
|
||||||
public ushort ListenPort { get; set; } = 22023;
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
namespace Impostor.Api.Config
|
|
||||||
{
|
|
||||||
public class TimeoutConfig
|
|
||||||
{
|
|
||||||
public const string Section = "Timeout";
|
|
||||||
|
|
||||||
public int SpawnTimeout { get; set; } = 2500;
|
|
||||||
|
|
||||||
public int ConnectionTimeout { get; set; } = 2500;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using Impostor.Api.Net;
|
using Impostor.Api.Net;
|
||||||
|
using Impostor.Api.Net.Messages;
|
||||||
|
|
||||||
namespace Impostor.Api.Events.Client
|
namespace Impostor.Api.Events.Client
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,24 +1,11 @@
|
|||||||
using Impostor.Api.Games;
|
using Impostor.Api.Games;
|
||||||
using Impostor.Api.Net;
|
|
||||||
|
|
||||||
namespace Impostor.Api.Events
|
namespace Impostor.Api.Events
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called whenever a new <see cref="IGame" /> is created.
|
/// Called whenever a new <see cref="IGame" /> is created.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
|
||||||
/// Note that the game just has been created, so no players have joined
|
|
||||||
/// it yet. If you want to know the future host of this game, use the
|
|
||||||
/// <see cref="Host"/> property.
|
|
||||||
/// </remarks>
|
|
||||||
public interface IGameCreatedEvent : IGameEvent
|
public interface IGameCreatedEvent : IGameEvent
|
||||||
{
|
{
|
||||||
/// <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? Host { get; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
using Impostor.Api.Games;
|
|
||||||
|
|
||||||
namespace Impostor.Api.Events
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// This event is triggered when game options are going to be changed.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Be careful when calling SyncSettingsAsync while handling this event,
|
|
||||||
/// as it may call this event again in some cases.
|
|
||||||
/// </remarks>
|
|
||||||
public interface IGameOptionsChangedEvent : IGameEvent
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Lists the possible reasons that the game options may have changed.
|
|
||||||
/// </summary>
|
|
||||||
public enum ChangeReason
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The options were changed by the host using LogicOptions deserialization.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This event does not change the message sent to other players,
|
|
||||||
/// so changes made to Game.Options are not synced until
|
|
||||||
/// SyncSettingsAsync is called afterwards.
|
|
||||||
/// </remarks>
|
|
||||||
Host,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The options were changed by a plugin using the
|
|
||||||
/// SyncSettingsAsync method in <see cref="IGame"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This event is called after serializing the settings, which
|
|
||||||
/// means that changes made by event handlers will not be synced
|
|
||||||
/// over.
|
|
||||||
///
|
|
||||||
/// We strongly recommend against calling SyncSettingsAsync while
|
|
||||||
/// handling this event.
|
|
||||||
/// </remarks>
|
|
||||||
Api,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the reason that the game options have changed.
|
|
||||||
/// </summary>
|
|
||||||
public ChangeReason ChangedBy { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using Impostor.Api.Net.Inner.Objects;
|
using Impostor.Api.Net.Inner.Objects;
|
||||||
|
|
||||||
namespace Impostor.Api.Events.Meeting
|
namespace Impostor.Api.Events.Meeting
|
||||||
{
|
{
|
||||||
@@ -13,15 +13,5 @@ namespace Impostor.Api.Events.Meeting
|
|||||||
/// Gets a value indicating whether meeting result is a tie.
|
/// Gets a value indicating whether meeting result is a tie.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool IsTie { get; }
|
bool IsTie { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether a Judge overruled the vote result.
|
|
||||||
/// </summary>
|
|
||||||
bool WasOverruled { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the nonce of the winning Judge overrule, or 0 if the meeting wasn't overruled.
|
|
||||||
/// </summary>
|
|
||||||
ushort OverrideId { get; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Impostor.Api.Events.Player
|
namespace Impostor.Api.Events.Player
|
||||||
{
|
{
|
||||||
public interface IPlayerChatEvent : IPlayerEvent, IEventCancelable
|
public interface IPlayerChatEvent : IPlayerEvent, IEventCancelable
|
||||||
{
|
{
|
||||||
@@ -6,12 +6,5 @@ namespace Impostor.Api.Events.Player
|
|||||||
/// Gets the message sent by the player.
|
/// Gets the message sent by the player.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
string Message { get; }
|
string Message { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether the message is sent to
|
|
||||||
/// all players (true) or only to the host (false).
|
|
||||||
/// To not send this message at all, cancel this event instead.
|
|
||||||
/// </summary>
|
|
||||||
bool SendToAllPlayers { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
using Impostor.Api.Innersloth;
|
|
||||||
using Impostor.Api.Net.Inner.Objects;
|
|
||||||
|
|
||||||
namespace Impostor.Api.Events.Player
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Event that allows changing or canceling an upcoming player murder.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Note that this event only triggers if the Host of the Game did not disable server authority.
|
|
||||||
///
|
|
||||||
/// If you want to get an event after the murder took place, listen to <see cref="IPlayerMurderEvent"/>.
|
|
||||||
/// </remarks>
|
|
||||||
public interface IPlayerCheckMurderEvent : IPlayerEvent, IEventCancelable
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the player who will be murdered.
|
|
||||||
/// </summary>
|
|
||||||
IInnerPlayerControl Victim { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the result of this event.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Its initial value is what would have happened in the normal game flow.
|
|
||||||
/// - If set to Succeeded, the Victim will die.
|
|
||||||
/// - If set to FailedProtected, the Victim will be protected with a shield animation and the attacker will have a cooldown set.
|
|
||||||
/// </remarks>
|
|
||||||
MurderResultFlags Result { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using Impostor.Api.Innersloth.Maps;
|
using Impostor.Api.Innersloth;
|
||||||
|
|
||||||
namespace Impostor.Api.Events.Player
|
namespace Impostor.Api.Events.Player
|
||||||
{
|
{
|
||||||
@@ -10,6 +10,6 @@ namespace Impostor.Api.Events.Player
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the entered vent.
|
/// Gets the entered vent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public VentData Vent { get; }
|
public IVent Vent { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using Impostor.Api.Innersloth.Maps;
|
using Impostor.Api.Innersloth;
|
||||||
|
|
||||||
namespace Impostor.Api.Events.Player
|
namespace Impostor.Api.Events.Player
|
||||||
{
|
{
|
||||||
@@ -10,6 +10,6 @@ namespace Impostor.Api.Events.Player
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the exited vent.
|
/// Gets the exited vent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public VentData Vent { get; }
|
public IVent Vent { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,30 +1,12 @@
|
|||||||
using Impostor.Api.Innersloth;
|
|
||||||
using Impostor.Api.Net.Inner.Objects;
|
using Impostor.Api.Net.Inner.Objects;
|
||||||
|
|
||||||
namespace Impostor.Api.Events.Player
|
namespace Impostor.Api.Events.Player
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Event that is called when a player is killed by another player.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This event works regardless of server authority is enabled or not.
|
|
||||||
///
|
|
||||||
/// If you want to cancel this kill, listen to <see cref="IPlayerCheckMurderEvent"/>.
|
|
||||||
/// If you want to know about players that were voted out, listed to <see cref="IPlayerExileEvent"/>.
|
|
||||||
/// </remarks>
|
|
||||||
public interface IPlayerMurderEvent : IPlayerEvent
|
public interface IPlayerMurderEvent : IPlayerEvent
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the player who got murdered.
|
/// Gets the player who got murdered.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IInnerPlayerControl Victim { get; }
|
IInnerPlayerControl Victim { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the result of the event.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Note that if FailedError or FailedProtected is set, the kill did not take place.
|
|
||||||
/// </remarks>
|
|
||||||
MurderResultFlags Result { get; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using Impostor.Api.Innersloth.Maps;
|
using Impostor.Api.Innersloth;
|
||||||
|
|
||||||
namespace Impostor.Api.Events.Player
|
namespace Impostor.Api.Events.Player
|
||||||
{
|
{
|
||||||
@@ -10,6 +10,6 @@ namespace Impostor.Api.Events.Player
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the vent player moved to.
|
/// Gets the vent player moved to.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public VentData NewVent { get; }
|
public IVent NewVent { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,12 +2,10 @@ using Impostor.Api.Net.Inner.Objects;
|
|||||||
|
|
||||||
namespace Impostor.Api.Events.Player
|
namespace Impostor.Api.Events.Player
|
||||||
{
|
{
|
||||||
public enum VoteType : byte
|
public enum VoteType : sbyte
|
||||||
{
|
{
|
||||||
HasNotVoted = 255,
|
ForceSkip = -2,
|
||||||
Missed = 254,
|
Skip = -1,
|
||||||
Skipped = 253,
|
|
||||||
Dead = 252,
|
|
||||||
Player = 0,
|
Player = 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
|
||||||
namespace Impostor.Api
|
namespace Impostor.Api
|
||||||
{
|
{
|
||||||
@@ -15,5 +16,9 @@ namespace Impostor.Api
|
|||||||
public ImpostorConfigException(string? message, Exception? innerException) : base(message, innerException)
|
public ImpostorConfigException(string? message, Exception? innerException) : base(message, innerException)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected ImpostorConfigException(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
|
||||||
namespace Impostor.Api
|
namespace Impostor.Api
|
||||||
{
|
{
|
||||||
@@ -15,5 +16,9 @@ namespace Impostor.Api
|
|||||||
public ImpostorException(string? message, Exception? innerException) : base(message, innerException)
|
public ImpostorException(string? message, Exception? innerException) : base(message, innerException)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected ImpostorException(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
|
||||||
namespace Impostor.Api
|
namespace Impostor.Api
|
||||||
{
|
{
|
||||||
@@ -15,5 +16,9 @@ namespace Impostor.Api
|
|||||||
public ImpostorProtocolException(string? message, Exception? innerException) : base(message, innerException)
|
public ImpostorProtocolException(string? message, Exception? innerException) : base(message, innerException)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected ImpostorProtocolException(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
using Impostor.Api.Innersloth;
|
|
||||||
|
|
||||||
namespace Impostor.Api;
|
|
||||||
|
|
||||||
public static class MurderResultFlagsExtensions
|
|
||||||
{
|
|
||||||
public static bool IsFailed(this MurderResultFlags value)
|
|
||||||
{
|
|
||||||
return (value & (MurderResultFlags.FailedError | MurderResultFlags.FailedProtected)) != 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -16,13 +16,6 @@ namespace Impostor.Api
|
|||||||
return original[0];
|
return original[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static short ReadInt16(this ref ReadOnlySpan<byte> input)
|
|
||||||
{
|
|
||||||
var original = Advance<short>(ref input);
|
|
||||||
return BinaryPrimitives.ReadInt16LittleEndian(original);
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static int ReadInt32(this ref ReadOnlySpan<byte> input)
|
public static int ReadInt32(this ref ReadOnlySpan<byte> input)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Impostor.Api.Net;
|
using Impostor.Api.Net;
|
||||||
|
using Impostor.Api.Net.Messages;
|
||||||
|
|
||||||
namespace Impostor.Api.Games
|
namespace Impostor.Api.Games
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -37,16 +37,6 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
GameDestroyed,
|
GameDestroyed,
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The host has a newer version of the game and the client should update.
|
|
||||||
/// </summary>
|
|
||||||
ClientOutdated,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The host has an older version of the game and the client should downgrade.
|
|
||||||
/// </summary>
|
|
||||||
ClientTooNew,
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Custom error by a plugin.
|
/// Custom error by a plugin.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,19 +1,16 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Impostor.Api.Innersloth;
|
using Impostor.Api.Innersloth;
|
||||||
using Impostor.Api.Innersloth.GameOptions;
|
|
||||||
using Impostor.Api.Net;
|
using Impostor.Api.Net;
|
||||||
using Impostor.Api.Net.Inner;
|
using Impostor.Api.Net.Inner;
|
||||||
|
using Impostor.Api.Net.Messages;
|
||||||
|
|
||||||
namespace Impostor.Api.Games
|
namespace Impostor.Api.Games
|
||||||
{
|
{
|
||||||
public interface IGame
|
public interface IGame
|
||||||
{
|
{
|
||||||
IGameOptions Options { get; }
|
GameOptionsData Options { get; }
|
||||||
|
|
||||||
GameFilterOptions FilterOptions { get; }
|
|
||||||
|
|
||||||
GameCode Code { get; }
|
GameCode Code { get; }
|
||||||
|
|
||||||
@@ -40,19 +37,6 @@ namespace Impostor.Api.Games
|
|||||||
|
|
||||||
int HostId { get; }
|
int HostId { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether the Host of the game has requested host authority.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Vanilla Among Us does not request this, but certain client-side mods will.
|
|
||||||
/// </remarks>
|
|
||||||
bool IsHostAuthoritive { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the mod GUID that the game was registered with through the AMCI.
|
|
||||||
/// </summary>
|
|
||||||
Guid? ModGuid { get; }
|
|
||||||
|
|
||||||
IClientPlayer? GetClientPlayer(int clientId);
|
IClientPlayer? GetClientPlayer(int clientId);
|
||||||
|
|
||||||
T? FindObjectByNetId<T>(uint netId)
|
T? FindObjectByNetId<T>(uint netId)
|
||||||
@@ -69,7 +53,7 @@ namespace Impostor.Api.Games
|
|||||||
void BanIp(IPAddress ipAddress);
|
void BanIp(IPAddress ipAddress);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Syncs the internal <see cref="IGameOptions" /> 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.
|
/// Necessary to do if you modified it, otherwise it won't be used.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
|
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
|
||||||
@@ -107,41 +91,22 @@ namespace Impostor.Api.Games
|
|||||||
/// <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);
|
ValueTask SendToAsync(IMessageWriter writer, int id);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Start a GameData(To) message.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>Use with caution, recommended only for advanced developers.</remarks>
|
|
||||||
/// <param name="targetClientId">The client to target if needed, `null` if the message should be sent to all players.</param>
|
|
||||||
/// <param name="type">Message type of the message.</param>
|
|
||||||
/// <returns>A <see cref="IMessageWriter" /> that you can fill and send using <see cref="FinishGameDataAsync"/>.</returns>
|
|
||||||
IMessageWriter StartGameData(int? targetClientId = null, MessageType type = MessageType.Reliable);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finishes GameData message and sends it to either the target or all players.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>Use with caution, recommended only for advanced developers.</remarks>
|
|
||||||
/// <param name="writer">MessageWriter received from <see cref="StartGameData"/>.</param>
|
|
||||||
/// <param name="targetClientId">Same target ClientId passed to StartGameData.</param>
|
|
||||||
/// <returns>Task that sends the packet.</returns>
|
|
||||||
ValueTask FinishGameDataAsync(IMessageWriter writer, int? targetClientId = null);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a MessageWriter with GameData header.
|
/// Creates a MessageWriter with GameData header.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>Use with caution, recommended only for advanced developers.</remarks>
|
/// <remarks>Use with caution, recommended only for advanced developers.</remarks>
|
||||||
/// <param name="targetNetId">Net id of the InnerNetObject.</param>
|
/// <param name="targetNetId">Net id of the InnerNetObject.</param>
|
||||||
/// <param name="callId">Rpc id of the message.</param>
|
/// <param name="callId">Rpc id of the message.</param>
|
||||||
/// <param name="targetClientId">The client to target if needed, `null` if the message should be sent to all players.</param>
|
/// <param name="targetClientId">Client id of GameDataTo's target.</param>
|
||||||
/// <param name="type">Message type of the message.</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>
|
/// <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 = null, MessageType type = MessageType.Reliable);
|
IMessageWriter StartRpc(uint targetNetId, RpcCalls callId, int? targetClientId, MessageType type = MessageType.Reliable);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finishes rpc message and sends it to either the target or all players.
|
/// Finishes rpc message and sends it to the target.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>Use with caution, recommended only for advanced developers.</remarks>
|
|
||||||
/// <param name="writer">Message writer of the rpc.</param>
|
/// <param name="writer">Message writer of the rpc.</param>
|
||||||
/// <param name="targetClientId">Same target client id passed to <see cref="StartRpc"/>.</param>
|
/// <param name="targetClientId">Id of the receiving client.</param>
|
||||||
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
|
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
|
||||||
ValueTask FinishRpcAsync(IMessageWriter writer, int? targetClientId = null);
|
ValueTask FinishRpcAsync(IMessageWriter writer, int? targetClientId = null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Impostor.Api.Innersloth;
|
using Impostor.Api.Innersloth;
|
||||||
using Impostor.Api.Innersloth.GameOptions;
|
|
||||||
|
|
||||||
namespace Impostor.Api.Games.Managers
|
namespace Impostor.Api.Games.Managers
|
||||||
{
|
{
|
||||||
@@ -15,9 +14,8 @@ namespace Impostor.Api.Games.Managers
|
|||||||
/// Creates a new game.
|
/// Creates a new game.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="options">Game options.</param>
|
/// <param name="options">Game options.</param>
|
||||||
/// <param name="filterOptions">Filter options.</param>
|
|
||||||
/// <returns>Created game or null if creation was cancelled by a plugin.</returns>
|
/// <returns>Created game or null if creation was cancelled by a plugin.</returns>
|
||||||
/// <exception cref="ImpostorException">Thrown when game creation failed.</exception>
|
/// <exception cref="ImpostorException">Thrown when game creation failed.</exception>
|
||||||
ValueTask<IGame?> CreateAsync(IGameOptions options, GameFilterOptions filterOptions);
|
ValueTask<IGame?> CreateAsync(GameOptionsData options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1 +0,0 @@
|
|||||||
global using Impostor.Hazel.Abstractions;
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Impostor.Api.Games;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
|
|
||||||
namespace Impostor.Api.Http;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Register a method to filter listings on.
|
|
||||||
/// </summary>
|
|
||||||
public interface IListingFilter
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Return a filter to filter listings on.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="context">HTTP Context of this request.</param>
|
|
||||||
/// <returns>A function that looks at a game and returns true iff the connecting player is compatible with this game.</returns>
|
|
||||||
Func<IGame, bool> GetFilter(HttpContext context);
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
<CodeAnalysisRuleSet>../ProjectRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>../ProjectRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<LangVersion>9</LangVersion>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<IncludeSymbols>true</IncludeSymbols>
|
<IncludeSymbols>true</IncludeSymbols>
|
||||||
@@ -25,14 +27,16 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0" />
|
<PackageReference Include="Nullable" Version="1.3.0">
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556" PrivateAssets="all" />
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<PackageReference Include="Impostor.Hazel.Abstractions" Version="1.0.1" />
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
<ProjectReference Include="..\Impostor.Api.Innersloth.Generator\Impostor.Api.Innersloth.Generator.csproj" ReferenceOutputAssembly="false" OutputItemType="Analyzer" />
|
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
||||||
<AdditionalFiles Include="Innersloth/Data/**/*.json" />
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -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,17 +0,0 @@
|
|||||||
namespace Impostor.Api.Innersloth;
|
|
||||||
|
|
||||||
public enum CrossplayFlags
|
|
||||||
{
|
|
||||||
Unknown = 0,
|
|
||||||
StandaloneEpicPC = 1 << 1,
|
|
||||||
StandaloneSteamPC = 1 << 2,
|
|
||||||
StandaloneMac = 1 << 3,
|
|
||||||
StandaloneWin10 = 1 << 4,
|
|
||||||
StandaloneItch = 1 << 5,
|
|
||||||
IPhone = 1 << 6,
|
|
||||||
Android = 1 << 7,
|
|
||||||
Switch = 1 << 8,
|
|
||||||
Xbox = 1 << 9,
|
|
||||||
Playstation = 1 << 10,
|
|
||||||
All = int.MaxValue,
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
namespace Impostor.Api.Innersloth.Customization
|
||||||
|
{
|
||||||
|
public enum ColorType
|
||||||
|
{
|
||||||
|
Red = 0,
|
||||||
|
Blue = 1,
|
||||||
|
Green = 2,
|
||||||
|
Pink = 3,
|
||||||
|
Orange = 4,
|
||||||
|
Yellow = 5,
|
||||||
|
Black = 6,
|
||||||
|
White = 7,
|
||||||
|
Purple = 8,
|
||||||
|
Brown = 9,
|
||||||
|
Cyan = 10,
|
||||||
|
Lime = 11,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
namespace Impostor.Api.Innersloth.Customization
|
||||||
|
{
|
||||||
|
public enum HatType : uint
|
||||||
|
{
|
||||||
|
NoHat = 0,
|
||||||
|
Astronaut = 1,
|
||||||
|
BaseballCap = 2,
|
||||||
|
BrainSlug = 3,
|
||||||
|
BushHat = 4,
|
||||||
|
CaptainsHat = 5,
|
||||||
|
DoubleTopHat = 6,
|
||||||
|
Flowerpot = 7,
|
||||||
|
Goggles = 8,
|
||||||
|
HardHat = 9,
|
||||||
|
Military = 10,
|
||||||
|
PaperHat = 11,
|
||||||
|
PartyHat = 12,
|
||||||
|
Police = 13,
|
||||||
|
Stethescope = 14,
|
||||||
|
TopHat = 15,
|
||||||
|
TowelWizard = 16,
|
||||||
|
Ushanka = 17,
|
||||||
|
Viking = 18,
|
||||||
|
WallCap = 19,
|
||||||
|
Snowman = 20,
|
||||||
|
Reindeer = 21,
|
||||||
|
Lights = 22,
|
||||||
|
Santa = 23,
|
||||||
|
Tree = 24,
|
||||||
|
Present = 25,
|
||||||
|
Candycanes = 26,
|
||||||
|
ElfHat = 27,
|
||||||
|
NewYears2018 = 28,
|
||||||
|
WhiteHat = 29,
|
||||||
|
Crown = 30,
|
||||||
|
Eyebrows = 31,
|
||||||
|
HaloHat = 32,
|
||||||
|
HeroCap = 33,
|
||||||
|
PipCap = 34,
|
||||||
|
PlungerHat = 35,
|
||||||
|
ScubaHat = 36,
|
||||||
|
StickminHat = 37,
|
||||||
|
StrawHat = 38,
|
||||||
|
TenGallonHat = 39,
|
||||||
|
ThirdEyeHat = 40,
|
||||||
|
ToiletPaperHat = 41,
|
||||||
|
Toppat = 42,
|
||||||
|
BlackFedora = 43,
|
||||||
|
SkiGoggles = 44,
|
||||||
|
Headphones = 45,
|
||||||
|
MaskHat = 46,
|
||||||
|
PaperMask = 47,
|
||||||
|
Security = 48,
|
||||||
|
StrapHat = 49,
|
||||||
|
Banana = 50,
|
||||||
|
Beanie = 51,
|
||||||
|
Bear = 52,
|
||||||
|
Cheese = 53,
|
||||||
|
Cherry = 54,
|
||||||
|
Egg = 55,
|
||||||
|
GreenFedora = 56,
|
||||||
|
Flamingo = 57,
|
||||||
|
FlowerPin = 58,
|
||||||
|
Helmet = 59,
|
||||||
|
Plant = 60,
|
||||||
|
BatEyes = 61,
|
||||||
|
BatWings = 62,
|
||||||
|
Horns = 63,
|
||||||
|
Mohawk = 64,
|
||||||
|
Pumpkin = 65,
|
||||||
|
ScaryBag = 66,
|
||||||
|
Witch = 67,
|
||||||
|
Wolf = 68,
|
||||||
|
Pirate = 69,
|
||||||
|
Plague = 70,
|
||||||
|
Machete = 71,
|
||||||
|
Fred = 72,
|
||||||
|
MinerCap = 73,
|
||||||
|
WinterHat = 74,
|
||||||
|
Archae = 75,
|
||||||
|
Antenna = 76,
|
||||||
|
Balloon = 77,
|
||||||
|
BirdNest = 78,
|
||||||
|
BlackBelt = 79,
|
||||||
|
Caution = 80,
|
||||||
|
Chef = 81,
|
||||||
|
CopHat = 82,
|
||||||
|
DoRag = 83,
|
||||||
|
DumSticker = 84,
|
||||||
|
Fez = 85,
|
||||||
|
GeneralHat = 86,
|
||||||
|
GreyThing = 87,
|
||||||
|
HunterCap = 88,
|
||||||
|
JungleHat = 89,
|
||||||
|
MiniCrewmate = 90,
|
||||||
|
NinjaMask = 91,
|
||||||
|
RamHorns = 92,
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
namespace Impostor.Api.Innersloth.Customization
|
||||||
|
{
|
||||||
|
public enum PetType : uint
|
||||||
|
{
|
||||||
|
NoPet = 0,
|
||||||
|
Alien = 1,
|
||||||
|
Crewmate = 2,
|
||||||
|
Doggy = 3,
|
||||||
|
Stickmin = 4,
|
||||||
|
Hamster = 5,
|
||||||
|
Robot = 6,
|
||||||
|
Ufo = 7,
|
||||||
|
Ellie = 8,
|
||||||
|
Squig = 9,
|
||||||
|
Bedcrab = 10,
|
||||||
|
Glitch = 11,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,125 +0,0 @@
|
|||||||
namespace Impostor.Api.Innersloth.Customization
|
|
||||||
{
|
|
||||||
public class PlayerOutfit
|
|
||||||
{
|
|
||||||
// Magic value that is assigned by default when the outfit is initially created. This is not
|
|
||||||
// `null` because existing API already exposed this magic value. It's also not 0 (which is
|
|
||||||
// the value exposed when serializing) because SetColor anticheat checks exist.
|
|
||||||
private const ColorType UnknownColor = (ColorType)(-1);
|
|
||||||
|
|
||||||
private string _playerName = string.Empty;
|
|
||||||
private ColorType _color = UnknownColor;
|
|
||||||
private string _hatId = "missing";
|
|
||||||
private string _petId = "missing";
|
|
||||||
private string _skinId = "missing";
|
|
||||||
private string _visorId = "missing";
|
|
||||||
private string _namePlateId = "missing";
|
|
||||||
|
|
||||||
public bool IsDirty { get; internal set; }
|
|
||||||
|
|
||||||
public string PlayerName
|
|
||||||
{
|
|
||||||
get => _playerName;
|
|
||||||
internal set => SetField(ref _playerName, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ColorType Color
|
|
||||||
{
|
|
||||||
get => _color;
|
|
||||||
internal set => SetField(ref _color, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string HatId
|
|
||||||
{
|
|
||||||
get => _hatId;
|
|
||||||
internal set => SetField(ref _hatId, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string PetId
|
|
||||||
{
|
|
||||||
get => _petId;
|
|
||||||
internal set => SetField(ref _petId, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string SkinId
|
|
||||||
{
|
|
||||||
get => _skinId;
|
|
||||||
internal set => SetField(ref _skinId, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string VisorId
|
|
||||||
{
|
|
||||||
get => _visorId;
|
|
||||||
internal set => SetField(ref _visorId, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string NamePlateId
|
|
||||||
{
|
|
||||||
get => _namePlateId;
|
|
||||||
internal set => SetField(ref _namePlateId, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal byte HatSequenceId { get; set; } = 0;
|
|
||||||
|
|
||||||
internal byte PetSequenceId { get; set; } = 0;
|
|
||||||
|
|
||||||
internal byte SkinSequenceId { get; set; } = 0;
|
|
||||||
|
|
||||||
internal byte VisorSequenceId { get; set; } = 0;
|
|
||||||
|
|
||||||
internal byte NamePlateSequenceId { get; set; } = 0;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether a player outfit is complete or whether it needs to receive additional cosmetics.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>true if the outfit is incomplete, false if the outfit is complete.</returns>
|
|
||||||
public bool IsIncomplete => string.IsNullOrEmpty(PlayerName)
|
|
||||||
|| Color == UnknownColor
|
|
||||||
|| HatId == "missing"
|
|
||||||
|| PetId == "missing"
|
|
||||||
|| SkinId == "missing"
|
|
||||||
|| VisorId == "missing"
|
|
||||||
|| NamePlateId == "missing";
|
|
||||||
|
|
||||||
public void Serialize(IMessageWriter writer)
|
|
||||||
{
|
|
||||||
writer.Write(PlayerName);
|
|
||||||
|
|
||||||
// Follow officials by not sending a color value that is out of range. Sending -1 can cause exceptions on the client side.
|
|
||||||
writer.WritePacked(Color == UnknownColor ? 0 : (int)Color);
|
|
||||||
|
|
||||||
writer.Write(HatId);
|
|
||||||
writer.Write(PetId);
|
|
||||||
writer.Write(SkinId);
|
|
||||||
writer.Write(VisorId);
|
|
||||||
writer.Write(NamePlateId);
|
|
||||||
writer.Write(HatSequenceId);
|
|
||||||
writer.Write(PetSequenceId);
|
|
||||||
writer.Write(SkinSequenceId);
|
|
||||||
writer.Write(VisorSequenceId);
|
|
||||||
writer.Write(NamePlateSequenceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Deserialize(IMessageReader reader)
|
|
||||||
{
|
|
||||||
PlayerName = reader.ReadString();
|
|
||||||
Color = (ColorType)reader.ReadPackedInt32();
|
|
||||||
HatId = reader.ReadString();
|
|
||||||
PetId = reader.ReadString();
|
|
||||||
SkinId = reader.ReadString();
|
|
||||||
VisorId = reader.ReadString();
|
|
||||||
NamePlateId = reader.ReadString();
|
|
||||||
HatSequenceId = reader.ReadByte();
|
|
||||||
PetSequenceId = reader.ReadByte();
|
|
||||||
SkinSequenceId = reader.ReadByte();
|
|
||||||
VisorSequenceId = reader.ReadByte();
|
|
||||||
NamePlateSequenceId = reader.ReadByte();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetField<T>(ref T field, T value)
|
|
||||||
{
|
|
||||||
field = value;
|
|
||||||
IsDirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
namespace Impostor.Api.Innersloth.Customization
|
|
||||||
{
|
|
||||||
public enum PlayerOutfitType
|
|
||||||
{
|
|
||||||
Default,
|
|
||||||
Shapeshifted,
|
|
||||||
HorseWrangler,
|
|
||||||
MushroomMixup,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
namespace Impostor.Api.Innersloth.Customization
|
||||||
|
{
|
||||||
|
public enum SkinType : uint
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Astro = 1,
|
||||||
|
Capt = 2,
|
||||||
|
Mech = 3,
|
||||||
|
Military = 4,
|
||||||
|
Police = 5,
|
||||||
|
Science = 6,
|
||||||
|
SuitB = 7,
|
||||||
|
SuitW = 8,
|
||||||
|
Wall = 9,
|
||||||
|
Hazmat = 10,
|
||||||
|
Security = 11,
|
||||||
|
Tarmac = 12,
|
||||||
|
Miner = 13,
|
||||||
|
Winter = 14,
|
||||||
|
Archae = 15,
|
||||||
|
Prisoner = 16,
|
||||||
|
CCC = 17,
|
||||||
|
RightHandMan = 18,
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"0": "SkeldShipStatus",
|
|
||||||
"1": "MeetingHud",
|
|
||||||
"2": "LobbyBehaviour",
|
|
||||||
"4": "PlayerControl",
|
|
||||||
"5": "MiraShipStatus",
|
|
||||||
"6": "PolusShipStatus",
|
|
||||||
"7": "SkeldShipStatus",
|
|
||||||
"8": "AirshipStatus",
|
|
||||||
"9": "HideAndSeekManager",
|
|
||||||
"10": "NormalGameManager",
|
|
||||||
"11": "NetworkedPlayerInfo",
|
|
||||||
"12": "VoteBanSystem",
|
|
||||||
"13": "FungleShipStatus"
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"Invalid": 0,
|
|
||||||
"VisualTasks": 1,
|
|
||||||
"GhostsDoTasks": 2,
|
|
||||||
"ConfirmImpostor": 3,
|
|
||||||
"AnonymousVotes": 4,
|
|
||||||
"IsDefaults": 5,
|
|
||||||
"UseFlashlight": 6,
|
|
||||||
"SeekerFinalVents": 7,
|
|
||||||
"SeekerFinalMap": 8,
|
|
||||||
"SeekerPings": 9,
|
|
||||||
"ShowCrewmateNames": 10,
|
|
||||||
"Roles": 11,
|
|
||||||
"ShapeshifterLeaveSkin": 1000,
|
|
||||||
"ImpostorsCanSeeProtect": 1100,
|
|
||||||
"NoisemakerImpostorAlert": 1300
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"Invalid": 0,
|
|
||||||
"MapId": 1
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"KillCooldown": 0,
|
|
||||||
"PlayerSpeed": 1,
|
|
||||||
"EmergencyMeetingCount": 2,
|
|
||||||
"EmergencyMeetingCooldown": 3,
|
|
||||||
"DiscussionTime": 4,
|
|
||||||
"VotingTime": 5,
|
|
||||||
"CrewmateVision": 6,
|
|
||||||
"HidingTime": 7,
|
|
||||||
"MaxTimeInVent": 8,
|
|
||||||
"ImposterVision": 9,
|
|
||||||
"FinalHideTime": 10,
|
|
||||||
"FinalHideImposterSpeed": 11
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"Red": 0,
|
|
||||||
"Blue": 1,
|
|
||||||
"Green": 2,
|
|
||||||
"Pink": 3,
|
|
||||||
"Orange": 4,
|
|
||||||
"Yellow": 5,
|
|
||||||
"Black": 6,
|
|
||||||
"White": 7,
|
|
||||||
"Purple": 8,
|
|
||||||
"Brown": 9,
|
|
||||||
"Cyan": 10,
|
|
||||||
"Lime": 11,
|
|
||||||
"Maroon": 12,
|
|
||||||
"Rose": 13,
|
|
||||||
"Banana": 14,
|
|
||||||
"Gray": 15,
|
|
||||||
"Tan": 16,
|
|
||||||
"Coral": 17
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
{
|
|
||||||
"ExitGame": 0,
|
|
||||||
"GameFull": 1,
|
|
||||||
"GameStarted": 2,
|
|
||||||
"GameNotFound": 3,
|
|
||||||
"IncorrectVersion": 5,
|
|
||||||
"Banned": 6,
|
|
||||||
"Kicked": 7,
|
|
||||||
"Custom": 8,
|
|
||||||
"InvalidName": 9,
|
|
||||||
"Hacking": 10,
|
|
||||||
"NotAuthorized": 11,
|
|
||||||
"ConnectionLimit": 12,
|
|
||||||
"Destroy": 16,
|
|
||||||
"Error": 17,
|
|
||||||
"IncorrectGame": 18,
|
|
||||||
"ServerRequest": 19,
|
|
||||||
"ServerFull": 20,
|
|
||||||
"MismatchedVersion": 21,
|
|
||||||
"InternalPlayerMissing": 100,
|
|
||||||
"InternalNonceFailure": 101,
|
|
||||||
"InternalConnectionToken": 102,
|
|
||||||
"PlatformLock": 103,
|
|
||||||
"LobbyInactivity": 104,
|
|
||||||
"MatchmakerInactivity": 105,
|
|
||||||
"InvalidGameOptions": 106,
|
|
||||||
"NoServersAvailable": 107,
|
|
||||||
"QuickmatchDisabled": 108,
|
|
||||||
"TooManyGames": 109,
|
|
||||||
"QuickchatLock": 110,
|
|
||||||
"MatchmakerFull": 111,
|
|
||||||
"Sanctions": 112,
|
|
||||||
"ServerError": 113,
|
|
||||||
"SelfPlatformLock": 114,
|
|
||||||
"DuplicateConnectionDetected": 115,
|
|
||||||
"TooManyRequests": 116,
|
|
||||||
"FocusLostBackground": 207,
|
|
||||||
"IntentionalLeaving": 208,
|
|
||||||
"FocusLost": 209,
|
|
||||||
"NewConnection": 210,
|
|
||||||
"PlatformParentalControlsBlock": 211,
|
|
||||||
"PlatformUserBlock": 212,
|
|
||||||
"PlatformFailedToGetUserBlock": 213,
|
|
||||||
"ServerNotFound": 214,
|
|
||||||
"ClientTimeout": 215,
|
|
||||||
"ErrorAuthNonceFailure": 216,
|
|
||||||
"Unknown": 255
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"Invalid": 0,
|
|
||||||
"KillDistances": 1
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"Invalid": 0,
|
|
||||||
"KillCooldown": 1,
|
|
||||||
"PlayerSpeedMod": 2,
|
|
||||||
"ImpostorLightMod": 3,
|
|
||||||
"CrewLightMod": 4,
|
|
||||||
"CrewmateTimeInVent": 100,
|
|
||||||
"FinalEscapeTime": 101,
|
|
||||||
"EscapeTime": 102,
|
|
||||||
"SeekerFinalSpeed": 103,
|
|
||||||
"MaxPingTime": 104,
|
|
||||||
"CrewmateFlashlightSize": 105,
|
|
||||||
"ImpostorFlashlightSize": 106,
|
|
||||||
"ShapeshifterCooldown": 1000,
|
|
||||||
"ShapeshifterDuration": 1001,
|
|
||||||
"ProtectionDurationSeconds": 1100,
|
|
||||||
"GuardianAngelCooldown": 1101,
|
|
||||||
"ScientistCooldown": 1200,
|
|
||||||
"ScientistBatteryCharge": 1201,
|
|
||||||
"EngineerCooldown": 1300,
|
|
||||||
"EngineerInVentMaxTime": 1301,
|
|
||||||
"PhantomCooldown": 1500,
|
|
||||||
"PhantomDuration": 1501,
|
|
||||||
"TrackerCooldown": 1550,
|
|
||||||
"TrackerDuration": 1551,
|
|
||||||
"TrackerDelay": 1552,
|
|
||||||
"NoisemakerAlertDuration": 1600,
|
|
||||||
"ViperDissolveTime": 1601,
|
|
||||||
"DetectiveSuspectLimit": 1602,
|
|
||||||
"JudgeTaskRequirementPercentage": 1620,
|
|
||||||
"SpiritGuideCooldownSeconds": 1640
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
{
|
|
||||||
"All": 0,
|
|
||||||
"Other": 1,
|
|
||||||
"SpanishLA": 2,
|
|
||||||
"Korean": 4,
|
|
||||||
"Russian": 8,
|
|
||||||
"Portuguese": 16,
|
|
||||||
"Arabic": 32,
|
|
||||||
"Filipino": 64,
|
|
||||||
"Polish": 128,
|
|
||||||
"English": 256,
|
|
||||||
"Japanese": 512,
|
|
||||||
"SpanishEU": 1024,
|
|
||||||
"Brazilian": 2048,
|
|
||||||
"Dutch": 4096,
|
|
||||||
"French": 8192,
|
|
||||||
"German": 16384,
|
|
||||||
"Italian": 32768,
|
|
||||||
"SChinese": 65536,
|
|
||||||
"TChinese": 131072,
|
|
||||||
"Irish": 262144
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"CrewmatesByVote": 0,
|
|
||||||
"CrewmatesByTask": 1,
|
|
||||||
"ImpostorsByVote": 2,
|
|
||||||
"ImpostorsByKill": 3,
|
|
||||||
"ImpostorsBySabotage": 4,
|
|
||||||
"ImpostorDisconnect": 5,
|
|
||||||
"CrewmateDisconnect": 6,
|
|
||||||
"HideAndSeek_CrewmatesByTimer": 7,
|
|
||||||
"HideAndSeek_ImpostorsByKills": 8
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"Invalid": 0,
|
|
||||||
"MaxImpostors": 1,
|
|
||||||
"MinPlayers": 2
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
{
|
|
||||||
"Invalid": 0,
|
|
||||||
"NumImpostors": 1,
|
|
||||||
"KillDistance": 2,
|
|
||||||
"NumEmergencyMeetings": 3,
|
|
||||||
"EmergencyCooldown": 4,
|
|
||||||
"DiscussionTime": 5,
|
|
||||||
"VotingTime": 6,
|
|
||||||
"MaxImpostors": 7,
|
|
||||||
"MinPlayers": 8,
|
|
||||||
"MaxPlayers": 9,
|
|
||||||
"NumCommonTasks": 10,
|
|
||||||
"NumShortTasks": 11,
|
|
||||||
"NumLongTasks": 12,
|
|
||||||
"TaskBarMode": 13,
|
|
||||||
"Tag": 14,
|
|
||||||
"CrewmatesRemainingForVitals": 100,
|
|
||||||
"CrewmateVentUses": 101,
|
|
||||||
"ImpostorPlayerID": 102,
|
|
||||||
"RulePreset": 200
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"Unknown": 0,
|
|
||||||
"StandaloneEpicPC": 1,
|
|
||||||
"StandaloneSteamPC": 2,
|
|
||||||
"StandaloneMac": 3,
|
|
||||||
"StandaloneWin10": 4,
|
|
||||||
"StandaloneItch": 5,
|
|
||||||
"IPhone": 6,
|
|
||||||
"Android": 7,
|
|
||||||
"Switch": 8,
|
|
||||||
"Xbox": 9,
|
|
||||||
"Playstation": 10
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"Crewmate": 0,
|
|
||||||
"Impostor": 1,
|
|
||||||
"Scientist": 2,
|
|
||||||
"Engineer": 3,
|
|
||||||
"GuardianAngel": 4,
|
|
||||||
"Shapeshifter": 5,
|
|
||||||
"CrewmateGhost": 6,
|
|
||||||
"ImpostorGhost": 7,
|
|
||||||
"Noisemaker": 8,
|
|
||||||
"Phantom": 9,
|
|
||||||
"Tracker": 10,
|
|
||||||
"Detective": 12,
|
|
||||||
"Viper": 18,
|
|
||||||
"Judge": 19,
|
|
||||||
"SpiritGuide": 21
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
{
|
|
||||||
"PlayAnimation": 0,
|
|
||||||
"CompleteTask": 1,
|
|
||||||
"SyncSettings": 2,
|
|
||||||
"SetInfected": 3,
|
|
||||||
"Exiled": 4,
|
|
||||||
"CheckName": 5,
|
|
||||||
"SetName": 6,
|
|
||||||
"CheckColor": 7,
|
|
||||||
"SetColor": 8,
|
|
||||||
"SetHat_Deprecated": 9,
|
|
||||||
"SetSkin_Deprecated": 10,
|
|
||||||
"ReportDeadBody": 11,
|
|
||||||
"MurderPlayer": 12,
|
|
||||||
"SendChat": 13,
|
|
||||||
"StartMeeting": 14,
|
|
||||||
"SetScanner": 15,
|
|
||||||
"SendChatNote": 16,
|
|
||||||
"SetPet_Deprecated": 17,
|
|
||||||
"SetStartCounter": 18,
|
|
||||||
"EnterVent": 19,
|
|
||||||
"ExitVent": 20,
|
|
||||||
"SnapTo": 21,
|
|
||||||
"CloseMeeting": 22,
|
|
||||||
"VotingComplete": 23,
|
|
||||||
"CastVote": 24,
|
|
||||||
"ClearVote": 25,
|
|
||||||
"AddVote": 26,
|
|
||||||
"CloseDoorsOfType": 27,
|
|
||||||
"SetTasks": 29,
|
|
||||||
"ClimbLadder": 31,
|
|
||||||
"UsePlatform": 32,
|
|
||||||
"SendQuickChat": 33,
|
|
||||||
"BootFromVent": 34,
|
|
||||||
"UpdateSystem": 35,
|
|
||||||
"SetVisor_Deprecated": 36,
|
|
||||||
"SetNamePlate_Deprecated": 37,
|
|
||||||
"SetLevel": 38,
|
|
||||||
"SetHatStr": 39,
|
|
||||||
"SetSkinStr": 40,
|
|
||||||
"SetPetStr": 41,
|
|
||||||
"SetVisorStr": 42,
|
|
||||||
"SetNamePlateStr": 43,
|
|
||||||
"SetRole": 44,
|
|
||||||
"ProtectPlayer": 45,
|
|
||||||
"Shapeshift": 46,
|
|
||||||
"CheckMurder": 47,
|
|
||||||
"CheckProtect": 48,
|
|
||||||
"Pet": 49,
|
|
||||||
"CancelPet": 50,
|
|
||||||
"CheckZipline": 51,
|
|
||||||
"UseZipline": 52,
|
|
||||||
"TriggerSpores": 53,
|
|
||||||
"CheckSpore": 54,
|
|
||||||
"CheckShapeshift": 55,
|
|
||||||
"RejectShapeshift": 56,
|
|
||||||
"LobbyTimeExpiring": 60,
|
|
||||||
"ExtendLobbyTimer": 61,
|
|
||||||
"CheckVanish": 62,
|
|
||||||
"StartVanish": 63,
|
|
||||||
"CheckAppear": 64,
|
|
||||||
"StartAppear": 65,
|
|
||||||
"QueueOverruleVotes": 66,
|
|
||||||
"SpiritGuideMessage": 67
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"Standard": 0,
|
|
||||||
"StandardRoles": 1,
|
|
||||||
"Flashlight": 2,
|
|
||||||
"Custom": 100
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
"None": 0,
|
|
||||||
"ImpersonationCeleb": 1,
|
|
||||||
"Spamming": 2,
|
|
||||||
"InappropriateNameUnsportsmanlike": 3,
|
|
||||||
"UnsportsmanlikeConduct": 4,
|
|
||||||
"ImpersonationDevelopers": 5,
|
|
||||||
"InappropriateChatPersonalInfo": 6,
|
|
||||||
"InappropriateNameDerogatory": 7,
|
|
||||||
"InappropriateNameNsfw": 8,
|
|
||||||
"Bullying": 9,
|
|
||||||
"CheatingHacking": 10,
|
|
||||||
"InappropriateChatDating": 11,
|
|
||||||
"WeaponizingRules": 12,
|
|
||||||
"RepeatOffender3": 13,
|
|
||||||
"SexualMisconduct": 14,
|
|
||||||
"Doxing": 15,
|
|
||||||
"IllegalActivity": 16,
|
|
||||||
"Harassment": 17,
|
|
||||||
"SelfHarmPromotion": 18,
|
|
||||||
"RepeatOffender10": 19,
|
|
||||||
"InvalidUser": 20
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"None": 0,
|
|
||||||
"AprilFools": 1
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"English": 0,
|
|
||||||
"Latam": 1,
|
|
||||||
"Brazilian": 2,
|
|
||||||
"Portuguese": 3,
|
|
||||||
"Korean": 4,
|
|
||||||
"Russian": 5,
|
|
||||||
"Dutch": 6,
|
|
||||||
"Filipino": 7,
|
|
||||||
"French": 8,
|
|
||||||
"German": 9,
|
|
||||||
"Italian": 10,
|
|
||||||
"Japanese": 11,
|
|
||||||
"Spanish": 12,
|
|
||||||
"SChinese": 13,
|
|
||||||
"TChinese": 14,
|
|
||||||
"Irish": 15
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
{
|
|
||||||
"Hallway": 0,
|
|
||||||
"Storage": 1,
|
|
||||||
"Cafeteria": 2,
|
|
||||||
"Reactor": 3,
|
|
||||||
"UpperEngine": 4,
|
|
||||||
"Nav": 5,
|
|
||||||
"Admin": 6,
|
|
||||||
"Electrical": 7,
|
|
||||||
"LifeSupp": 8,
|
|
||||||
"Shields": 9,
|
|
||||||
"MedBay": 10,
|
|
||||||
"Security": 11,
|
|
||||||
"Weapons": 12,
|
|
||||||
"LowerEngine": 13,
|
|
||||||
"Comms": 14,
|
|
||||||
"ShipTasks": 15,
|
|
||||||
"Doors": 16,
|
|
||||||
"Sabotage": 17,
|
|
||||||
"Decontamination": 18,
|
|
||||||
"Launchpad": 19,
|
|
||||||
"LockerRoom": 20,
|
|
||||||
"Laboratory": 21,
|
|
||||||
"Balcony": 22,
|
|
||||||
"Office": 23,
|
|
||||||
"Greenhouse": 24,
|
|
||||||
"Dropship": 25,
|
|
||||||
"Decontamination2": 26,
|
|
||||||
"Outside": 27,
|
|
||||||
"Specimens": 28,
|
|
||||||
"BoilerRoom": 29,
|
|
||||||
"VaultRoom": 30,
|
|
||||||
"Cockpit": 31,
|
|
||||||
"Armory": 32,
|
|
||||||
"Kitchen": 33,
|
|
||||||
"ViewingDeck": 34,
|
|
||||||
"HallOfPortraits": 35,
|
|
||||||
"CargoBay": 36,
|
|
||||||
"Ventilation": 37,
|
|
||||||
"Showers": 38,
|
|
||||||
"Engine": 39,
|
|
||||||
"Brig": 40,
|
|
||||||
"MeetingRoom": 41,
|
|
||||||
"Records": 42,
|
|
||||||
"Lounge": 43,
|
|
||||||
"GapRoom": 44,
|
|
||||||
"MainHall": 45,
|
|
||||||
"Medical": 46,
|
|
||||||
"Decontamination3": 47,
|
|
||||||
"Zipline": 48,
|
|
||||||
"MiningPit": 49,
|
|
||||||
"FishingDock": 50,
|
|
||||||
"RecRoom": 51,
|
|
||||||
"Lookout": 52,
|
|
||||||
"Beach": 53,
|
|
||||||
"Highlands": 54,
|
|
||||||
"Jungle": 55,
|
|
||||||
"SleepingQuarters": 56,
|
|
||||||
"MushroomMixupSabotage": 57,
|
|
||||||
"HeliSabotage": 58
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
{
|
|
||||||
"SubmitScan": 0,
|
|
||||||
"PrimeShields": 1,
|
|
||||||
"FuelEngines": 2,
|
|
||||||
"ChartCourse": 3,
|
|
||||||
"StartReactor": 4,
|
|
||||||
"SwipeCard": 5,
|
|
||||||
"ClearAsteroids": 6,
|
|
||||||
"UploadData": 7,
|
|
||||||
"InspectSample": 8,
|
|
||||||
"EmptyChute": 9,
|
|
||||||
"EmptyGarbage": 10,
|
|
||||||
"AlignEngineOutput": 11,
|
|
||||||
"FixWiring": 12,
|
|
||||||
"CalibrateDistributor": 13,
|
|
||||||
"DivertPower": 14,
|
|
||||||
"UnlockManifolds": 15,
|
|
||||||
"ResetReactor": 16,
|
|
||||||
"FixLights": 17,
|
|
||||||
"CleanO2Filter": 18,
|
|
||||||
"FixComms": 19,
|
|
||||||
"RestoreOxy": 20,
|
|
||||||
"StabilizeSteering": 21,
|
|
||||||
"AssembleArtifact": 22,
|
|
||||||
"SortSamples": 23,
|
|
||||||
"MeasureWeather": 24,
|
|
||||||
"EnterIdCode": 25,
|
|
||||||
"BuyBeverage": 26,
|
|
||||||
"ProcessData": 27,
|
|
||||||
"RunDiagnostics": 28,
|
|
||||||
"WaterPlants": 29,
|
|
||||||
"MonitorOxygen": 30,
|
|
||||||
"StoreArtifacts": 31,
|
|
||||||
"FillCanisters": 32,
|
|
||||||
"FixWeatherNode": 33,
|
|
||||||
"InsertKeys": 34,
|
|
||||||
"ResetSeismic": 35,
|
|
||||||
"ScanBoardingPass": 36,
|
|
||||||
"OpenWaterways": 37,
|
|
||||||
"ReplaceWaterJug": 38,
|
|
||||||
"RepairDrill": 39,
|
|
||||||
"AlignTelescope": 40,
|
|
||||||
"RecordTemperature": 41,
|
|
||||||
"RebootWifi": 42,
|
|
||||||
"PolishRuby": 43,
|
|
||||||
"ResetBreakers": 44,
|
|
||||||
"Decontaminate": 45,
|
|
||||||
"MakeBurger": 46,
|
|
||||||
"UnlockSafe": 47,
|
|
||||||
"SortRecords": 48,
|
|
||||||
"PutAwayPistols": 49,
|
|
||||||
"FixShower": 50,
|
|
||||||
"CleanToilet": 51,
|
|
||||||
"DressMannequin": 52,
|
|
||||||
"PickUpTowels": 53,
|
|
||||||
"RewindTapes": 54,
|
|
||||||
"StartFans": 55,
|
|
||||||
"DevelopPhotos": 56,
|
|
||||||
"GetBiggolSword": 57,
|
|
||||||
"PutAwayRifles": 58,
|
|
||||||
"StopCharles": 59,
|
|
||||||
"VentCleaning": 60,
|
|
||||||
"None": 61,
|
|
||||||
"BuildSandcastle": 62,
|
|
||||||
"CatchFish": 63,
|
|
||||||
"CollectShells": 64,
|
|
||||||
"LiftWeights": 65,
|
|
||||||
"RoastMarshmallow": 66,
|
|
||||||
"TestFrisbee": 67,
|
|
||||||
"CollectSamples": 68,
|
|
||||||
"CollectVegetables": 69,
|
|
||||||
"HoistSupplies": 70,
|
|
||||||
"MineOres": 71,
|
|
||||||
"PolishGem": 72,
|
|
||||||
"ReplaceParts": 73,
|
|
||||||
"HelpCritter": 74,
|
|
||||||
"CrankGenerator": 75,
|
|
||||||
"FixAntenna": 76,
|
|
||||||
"TuneRadio": 77,
|
|
||||||
"MushroomMixupSabotage": 78,
|
|
||||||
"ExtractFuel": 79,
|
|
||||||
"MonitorMushroom": 80,
|
|
||||||
"PlayVideogame": 81
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"Invalid": 0,
|
|
||||||
"Keywords": 1
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"dumpostorVersion": "1.0.2-dev",
|
|
||||||
"gameVersion": "2026.9.29",
|
|
||||||
"platformType": "StandaloneItch"
|
|
||||||
}
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
{
|
|
||||||
"0": {
|
|
||||||
"room": "Comms",
|
|
||||||
"position": {
|
|
||||||
"x": -16.191698,
|
|
||||||
"y": -0.90999997
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"1": {
|
|
||||||
"room": "Comms",
|
|
||||||
"position": {
|
|
||||||
"x": -8.663198,
|
|
||||||
"y": -0.9099996
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"room": "Comms",
|
|
||||||
"position": {
|
|
||||||
"x": -13.362299,
|
|
||||||
"y": -0.015400052
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"room": "Comms",
|
|
||||||
"position": {
|
|
||||||
"x": -10.975999,
|
|
||||||
"y": -2.3309999
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"room": "Brig",
|
|
||||||
"position": {
|
|
||||||
"x": -0.9260999,
|
|
||||||
"y": 7.100799
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"5": {
|
|
||||||
"room": "Brig",
|
|
||||||
"position": {
|
|
||||||
"x": -3.6364996,
|
|
||||||
"y": 8.784999
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"6": {
|
|
||||||
"room": "Brig",
|
|
||||||
"position": {
|
|
||||||
"x": 2.7145998,
|
|
||||||
"y": 8.850798
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"7": {
|
|
||||||
"room": "Kitchen",
|
|
||||||
"position": {
|
|
||||||
"x": -8.764699,
|
|
||||||
"y": -7.2687993
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"8": {
|
|
||||||
"room": "Kitchen",
|
|
||||||
"position": {
|
|
||||||
"x": -8.764699,
|
|
||||||
"y": -11.976298
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"9": {
|
|
||||||
"room": "Kitchen",
|
|
||||||
"position": {
|
|
||||||
"x": -1.4979999,
|
|
||||||
"y": -12.040699
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"10": {
|
|
||||||
"room": "MainHall",
|
|
||||||
"position": {
|
|
||||||
"x": 4.2496986,
|
|
||||||
"y": 0.042
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"11": {
|
|
||||||
"room": "MainHall",
|
|
||||||
"position": {
|
|
||||||
"x": 17.490198,
|
|
||||||
"y": 0.04619999
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"12": {
|
|
||||||
"room": "Records",
|
|
||||||
"position": {
|
|
||||||
"x": 16.382797,
|
|
||||||
"y": 9.368099
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"13": {
|
|
||||||
"room": "Records",
|
|
||||||
"position": {
|
|
||||||
"x": 23.97472,
|
|
||||||
"y": 9.368099
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"14": {
|
|
||||||
"room": "Records",
|
|
||||||
"position": {
|
|
||||||
"x": 19.858297,
|
|
||||||
"y": 5.601399
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"15": {
|
|
||||||
"room": "Lounge",
|
|
||||||
"position": {
|
|
||||||
"x": 29.2544,
|
|
||||||
"y": 6.6990004
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"16": {
|
|
||||||
"room": "Lounge",
|
|
||||||
"position": {
|
|
||||||
"x": 30.7944,
|
|
||||||
"y": 6.6990004
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"17": {
|
|
||||||
"room": "Lounge",
|
|
||||||
"position": {
|
|
||||||
"x": 32.2924,
|
|
||||||
"y": 6.6990004
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"18": {
|
|
||||||
"room": "Lounge",
|
|
||||||
"position": {
|
|
||||||
"x": 33.7771,
|
|
||||||
"y": 6.6990004
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"19": {
|
|
||||||
"room": "Medical",
|
|
||||||
"position": {
|
|
||||||
"x": 21.314297,
|
|
||||||
"y": -8.416099
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"20": {
|
|
||||||
"room": "Medical",
|
|
||||||
"position": {
|
|
||||||
"x": 32.540195,
|
|
||||||
"y": -4.694899
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"initialSpawnCenter": {
|
|
||||||
"x": -25,
|
|
||||||
"y": 40
|
|
||||||
},
|
|
||||||
"meetingSpawnCenter": {
|
|
||||||
"x": 20,
|
|
||||||
"y": 9
|
|
||||||
},
|
|
||||||
"meetingSpawnCenter2": {
|
|
||||||
"x": 20,
|
|
||||||
"y": 9
|
|
||||||
},
|
|
||||||
"spawnRadius": 1.55
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"Electrical": "SwitchSystem",
|
|
||||||
"MedBay": "MedScanSystem",
|
|
||||||
"Doors": "DoorsSystemType",
|
|
||||||
"Comms": "HudOverrideSystemType",
|
|
||||||
"GapRoom": "MovingPlatformBehaviour",
|
|
||||||
"HeliSabotage": "HeliSabotageSystem",
|
|
||||||
"Decontamination": "ElectricalDoors",
|
|
||||||
"Decontamination2": "AutoDoorsSystemType",
|
|
||||||
"Security": "SecurityCameraSystemType",
|
|
||||||
"Ventilation": "VentilationSystem",
|
|
||||||
"Sabotage": "SabotageSystemType"
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -1,122 +0,0 @@
|
|||||||
{
|
|
||||||
"0": {
|
|
||||||
"name": "VaultVent",
|
|
||||||
"position": {
|
|
||||||
"x": -12.632198,
|
|
||||||
"y": 8.4735
|
|
||||||
},
|
|
||||||
"left": 1,
|
|
||||||
"center": null,
|
|
||||||
"right": null
|
|
||||||
},
|
|
||||||
"1": {
|
|
||||||
"name": "CockpitVent",
|
|
||||||
"position": {
|
|
||||||
"x": -22.098999,
|
|
||||||
"y": -1.5120001
|
|
||||||
},
|
|
||||||
"left": 0,
|
|
||||||
"center": null,
|
|
||||||
"right": 2
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"name": "EjectionVent",
|
|
||||||
"position": {
|
|
||||||
"x": -15.658999,
|
|
||||||
"y": -11.6991005
|
|
||||||
},
|
|
||||||
"left": 1,
|
|
||||||
"center": null,
|
|
||||||
"right": null
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"name": "EngineVent",
|
|
||||||
"position": {
|
|
||||||
"x": 0.20299996,
|
|
||||||
"y": -2.5361004
|
|
||||||
},
|
|
||||||
"left": 4,
|
|
||||||
"center": null,
|
|
||||||
"right": 5
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"name": "KitchenVent",
|
|
||||||
"position": {
|
|
||||||
"x": -2.6018999,
|
|
||||||
"y": -9.338
|
|
||||||
},
|
|
||||||
"left": 3,
|
|
||||||
"center": null,
|
|
||||||
"right": 5
|
|
||||||
},
|
|
||||||
"5": {
|
|
||||||
"name": "HallwayVent1",
|
|
||||||
"position": {
|
|
||||||
"x": 7.0210004,
|
|
||||||
"y": -3.7309995
|
|
||||||
},
|
|
||||||
"left": 3,
|
|
||||||
"center": null,
|
|
||||||
"right": 4
|
|
||||||
},
|
|
||||||
"6": {
|
|
||||||
"name": "HallwayVent2",
|
|
||||||
"position": {
|
|
||||||
"x": 9.814,
|
|
||||||
"y": 3.2060003
|
|
||||||
},
|
|
||||||
"left": 8,
|
|
||||||
"center": null,
|
|
||||||
"right": 7
|
|
||||||
},
|
|
||||||
"7": {
|
|
||||||
"name": "GaproomVent2",
|
|
||||||
"position": {
|
|
||||||
"x": 12.663,
|
|
||||||
"y": 5.922
|
|
||||||
},
|
|
||||||
"left": 8,
|
|
||||||
"center": null,
|
|
||||||
"right": 6
|
|
||||||
},
|
|
||||||
"8": {
|
|
||||||
"name": "GaproomVent1",
|
|
||||||
"position": {
|
|
||||||
"x": 3.6049998,
|
|
||||||
"y": 6.9230003
|
|
||||||
},
|
|
||||||
"left": 7,
|
|
||||||
"center": null,
|
|
||||||
"right": 6
|
|
||||||
},
|
|
||||||
"9": {
|
|
||||||
"name": "ShowersVent",
|
|
||||||
"position": {
|
|
||||||
"x": 23.9869,
|
|
||||||
"y": -1.386
|
|
||||||
},
|
|
||||||
"left": 10,
|
|
||||||
"center": null,
|
|
||||||
"right": 11
|
|
||||||
},
|
|
||||||
"10": {
|
|
||||||
"name": "RecordsVent",
|
|
||||||
"position": {
|
|
||||||
"x": 23.279898,
|
|
||||||
"y": 8.259998
|
|
||||||
},
|
|
||||||
"left": 9,
|
|
||||||
"center": null,
|
|
||||||
"right": 11
|
|
||||||
},
|
|
||||||
"11": {
|
|
||||||
"name": "StorageVent",
|
|
||||||
"position": {
|
|
||||||
"x": 30.440897,
|
|
||||||
"y": -3.5770001
|
|
||||||
},
|
|
||||||
"left": 9,
|
|
||||||
"center": null,
|
|
||||||
"right": 10
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
{
|
|
||||||
"0": {
|
|
||||||
"room": "Cafeteria",
|
|
||||||
"position": {
|
|
||||||
"x": -5.1432004,
|
|
||||||
"y": 1.3355999
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"1": {
|
|
||||||
"room": "Cafeteria",
|
|
||||||
"position": {
|
|
||||||
"x": 0.708,
|
|
||||||
"y": -4.992
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"2": {
|
|
||||||
"room": "Cafeteria",
|
|
||||||
"position": {
|
|
||||||
"x": 6.3936,
|
|
||||||
"y": 1.33848
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"room": "Electrical",
|
|
||||||
"position": {
|
|
||||||
"x": 9.53616,
|
|
||||||
"y": -13.416001
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"4": {
|
|
||||||
"room": "Storage",
|
|
||||||
"position": {
|
|
||||||
"x": -1.1316001,
|
|
||||||
"y": -11.98128
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"5": {
|
|
||||||
"room": "Storage",
|
|
||||||
"position": {
|
|
||||||
"x": 0.70919997,
|
|
||||||
"y": -8.560801
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"6": {
|
|
||||||
"room": "Storage",
|
|
||||||
"position": {
|
|
||||||
"x": 5.268,
|
|
||||||
"y": -14.2884
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"7": {
|
|
||||||
"room": "LowerEngine",
|
|
||||||
"position": {
|
|
||||||
"x": 14.6808,
|
|
||||||
"y": -11.472
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"8": {
|
|
||||||
"room": "LowerEngine",
|
|
||||||
"position": {
|
|
||||||
"x": 16.930801,
|
|
||||||
"y": -8.9664
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"9": {
|
|
||||||
"room": "UpperEngine",
|
|
||||||
"position": {
|
|
||||||
"x": 14.676002,
|
|
||||||
"y": 1.3406401
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"10": {
|
|
||||||
"room": "UpperEngine",
|
|
||||||
"position": {
|
|
||||||
"x": 16.930801,
|
|
||||||
"y": -2.1276002
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"11": {
|
|
||||||
"room": "Security",
|
|
||||||
"position": {
|
|
||||||
"x": 14.734801,
|
|
||||||
"y": -5.1417603
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"12": {
|
|
||||||
"room": "MedBay",
|
|
||||||
"position": {
|
|
||||||
"x": 9.1452,
|
|
||||||
"y": -0.4439999
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"initialSpawnCenter": {
|
|
||||||
"x": 0.87,
|
|
||||||
"y": 0.69
|
|
||||||
},
|
|
||||||
"meetingSpawnCenter": {
|
|
||||||
"x": 0.87,
|
|
||||||
"y": 0.69
|
|
||||||
},
|
|
||||||
"meetingSpawnCenter2": {
|
|
||||||
"x": 0,
|
|
||||||
"y": 0
|
|
||||||
},
|
|
||||||
"spawnRadius": 1.6
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"Electrical": "SwitchSystem",
|
|
||||||
"MedBay": "MedScanSystem",
|
|
||||||
"Doors": "AutoDoorsSystemType",
|
|
||||||
"Comms": "HudOverrideSystemType",
|
|
||||||
"Security": "SecurityCameraSystemType",
|
|
||||||
"Reactor": "ReactorSystemType",
|
|
||||||
"LifeSupp": "LifeSuppSystemType",
|
|
||||||
"Ventilation": "VentilationSystem",
|
|
||||||
"Sabotage": "SabotageSystemType"
|
|
||||||
}
|
|
||||||
Loaded 100 of 484 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user