Compare commits

..
39 Commits
Author SHA1 Message Date
js6pak 0a30fe5a3e Bring back tar.gz for unix builds 2021-04-05 15:27:25 +02:00
js6pak a0627bbc87 Always hook control with playerInfo 2021-03-28 20:46:31 +02:00
js6pak 40a41f3573 Fix a bug causing InnerPlayerInfo.Controller to be always null 2021-03-28 19:27:49 +02:00
js6pak 8621f09761 Merge pull request #333 from Impostor/fix/style-warnings
Fix warnings
2021-03-25 20:37:47 +00:00
js6pak 3321e3049f Make configs actually work with dependency injection 2021-03-24 20:05:26 +01:00
js6pak a90bbebab9 Update appveyor.yml for the ultimate yellow-less experience 2021-03-24 20:04:40 +01:00
js6pak f4dc0cd403 Revert hazel changes for easier merging with its upstream 2021-03-24 19:53:01 +01:00
js6pak fbed06bf81 Add icon to nuspec 2021-03-24 19:08:23 +01:00
js6pak ef5320c820 Update cake 2021-03-24 19:04:11 +01:00
js6pak bc85ef6810 Fix xmldoc warnings 2021-03-24 17:55:15 +01:00
js6pak e90ba734ab Code cleanup 2021-03-24 16:57:11 +01:00
js6pak 0f6bfb3597 Fix warnings 2021-03-24 16:38:23 +01:00
js6pak dc759b1d57 Fix FloatRange ranges 2021-03-23 21:21:11 +01:00
Minorusama be332e21d1 Add IInnerPlayerControl#ExileAsync (#271) 2021-03-23 20:12:39 +00:00
js6pak fe7a641bad Set VERSIONSUFFIX to docker by default 2021-03-16 22:12:56 +01:00
js6pak e0041e89d8 Update docker CI 2021-03-16 21:40:54 +01:00
js6pak f04bacf0de Update Server-configuration.md 2021-03-14 22:30:01 +00:00
js6pak 7e16b5595a Include AntiCheat.Enabled in default config.json 2021-03-14 23:25:56 +01:00
js6pak a1c59363a1 Merge remote-tracking branch 'origin/2021.3.5' 2021-03-14 23:19:35 +01:00
js6pak ea1085406a Fix typo in README.md 2021-03-14 21:23:10 +00:00
js6pak e359f0a15d Update README.md 2021-03-14 22:19:48 +01:00
js6pak 72f1e81c5f Merge branch '2021.3.5' 2021-03-14 22:04:44 +01:00
js6pak 443168ef71 Add DateTime to server replays (#349) 2021-03-14 20:50:55 +00:00
Galster-dev 20d5284a7a minor README.md changes (#342) 2021-03-10 23:06:12 +01:00
js6pak 9915f8b0cf Expose IsCancelled to IPlayerChatEvent 2021-03-07 16:49:57 +01:00
js6pak 0901be56f5 Implement GameData 205 2021-03-07 16:41:19 +01:00
miniduikboot 3090cea768 Remove fake player joining (#341) 2021-03-07 16:36:37 +01:00
js6pak 1059a4da16 Add debug logs in AnnouncementsService 2021-03-06 18:13:16 +01:00
js6pak acd2a56898 Simplify Message01JoinGameC2S 2021-03-06 17:20:36 +01:00
js6pak 575ad25fb6 New GameDataTags 2021-03-06 17:15:12 +01:00
AeonLucid 781ba34e1b Fix Impostor.Tools.ServerReplay compilation 2021-03-06 17:07:35 +01:00
js6pak 9bd43b4629 2021.3.5 2021-03-06 00:45:46 +01:00
js6pak e769b874c8 Add create game api (#241) 2021-03-04 09:11:50 +00:00
miniduikboot be19b1524b Warn if plugin loader paths don't exist (#330) 2021-03-03 14:36:17 +00:00
112batman 020a1b6447 Implement IInnerNetObject in IInnerMeetingHud (#256) 2021-03-03 09:23:38 +00:00
js6pak bbbf368a6f Bump version 2021-03-03 10:15:48 +01:00
js6pak d4bffd20ad [skip ci] Update Building-from-source.md 2021-03-03 09:05:33 +00:00
87a062c1b3 Sync Impostor with 6pak fork (#327)
Co-authored-by: DatGuy1 <datguysteam@gmail.com>
Co-authored-by: miniduikboot <5243971+miniduikboot@users.noreply.github.com>
2021-03-03 08:53:53 +00:00
js6pak f2d6531063 Add CheckName/SetName/CheckColor/SetColor anticheat checks (#278)
* Add CheckName/SetName/CheckColor/SetColor anticheat checks

* Disable expected checks for the host
2021-01-08 18:42:41 +01:00
316 changed files with 4135 additions and 2702 deletions

No files matched your search

+1 -1
View File
@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"cake.tool": {
"version": "0.38.5",
"version": "1.1.0",
"commands": [
"dotnet-cake"
]
-17
View File
@@ -1,17 +0,0 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- pinned
- security
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false
+9 -5
View File
@@ -2,7 +2,7 @@ name: Docker
on:
push:
branches: dev
branches: master
paths:
- 'src/Impostor.Server/**'
- 'src/Impostor.Shared/**'
@@ -33,15 +33,16 @@ jobs:
run: |
DOCKER_IMAGE=aeonlucid/impostor
VERSION=noop
VERSIONSUFFIX=docker
if [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
VERSIONSUFFIX=none
elif [[ $GITHUB_REF == refs/heads/* ]]; then
VERSION=$(echo ${GITHUB_REF#refs/heads/} | sed -r 's#/+#-#g')
if [ "${{ github.event.repository.default_branch }}" = "dev" ]; then
VERSION=nightly
fi
VERSION=nightly
VERSIONSUFFIX=docker.${{ github.run_number }}
elif [[ $GITHUB_REF == refs/pull/* ]]; then
VERSION=pr-${{ github.event.number }}
VERSIONSUFFIX=pr.${{ github.event.number }}
fi
TAGS="${DOCKER_IMAGE}:${VERSION}"
if [[ $VERSION =~ ^v[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
@@ -49,6 +50,7 @@ jobs:
fi
echo ::set-output name=version::${VERSION}
echo ::set-output name=tags::${TAGS}
echo ::set-output name=versionsuffix::${VERSIONSUFFIX}
echo ::set-output name=created::$(date -u +'%Y-%m-%dT%H:%M:%SZ')
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
@@ -68,3 +70,5 @@ jobs:
platforms: linux/amd64,linux/arm/v7,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.prep.outputs.tags }}
build-args: |
VERSIONSUFFIX=${{ steps.prep.outputs.versionsuffix }}
+4 -1
View File
@@ -4,6 +4,8 @@ FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:5.0 AS build
# https://github.com/containerd/containerd/blob/master/platforms/platforms.go#L17
ARG TARGETARCH
ARG VERSIONSUFFIX="docker"
WORKDIR /source
# Copy csproj and restore.
@@ -29,7 +31,8 @@ RUN case "$TARGETARCH" in \
arm) NETCORE_PLATFORM='linux-arm';; \
*) echo "unsupported architecture"; exit 1 ;; \
esac && \
dotnet publish -c release -o /app -r "$NETCORE_PLATFORM" --no-restore ./src/Impostor.Server/Impostor.Server.csproj
[[ $VERSIONSUFFIX = "none" ]] && VERSIONSUFFIX=; \
dotnet publish -c release -o /app -r "$NETCORE_PLATFORM" -p:VersionSuffix="$VERSIONSUFFIX" --no-restore ./src/Impostor.Server/Impostor.Server.csproj
# Final image.
FROM --platform=$TARGETPLATFORM mcr.microsoft.com/dotnet/runtime:5.0
+5 -6
View File
@@ -1,16 +1,15 @@
# Impostor
[![Discord](https://img.shields.io/badge/Discord-chat-blue?style=flat-square)](https://discord.gg/Mk3w6Tb)
[![AppVeyor](https://img.shields.io/appveyor/build/Impostor/Impostor/dev?style=flat-square)](https://ci.appveyor.com/project/Impostor/Impostor/branch/dev)
[![AppVeyor](https://img.shields.io/appveyor/build/Impostor/Impostor/master?style=flat-square)](https://ci.appveyor.com/project/Impostor/Impostor/branch/master)
Impostor is one of the first **Among Us** private servers, written in C#.
We support Steam, Itch, Android and iOS. The latest version supported is `2020.9.22`, the `dev` build currently supports `2020.11.17`.
| Impostor version | Among Us version | Experimental | Download |
|-|-|-|-|
| 1.1.0 | 2020.09.07 - 2020.09.22 | No | [![Download](https://img.shields.io/badge/Download-v1.1.0-blue?style=flat-square)](https://github.com/Impostor/Impostor/releases/tag/v1.1.0) |
| 1.2.2 | 2020.09.22 - 2020.11.17 | Yes | [![Download](https://img.shields.io/badge/Download-v1.2.2-blue?style=flat-square)](https://ci.appveyor.com/project/Impostor/Impostor/branch/dev/artifacts) |
| 1.2.2 | 2020.09.22 - 2020.11.17 | No | [![Download](https://img.shields.io/badge/Download-v1.2.2-blue?style=flat-square)](https://github.com/Impostor/Impostor/releases/tag/v1.2.2) |
| 1.3.0 | 2021.3.5 | Yes | [![Download](https://img.shields.io/badge/Download-master-blue?style=flat-square)](https://ci.appveyor.com/project/Impostor/Impostor/branch/master/artifacts) |
## Features
@@ -27,9 +26,9 @@ If you just want to play on a server hosted by someone else, you need to follow
#### Windows
1. Find the [latest release](https://github.com/AeonLucid/Impostor/releases/latest).
2. Download `Impostor-Client-win-x64.zip`.
2. Download `Impostor-Patcher-win-x64.zip`.
3. Extract the zip.
4. Run `Impostor.Client.exe`.
4. Run `Impostor.Patcher.exe`.
5. Follow the instructions inside the application.
![Client](docs/images/client.jpg)
+2 -3
View File
@@ -1,12 +1,11 @@
version: '{build}'
environment:
IMPOSTOR_VERSION: '1.2.2'
DOTNET_CLI_TELEMETRY_OPTOUT: 1
branches:
except:
- gh-pages
- gh-pages
pull_requests:
do_not_increment_build_number: true
@@ -17,7 +16,7 @@ assembly_info:
dotnet_csproj:
patch: false
image: Visual Studio 2019 Preview
image: Ubuntu2004
install:
- git submodule update --init --recursive
+39 -56
View File
@@ -1,20 +1,25 @@
#addin "nuget:?package=SharpZipLib&Version=1.3.0"
#addin "nuget:?package=Cake.Compression&Version=0.2.4"
#addin "nuget:?package=Cake.FileHelpers&Version=3.3.0"
#addin "nuget:?package=SharpZipLib&Version=1.3.1"
#addin "nuget:?package=Cake.Compression&Version=0.2.6"
#addin "nuget:?package=Cake.FileHelpers&Version=4.0.1"
var buildId = EnvironmentVariable("APPVEYOR_BUILD_VERSION") ?? "0";
var buildVersion = EnvironmentVariable("IMPOSTOR_VERSION") ?? "1.0.0";
var buildBranch = EnvironmentVariable("APPVEYOR_REPO_BRANCH") ?? "dev";
var buildId = EnvironmentVariable("GITHUB_RUN_NUMBER") ?? EnvironmentVariable("APPVEYOR_BUILD_VERSION");
var buildRelease = EnvironmentVariable("APPVEYOR_REPO_TAG") == "true";
var buildVersion = FindRegexMatchGroupInFile("./src/Directory.Build.props", @"\<VersionPrefix\>(.*?)\<\/VersionPrefix\>", 1, System.Text.RegularExpressions.RegexOptions.None).Value;
var buildDir = MakeAbsolute(Directory("./build"));
var prNumber = EnvironmentVariable("APPVEYOR_PULL_REQUEST_NUMBER");
var target = Argument("target", "Deploy");
var configuration = Argument("configuration", "Release");
// On any branch that is not master, we need to tag the version as prerelease.
if (buildBranch != "master") {
buildVersion = buildVersion + "-ci." + buildId;
var msbuildSettings = new DotNetCoreMSBuildSettings();
if (buildRelease)
{
msbuildSettings.Properties["Version"] = new[] { buildVersion };
}
else if (buildId != null)
{
msbuildSettings.Properties["VersionSuffix"] = new[] { "ci." + buildId };
buildVersion += "-ci." + buildId;
}
//////////////////////////////////////////////////////////////////////
@@ -34,7 +39,8 @@ private void ImpostorPublish(string name, string project, string runtime, bool i
SelfContained = false,
PublishSingleFile = true,
PublishTrimmed = false,
OutputDirectory = projBuildDir
OutputDirectory = projBuildDir,
MSBuildSettings = msbuildSettings
});
if (isServer) {
@@ -62,7 +68,8 @@ private void ImpostorPublishNF(string name, string project) {
Configuration = configuration,
NoRestore = true,
Framework = "net472",
OutputDirectory = projBuildDir
OutputDirectory = projBuildDir,
MSBuildSettings = msbuildSettings
});
Zip(projBuildDir, projBuildZip);
@@ -86,13 +93,6 @@ Task("Restore")
DotNetCoreRestore("./src/Impostor.sln");
});
Task("Patch")
.WithCriteria(BuildSystem.AppVeyor.IsRunningOnAppVeyor)
.Does(() => {
ReplaceRegexInFiles("./src/**/*.csproj", @"<Version>.*?<\/Version>", "<Version>" + buildVersion + "</Version>");
ReplaceRegexInFiles("./src/**/*.props", @"<Version>.*?<\/Version>", "<Version>" + buildVersion + "</Version>");
});
Task("Replay")
.Does(() => {
// D:\Projects\GitHub\Impostor\Impostor\src\Impostor.Tools.ServerReplay\sessions
@@ -107,7 +107,6 @@ Task("Replay")
Task("Build")
.IsDependentOn("Clean")
.IsDependentOn("Patch")
.IsDependentOn("Restore")
.IsDependentOn("Replay")
.Does(() => {
@@ -116,44 +115,28 @@ Task("Build")
Configuration = configuration,
});
// Only build artifacts if;
// - buildBranch is master/dev
// - it is not a pull request
if ((buildBranch == "master" || buildBranch == "dev") && string.IsNullOrEmpty(prNumber)) {
// Client.
ImpostorPublishNF("Impostor-Patcher", "./src/Impostor.Patcher/Impostor.Patcher.WinForms/Impostor.Patcher.WinForms.csproj");
// Client.
ImpostorPublishNF("Impostor-Patcher", "./src/Impostor.Patcher/Impostor.Patcher.WinForms/Impostor.Patcher.WinForms.csproj");
ImpostorPublish("Impostor-Patcher-Cli", "./src/Impostor.Patcher/Impostor.Patcher.Cli/Impostor.Patcher.Cli.csproj", "win-x64");
ImpostorPublish("Impostor-Patcher-Cli", "./src/Impostor.Patcher/Impostor.Patcher.Cli/Impostor.Patcher.Cli.csproj", "osx-x64");
ImpostorPublish("Impostor-Patcher-Cli", "./src/Impostor.Patcher/Impostor.Patcher.Cli/Impostor.Patcher.Cli.csproj", "linux-x64");
ImpostorPublish("Impostor-Patcher-Cli", "./src/Impostor.Patcher/Impostor.Patcher.Cli/Impostor.Patcher.Cli.csproj", "win-x64");
ImpostorPublish("Impostor-Patcher-Cli", "./src/Impostor.Patcher/Impostor.Patcher.Cli/Impostor.Patcher.Cli.csproj", "osx-x64");
ImpostorPublish("Impostor-Patcher-Cli", "./src/Impostor.Patcher/Impostor.Patcher.Cli/Impostor.Patcher.Cli.csproj", "linux-x64");
// Server.
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "win-x64", true);
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "osx-x64", true);
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "linux-x64", true);
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "linux-arm", true);
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "linux-arm64", true);
// Server.
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "win-x64", true);
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "osx-x64", true);
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "linux-x64", true);
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "linux-arm", true);
ImpostorPublish("Impostor-Server", "./src/Impostor.Server/Impostor.Server.csproj", "linux-arm64", true);
// API.
DotNetCorePack("./src/Impostor.Api/Impostor.Api.csproj", new DotNetCorePackSettings {
Configuration = configuration,
OutputDirectory = buildDir,
IncludeSource = true,
IncludeSymbols = true
});
} else {
DotNetCoreBuild("./src/Impostor.Patcher/Impostor.Patcher.WinForms/Impostor.Patcher.WinForms.csproj", new DotNetCoreBuildSettings {
Configuration = configuration,
NoRestore = true,
Framework = "net472"
});
DotNetCoreBuild("./src/Impostor.Server/Impostor.Server.csproj", new DotNetCoreBuildSettings {
Configuration = configuration,
NoRestore = true,
Framework = "net5.0"
});
}
// API.
DotNetCorePack("./src/Impostor.Api/Impostor.Api.csproj", new DotNetCorePackSettings {
Configuration = configuration,
OutputDirectory = buildDir,
IncludeSource = true,
IncludeSymbols = true,
MSBuildSettings = msbuildSettings
});
});
Task("Test")
+8 -17
View File
@@ -1,29 +1,20 @@
# Building from source
The solution contains two main projects, the Impostor client and server. The client is built using [.NET Framework 4.7.2](https://dotnet.microsoft.com/download/dotnet-framework/net472) and the server with [.NET 5](https://dotnet.microsoft.com/download/dotnet/5.0).
Currently .NET 5 is not yet officially released, so in order to build using Visual Studio, you should have Visual Studio 2019 **Preview** installed.
This documentation will go over building both the [Server](#building-the-server) and the [Client](#building-the-client) and their requirements.
The solution contains two main projects, the Impostor server and patcher. The server is built using [.NET 5](https://dotnet.microsoft.com/download/dotnet/5.0) and the winforms patcher is with [.NET Framework 4.7.2](https://dotnet.microsoft.com/download/dotnet-framework/net472).
## Cloning Impostor
You need to clone Impostor with all submodules.
You need to clone Impostor using git.
```bash
git clone --recursive https://github.com/AeonLucid/Impostor.git
```
If you already have cloned Impostor but have errors related to Hazel, run the following.
```bash
git submodule update --init
git clone https://github.com/AeonLucid/Impostor.git
```
## Building the server
### Dependencies
- [.NET 5 SDK](https://dotnet.microsoft.com/download/dotnet/5.0)
- [Visual Studio Preview](https://visualstudio.microsoft.com/vs/preview/) (Optional, only if you want the full IDE experience)
- [Rider](https://www.jetbrains.com/rider/) or [Visual Studio](https://visualstudio.microsoft.com/vs/) (Optional, only if you want the full IDE experience)
### Build using the CLI
@@ -33,13 +24,13 @@ dotnet build
```
To setup the server, please look at [Running the server](Running-the-server.md).
## Building the client
## Building the winforms patcher
### Dependencies
* [.NET Framework 4.7.2 Developer Pack](https://dotnet.microsoft.com/download/dotnet-framework/thank-you/net472-developer-pack-offline-installer)
* [.NET Framework 4.7.2 Developer Pack](https://dotnet.microsoft.com/download/dotnet-framework/thank-you/net472-developer-pack-offline-installer) or [Mono](https://www.mono-project.com/download/)
### Build using the CLI
```bash
cd src/Impostor.Client/Impostor.Client.WinForms
cd src/Impostor.Patcher/Impostor.Patcher.WinForms
dotnet build
```
```
+3
View File
@@ -17,6 +17,7 @@ Some information about all the possible configurations. Click [here](https://git
| Key | Default | Value |
|-|-|-|
| **Enabled** | `true` | Whether the anticheat should be enabled. |
| **BanIpFromGame** | `true` | When a player is caught hacking, they will be kicked from the server. If this value is set to `true`, the player will be banned instead and will not be able to rejoin that specific game. **(Setting this to false does not disable the anti-cheat!)** |
### ServerRedirector
@@ -45,6 +46,7 @@ Server:PublicIp=127.0.0.1
Server:PublicPort=22023
Server:ListenIp=0.0.0.0
Server:ListenPort=22023
AntiCheat:Enabled=true
AntiCheat:BanIpFromGame=true
ServerRedirector:Enabled=false
ServerRedirector:Master=true
@@ -65,6 +67,7 @@ IMPOSTOR_Server__PublicIp=127.0.0.1
IMPOSTOR_Server__PublicPort=22023
IMPOSTOR_Server__ListenIp=0.0.0.0
IMPOSTOR_Server__ListenPort=22023
IMPOSTOR_AntiCheat__Enabled=true
IMPOSTOR_AntiCheat__BanIpFromGame=true
IMPOSTOR_ServerRedirector__Enabled=false
IMPOSTOR_ServerRedirector__Master=true
+6 -3
View File
@@ -4,8 +4,8 @@ root = true
# Don't use tabs for indentation.
[*]
charset = utf-8
end_of_line = crlf
insert_final_newline = false
end_of_line = lf
insert_final_newline = true
indent_style = space
# Code files
@@ -163,7 +163,7 @@ csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_object_initializers = true
# csharp_new_line_before_members_in_object_initializers = true TODO seems like Rider/ReSharper has the value inverted, uncomment when its fixed
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_between_query_expression_clauses = true
@@ -228,3 +228,6 @@ csharp_preserve_single_line_statements = true
# warning RS0037: PublicAPI.txt is missing '#nullable enable'
dotnet_diagnostic.RS0037.severity = none
# ReSharper properties
resharper_trailing_comma_in_multiline_lists = true
-149
View File
@@ -26,21 +26,6 @@ bld/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
@@ -72,32 +57,12 @@ artifacts/
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
@@ -112,72 +77,11 @@ _TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
#*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
@@ -197,13 +101,6 @@ ClientBin/
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
@@ -212,52 +109,6 @@ Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
+11
View File
@@ -0,0 +1,11 @@
<Project>
<PropertyGroup>
<VersionPrefix>1.3.0</VersionPrefix>
<VersionSuffix>dev</VersionSuffix>
</PropertyGroup>
<ItemGroup>
<AdditionalFiles Include="$(MSBuildThisFileDirectory)stylecop.json" />
</ItemGroup>
</Project>
+20
View File
@@ -0,0 +1,20 @@
using Impostor.Server.Net.Inner;
namespace Impostor.Api
{
public class CheatContext
{
public CheatContext(string name)
{
Name = name;
}
public static CheatContext Deserialize { get; } = new CheatContext(nameof(Deserialize));
public static CheatContext Serialize { get; } = new CheatContext(nameof(Serialize));
public string Name { get; }
public static implicit operator CheatContext(RpcCalls rpcCalls) => new CheatContext(rpcCalls.ToString());
}
}
@@ -0,0 +1,43 @@
using Impostor.Api.Innersloth;
namespace Impostor.Api.Events.Announcements
{
/// <summary>
/// Event fired after client requests a announcement.
/// </summary>
public interface IAnnouncementRequestEvent : IEvent
{
public interface IResponse
{
/// <summary>
/// Gets or sets FreeWeekendState, currently unused by the client.
/// </summary>
public FreeWeekendState FreeWeekendState { get; set; }
/// <summary>
/// Gets or sets a value indicating whether announcement should be loaded from client's cache, can save some bytes.
/// </summary>
public bool UseCached { get; set; }
/// <summary>
/// Gets or sets announcement, should be null when <see cref="UseCached" /> is set to true.
/// </summary>
public Announcement? Announcement { get; set; }
}
/// <summary>
/// Gets client's last announcement id.
/// </summary>
public int Id { get; }
/// <summary>
/// Gets client's language.
/// </summary>
public Language Language { get; }
/// <summary>
/// Gets or sets plugin made response.
/// </summary>
public IResponse Response { get; set; }
}
}
@@ -17,18 +17,18 @@ namespace Impostor.Api.Events
}
/// <summary>
/// The priority of the event listener.
/// Gets or sets the priority of the event listener.
/// </summary>
public EventPriority Priority { get; set; }
/// <summary>
/// The events that the listener is listening to.
/// Gets or sets the event that the listener is listening to.
/// </summary>
public Type? Event { get; set; }
/// <summary>
/// If set to true, the listener will be called regardless of the <see cref="IEventCancelable.IsCancelled"/>.
/// Gets or sets a value indicating whether the listener will be called regardless of the <see cref="IEventCancelable.IsCancelled" />.
/// </summary>
public bool IgnoreCancelled { get; set; }
}
}
}
@@ -3,7 +3,7 @@
namespace Impostor.Api.Events
{
/// <summary>
/// Called whenever a new <see cref="IGame"/> is created.
/// Called whenever a new <see cref="IGame" /> is created.
/// </summary>
public interface IGameCreatedEvent : IGameEvent
{
@@ -3,7 +3,7 @@
namespace Impostor.Api.Events
{
/// <summary>
/// Called whenever a new <see cref="IGame"/> is destroyed.
/// Called whenever a new <see cref="IGame" /> is destroyed.
/// </summary>
public interface IGameDestroyedEvent : IGameEvent
{
+1 -1
View File
@@ -5,7 +5,7 @@ namespace Impostor.Api.Events
public interface IGameEvent : IEvent
{
/// <summary>
/// Gets the <see cref="IGame"/> this event belongs to.
/// Gets the <see cref="IGame" /> this event belongs to.
/// </summary>
IGame Game { get; }
}
@@ -3,7 +3,7 @@
/// <summary>
/// Called when the game is going to start.
/// When this is called, not all players are initialized properly yet.
/// If you want to get correct player states, use <see cref="IGameStartedEvent"/>.
/// If you want to get correct player states, use <see cref="IGameStartedEvent" />.
/// </summary>
public interface IGameStartingEvent : IGameEvent
{
@@ -1,6 +1,6 @@
namespace Impostor.Api.Events.Player
{
public interface IPlayerChatEvent : IPlayerEvent
public interface IPlayerChatEvent : IPlayerEvent, IEventCancelable
{
/// <summary>
/// Gets the message sent by the player.
@@ -1,5 +1,4 @@
using Impostor.Api.Innersloth;
using Impostor.Api.Net.Inner.Objects;
using Impostor.Api.Net.Inner.Objects;
namespace Impostor.Api.Events.Player
{
@@ -6,14 +6,14 @@ namespace Impostor.Api.Events.Player
public interface IPlayerEvent : IGameEvent
{
/// <summary>
/// Gets the <see cref="IClientPlayer"/> that triggered this <see cref="IPlayerEvent"/>.
/// Gets the <see cref="IClientPlayer" /> that triggered this <see cref="IPlayerEvent" />.
/// </summary>
IClientPlayer ClientPlayer { get; }
/// <summary>
/// Gets the networked <see cref="IInnerPlayerControl"/> that triggered this <see cref="IPlayerEvent"/>.
/// This <see cref="IInnerPlayerControl"/> belongs to the <see cref="IClientPlayer"/>.
/// Gets the networked <see cref="IInnerPlayerControl" /> that triggered this <see cref="IPlayerEvent" />.
/// This <see cref="IInnerPlayerControl" /> belongs to the <see cref="IClientPlayer" />.
/// </summary>
IInnerPlayerControl PlayerControl { get; }
}
}
}
@@ -0,0 +1,6 @@
namespace Impostor.Api.Events.Player
{
public interface IPlayerMovementEvent : IPlayerEvent
{
}
}
@@ -5,7 +5,7 @@ namespace Impostor.Api.Events.Player
public interface IPlayerStartMeetingEvent : IPlayerEvent
{
/// <summary>
/// Gets the player who's body got reported. Is null when the meeting started by Emergency call button
/// Gets the player who's body got reported. Is null when the meeting started by Emergency call button.
/// </summary>
IInnerPlayerControl? Body { get; }
}
+1 -1
View File
@@ -3,4 +3,4 @@
public interface IEvent
{
}
}
}
+2 -2
View File
@@ -3,8 +3,8 @@
public interface IEventCancelable : IEvent
{
/// <summary>
/// True if the event was cancelled.
/// Gets or sets a value indicating whether the event was cancelled.
/// </summary>
bool IsCancelled { get; set; }
}
}
}
+1 -1
View File
@@ -3,4 +3,4 @@
public interface IEventListener
{
}
}
}
@@ -4,10 +4,10 @@ namespace Impostor.Api.Events
{
public interface IManualEventListener : IEventListener
{
EventPriority Priority { get; set; }
public bool CanExecute<T>();
public ValueTask Execute(IEvent @event);
EventPriority Priority { get; set; }
}
}
}
@@ -16,20 +16,20 @@ namespace Impostor.Api.Events.Managers
where TListener : IEventListener;
/// <summary>
/// Returns true if an event with the type <see cref="TEvent"/> is registered.
/// Returns true if an event with the type <typeparamref name="TEvent" /> is registered.
/// </summary>
/// <returns>True if the <see cref="TEvent"/> is registered.</returns>
/// <returns>True if the <typeparamref name="TEvent" /> is registered.</returns>
/// <typeparam name="TEvent">Type of the event.</typeparam>
bool IsRegistered<TEvent>()
where TEvent : IEvent;
/// <summary>
/// Call all the event listeners for the type <see cref="TEvent"/>.
/// Call all the event listeners for the type <typeparamref name="TEvent" />.
/// </summary>
/// <param name="event">The event argument.</param>
/// <typeparam name="TEvent">Type of the event.</typeparam>
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
ValueTask CallAsync<TEvent>(TEvent @event)
where TEvent : IEvent;
}
}
}
@@ -1,24 +0,0 @@
using System;
using System.Runtime.Serialization;
namespace Impostor.Api
{
public class ImpostorCheatException : ImpostorException
{
public ImpostorCheatException()
{
}
protected ImpostorCheatException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
public ImpostorCheatException(string? message) : base(message)
{
}
public ImpostorCheatException(string? message, Exception? innerException) : base(message, innerException)
{
}
}
}
@@ -9,10 +9,6 @@ namespace Impostor.Api
{
}
protected ImpostorConfigException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
public ImpostorConfigException(string? message) : base(message)
{
}
@@ -20,5 +16,9 @@ namespace Impostor.Api
public ImpostorConfigException(string? message, Exception? innerException) : base(message, innerException)
{
}
protected ImpostorConfigException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}
@@ -9,10 +9,6 @@ namespace Impostor.Api
{
}
protected ImpostorException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
public ImpostorException(string? message) : base(message)
{
}
@@ -20,5 +16,9 @@ namespace Impostor.Api
public ImpostorException(string? message, Exception? innerException) : base(message, innerException)
{
}
protected ImpostorException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}
}
@@ -9,10 +9,6 @@ namespace Impostor.Api
{
}
protected ImpostorProtocolException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
public ImpostorProtocolException(string? message) : base(message)
{
}
@@ -20,5 +16,9 @@ namespace Impostor.Api
public ImpostorProtocolException(string? message, Exception? innerException) : base(message, innerException)
{
}
protected ImpostorProtocolException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}
@@ -5,7 +5,7 @@ using System.Runtime.CompilerServices;
namespace Impostor.Api
{
/// <summary>
/// Priovides a StreamReader-like api throught extensions
/// Priovides a StreamReader-like api throught extensions.
/// </summary>
public static class SpanReaderExtensions
{
@@ -53,11 +53,11 @@ namespace Impostor.Api
}
/// <summary>
/// Advances the position of <see cref="input"/> by the size of <see cref="T"/>.
/// Advances the position of <paramref name="input" /> by the size of <typeparamref name="T" />.
/// </summary>
/// <typeparam name="T">Type that will be read.</typeparam>
/// <param name="input">input "stream"/span.</param>
/// <returns>The original input</returns>
/// <returns>The original input.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe ReadOnlySpan<byte> Advance<T>(ref ReadOnlySpan<byte> input)
where T : unmanaged
@@ -67,4 +67,4 @@ namespace Impostor.Api
return original;
}
}
}
}
@@ -9,4 +9,4 @@ namespace Impostor.Api
return SystemTypeHelpers.Names[(int)type];
}
}
}
}
@@ -39,4 +39,4 @@ namespace Impostor.Api.Games
return game.SendToAsync(writer, player.Client);
}
}
}
}
@@ -8,7 +8,7 @@ namespace Impostor.Api.Games
{
public static int GetGameCount(this IGameManager manager, MapFlags map)
{
return manager.Games.Count(game => map.HasFlag((MapFlags)(1 << game.Options.MapId)));
return manager.Games.Count(game => map.HasFlag((MapFlags)(1 << (byte)game.Options.Map)));
}
}
}
}
+4 -4
View File
@@ -48,19 +48,19 @@ namespace Impostor.Api.Games
public static GameCode From(string value) => new GameCode(value);
/// <inheritdoc/>
/// <inheritdoc />
public bool Equals(GameCode other)
{
return Code == other.Code && Value == other.Value;
}
/// <inheritdoc/>
/// <inheritdoc />
public override bool Equals(object? obj)
{
return obj is GameCode other && Equals(other);
}
/// <inheritdoc/>
/// <inheritdoc />
public override int GetHashCode()
{
return HashCode.Combine(Code, Value);
@@ -71,4 +71,4 @@ namespace Impostor.Api.Games
return Code;
}
}
}
}
+2 -2
View File
@@ -41,8 +41,8 @@
/// Custom error by a plugin.
/// </summary>
/// <remarks>
/// A custom message can be set in <see cref="GameJoinResult.Message"/>.
/// A custom message can be set in <see cref="GameJoinResult.Message" />.
/// </remarks>
Custom,
}
}
}
+1 -1
View File
@@ -45,4 +45,4 @@ namespace Impostor.Api.Games
return new GameJoinResult(error);
}
}
}
}
+23 -17
View File
@@ -4,7 +4,6 @@ using System.Threading.Tasks;
using Impostor.Api.Innersloth;
using Impostor.Api.Net;
using Impostor.Api.Net.Inner;
using Impostor.Api.Net.Inner.Objects;
using Impostor.Api.Net.Messages;
namespace Impostor.Api.Games
@@ -25,47 +24,54 @@ namespace Impostor.Api.Games
int PlayerCount { get; }
IClientPlayer Host { get; }
IClientPlayer? Host { get; }
bool IsPublic { get; }
/// <summary>
/// Gets or sets display name on game list.
/// </summary>
string? DisplayName { get; set; }
IDictionary<object, object> Items { get; }
int HostId { get; }
IClientPlayer GetClientPlayer(int clientId);
IClientPlayer? GetClientPlayer(int clientId);
T? FindObjectByNetId<T>(uint netId)
where T : IInnerNetObject;
/// <summary>
/// Adds an <see cref="IPAddress"/> to the ban list of this game.
/// Prevents all future joins from this <see cref="IPAddress"/>.
///
/// This does not kick the player with that <see cref="IPAddress"/> from the lobby.
/// Adds an <see cref="IPAddress" /> to the ban list of this game.
/// Prevents all future joins from this <see cref="IPAddress" />.
/// This does not kick the player with that <see cref="IPAddress" /> from the lobby.
/// </summary>
/// <param name="ipAddress">
/// The <see cref="IPAddress"/> to ban.
/// The <see cref="IPAddress" /> to ban.
/// </param>
void BanIp(IPAddress ipAddress);
/// <summary>
/// Syncs the internal <see cref="GameOptionsData"/> to all players.
/// Syncs the internal <see cref="GameOptionsData" /> to all players.
/// Necessary to do if you modified it, otherwise it won't be used.
/// </summary>
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
ValueTask SyncSettingsAsync();
/// <summary>
/// Sets the specified list as Impostor on all connected players.
/// Sets game's privacy.
/// </summary>
/// <param name="players">List of players to be Impostor.</param>
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
ValueTask SetInfectedAsync(IEnumerable<IInnerPlayerControl> players);
/// <param name="isPublic">Privacy to set.</param>
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
ValueTask SetPrivacyAsync(bool isPublic);
/// <summary>
/// Send the message to all players.
/// </summary>
/// <param name="writer">Message to send.</param>
/// <param name="states">Required limbo state of the player.</param>
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
ValueTask SendToAllAsync(IMessageWriter writer, LimboStates states = LimboStates.NotLimbo);
/// <summary>
@@ -74,7 +80,7 @@ namespace Impostor.Api.Games
/// <param name="writer">Message to send.</param>
/// <param name="senderId">The player to exclude from sending the message.</param>
/// <param name="states">Required limbo state of the player.</param>
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
ValueTask SendToAllExceptAsync(IMessageWriter writer, int senderId, LimboStates states = LimboStates.NotLimbo);
/// <summary>
@@ -82,7 +88,7 @@ namespace Impostor.Api.Games
/// </summary>
/// <param name="writer">Message to send.</param>
/// <param name="id">ID of the client.</param>
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
ValueTask SendToAsync(IMessageWriter writer, int id);
}
}
+1 -1
View File
@@ -4,4 +4,4 @@
{
GameCode Create();
}
}
}
@@ -1,4 +1,6 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Impostor.Api.Innersloth;
namespace Impostor.Api.Games.Managers
{
@@ -7,5 +9,7 @@ namespace Impostor.Api.Games.Managers
IEnumerable<IGame> Games { get; }
IGame? Find(GameCode code);
ValueTask<IGame> CreateAsync(GameOptionsData options);
}
}
}
+9
View File
@@ -0,0 +1,9 @@
using System;
namespace Impostor.Api
{
public interface IDateTimeProvider
{
DateTimeOffset UtcNow { get; }
}
}
+9 -5
View File
@@ -1,12 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<CodeAnalysisRuleSet>ProjectRules.ruleset</CodeAnalysisRuleSet>
<TargetFramework>netstandard2.1</TargetFramework>
<CodeAnalysisRuleSet>../ProjectRules.ruleset</CodeAnalysisRuleSet>
<LangVersion>9</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Nullable>enable</Nullable>
<Version>1.0.0</Version>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<AssemblyName>Impostor.Api</AssemblyName>
@@ -16,13 +15,18 @@
<PackageId>Impostor.Api</PackageId>
<PackageTags>Among Us;Impostor;Impostor Plugin</PackageTags>
<PackageIconUrl>https://raw.githubusercontent.com/Impostor/Impostor/dev/docs/images/logo_64.png</PackageIconUrl>
<PackageIcon>logo_64.png</PackageIcon>
<PackageProjectUrl>https://github.com/Impostor/Impostor</PackageProjectUrl>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/Impostor/Impostor</RepositoryUrl>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Bcl.HashCode" Version="1.1.0" />
<None Include="../../docs/images/logo_64.png" Pack="true" PackagePath="\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0" />
<PackageReference Include="Nullable" Version="1.3.0">
@@ -35,4 +39,4 @@
</PackageReference>
</ItemGroup>
</Project>
</Project>
+1 -1
View File
@@ -4,4 +4,4 @@
{
ChangePrivacy = 1,
}
}
}
@@ -0,0 +1,14 @@
namespace Impostor.Api.Innersloth
{
public readonly struct Announcement
{
public readonly int Id;
public readonly string Message;
public Announcement(int id, string message)
{
Id = id;
Message = message;
}
}
}
+1 -1
View File
@@ -4,4 +4,4 @@
{
DidVote = 0,
}
}
}
+8
View File
@@ -0,0 +1,8 @@
namespace Impostor.Api.Innersloth
{
public enum ChatType
{
FreeChatOrQuickChat = 1,
QuickChatOnly = 2,
}
}
@@ -1,6 +1,6 @@
namespace Impostor.Api.Innersloth.Customization
{
public enum HatType
public enum HatType : uint
{
NoHat = 0,
Astronaut = 1,
@@ -45,8 +45,8 @@
ThirdEyeHat = 40,
ToiletPaperHat = 41,
Toppat = 42,
Fedora = 43,
Goggles2 = 44,
BlackFedora = 43,
SkiGoggles = 44,
Headphones = 45,
MaskHat = 46,
PaperMask = 47,
@@ -58,7 +58,7 @@
Cheese = 53,
Cherry = 54,
Egg = 55,
Fedora2 = 56,
GreenFedora = 56,
Flamingo = 57,
FlowerPin = 58,
Helmet = 59,
@@ -95,6 +95,7 @@
MiniCrewmate = 90,
NinjaMask = 91,
RamHorns = 92,
Snowman2 = 93,
SnowCrewmate = 93,
GeoffHat = 94,
}
}
@@ -1,6 +1,6 @@
namespace Impostor.Api.Innersloth.Customization
{
public enum PetType
public enum PetType : uint
{
NoPet = 0,
Alien = 1,
@@ -1,6 +1,6 @@
namespace Impostor.Api.Innersloth.Customization
{
public enum SkinType : byte
public enum SkinType : uint
{
None = 0,
Astro = 1,
+1 -1
View File
@@ -6,4 +6,4 @@
Kill = 1,
Disconnect = 2,
}
}
}
+27 -13
View File
@@ -3,52 +3,66 @@
public enum DisconnectReason
{
ExitGame = 0,
Destroy = 16,
// The game you tried to join is full.
// Check with the host to see if you can join next round.
GameFull = 1,
// The game you tried to join already started.
// Check with the host to see if you can join next round.
GameStarted = 2,
// Could not find the game you're looking for.
// Could not find the game you're looking for..
GameMissing = 3,
IncorrectGame = 18,
// For these a message can be given, specifying an empty message shows
// For this a message can be given, specifying an empty message shows
// "An unknown error disconnected you from the server."
CustomMessage1 = 4,
// 4, 12, 13, 14, 15 also count as Custom
Custom = 8,
// CustomMessage3 = 11,
// CustomMessage4 = 12,
// CustomMessage5 = 13,
// CustomMessage6 = 14,
// CustomMessage7 = 15,
// You are running an older version of the game.
// Please update to play with others.
IncorrectVersion = 5,
// You were banned from { GameCode ?? "the room" }
// You cannot rejoin that room.
// You were banned
Banned = 6,
// You can rejoin if the room hasn't started
// You were kicked
// You were kicked from { GameCode ?? "the room" }
// You can rejoin if the room hasn't started.
Kicked = 7,
// You were banned for hacking.
// Please stop.
Hacking = 10,
Destroy = 16,
// GameModes.LocalGame:
// You disconnected from the host.
// If this happens often, check your WiFi strength.
//
// GameModes.OnlineGame:
// You disconnected from the server.
// If this happens often, check your network strength.
// This may also be a server issue.
Error = 17,
// The server stopped this game. Possibly due to inactivity.
ServerRequest = 19,
// The Among Us servers are overloaded.
// Sorry! Please try again later!
ServerFull = 20,
FocusLostBackground = 207,
// You may not join another game for another { BanMinutesLeft } minutes after intentionally disconnecting.
IntentionalLeaving = 208,
// You were disconnected because Among Us was suspended by another app.
FocusLost = 209,
NewConnection = 210,
}
}
}
-22
View File
@@ -1,22 +0,0 @@
using Impostor.Api.Unity;
namespace Impostor.Api.Innersloth
{
public class FloatRange
{
private readonly float _min;
private readonly float _max;
public FloatRange(float min, float max)
{
_min = min;
_max = max;
}
public float Width => _max - _min;
public float Lerp(float v) => Mathf.Lerp(_min, _max, v);
public float ReverseLerp(float t) => Mathf.Clamp((t - _min) / Width, 0.0f, 1f);
}
}
@@ -0,0 +1,12 @@
using System;
namespace Impostor.Api.Innersloth
{
[Flags]
public enum FreeWeekendState : byte
{
NotFree,
FreeMIRA,
FreePolus,
}
}
+40 -65
View File
@@ -9,36 +9,11 @@ namespace Impostor.Api.Innersloth
public static class GameCodeParser
{
private const string V2 = "QWXRTYLPESDFGHUJKZOCVBINMA";
private static readonly int[] V2Map = {
25,
21,
19,
10,
8,
11,
12,
13,
22,
15,
16,
6,
24,
23,
18,
7,
0,
3,
9,
4,
14,
20,
1,
2,
5,
17
};
private static readonly int[] V2Map = Enumerable.Range(65, 26).Select(v => V2.IndexOf((char)v)).ToArray();
private static readonly RNGCryptoServiceProvider Random = new RNGCryptoServiceProvider();
public static string IntToGameName(int input)
{
// V2.
@@ -57,22 +32,6 @@ namespace Impostor.Api.Innersloth
#endif
}
private static string IntToGameNameV2(int input)
{
var a = input & 0x3FF;
var b = (input >> 10) & 0xFFFFF;
return new string(new []
{
V2[a % 26],
V2[a / 26],
V2[b % 26],
V2[b / 26 % 26],
V2[b / (26 * 26) % 26],
V2[b / (26 * 26 * 26) % 26]
});
}
public static int GameNameToInt(string code)
{
var upper = code.ToUpperInvariant();
@@ -80,7 +39,7 @@ namespace Impostor.Api.Innersloth
{
return -1;
}
var len = code.Length;
if (len == 6)
{
@@ -91,24 +50,9 @@ namespace Impostor.Api.Innersloth
{
return code[0] | ((code[1] | ((code[2] | (code[3] << 8)) << 8)) << 8);
}
return -1;
}
private static int GameNameToIntV2(string code)
{
var a = V2Map[code[0] - 65];
var b = V2Map[code[1] - 65];
var c = V2Map[code[2] - 65];
var d = V2Map[code[3] - 65];
var e = V2Map[code[4] - 65];
var f = V2Map[code[5] - 65];
var one = (a + 26 * b) & 0x3FF;
var two = (c + 26 * (d + 26 * (e + 26 * f)));
return (int) (one | ((two << 10) & 0x3FFFFC00) | 0x80000000);
}
public static int GenerateCode(int len)
{
@@ -116,7 +60,7 @@ namespace Impostor.Api.Innersloth
{
throw new ArgumentException("should be 4 or 6", nameof(len));
}
// Generate random bytes.
#if NETSTANDARD2_0
var data = new byte[len];
@@ -124,7 +68,7 @@ namespace Impostor.Api.Innersloth
Span<byte> data = stackalloc byte[len];
#endif
Random.GetBytes(data);
// Convert to their char representation.
Span<char> dataChar = stackalloc char[len];
for (var i = 0; i < len; i++)
@@ -138,5 +82,36 @@ namespace Impostor.Api.Innersloth
return GameNameToInt(new string(dataChar));
#endif
}
private static string IntToGameNameV2(int input)
{
var a = input & 0x3FF;
var b = (input >> 10) & 0xFFFFF;
return new string(new[]
{
V2[a % 26],
V2[a / 26],
V2[b % 26],
V2[(b / 26) % 26],
V2[(b / (26 * 26)) % 26],
V2[(b / (26 * 26 * 26)) % 26],
});
}
private static int GameNameToIntV2(string code)
{
var a = V2Map[code[0] - 65];
var b = V2Map[code[1] - 65];
var c = V2Map[code[2] - 65];
var d = V2Map[code[3] - 65];
var e = V2Map[code[4] - 65];
var f = V2Map[code[5] - 65];
var one = (a + (26 * b)) & 0x3FF;
var two = c + (26 * (d + (26 * (e + (26 * f)))));
return (int)(one | ((two << 10) & 0x3FFFFC00) | 0x80000000);
}
}
}
}
+1 -1
View File
@@ -16,4 +16,4 @@ namespace Impostor.Api.Innersloth
Polish = 128,
English = 256,
}
}
}
+109 -116
View File
@@ -7,145 +7,130 @@ namespace Impostor.Api.Innersloth
public class GameOptionsData
{
/// <summary>
/// The latest major version of the game client.
/// The latest major version of the game client.
/// </summary>
public const int LatestVersion = 4;
/// <summary>
/// Gets or sets host's version of the game.
/// Gets or sets host's version of the game.
/// </summary>
public byte Version { get; set; }
public byte Version { get; set; } = LatestVersion;
/// <summary>
/// Gets or sets the maximum amount of players for this lobby.
/// Gets or sets the maximum amount of players for this lobby.
/// </summary>
public byte MaxPlayers { get; set; }
public byte MaxPlayers { get; set; } = 10;
/// <summary>
/// Gets or sets the language of the lobby as per <see cref="GameKeywords"/> enum.
/// Gets or sets the language of the lobby as per <see cref="GameKeywords" /> enum.
/// </summary>
public GameKeywords Keywords { get; set; }
public GameKeywords Keywords { get; set; } = GameKeywords.English;
/// <summary>
/// Gets or sets the MapId selected for this lobby
/// Gets or sets the Map selected for this lobby.
/// </summary>
public MapTypes Map { get; set; } = MapTypes.Skeld;
/// <summary>
/// Gets or sets the Player speed modifier.
/// </summary>
public float PlayerSpeedMod { get; set; } = 1f;
/// <summary>
/// Gets or sets the Light modifier for the players that are members of the crew as a multiplier value.
/// </summary>
public float CrewLightMod { get; set; } = 1f;
/// <summary>
/// Gets or sets the Light modifier for the players that are Impostors as a multiplier value.
/// </summary>
public float ImpostorLightMod { get; set; } = 1f;
/// <summary>
/// Gets or sets the Impostor cooldown to kill in seconds.
/// </summary>
public float KillCooldown { get; set; } = 15f;
/// <summary>
/// Gets or sets the number of common tasks.
/// </summary>
public int NumCommonTasks { get; set; } = 1;
/// <summary>
/// Gets or sets the number of long tasks.
/// </summary>
public int NumLongTasks { get; set; } = 1;
/// <summary>
/// Gets or sets the number of short tasks.
/// </summary>
public int NumShortTasks { get; set; } = 2;
/// <summary>
/// Gets or sets the maximum amount of emergency meetings each player can call during the game in seconds.
/// </summary>
public int NumEmergencyMeetings { get; set; } = 1;
/// <summary>
/// Gets or sets the cooldown between each time any player can call an emergency meeting in seconds.
/// </summary>
public int EmergencyCooldown { get; set; } = 15;
/// <summary>
/// Gets or sets the number of impostors for this lobby.
/// </summary>
public int NumImpostors { get; set; } = 1;
/// <summary>
/// Gets or sets a value indicating whether ghosts (dead crew members) can do tasks.
/// </summary>
public bool GhostsDoTasks { get; set; } = true;
/// <summary>
/// Gets or sets the Kill as per values in <see cref="KillDistances" />.
/// </summary>
public KillDistances KillDistance { get; set; } = KillDistances.Normal;
/// <summary>
/// Gets or sets the time for discussion before voting time in seconds.
/// </summary>
public int DiscussionTime { get; set; } = 15;
/// <summary>
/// Gets or sets the time for voting in seconds.
/// </summary>
public int VotingTime { get; set; } = 120;
/// <summary>
/// Gets or sets a value indicating whether an ejected player is an impostor or not.
/// </summary>
public bool ConfirmImpostor { get; set; } = true;
/// <summary>
/// Gets or sets a value indicating whether players are able to see tasks being performed by other players.
/// </summary>
/// <remarks>
/// Skeld = 0, MiraHQ = 1, Polus = 2.
/// By being set to true, tasks such as Empty Garbage, Submit Scan, Clear asteroids, Prime shields execution will be visible to other players.
/// </remarks>
internal byte MapId { get; set; }
public bool VisualTasks { get; set; } = true;
/// <summary>
/// Gets or sets the map selected for this lobby
/// </summary>
public MapTypes Map
{
get => (MapTypes)MapId;
set => MapId = (byte)value;
}
/// <summary>
/// Gets or sets the Player speed modifier.
/// </summary>
public float PlayerSpeedMod { get; set; }
/// <summary>
/// Gets or sets the Light modifier for the players that are members of the crew as a multiplier value.
/// </summary>
public float CrewLightMod { get; set; }
/// <summary>
/// Gets or sets the Light modifier for the players that are Impostors as a multiplier value.
/// </summary>
public float ImpostorLightMod { get; set; }
/// <summary>
/// Gets or sets the Impostor cooldown to kill in seconds.
/// </summary>
public float KillCooldown { get; set; }
/// <summary>
/// Gets or sets the number of common tasks.
/// </summary>
public int NumCommonTasks { get; set; }
/// <summary>
/// Gets or sets the number of long tasks.
/// </summary>
public int NumLongTasks { get; set; }
/// <summary>
/// Gets or sets the number of short tasks.
/// </summary>
public int NumShortTasks { get; set; }
/// <summary>
/// Gets or sets the maximum amount of emergency meetings each player can call during the game in seconds.
/// </summary>
public int NumEmergencyMeetings { get; set; }
/// <summary>
/// Gets or sets the cooldown between each time any player can call an emergency meeting in seconds.
/// </summary>
public int EmergencyCooldown { get; set; }
/// <summary>
/// Gets or sets the number of impostors for this lobby.
/// </summary>
public int NumImpostors { get; set; }
/// <summary>
/// Gets or sets a value indicating whether ghosts (dead crew members) can do tasks.
/// </summary>
public bool GhostsDoTasks { get; set; }
/// <summary>
/// Gets or sets the Kill as per values in <see cref="KillDistances"/>.
/// </summary>
/// <remarks>
/// Short = 0, Normal = 1, Long = 2.
/// </remarks>
public KillDistances KillDistance { get; set; }
/// <summary>
/// Gets or sets the time for discussion before voting time in seconds.
/// </summary>
public int DiscussionTime { get; set; }
/// <summary>
/// Gets or sets the time for voting in seconds.
/// </summary>
public int VotingTime { get; set; }
/// <summary>
/// Gets or sets a value indicating whether an ejected player is an impostor or not.
/// </summary>
public bool ConfirmImpostor { get; set; }
/// <summary>
/// Gets or sets a value indicating whether players are able to see tasks being performed by other players.
/// </summary>
/// <remarks>
/// By being set to true, tasks such as Empty Garbage, Submit Scan, Clear asteroids, Prime shields execution will be visible to other players.
/// </remarks>
public bool VisualTasks { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the vote is anonymous.
/// Gets or sets a value indicating whether the vote is anonymous.
/// </summary>
public bool AnonymousVotes { get; set; }
/// <summary>
/// Gets or sets the task bar update mode as per values in <see cref="Innersloth.TaskBarUpdate"/>.
/// Gets or sets the task bar update mode as per values in <see cref="Innersloth.TaskBarUpdate" />.
/// </summary>
public TaskBarUpdate TaskBarUpdate { get; set; }
public TaskBarUpdate TaskBarUpdate { get; set; } = TaskBarUpdate.Always;
/// <summary>
/// Gets or sets a value indicating whether the GameOptions are the default ones.
/// Gets or sets a value indicating whether the GameOptions are the default ones.
/// </summary>
public bool IsDefaults { get; set; }
public bool IsDefaults { get; set; } = true;
/// <summary>
/// Deserialize a packet/message to a new GameOptionsData object.
/// Deserialize a packet/message to a new GameOptionsData object.
/// </summary>
/// <param name="reader">Message reader object containing the raw message.</param>
/// <returns>GameOptionsData object.</returns>
@@ -157,16 +142,16 @@ namespace Impostor.Api.Innersloth
}
/// <summary>
/// Serializes this instance of GameOptionsData object to a specified BinaryWriter.
/// Serializes this instance of GameOptionsData object to a specified BinaryWriter.
/// </summary>
/// <param name="writer">The stream to write the message to.</param>
/// <param name="version">The version of the game.</param>
public void Serialize(BinaryWriter writer, byte version)
public void Serialize(BinaryWriter writer, byte version = LatestVersion)
{
writer.Write((byte)version);
writer.Write((byte)MaxPlayers);
writer.Write((uint)Keywords);
writer.Write((byte)MapId);
writer.Write((byte)Map);
writer.Write((float)PlayerSpeedMod);
writer.Write((float)CrewLightMod);
writer.Write((float)ImpostorLightMod);
@@ -204,8 +189,16 @@ namespace Impostor.Api.Innersloth
}
}
public void Serialize(IMessageWriter writer)
{
using var memory = new MemoryStream();
using var writerBin = new BinaryWriter(memory);
Serialize(writerBin);
writer.WriteBytesAndSize(memory.ToArray());
}
/// <summary>
/// Deserialize a ReadOnlyMemory object to this instance of the GameOptionsData object.
/// Deserialize a ReadOnlyMemory object to this instance of the GameOptionsData object.
/// </summary>
/// <param name="memory">Memory containing the message/packet.</param>
public void Deserialize(ReadOnlyMemory<byte> memory)
@@ -215,7 +208,7 @@ namespace Impostor.Api.Innersloth
Version = bytes.ReadByte();
MaxPlayers = bytes.ReadByte();
Keywords = (GameKeywords)bytes.ReadUInt32();
MapId = bytes.ReadByte();
Map = (MapTypes)bytes.ReadByte();
PlayerSpeedMod = bytes.ReadSingle();
CrewLightMod = bytes.ReadSingle();
@@ -7,9 +7,7 @@
ImpostorByVote = 2,
ImpostorByKill = 3,
ImpostorBySabotage = 4,
// Unused (?)
ImpostorDisconnect = 5,
HumansDisconnect = 6,
}
}
}
+1 -1
View File
@@ -8,4 +8,4 @@
Ended = 3,
Destroyed = 4,
}
}
}
+1 -1
View File
@@ -7,4 +7,4 @@ namespace Impostor.Api.Innersloth
return (year * 25000) + (month * 1800) + (day * 50) + rev;
}
}
}
}
+11
View File
@@ -0,0 +1,11 @@
namespace Impostor.Api.Innersloth
{
public enum Language
{
English,
Spanish,
Portuguese,
Korean,
Russian,
}
}
+1 -1
View File
@@ -9,4 +9,4 @@ namespace Impostor.Api.Innersloth
MiraHQ = 2,
Polus = 4,
}
}
}
+45
View File
@@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Numerics;
namespace Impostor.Api.Innersloth
{
public class MapSpawn
{
private MapSpawn(float spawnRadius, Vector2 initialSpawnCenter, Vector2 meetingSpawnCenter)
{
SpawnRadius = spawnRadius;
InitialSpawnCenter = initialSpawnCenter;
MeetingSpawnCenter = meetingSpawnCenter;
}
public static Dictionary<MapTypes, MapSpawn> Maps { get; } = new Dictionary<MapTypes, MapSpawn>
{
[MapTypes.Skeld] = new MapSpawn(1.6f, new Vector2(-0.72f, 0.62f), new Vector2(-0.72f, 0.62f)),
[MapTypes.MiraHQ] = new MapSpawn(1.55f, new Vector2(-4.4f, 2.2f), new Vector2(24.043f, 1.72f)),
[MapTypes.Polus] = new MapSpawn(1f, new Vector2(16.64f, -2.46f), new Vector2(17.726f, -16.286f)),
};
public float SpawnRadius { get; }
public Vector2 InitialSpawnCenter { get; }
public Vector2 MeetingSpawnCenter { get; }
public Vector2 GetSpawnLocation(int playerId, int numPlayer, bool initialSpawn)
{
var vector = new Vector2(0, 1);
vector = Rotate(vector, (playerId - 1) * (360f / numPlayer));
vector *= this.SpawnRadius;
return (initialSpawn ? this.InitialSpawnCenter : this.MeetingSpawnCenter) + vector + new Vector2(0f, 0.3636f);
}
private static Vector2 Rotate(Vector2 self, float degrees)
{
var f = 0.017453292f * degrees;
var num = (float)Math.Cos(f);
var num2 = (float)Math.Sin(f);
return new Vector2((self.X * num) - (num2 * self.Y), (self.X * num2) + (num * self.Y));
}
}
}
+2 -2
View File
@@ -1,9 +1,9 @@
namespace Impostor.Api.Innersloth
{
public enum MapTypes
public enum MapTypes : byte
{
Skeld = 0,
MiraHQ = 1,
Polus = 2,
}
}
}
+16 -14
View File
@@ -13,22 +13,11 @@ namespace Impostor.Api.Innersloth
}
public string Name { get; }
public string Ping { get; }
public IReadOnlyList<ServerInfo> Servers { get; }
public void Serialize(BinaryWriter writer)
{
writer.Write(0);
writer.Write(Name);
writer.Write(Ping);
writer.Write(Servers.Count);
foreach (var server in Servers)
{
server.Serialize(writer);
}
}
public static RegionInfo Deserialize(BinaryReader reader)
{
var unknown = reader.ReadInt32();
@@ -44,5 +33,18 @@ namespace Impostor.Api.Innersloth
return new RegionInfo(name, ping, servers);
}
public void Serialize(BinaryWriter writer)
{
writer.Write(0);
writer.Write(Name);
writer.Write(Ping);
writer.Write(Servers.Count);
foreach (var server in Servers)
{
server.Serialize(writer);
}
}
}
}
}
+16 -14
View File
@@ -5,24 +5,18 @@ namespace Impostor.Api.Innersloth
{
public class ServerInfo
{
public string Name { get; }
public string Ip { get; }
public ushort Port { get; }
public ServerInfo(string name, string ip, ushort port)
{
Name = name;
Ip = ip;
Port = port;
}
public void Serialize(BinaryWriter writer)
{
writer.Write(Name);
writer.Write(IPAddress.Parse(Ip).GetAddressBytes());
writer.Write(Port);
writer.Write(0);
}
public string Name { get; }
public string Ip { get; }
public ushort Port { get; }
public static ServerInfo Deserialize(BinaryReader reader)
{
@@ -30,8 +24,16 @@ namespace Impostor.Api.Innersloth
var ip = new IPAddress(reader.ReadBytes(4)).ToString();
var port = reader.ReadUInt16();
var unknown = reader.ReadInt32();
return new ServerInfo(name, ip, port);
}
public void Serialize(BinaryWriter writer)
{
writer.Write(Name);
writer.Write(IPAddress.Parse(Ip).GetAddressBytes());
writer.Write(Port);
writer.Write(0);
}
}
}
}
@@ -20,9 +20,9 @@ namespace Impostor.Api.Innersloth
SystemTypes.LifeSupp => "O2",
SystemTypes.LowerEngine => "Lower Engine",
SystemTypes.LockerRoom => "Locker Room",
_ => x.ToString()
_ => x.ToString(),
};
}).ToArray();
}
}
}
}
+33 -4
View File
@@ -3,40 +3,69 @@
public enum SystemTypes : byte
{
Hallway = 0,
Storage = 1,
Cafeteria = 2,
Reactor = 3,
UpperEngine = 4,
Nav = 5,
Admin = 6,
Electrical = 7,
LifeSupp = 8,
Shields = 9,
MedBay = 10,
Security = 11,
Weapons = 12,
LowerEngine = 13,
Comms = 14,
ShipTasks = 15,
Doors = 16,
Sabotage = 17,
/// <summary>
/// Decontam on Mira and bottom decontam on Polus
/// Decontam on Mira and bottom decontam on Polus
/// </summary>
Decontamination = 18,
Launchpad = 19,
LockerRoom = 20,
Laboratory = 21,
Balcony = 22,
Office = 23,
Greenhouse = 24,
Dropship = 25,
/// <summary>
/// Top decontam on Polus
/// Top decontam on Polus
/// </summary>
Decontamination2 = 26,
Outside = 27,
Specimens = 28,
BoilerRoom = 29
BoilerRoom = 29,
}
}
}
+2 -2
View File
@@ -4,6 +4,6 @@
{
Always = 0,
Meetings = 1,
Never = 2
Never = 2,
}
}
}
+1 -1
View File
@@ -46,4 +46,4 @@
RecordTemperature = 41,
RebootWifi = 42,
}
}
}
+1 -1
View File
@@ -7,4 +7,4 @@
return i == ' ' || (i >= 'A' && i <= 'Z') || (i >= 'a' && i <= 'z') || (i >= '0' && i <= '9') || (i >= 'À' && i <= 'ÿ') || (i >= 'Ѐ' && i <= 'џ') || (i >= 'ㄱ' && i <= 'ㆎ') || (i >= '가' && i <= '힣');
}
}
}
}
+12 -4
View File
@@ -2,6 +2,7 @@
using System.Threading.Tasks;
using Impostor.Api.Innersloth;
using Impostor.Api.Net.Messages;
using Impostor.Api.Reactor;
namespace Impostor.Api.Net
{
@@ -27,6 +28,11 @@ namespace Impostor.Api.Net
/// </remarks>
string Name { get; }
/// <summary>
/// Gets mods sent by client in modded handshake.
/// </summary>
ISet<Mod> Mods { get; }
/// <summary>
/// Gets the connection of the client.
/// </summary>
@@ -51,25 +57,27 @@ namespace Impostor.Api.Net
IDictionary<object, object> Items { get; }
/// <summary>
/// Gets or sets the current game data of the <see cref="IClient"/>.
/// Gets the current game data of the <see cref="IClient" />.
/// </summary>
IClientPlayer? Player { get; }
ValueTask<bool> ReportCheatAsync(CheatContext context, string message);
ValueTask HandleMessageAsync(IMessageReader message, MessageType messageType);
ValueTask HandleDisconnectAsync(string reason);
/// <summary>
/// Disconnect the client with a <see cref="DisconnectReason"/>.
/// Disconnect the client with a <see cref="DisconnectReason" />.
/// </summary>
/// <param name="reason">
/// The message to show to the player.
/// </param>
/// <param name="message">
/// Only used when <see cref="reason"/> is set to <see cref="DisconnectReason.Custom"/>.
/// Only used when <paramref name="reason" /> is set to <see cref="DisconnectReason.Custom" />.
/// </param>
/// <returns>
/// A <see cref="ValueTask"/> representing the asynchronous operation.
/// A <see cref="ValueTask" /> representing the asynchronous operation.
/// </returns>
ValueTask DisconnectAsync(DisconnectReason reason, string? message = null);
}
+5 -5
View File
@@ -6,7 +6,7 @@ using Impostor.Api.Net.Inner.Objects;
namespace Impostor.Api.Net
{
/// <summary>
/// Represents a player in <see cref="IGame"/>.
/// Represents a player in <see cref="IGame" />.
/// </summary>
public interface IClientPlayer
{
@@ -16,7 +16,7 @@ namespace Impostor.Api.Net
IClient Client { get; }
/// <summary>
/// Gets the game where the <see cref="IClientPlayer"/> belongs to.
/// Gets the game where the <see cref="IClientPlayer" /> belongs to.
/// </summary>
IGame Game { get; }
@@ -30,10 +30,10 @@ namespace Impostor.Api.Net
public bool IsHost { get; }
/// <summary>
/// Checks if the specified <see cref="IInnerNetObject"/> is owned by <see cref="IClientPlayer"/>.
/// Checks if the specified <see cref="IInnerNetObject" /> is owned by <see cref="IClientPlayer" />.
/// </summary>
/// <param name="netObject">The <see cref="IInnerNetObject"/>.</param>
/// <returns>Returns true if owned by <see cref="IClientPlayer"/>.</returns>
/// <param name="netObject">The <see cref="IInnerNetObject" />.</param>
/// <returns>Returns true if owned by <see cref="IClientPlayer" />.</returns>
bool IsOwner(IInnerNetObject netObject);
ValueTask KickAsync();
+1 -2
View File
@@ -2,6 +2,5 @@
{
public interface IConnection
{
}
}
}
+4 -4
View File
@@ -20,7 +20,7 @@ namespace Impostor.Api.Net
bool IsConnected { get; }
/// <summary>
/// Gets the client of the connection.
/// Gets or sets the client of the connection.
/// </summary>
IClient? Client { get; set; }
@@ -28,14 +28,14 @@ namespace Impostor.Api.Net
/// Sends a message writer to the connection.
/// </summary>
/// <param name="writer">The message.</param>
/// <returns></returns>
/// <returns>Task that must be awaited.</returns>
ValueTask SendAsync(IMessageWriter writer);
/// <summary>
/// Disconnects the client and invokes the disconnect handler.
/// </summary>
/// <param name="reason">A reason.</param>
/// <returns></returns>
/// <returns>Task that must be awaited.</returns>
ValueTask DisconnectAsync(string? reason);
}
}
}
+5 -5
View File
@@ -7,12 +7,12 @@ namespace Impostor.Api.Net.Inner
/// </summary>
public interface IGameNet
{
IInnerLobbyBehaviour LobbyBehaviour { get; }
IInnerLobbyBehaviour? LobbyBehaviour { get; }
IInnerGameData GameData { get; }
IInnerGameData? GameData { get; }
IInnerVoteBanSystem VoteBan { get; }
IInnerVoteBanSystem? VoteBan { get; }
IInnerShipStatus ShipStatus { get; }
IInnerShipStatus? ShipStatus { get; }
}
}
}
@@ -6,4 +6,4 @@
public int OwnerId { get; }
}
}
}
@@ -6,7 +6,17 @@ namespace Impostor.Api.Net.Inner.Objects.Components
public interface IInnerCustomNetworkTransform : IInnerNetObject
{
/// <summary>
/// Snaps the current to the given position <see cref="IInnerPlayerControl"/>.
/// Gets position where the object thinks it is (not interpolated).
/// </summary>
Vector2 Position { get; }
/// <summary>
/// Gets current object's velocity.
/// </summary>
Vector2 Velocity { get; }
/// <summary>
/// Snaps the current to the given position <see cref="IInnerPlayerControl" />.
/// </summary>
/// <param name="position">The target position.</param>
/// <returns>Task that must be awaited.</returns>
@@ -1,6 +1,6 @@
namespace Impostor.Api.Net.Inner.Objects
{
public interface IInnerMeetingHud
public interface IInnerMeetingHud : IInnerNetObject
{
}
}
@@ -7,30 +7,30 @@ namespace Impostor.Api.Net.Inner.Objects
public interface IInnerPlayerControl : IInnerNetObject
{
/// <summary>
/// Gets the <see cref="PlayerId"/> assigned by the client of the host of the game.
/// Gets the <see cref="PlayerId" /> assigned by the client of the host of the game.
/// </summary>
byte PlayerId { get; }
/// <summary>
/// Gets the <see cref="IInnerPlayerPhysics"/> of the <see cref="IInnerPlayerControl"/>.
/// Gets the <see cref="IInnerPlayerPhysics" /> of the <see cref="IInnerPlayerControl" />.
/// Contains vent logic.
/// </summary>
IInnerPlayerPhysics Physics { get; }
/// <summary>
/// Gets the <see cref="IInnerCustomNetworkTransform"/> of the <see cref="IInnerPlayerControl"/>.
/// Gets the <see cref="IInnerCustomNetworkTransform" /> of the <see cref="IInnerPlayerControl" />.
/// Contains position data about the player.
/// </summary>
IInnerCustomNetworkTransform NetworkTransform { get; }
/// <summary>
/// Gets the <see cref="IInnerPlayerInfo"/> of the <see cref="IInnerPlayerControl"/>.
/// Gets the <see cref="IInnerPlayerInfo" /> of the <see cref="IInnerPlayerControl" />.
/// Contains metadata about the player.
/// </summary>
IInnerPlayerInfo PlayerInfo { get; }
/// <summary>
/// Sets the name of the current <see cref="IInnerPlayerControl"/>.
/// Sets the name of the current <see cref="IInnerPlayerControl" />.
/// Visible to all players.
/// </summary>
/// <param name="name">A name for the player.</param>
@@ -38,55 +38,39 @@ namespace Impostor.Api.Net.Inner.Objects
ValueTask SetNameAsync(string name);
/// <summary>
/// Sets the color of the current <see cref="IInnerPlayerControl"/>.
/// Sets the color of the current <see cref="IInnerPlayerControl" />.
/// Visible to all players.
/// </summary>
/// <param name="colorId">A color for the player.</param>
/// <returns>Task that must be awaited.</returns>
ValueTask SetColorAsync(byte colorId);
/// <param name="colorType">A color for the player.</param>
/// <inheritdoc cref="SetColorAsync(byte)" />
/// <returns>Task that must be awaited.</returns>
ValueTask SetColorAsync(ColorType colorType);
/// <summary>
/// Sets the hat of the current <see cref="IInnerPlayerControl"/>.
/// Sets the hat of the current <see cref="IInnerPlayerControl" />.
/// Visible to all players.
/// </summary>
/// <param name="hatId">An hat for the player.</param>
/// <returns>Task that must be awaited.</returns>
ValueTask SetHatAsync(uint hatId);
/// <param name="hatType">An hat for the player.</param>
/// <inheritdoc cref="SetHatAsync(uint)" />
/// <returns>Task that must be awaited.</returns>
ValueTask SetHatAsync(HatType hatType);
/// <summary>
/// Sets the pet of the current <see cref="IInnerPlayerControl"/>.
/// Sets the pet of the current <see cref="IInnerPlayerControl" />.
/// Visible to all players.
/// </summary>
/// <param name="petId">A pet for the player.</param>
/// <returns>Task that must be awaited.</returns>
ValueTask SetPetAsync(uint petId);
/// <param name="petType">A pet for the player.</param>
/// <inheritdoc cref="SetPetAsync(uint)" />
/// <returns>Task that must be awaited.</returns>
ValueTask SetPetAsync(PetType petType);
/// <summary>
/// Sets the skin of the current <see cref="IInnerPlayerControl"/>.
/// Sets the skin of the current <see cref="IInnerPlayerControl" />.
/// Visible to all players.
/// </summary>
/// <param name="skinId">A skin for the player.</param>
/// <returns>Task that must be awaited.</returns>
ValueTask SetSkinAsync(uint skinId);
/// <param name="skinType">A skin for the player.</param>
/// <inheritdoc cref="SetSkinAsync(uint)" />
/// <returns>Task that must be awaited.</returns>
ValueTask SetSkinAsync(SkinType skinType);
/// <summary>
/// Send a chat message as the current <see cref="IInnerPlayerControl"/>.
/// Send a chat message as the current <see cref="IInnerPlayerControl" />.
/// Visible to all players.
/// </summary>
/// <param name="text">The message to send.</param>
@@ -94,7 +78,7 @@ namespace Impostor.Api.Net.Inner.Objects
ValueTask SendChatAsync(string text);
/// <summary>
/// Send a chat message as the current <see cref="IInnerPlayerControl"/>.
/// Send a chat message as the current <see cref="IInnerPlayerControl" />.
/// Visible to only the current.
/// </summary>
/// <param name="text">The message to send.</param>
@@ -106,11 +90,20 @@ namespace Impostor.Api.Net.Inner.Objects
ValueTask SendChatToPlayerAsync(string text, IInnerPlayerControl? player = null);
/// <summary>
/// Sets the current to be murdered by an impostor <see cref="IInnerPlayerControl"/>.
/// Murder <paramref name="target" /> player.
/// </summary>
/// <param name="target">Target player to murder.</param>
/// <exception cref="ImpostorProtocolException">Thrown when player is not the impostor.</exception>
/// <exception cref="ImpostorProtocolException">Thrown when player is dead.</exception>
/// <exception cref="ImpostorProtocolException">Thrown when target is dead.</exception>
/// <returns>Task that must be awaited.</returns>
ValueTask MurderPlayerAsync(IInnerPlayerControl target);
/// <summary>
/// Exile the current player. This doesn't produce a body to be reported.
/// Visible to all players.
/// </summary>
/// /// <param name="impostor">The Impostor who kill.</param>
/// <returns>Task that must be awaited.</returns>
ValueTask SetMurderedByAsync(IClientPlayer impostor);
ValueTask ExileAsync();
}
}
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using Impostor.Api.Innersloth;
using Impostor.Api.Innersloth.Customization;
namespace Impostor.Api.Net.Inner.Objects
{
@@ -14,22 +15,22 @@ namespace Impostor.Api.Net.Inner.Objects
/// <summary>
/// Gets the color of the player.
/// </summary>
byte ColorId { get; }
ColorType Color { get; }
/// <summary>
/// Gets the hat of the player.
/// </summary>
uint HatId { get; }
HatType Hat { get; }
/// <summary>
/// Gets the pet of the player.
/// </summary>
uint PetId { get; }
PetType Pet { get; }
/// <summary>
/// Gets the skin of the player.
/// </summary>
uint SkinId { get; }
SkinType Skin { get; }
/// <summary>
/// Gets a value indicating whether the player is an impostor.
@@ -2,6 +2,5 @@
{
public interface IInnerShipStatus : IInnerNetObject
{
}
}
}
@@ -2,6 +2,5 @@
{
public interface IInnerVoteBanSystem : IInnerNetObject
{
}
}
}
@@ -1,5 +1,4 @@
using Impostor.Api.Innersloth;
using Impostor.Api.Net.Messages;
namespace Impostor.Api.Net.Inner.Objects
{
@@ -33,5 +33,6 @@
RepairSystem = 28,
SetTasks = 29,
UpdateGameData = 30,
CustomRpc = byte.MaxValue,
}
}
}
+1 -1
View File
@@ -10,4 +10,4 @@ namespace Impostor.Api.Net
WaitingForHost = 4,
All = PreSpawn | NotLimbo | WaitingForHost,
}
}
}
@@ -6,4 +6,4 @@ namespace Impostor.Api.Net.Manager
{
IEnumerable<IClient> Clients { get; }
}
}
}
@@ -0,0 +1,15 @@
namespace Impostor.Api.Net.Messages.Announcements
{
public static class Message00UseCache
{
public static void Serialize(IMessageWriter writer)
{
writer.StartMessage(AnnouncementsMessageFlags.UseCache);
writer.EndMessage();
}
public static void Deserialize(IMessageReader reader)
{
}
}
}
@@ -0,0 +1,19 @@
namespace Impostor.Api.Net.Messages.Announcements
{
public static class Message01Update
{
public static void Serialize(IMessageWriter writer, int id, string message)
{
writer.StartMessage(AnnouncementsMessageFlags.SetUpdate);
writer.WritePacked(id);
writer.Write(message);
writer.EndMessage();
}
public static void Deserialize(IMessageReader reader, out int id, out string message)
{
id = reader.ReadPackedInt32();
message = reader.ReadString();
}
}
}
@@ -0,0 +1,19 @@
using Impostor.Api.Innersloth;
namespace Impostor.Api.Net.Messages.Announcements
{
public static class Message02SetFreeWeekend
{
public static void Serialize(IMessageWriter writer, FreeWeekendState state)
{
writer.StartMessage(AnnouncementsMessageFlags.SetFreeWeekend);
writer.Write((byte)state);
writer.EndMessage();
}
public static void Deserialize(IMessageReader reader, out FreeWeekendState state)
{
state = (FreeWeekendState)reader.ReadByte();
}
}
}
@@ -0,0 +1,15 @@
using Impostor.Api.Innersloth;
namespace Impostor.Api.Net.Messages.Announcements
{
public class MessageHello
{
public static void Deserialize(IMessageReader reader, out int announcementVersion, out int id, out Language language)
{
reader.ReadByte(); // SendOption header, probably added by accident
announcementVersion = reader.ReadPackedInt32();
id = reader.ReadPackedInt32();
language = (Language)reader.ReadPackedInt32();
}
}
}
@@ -0,0 +1,9 @@
namespace Impostor.Api.Net.Messages
{
public class AnnouncementsMessageFlags
{
public const byte UseCache = 0;
public const byte SetUpdate = 1;
public const byte SetFreeWeekend = 2;
}
}
@@ -1,5 +1,4 @@
using System.IO;
using Impostor.Api.Innersloth;
using Impostor.Api.Innersloth;
namespace Impostor.Api.Net.Messages.C2S
{
@@ -8,20 +7,22 @@ namespace Impostor.Api.Net.Messages.C2S
public static void Serialize(IMessageWriter writer, GameOptionsData gameOptionsData)
{
writer.StartMessage(MessageFlags.HostGame);
using (var memory = new MemoryStream())
using (var writerBin = new BinaryWriter(memory))
{
gameOptionsData.Serialize(writerBin, GameOptionsData.LatestVersion);
writer.WriteBytesAndSize(memory.ToArray());
}
gameOptionsData.Serialize(writer);
writer.EndMessage();
}
public static GameOptionsData Deserialize(IMessageReader reader)
/// <summary>
/// Deserialize a packet.
/// </summary>
/// <param name="reader"><see cref="IMessageReader" /> with <see cref="IMessageReader.Tag" /> 0.</param>
/// <param name="chatType">The chat type selected in the client of the player.</param>
/// <returns>Deserialized <see cref="GameOptionsData" />.</returns>
public static GameOptionsData Deserialize(IMessageReader reader, out ChatType chatType)
{
return GameOptionsData.DeserializeCreate(reader);
var gameOptionsData = GameOptionsData.DeserializeCreate(reader);
chatType = (ChatType)reader.ReadByte();
return gameOptionsData;
}
}
}
}
@@ -1,4 +1,5 @@
using System;
using Impostor.Api.Games;
namespace Impostor.Api.Net.Messages.C2S
{
@@ -6,15 +7,12 @@ namespace Impostor.Api.Net.Messages.C2S
{
public static void Serialize(IMessageWriter writer)
{
throw new System.NotImplementedException();
throw new NotImplementedException();
}
public static void Deserialize(IMessageReader reader, out int gameCode, out byte unknown)
public static void Deserialize(IMessageReader reader, out GameCode gameCode)
{
var slice = reader.ReadBytes(sizeof(Int32) + sizeof(byte)).Span;
gameCode = slice.ReadInt32();
unknown = slice.ReadByte();
gameCode = reader.ReadInt32();
}
}
}
}
@@ -1,10 +1,12 @@
namespace Impostor.Api.Net.Messages.C2S
using System;
namespace Impostor.Api.Net.Messages.C2S
{
public class Message04RemovePlayerC2S
{
public static void Serialize(IMessageWriter writer)
{
throw new System.NotImplementedException();
throw new NotImplementedException();
}
public static void Deserialize(IMessageReader reader, out int playerId, out byte reason)
@@ -13,4 +15,4 @@
reason = reader.ReadByte();
}
}
}
}
@@ -1,4 +1,5 @@
using Impostor.Api.Innersloth;
using System;
using Impostor.Api.Innersloth;
namespace Impostor.Api.Net.Messages.C2S
{
@@ -6,7 +7,7 @@ namespace Impostor.Api.Net.Messages.C2S
{
public static void Serialize(IMessageWriter writer)
{
throw new System.NotImplementedException();
throw new NotImplementedException();
}
public static void Deserialize(IMessageReader reader, out GameOverReason gameOverReason)
@@ -15,4 +16,4 @@ namespace Impostor.Api.Net.Messages.C2S
reader.ReadBoolean(); // showAd
}
}
}
}
@@ -1,4 +1,5 @@
using Impostor.Api.Innersloth;
using System;
using Impostor.Api.Innersloth;
namespace Impostor.Api.Net.Messages.C2S
{
@@ -6,7 +7,7 @@ namespace Impostor.Api.Net.Messages.C2S
{
public static void Serialize(IMessageWriter writer)
{
throw new System.NotImplementedException();
throw new NotImplementedException();
}
public static void Deserialize(IMessageReader reader, out AlterGameTags gameTag, out bool isPublic)
@@ -17,4 +18,4 @@ namespace Impostor.Api.Net.Messages.C2S
isPublic = slice.ReadBoolean();
}
}
}
}
@@ -1,10 +1,12 @@
namespace Impostor.Api.Net.Messages.C2S
using System;
namespace Impostor.Api.Net.Messages.C2S
{
public class Message11KickPlayerC2S
{
public static void Serialize(IMessageWriter writer)
{
throw new System.NotImplementedException();
throw new NotImplementedException();
}
public static void Deserialize(IMessageReader reader, out int playerId, out bool isBan)
@@ -13,4 +15,4 @@
isBan = reader.ReadBoolean();
}
}
}
}
Loaded 100 of 316 files, more files were not shown because too many files have changed in this diff. Show more