Compare commits

...
201 Commits
Author SHA1 Message Date
miniduikboot 6b6fa08125 Version bump for 2022.6.21 (#486)
Mostly untested, ran through a few games and seems to work fine
2022-06-22 21:36:58 +02:00
AeonLucid cea3d8980f Update appveyor.yml, replace NuGet auth token 2022-06-12 02:33:43 +03:00
js6pak d1ffdb95e1 Update appveyor.yml
crappveyor
2022-06-11 15:41:48 +00:00
miniduikboot 4d11cf91ad Remove Auth- and AnnouncementsServer sections (#484) 2022-06-03 18:58:00 +00:00
miniduikboot 84aba52198 Remove 75% of the question marks of PR #481 (#482) 2022-06-03 18:57:47 +00:00
js6pakandminiduikboot 6e4bb71289 Add Serilog.Settings.Configuration (#468)
* Add Serilog.Settings.Configuration

* Add docs section for logging

* Elaborate Serilog documentation

Co-authored-by: miniduikboot <mini@duikbo.at>
2022-06-03 20:31:52 +02:00
js6pak 8fec1a211e Merge pull request #483 from js6pak/fix-disconnect-reason
Fix non custom disconnect reasons
2022-06-03 20:31:10 +02:00
js6pak 85a2fce6c1 Fix non custom disconnect reasons 2022-06-03 20:17:59 +02:00
miniduikboot 224fdd1d5b Allow adding custom tasks on standard maps (#481)
This is needed for mods that add tasks to standard maps, but also mods
that add custom maps: because their custom netobjects don't get
registered Impostor thinks people are still on the old map when people
switch to the custom map after playing a game.
2022-05-25 19:53:32 +02:00
miniduikboot 380ba46f11 Upgrade to .NET 6 (#479)
* Upgrade to .NET 6

.NET 5 has gone EOL, so move to a supported version.

* Upgrade Docker container as well
* Update docs for .NET 6
* Re-add hack for System.IO.Pipelines
* Bump dependency versions
* Update the deps of the other projects too
* Only declare TargetFramework once
* Dockerfile: also copy over Directory.Build.props
* Cake: pick up target framework automatically
* Upgrade Cake as well
2022-05-25 19:52:22 +02:00
miniduikboot aeefc40ef1 Merge pull request #474 from SubmergedAmongUs/master
Add handling for null ShipStatus
2022-04-20 18:49:37 +02:00
AlexejheroYTB 743b8ed5cb Remove null check for ShipStatus known to not be null 2022-04-20 08:07:59 +03:00
AlexejheroYTB ed008872f6 Add handling for null ShipStatus 2022-04-16 17:11:58 +03:00
js6pak 4797d899af Merge pull request #471 from Impostor/feature/2022.3.29 2022-04-09 12:42:51 +00:00
js6pak c834013bd3 Simplify Message07JoinedGameS2CPre20220202 2022-04-07 16:58:33 +02:00
js6pak 70c180fb19 Make GameOptionsData de/serialization less confusing 2022-04-07 11:58:16 +02:00
miniduikboot 729368d777 Do not add ProductUserId/Friendcode on <2.24
Because it is fine to add data to the end of messages the new fields
could be added to Message 1 just fine, but because Message 7 contains a
loop, we need to send a different message to old clients there.
2022-04-05 20:05:06 +02:00
miniduikboot 5c06d1dd4d fixup! Add empty ProductUserId and FriendCode to packets 2022-04-05 19:52:25 +02:00
miniduikboot 446e5b8705 Add empty ProductUserId and FriendCode to packets
They are not sent to the server and no clue how to retrieve them out of band.
2022-04-05 19:52:25 +02:00
miniduikboot ae00ff9295 Barebones port 2022-04-05 19:52:25 +02:00
miniduikboot 400592b99c Merge pull request #467 from miniduikboot/fix/race-dc-send-all-except
Do not broadcast messages to disconnected clients
2022-03-26 10:35:54 +01:00
miniduikboot 9906c409da Do not broadcast messages to disconnected clients
This method is used when players have disconnected. If multiple players
disconnect at once, this method leads to exceptions.
2022-03-17 21:35:08 +01:00
miniduikboot c26d03a8bc Merge pull request #464 from miniduikboot/fix/custom-dc-msg
Fix/custom dc msg
2022-02-28 18:04:47 +01:00
miniduikboot ca48d672d5 Reword obsoletion message 2022-02-26 20:33:02 +01:00
miniduikboot 0b431dc5fa Change DisconnectAsync to use extension instead 2022-02-26 20:31:45 +01:00
miniduikboot 0b0c8274aa Turn DisconnectConnection into an extension 2022-02-26 20:31:23 +01:00
miniduikboot 36f8255e26 Fixup 608414326d
Oops, I accidentally forgot to remove the previous line when adding the
file to my commit
2022-02-26 19:08:57 +01:00
miniduikboot 919b094018 Deprecate JoinGame errors
Starting from version 2021.11.9, join errors no longer exist, instead a
client will show the message "An unknown error disconnected you from the
server". As a workaround, the connection is disconnected entirely when
an error occurs, which allows us to show a custom message.
2022-02-26 19:08:57 +01:00
js6pak 6125fd7006 Merge pull request #465 from miniduikboot/fix/2-28-bump 2022-02-26 17:26:54 +01:00
miniduikboot a3c0c8cacf Bump network version 2022-02-25 07:05:22 +01:00
miniduikboot b252bf2ee7 Merge pull request #460 from miniduikboot/feature/queryplatformids
Add QueryPlatformIds
2022-02-14 22:12:47 +01:00
miniduikboot 9b5a63e030 Add QueryPlatformIds
Some platforms (notable the Microsoft Store version) ask for this before connecting.
2022-02-02 22:17:47 +01:00
miniduikboot 6a8f089576 Merge pull request #455 from miniduikboot/fix/i18n-nicknames
Fix/i18n nicknames
2022-01-27 19:23:30 +01:00
miniduikboot d994323083 Merge pull request #458 from miniduikboot/fix/ac-engineer-snapto
AC: Allow engineers to move to a different vent.
2022-01-27 19:22:59 +01:00
miniduikboot 3f374da44b Partial revert of cc8d5d2: Readd length check
Oversized nicknames can cause bigger issues, so it is desireable to
still block them. .Length counts codepoints, not bytes, which means
that 10 character Japanese nicknames, which are configurable ingame,
should still be allowed.
2022-01-27 18:24:02 +01:00
miniduikboot bfd2efa716 AC: Allow engineers to move to a different vent. 2022-01-27 18:10:46 +01:00
miniduikboot 6867dec7ee Merge pull request #453 from miniduikboot/fix/ga-half-cooldown
AC CheckMurder: Require half of cooldown
2022-01-14 23:06:28 +01:00
miniduikboot 7132dc2d38 Add comment to clarify why this exists 2022-01-14 19:47:58 +01:00
miniduikboot 682bfac558 Merge pull request #452 from miniduikboot/fix/host-migrate
Before this commit, when the host of a game disconnects, the InnerPlayerInfo from the player is removed, which causes the new host to disconnect because of a deserialization error. This PR fixes this issue
2022-01-14 18:21:16 +01:00
miniduikboot cc8d5d2a45 Remove name length/validity checks from JoinGame
Length and validity are checked also checked by the anticheat. In case
Impostor goes out of sync with the allowed characters again, this can
just be fixed by disabling the Anticheat.

Check for NullOrWhiteSpace is kept because an empty username could be annoying
2022-01-10 20:54:45 +01:00
miniduikboot e6a35344c3 Sync IsCharAllowed with Innersloth implementation 2022-01-10 20:54:45 +01:00
miniduikboot db52b48cd6 AC CheckMurder: Require half of cooldown
When the Guardian Angel protects a player, the impostor that just missed
their kill gets back half of their cooldown. Keeping track of whether or
not the player was protected is more difficult due to how the Guardian
Angel is implemented, so instead we halve the minimum time between kill
in order to minimize false positives.
2022-01-08 19:20:11 +01:00
miniduikboot 50a526a02d Clamp taskCount to the length of the task list
New tasks cannot be created at this point because we don't know the
underlying tasks. So we try to maintain the tasks we do know of.
2022-01-08 17:42:05 +01:00
miniduikboot 608414326d Do not destroy PlayerControl if game is starting
This player may still get assigned tasks, which could lead to
deserialization problems.
2022-01-08 17:41:52 +01:00
miniduikboot d8bcb52c90 Mark game as started when RPC SetRole is called
This used to be done when SetInfected was called, but this RPC is no
longer used since 2021.11.9 in favor of this RPC.
2022-01-08 17:41:14 +01:00
miniduikboot d7d7547182 Merge pull request #442 from Impostor/2021.11.9
2021.11.9 and 2021.12.14 support
2021-12-21 23:27:38 +01:00
js6pak 64e27c3e21 Set RoleType in PlayerInfo.Deserialize 2021-12-15 15:36:01 +01:00
js6pak a0b433500c Don't do public methods in interfaces 2021-12-15 15:35:46 +01:00
js6pak c51a1f9c1f Readd HandleSet{Pet/Hat/Skin} 2021-12-15 15:33:01 +01:00
js6pak e15ac51dcf Implement cosmetic rpc methods 2021-12-15 15:22:18 +01:00
js6pak bde3a22f6e Document IClient.PlatformSpecificData 2021-12-15 14:52:22 +01:00
js6pak 6118e6b7b8 Change RoleOptionsData floats to be bytes as they can't ever be floats anyway 2021-12-15 14:51:07 +01:00
miniduikboot 32ecfedfba Add initial support for 2021.12.14 2021-12-14 21:38:26 +01:00
miniduikboot b6fe79cc8b Add RPC's for CheckProtect and ProtectPlayer 2021-11-22 23:04:56 +01:00
miniduikboot aeaffc849a Implement new MurderPlayer logic
In 2021.11.9, the host now uses MurderPlayer instead of impostors.
Impostor now use CheckMurder to request the host to kill a player. This
allows the host to prevent the target of the Guardian Angel from dying.

However, if the impostor that is checking the kill is also the host, AU
internally processes the CheckMurder RPC and sends the MurderPlayer RPC
first, *then* it sends the CheckMurder RPC.
2021-11-22 22:12:34 +01:00
miniduikboot a15f1b6a4c Add platform data to GameList 2021-11-15 22:55:57 +01:00
js6pak afb7051218 Fix ServerReplay 2021-11-13 19:51:52 +01:00
miniduikboot 8a0e9e876e Bump to 1.7 2021-11-12 23:12:47 +01:00
miniduikboot 22f1d74cdf Allow Shapeshifters to use RPC Shapeshift 2021-11-12 23:12:47 +01:00
miniduikboot e6d38f4b72 Allow Engineers to vent 2021-11-12 22:57:29 +01:00
miniduikboot 93c80c1412 Implement Rpc 44: SetRole 2021-11-12 22:56:35 +01:00
miniduikboot c3e0157209 Add name/psd/level to JoinGame- and JoinedGameS2C
Two players can now connect to the same lobby
2021-11-12 21:11:48 +01:00
miniduikboot 0769752407 Remove initial state flag from InnerGameData 2021-11-10 23:04:21 +01:00
miniduikboot fba1a894cc Implement SetActivePodType 2021-11-10 21:23:00 +01:00
js6pak 4d1aec9070 WIP 2021-11-10 20:46:56 +01:00
js6pak e0c7086973 RIP AnnouncementsServer 2021-11-10 13:52:15 +01:00
js6pak 125da11d61 [skip ci] Auto deploy github releases 2021-08-05 14:24:51 +02:00
js6pak d86efc1345 Merge pull request #431 from miniduikboot/feature/2021.6.30 2021-07-30 20:41:57 +02:00
js6pak 301a851ec3 Handle all handshake versions 2021-07-27 17:42:11 +02:00
js6pak 86c27402e2 Language and chat mode api 2021-07-27 16:59:09 +02:00
miniduikboot c63eb3b2d1 Improve docs (#435) 2021-07-25 19:53:43 +00:00
miniduikboot a1dac9f8b7 Address feedback 2021-07-25 20:22:02 +02:00
miniduikboot 3065e8df48 Check client version when parsing C2S handshake
2021.6.30 added new fields, which aren't present on old clients.

This commit makes sure players on old versions are disconnected properly
instead of the server erroring internally.
2021-07-21 21:53:22 +02:00
miniduikboot dc52e478dc Disable ownership check for BootFromVent 2021-07-21 20:46:33 +02:00
miniduikboot eb86c3c683 Implement RPC 35: Update System 2021-07-21 20:46:33 +02:00
miniduikboot e7c83769ef Implement RPC 34: Boot from vent 2021-07-21 20:46:33 +02:00
miniduikboot c6b8066794 Bump to 1.6 because new net version 2021-07-21 20:46:33 +02:00
miniduikboot 1ec5a050ad Add Vent Cleaning task
As these spawn in various rooms under the same task id the name of this
task does not include a room name
2021-07-21 20:46:33 +02:00
miniduikboot 1e7d132f31 Add Airship Lounge/Showers Empty Garbage tasks
Also Calibrate Distributor moved up
2021-07-21 20:46:33 +02:00
miniduikboot 9543134ef3 Add two extra fields to handshake 2021-07-21 20:46:33 +02:00
miniduikboot 389c72caa6 Bump client version 2021-07-21 20:46:33 +02:00
miniduikbootandjs6pak 66b4d860a9 Improve error when client version is unsupported (#432)
* Improve error when client version is unsupported

In the default message that was used previously the user is asked to
upgrade his game. This is not always correct, as sometimes the Impostor
server is too old and should be updated instead. Therefore custom
disconnect messages are used that blames either the user or the server
operator, which is hopefully more accurate.

I've chosen not to include the game version that is supported by the
server in this message because the network version rarely matches the
advertised version in the main menu.

* Rewrite versionCompare switch case

Co-authored-by: js6pak <kubastaron@hotmail.com>

Co-authored-by: js6pak <kubastaron@hotmail.com>
2021-07-13 22:48:24 +02:00
js6pak dca26cff59 Log unsupported version 2021-07-07 19:01:48 +02:00
js6pak 3437c86bff Merge pull request #430 from Bramux/fix-hat-mismatch
Fix mismatched hats
2021-07-05 23:19:30 +02:00
Bramux 66fb8426a6 Correct hat mismatches 2021-07-05 22:26:28 +02:00
js6pak 4c839e2dd8 Merge pull request #429 from miniduikboot/fix/style 2021-07-05 21:22:28 +02:00
js6pak c6aa596e3b Fix warnings in Impostor.Benchmarks 2021-07-05 21:13:56 +02:00
miniduikboot d8843db3eb Use var instead of explicit type
Also prevent future issues
2021-07-05 20:36:56 +02:00
miniduikboot b918f25443 Remove unnecessary imports
And add rule to prevent future issues
2021-07-05 20:36:56 +02:00
js6pak 824359f93b Merge pull request #428 from miniduikboot/fix/colortype
Correct ColorType array
2021-07-05 20:33:11 +02:00
js6pak 046d09b5fa Merge pull request #427 from miniduikboot/fix/airship-spawn
Stop cancelling initial Airship spawn SnapTo RPC
2021-07-05 20:30:12 +02:00
miniduikboot 5410c71280 Correct ColorType array
When creating this array for the update, I used the wrong array. Oops!
Turns out 5 of these colors aren't actually in the game.
2021-07-05 20:06:21 +02:00
miniduikboot 241e867343 Stop cancelling initial Airship spawn SnapTo RPC
This is used to hide players that are still selecting their spawn
location. If this is cancelled, players are left standing at the
location they were at when the last meeting was called, which is undesirable.
2021-07-05 20:01:20 +02:00
js6pak 11f2ffd24d Remove legacy regionInfo patcher 2021-07-05 18:27:59 +02:00
js6pak 9df01d2cf7 Merge pull request #423 from miniduikboot/feature/2021.6.15 2021-06-26 20:26:07 +00:00
miniduikboot d2720442e9 Turn derived properties into getters
There is no significant performance difference: while accessing the
getters is slightly slower, this can be balanced against the cost of
setting the property. As this is also cleaner, switch to getters.
2021-06-25 18:46:28 +02:00
miniduikboot ddedffd121 Refactor Polus meeting room spawning logic
Also adjust the constants to the new constants used in game
2021-06-25 18:46:28 +02:00
miniduikboot 2f04f6ea98 Stub implementation of SendQuickChat
Proper API will follow later
2021-06-25 18:46:28 +02:00
miniduikboot 5f4c40bf36 Remove the table from the Readme
As Among Us is getting a lot of small network-compatible bugfix releases
nowadays, it doesn't seem necessary to maintain the table anymore.
Release notes state clearly which network version is supported and there
is limited support for old versions anyway.
2021-06-25 18:46:28 +02:00
miniduikboot ef4cc5646b Simplify the setup instructions
The patcher has not been updated to support the new JSON format and is
less necessary now that JSON is used for the region file format.

The website also now has deeplinking support, so we point Android/iOS
people to the website now too as that is more convenient compared to the
previous methods.
2021-06-25 18:46:28 +02:00
js6pak d894e9adc3 Meeting changes 2021-06-25 18:46:28 +02:00
js6pak c086cf80b1 Announcements protocol changes 2021-06-25 18:46:28 +02:00
js6pak 1118a59167 Update GameKeywords 2021-06-25 18:46:28 +02:00
miniduikboot 5154dd9aa5 Adjust Polus Meeting table spawn locations 2021-06-25 18:46:28 +02:00
miniduikboot a621225fcd Add new colors 2021-06-25 18:46:28 +02:00
miniduikboot 73a5463848 Update supported GameVersions 2021-06-25 18:46:28 +02:00
miniduikboot 02d25a290f Bump version because new net version 2021-06-15 22:20:07 +02:00
ced530b83a Added player voted event (#181)
Co-authored-by: AeonLucid <aeonlucid@outlook.com>
Co-authored-by: js6pak <kubastaron@hotmail.com>
2021-06-11 12:33:38 +00:00
8f1cba8429 Using MapData for Tasks (#395)
Co-authored-by: John Tran <john.tran.84@live.com.au>
Co-authored-by: js6pak <kubastaron@hotmail.com>
2021-06-10 18:54:34 +00:00
js6pak 9009bac883 Merge pull request #417 from miniduikboot/fix/initialize-color 2021-06-10 18:38:17 +00:00
miniduikboot f3460f05bc Initialize Color to -1 instead of Red
This could lead to an AC disconnect if the host picked red and waited
for other players to rejoin before joining back himself. Before this
commit, the host would SetColor himself to Red, but this would be
flagged as all other players would have been set to Red as enums
initialize to 0 (= Red) by default.

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

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

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

* Disable expected checks for the host
2021-01-08 18:42:41 +01:00
429 changed files with 7748 additions and 10809 deletions

No files matched your search

+1 -1
View File
@@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"cake.tool": {
"version": "0.38.5",
"version": "2.2.0",
"commands": [
"dotnet-cake"
]
-17
View File
@@ -1,17 +0,0 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- pinned
- security
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false
+9 -5
View File
@@ -2,7 +2,7 @@ name: Docker
on:
push:
branches: dev
branches: master
paths:
- 'src/Impostor.Server/**'
- 'src/Impostor.Shared/**'
@@ -33,15 +33,16 @@ jobs:
run: |
DOCKER_IMAGE=aeonlucid/impostor
VERSION=noop
VERSIONSUFFIX=docker
if [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
VERSIONSUFFIX=none
elif [[ $GITHUB_REF == refs/heads/* ]]; then
VERSION=$(echo ${GITHUB_REF#refs/heads/} | sed -r 's#/+#-#g')
if [ "${{ github.event.repository.default_branch }}" = "dev" ]; then
VERSION=nightly
fi
VERSION=nightly
VERSIONSUFFIX=docker.${{ github.run_number }}
elif [[ $GITHUB_REF == refs/pull/* ]]; then
VERSION=pr-${{ github.event.number }}
VERSIONSUFFIX=pr.${{ github.event.number }}
fi
TAGS="${DOCKER_IMAGE}:${VERSION}"
if [[ $VERSION =~ ^v[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
@@ -49,6 +50,7 @@ jobs:
fi
echo ::set-output name=version::${VERSION}
echo ::set-output name=tags::${TAGS}
echo ::set-output name=versionsuffix::${VERSIONSUFFIX}
echo ::set-output name=created::$(date -u +'%Y-%m-%dT%H:%M:%SZ')
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
@@ -68,3 +70,5 @@ jobs:
platforms: linux/amd64,linux/arm/v7,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.prep.outputs.tags }}
build-args: |
VERSIONSUFFIX=${{ steps.prep.outputs.versionsuffix }}
+3
View File
@@ -0,0 +1,3 @@
[submodule "src/Impostor.Hazel"]
path = src/Impostor.Hazel
url = https://github.com/Impostor/Impostor.Hazel
+3 -3
View File
@@ -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.
- 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.
- Stylecop is also enabled: please make sure your PR compiles without warnings.
## Pull requests
- Only make pull requests to the `dev` branch.
- 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.
- 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).
If you have any questions, let us know.
If you have any questions, let us know.
+10 -6
View File
@@ -1,15 +1,18 @@
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:5.0 AS build
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:6.0 AS build
# See for all possible platforms
# https://github.com/containerd/containerd/blob/master/platforms/platforms.go#L17
ARG TARGETARCH
ARG VERSIONSUFFIX="docker"
WORKDIR /source
# Copy csproj and restore.
COPY src/Impostor.Server/Impostor.Server.csproj ./src/Impostor.Server/Impostor.Server.csproj
COPY src/Impostor.Api/Impostor.Api.csproj ./src/Impostor.Api/Impostor.Api.csproj
COPY src/Impostor.Hazel/Impostor.Hazel.csproj ./src/Impostor.Hazel/Impostor.Hazel.csproj
COPY src/Impostor.Hazel/Hazel/Hazel.csproj ./src/Impostor.Hazel/Hazel/Hazel.csproj
COPY src/Directory.Build.props ./src/Directory.Build.props
RUN case "$TARGETARCH" in \
amd64) NETCORE_PLATFORM='linux-x64';; \
@@ -19,7 +22,7 @@ RUN case "$TARGETARCH" in \
esac && \
dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Server/Impostor.Server.csproj && \
dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Api/Impostor.Api.csproj && \
dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Hazel/Impostor.Hazel.csproj
dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Hazel/Hazel/Hazel.csproj
# Copy everything else.
COPY src/. ./src/
@@ -29,11 +32,12 @@ 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
FROM --platform=$TARGETPLATFORM mcr.microsoft.com/dotnet/runtime:6.0
WORKDIR /app
COPY --from=build /app ./
EXPOSE 22023/udp
ENTRYPOINT ["./Impostor.Server"]
ENTRYPOINT ["./Impostor.Server"]
+6 -36
View File
@@ -1,16 +1,13 @@
# 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#.
Impostor is the first working **Among Us** private server, 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`.
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 |
|-|-|-|-|
| 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) |
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.
## Features
@@ -22,34 +19,7 @@ We support Steam, Itch, Android and iOS. The latest version supported is `2020.9
### Client
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-Client-win-x64.zip`.
3. Extract the zip.
4. Run `Impostor.Client.exe`.
5. Follow the instructions inside the application.
![Client](docs/images/client.jpg)
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.
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.
### Server
@@ -57,7 +27,7 @@ See the [docs](docs/Running-the-server.md) for instructions on how to set it up.
## Troubleshooting
See [TROUBLESHOOTING](docs/TROUBLESHOOTING.md) to solve issues the Impostor client or the server.
See [TROUBLESHOOTING](docs/TROUBLESHOOTING.md) to solve issues with the Impostor client or the server.
## Contributing
+24 -13
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,15 +16,16 @@ assembly_info:
dotnet_csproj:
patch: false
image: Visual Studio 2019 Preview
image: Ubuntu2004
install:
- git submodule update --init --recursive
- ps: dotnet tool restore
- dotnet tool restore
build_script:
- ps: dotnet cake build.cake --bootstrap
- ps: dotnet cake build.cake --pack
- pwsh: if ($env:APPVEYOR_REPO_TAG_NAME) { Update-AppveyorBuild -Version "$($env:APPVEYOR_REPO_TAG_NAME -replace "v")" }
- dotnet cake build.cake --bootstrap
- dotnet cake build.cake --pack
test: off
@@ -35,13 +35,24 @@ artifacts:
- path: ./build/*.nupkg
- path: ./build/*.snupkg
# deploy:
# - provider: NuGet
# artifact: /.*(\.|\.s)nupkg/
# on:
# branch: dev
# api_key:
# secure: 4OHXl+m1KVi60hB1j54MpdP8tVv0UNfkdF4rVP+2AhAjN4a2MVT+Bl90gJZ96xHF
deploy:
# - provider: NuGet
# artifact: /.*(\.|\.s)nupkg/
# on:
# branch: master
# api_key:
# secure: 4OHXl+m1KVi60hB1j54MpdP8tVv0UNfkdF4rVP+2AhAjN4a2MVT+Bl90gJZ96xHF
- provider: GitHub
tag: $(APPVEYOR_REPO_TAG_NAME)
release: $(APPVEYOR_PROJECT_NAME) $(APPVEYOR_BUILD_VERSION)
description: 'DRAFT'
auth_token:
secure: /2Yz69s8BOfuNmV5NDcC37Zglw/QrT5QCUEDnGiJK8FIdO/owWPgm+KUqa8D/+9j
artifact: /.*/
draft: true
on:
APPVEYOR_REPO_TAG: true
only_commits:
files:
+42 -68
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.3"
#addin "nuget:?package=Cake.Compression&Version=0.3.0"
#addin "nuget:?package=Cake.FileHelpers&Version=5.0.0"
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 DotNetMSBuildSettings();
if (buildRelease)
{
msbuildSettings.Properties["Version"] = new[] { buildVersion };
}
else if (buildId != null)
{
msbuildSettings.Properties["VersionSuffix"] = new[] { "ci." + buildId };
buildVersion += "-ci." + buildId;
}
//////////////////////////////////////////////////////////////////////
@@ -26,15 +31,15 @@ private void ImpostorPublish(string name, string project, string runtime, bool i
var projBuildDir = buildDir.Combine(name + "_" + runtime);
var projBuildName = name + "_" + buildVersion + "_" + runtime;
DotNetCorePublish(project, new DotNetCorePublishSettings {
DotNetPublish(project, new DotNetPublishSettings {
Configuration = configuration,
NoRestore = true,
Framework = "net5.0",
Runtime = runtime,
SelfContained = false,
PublishSingleFile = true,
PublishTrimmed = false,
OutputDirectory = projBuildDir
OutputDirectory = projBuildDir,
MSBuildSettings = msbuildSettings
});
if (isServer) {
@@ -58,11 +63,12 @@ private void ImpostorPublishNF(string name, string project) {
var projBuildDir = buildDir.Combine(name + "_" + runtime);
var projBuildZip = buildDir.CombineWithFilePath(name + "_" + buildVersion + "_" + runtime + ".zip");
DotNetCorePublish(project, new DotNetCorePublishSettings {
DotNetPublish(project, new DotNetPublishSettings {
Configuration = configuration,
NoRestore = true,
Framework = "net472",
OutputDirectory = projBuildDir
OutputDirectory = projBuildDir,
MSBuildSettings = msbuildSettings
});
Zip(projBuildDir, projBuildZip);
@@ -83,83 +89,51 @@ Task("Clean")
Task("Restore")
.Does(() => {
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>");
DotNetRestore("./src/Impostor.sln");
});
Task("Replay")
.Does(() => {
// D:\Projects\GitHub\Impostor\Impostor\src\Impostor.Tools.ServerReplay\sessions
DotNetCoreRun(
DotNetRun(
"./src/Impostor.Tools.ServerReplay/Impostor.Tools.ServerReplay.csproj",
"./src/Impostor.Tools.ServerReplay/sessions", new DotNetCoreRunSettings {
"./src/Impostor.Tools.ServerReplay/sessions", new DotNetRunSettings {
Configuration = configuration,
NoRestore = true,
Framework = "net5.0"
});
});
Task("Build")
.IsDependentOn("Clean")
.IsDependentOn("Patch")
.IsDependentOn("Restore")
.IsDependentOn("Replay")
.Does(() => {
// Tests.
DotNetCoreBuild("./src/Impostor.Tests/Impostor.Tests.csproj", new DotNetCoreBuildSettings {
DotNetBuild("./src/Impostor.Tests/Impostor.Tests.csproj", new DotNetBuildSettings {
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");
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.
DotNetPack("./src/Impostor.Api/Impostor.Api.csproj", new DotNetPackSettings {
Configuration = configuration,
OutputDirectory = buildDir,
IncludeSource = true,
IncludeSymbols = true,
MSBuildSettings = msbuildSettings
});
});
Task("Test")
.IsDependentOn("Build")
.Does(() => {
DotNetCoreTest("./src/Impostor.Tests/Impostor.Tests.csproj", new DotNetCoreTestSettings {
DotNetTest("./src/Impostor.Tests/Impostor.Tests.csproj", new DotNetTestSettings {
Configuration = configuration,
NoBuild = true
});
@@ -175,4 +149,4 @@ Task("Deploy")
// EXECUTION
//////////////////////////////////////////////////////////////////////
RunTarget(target);
RunTarget(target);
+9 -25
View File
@@ -1,45 +1,29 @@
# 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 the Impostor server and its dependencies, like Hazel and the plugin API. The server is built using [.NET 6](https://dotnet.microsoft.com/download/dotnet/6.0).
## 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/Impostor/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)
- [.NET 6 SDK](https://dotnet.microsoft.com/download/dotnet/6.0)
- [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
```bash
cd src/Impostor.Server/
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).
## Building the client
### Dependencies
* [.NET Framework 4.7.2 Developer Pack](https://dotnet.microsoft.com/download/dotnet-framework/thank-you/net472-developer-pack-offline-installer)
### Build using the CLI
```bash
cd src/Impostor.Client/Impostor.Client.WinForms
dotnet build
```
+7 -3
View File
@@ -1,11 +1,15 @@
# Frequently Answered Questions
## 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?
Yes, Impostor can be used with both the Android and iOS\* versions of the game.
###### \* In order to play on an Impostor server with iOS, you _must_ have a jailbroken device.
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)
## 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!
If you're having issues with the server software, check the [Troubleshooting page](TROUBLESHOOTING.md).
+16 -15
View File
@@ -1,30 +1,31 @@
# Running the server
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.
There are currently two modes to run the Impostor server. The first way, Single Server, is the simplest one, can handle up to a few hundred simultaneous players, and is the one you should probably use. Multi-Server mode will distribute players across other servers and is intended for advanced users.
## Single server
### 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 dev release](https://ci.appveyor.com/project/Impostor/Impostor/branch/dev/artifacts).
3. Download either the Windows or the Linux version.
### Without Docker
1. Install the [.NET 6.0 runtime](https://dotnet.microsoft.com/download/6.0). Installing the SDK also works, but is not necessary unless you plan on developing Impostor or Impostor plugins. If you're asked to pick between a console, desktop or server runtime, the console runtime is enough.
2. Find the [latest release](https://github.com/Impostor/Impostor/releases) or the [latest CI build](https://ci.appveyor.com/project/Impostor/Impostor/branch/master/artifacts).
3. Download the version for your OS (linux/win/osx). Impostor is built for multiple CPU-architectures, you most likely want the x64 version, unless you are running on a Raspberry Pi or another device with an ARM processor.
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)
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` (Linux/macOS) or `Impostor.Server.exe` (Windows)
### Using docker
### Using Docker
[![Docker Image](https://img.shields.io/docker/v/aeonlucid/impostor?sort=semver)](https://hub.docker.com/repository/docker/aeonlucid/impostor)
[![Docker Image](https://img.shields.io/docker/v/aeonlucid/impostor/nightly)](https://hub.docker.com/repository/docker/aeonlucid/impostor)
[![Docker Image](https://img.shields.io/docker/v/aeonlucid/impostor?sort=semver)](https://hub.docker.com/r/aeonlucid/impostor)
[![Docker Image](https://img.shields.io/docker/v/aeonlucid/impostor/nightly)](https://hub.docker.com/r/aeonlucid/impostor)
After installing Docker, you can just start a Docker container with `docker run`:
```
docker run -p 22023:22023/udp aeonlucid/impostor:nightly
```
### Using docker-compose
### Using Docker Compose
```
version: '3.4'
@@ -42,7 +43,7 @@ services:
## Multiple servers
Follow the steps from the single server on two or more servers.
Follow the steps from the single server on two or more servers. You should only need to set this up if you have a very large server and can no longer fit everyone on one server: if this is your first time installing Impostor, use a single server.
### Master server
+70 -40
View File
@@ -1,34 +1,83 @@
# 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.
Some information about all the possible configurations. Click [here](https://github.com/Impostor/Impostor/blob/master/src/Impostor.Server/config-full.json) to see all the possible config options.
## Options
### Required Server Configuration
| 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. |
| **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. |
| **ListenPort** | `22023` | The listen port of the server, usually `22023`. |
| 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. |
| **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. |
| **ListenPort** | `22023` | The listen port of the server, usually `22023`. |
### AntiCheat
| Key | Default | Value |
|-|-|-|
| **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!)** |
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 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. |
### 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. |
### ServerRedirector
In a multi-node setup these need to be specified.
| Key | Default | Value |
|-|-|-|
| **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. |
| **Master** | `false` | Whether the current server is a master. A master is responsible for redirecting clients to nodes |
| **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. |
| **>Redis** | | Format `127.0.0.1.6379`, you can also use a password like so: `127.0.0.1.6379,password=value`. |
| **>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`. |
| **Nodes** | | An array containing public ips and ports of nodes. Only needs to be set on the master. See above for an example. |
In a multi-node setup these values need to be specified. Note that most people do not need to run a Multi-node setup.
| Key | Default | Value |
| ---------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| **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. |
| **Master** | `false` | Whether the current server is a master. A master is responsible for redirecting clients to nodes |
| **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. |
| **>Redis** | | Format `127.0.0.1.6379`, you can also use a password like so: `127.0.0.1.6379,password=value`. |
| **>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`. |
| **Nodes** | | An array containing public ips and ports of nodes. Only needs to be set on the master. See above for an example. |
### 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
@@ -36,35 +85,16 @@ In a multi-node setup these need to be specified.
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: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
TODO
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:
```
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
+38 -9
View File
@@ -1,28 +1,57 @@
# Troubleshooting
If you're reading this, something went wrong.
Don't worry though, as this is the most thorough guide to help you!
## `./Impostor.Server: line 1: ELF: not found` (plus other errors)
No idea where you got that system. But we clearly do **NOT** support it.
## `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).
Unless you are running Impostor on a SBC (Single-Board Computer), like the Raspberry Pi, you most likely want to use the x64 version.
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 computer like the Raspberry Pi, you most likely want to use the x64 version.
## `./Impostor.Server: Permission denied`
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.
You can solve this by doing: `chmod +x Impostor.Server`
## `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).
## Disconnected with `Your client is too new, please update your Impostor to play`
## `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 `127` nor `192`**
This happens when your game is too new for your copy of Impostor to support.
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 Appveyor](https://ci.appveyor.com/project/Impostor/Impostor/branch/master).
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 AppVeyor works](https://ci.appveyor.com/project/Impostor/Impostor/branch/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).
## `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.
## 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.
+9 -12
View File
@@ -19,24 +19,24 @@ Impostor has support for plugins. This document will help you to setup a develop
- [Impostor versions](#impostor-versions)
- [9. Missing/invalid data or want more functions?](#9-missinginvalid-data-or-want-more-functions)
## 1. Install .NET Core SDK
## 1. Install .NET SDK
Download and install the latest .NET Core SDK.
Download and install the latest .NET SDK.
https://dotnet.microsoft.com/download
## 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 5, which includes:
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 6, which includes:
- .NET Standard 2.0
- .NET Standard 2.1
- .NET Core 3.1
- .NET 5
- .NET 6
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.
> At the moment of writing this document, I recommend you to use **.NET Standard 2.1**. This should give you enough functionality. If not, upgrade to .NET 6.
When the project has been created, you should have `Class.cs` and `Project.csproj` files. Your `Project.csproj` should look something like this.
@@ -62,16 +62,13 @@ Make sure to get a prerelease if you are writing a plugin for a dev release of t
1. Right click your project.
2. Click `Manage NuGet Packages`.
3. Click `Browse`.
4. Next to the search bar, enable `Include prerelease`.
5. Search for `Impostor.Api`.
6. Click the `Impostor.Api` result and press install on the right side.
4. Search for `Impostor.Api`.
5. Click the `Impostor.Api` result and press install on the right side.
### 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.
2. Run `dotnet add package Impostor.Api -v "1.2.0-ci.58"`.
2. Run `dotnet add package Impostor.Api`.
## 4. The plugin class
@@ -340,4 +337,4 @@ Create an issue:
- [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 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)
+13 -4
View File
@@ -4,8 +4,8 @@ root = true
# Don't use tabs for indentation.
[*]
charset = utf-8
end_of_line = crlf
insert_final_newline = false
end_of_line = lf
insert_final_newline = true
indent_style = space
# Code files
@@ -144,6 +144,12 @@ dotnet_naming_style.end_in_async.word_separator =
# error RS2008: Enable analyzer release tracking for the analyzer project containing rule '{0}'
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
dotnet_diagnostic.IDE0035.severity = warning
@@ -163,7 +169,7 @@ csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_object_initializers = true
# csharp_new_line_before_members_in_object_initializers = true TODO seems like Rider/ReSharper has the value inverted, uncomment when its fixed
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_between_query_expression_clauses = true
@@ -171,7 +177,7 @@ csharp_new_line_between_query_expression_clauses = true
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_case_contents_when_block = false
csharp_indent_switch_labels = true
csharp_indent_labels = flush_left
@@ -228,3 +234,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
+13
View File
@@ -0,0 +1,13 @@
<Project>
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<VersionPrefix>1.7.1</VersionPrefix>
<VersionSuffix>dev</VersionSuffix>
<EnforceCodeStyleInBuild Condition="$(MSBuildProjectName)!='Hazel'">true</EnforceCodeStyleInBuild>
</PropertyGroup>
<ItemGroup>
<AdditionalFiles Include="$(MSBuildThisFileDirectory)stylecop.json" />
</ItemGroup>
</Project>
+20
View File
@@ -0,0 +1,20 @@
using Impostor.Api.Net.Inner;
namespace Impostor.Api
{
public class CheatContext
{
public CheatContext(string name)
{
Name = name;
}
public static CheatContext Deserialize { get; } = new CheatContext(nameof(Deserialize));
public static CheatContext Serialize { get; } = new CheatContext(nameof(Serialize));
public string Name { get; }
public static implicit operator CheatContext(RpcCalls rpcCalls) => new CheatContext(rpcCalls.ToString());
}
}
@@ -17,18 +17,18 @@ namespace Impostor.Api.Events
}
/// <summary>
/// The priority of the event listener.
/// Gets or sets the priority of the event listener.
/// </summary>
public EventPriority Priority { get; set; }
/// <summary>
/// The events that the listener is listening to.
/// Gets or sets the event that the listener is listening to.
/// </summary>
public Type? Event { get; set; }
/// <summary>
/// If set to true, the listener will be called regardless of the <see cref="IEventCancelable.IsCancelled"/>.
/// Gets or sets a value indicating whether the listener will be called regardless of the <see cref="IEventCancelable.IsCancelled" />.
/// </summary>
public bool IgnoreCancelled { get; set; }
}
}
}
@@ -0,0 +1,12 @@
using Impostor.Api.Net;
namespace Impostor.Api.Events.Client
{
/// <summary>
/// Called just after a <see cref="IClient"/> is created and connected.
/// </summary>
public interface IClientConnectedEvent : IClientEvent
{
IClient Client { get; }
}
}
@@ -0,0 +1,13 @@
using Impostor.Api.Net;
using Impostor.Api.Net.Messages;
namespace Impostor.Api.Events.Client
{
/// <summary>
/// Called just before a <see cref="IHazelConnection"/> is registered.
/// </summary>
public interface IClientConnectionEvent : IClientEvent
{
IMessageReader HandshakeData { get; }
}
}
@@ -0,0 +1,9 @@
using Impostor.Api.Net;
namespace Impostor.Api.Events.Client
{
public interface IClientEvent : IEvent
{
IHazelConnection Connection { get; }
}
}
@@ -3,7 +3,7 @@
namespace Impostor.Api.Events
{
/// <summary>
/// Called whenever a new <see cref="IGame"/> is created.
/// Called whenever a new <see cref="IGame" /> is created.
/// </summary>
public interface IGameCreatedEvent : IGameEvent
{
@@ -0,0 +1,25 @@
using Impostor.Api.Games;
using Impostor.Api.Net;
namespace Impostor.Api.Events
{
/// <summary>
/// Called just before a new <see cref="IGame"/> is created.
/// </summary>
public interface IGameCreationEvent : IEventCancelable
{
/// <summary>
/// Gets the client that requested creation of the game.
/// </summary>
/// <remarks>
/// Will be null if game creation was requested by a plugin.
/// </remarks>
IClient? Client { get; }
/// <summary>
/// Gets or sets the desired <see cref="Games.GameCode"/>.
/// </summary>
/// <exception cref="ImpostorException">If the GameCode is invalid or already used in another game.</exception>
GameCode? GameCode { get; set; }
}
}
@@ -3,7 +3,7 @@
namespace Impostor.Api.Events
{
/// <summary>
/// Called whenever a new <see cref="IGame"/> is destroyed.
/// Called whenever a new <see cref="IGame" /> is destroyed.
/// </summary>
public interface IGameDestroyedEvent : IGameEvent
{
+1 -1
View File
@@ -5,7 +5,7 @@ namespace Impostor.Api.Events
public interface IGameEvent : IEvent
{
/// <summary>
/// Gets the <see cref="IGame"/> this event belongs to.
/// Gets the <see cref="IGame" /> this event belongs to.
/// </summary>
IGame Game { get; }
}
@@ -0,0 +1,11 @@
using Impostor.Api.Net;
namespace Impostor.Api.Events
{
public interface IGameHostChangedEvent : IGameEvent
{
IClientPlayer PreviousHost { get; }
IClientPlayer? NewHost { get; }
}
}
@@ -1,6 +1,9 @@
namespace Impostor.Api.Events
using Impostor.Api.Net;
namespace Impostor.Api.Events
{
public interface IGamePlayerJoinedEvent : IGameEvent
{
IClientPlayer Player { get; }
}
}
@@ -0,0 +1,15 @@
using Impostor.Api.Games;
using Impostor.Api.Net;
namespace Impostor.Api.Events
{
/// <summary>
/// Called just before a <see cref="IClientPlayer"/> joins a game.
/// </summary>
public interface IGamePlayerJoiningEvent : IGameEvent
{
IClientPlayer Player { get; }
GameJoinResult? JoinResult { get; set; }
}
}
@@ -1,6 +1,11 @@
namespace Impostor.Api.Events
using Impostor.Api.Net;
namespace Impostor.Api.Events
{
public interface IGamePlayerLeftEvent : IGameEvent
{
IClientPlayer Player { get; }
bool IsBan { get; }
}
}
@@ -3,7 +3,7 @@
/// <summary>
/// Called when the game is going to start.
/// When this is called, not all players are initialized properly yet.
/// If you want to get correct player states, use <see cref="IGameStartedEvent"/>.
/// If you want to get correct player states, use <see cref="IGameStartedEvent" />.
/// </summary>
public interface IGameStartingEvent : IGameEvent
{
@@ -1,6 +1,17 @@
namespace Impostor.Api.Events.Meeting
using Impostor.Api.Net.Inner.Objects;
namespace Impostor.Api.Events.Meeting
{
public interface IMeetingEndedEvent : IMeetingEvent
{
/// <summary>
/// Gets the exiled player.
/// </summary>
IInnerPlayerControl? Exiled { get; }
/// <summary>
/// Gets a value indicating whether meeting result is a tie.
/// </summary>
bool IsTie { get; }
}
}
@@ -1,6 +1,6 @@
namespace Impostor.Api.Events.Player
{
public interface IPlayerChatEvent : IPlayerEvent
public interface IPlayerChatEvent : IPlayerEvent, IEventCancelable
{
/// <summary>
/// Gets the message sent by the player.
@@ -1,5 +1,4 @@
using Impostor.Api.Innersloth;
using Impostor.Api.Net.Inner.Objects;
using Impostor.Api.Net.Inner.Objects;
namespace Impostor.Api.Events.Player
{
@@ -0,0 +1,15 @@
using Impostor.Api.Innersloth;
namespace Impostor.Api.Events.Player
{
/// <summary>
/// Called whenever a player enters a vent.
/// </summary>
public interface IPlayerEnterVentEvent : IPlayerEvent
{
/// <summary>
/// Gets the entered vent.
/// </summary>
public IVent Vent { get; }
}
}
@@ -6,14 +6,14 @@ namespace Impostor.Api.Events.Player
public interface IPlayerEvent : IGameEvent
{
/// <summary>
/// Gets the <see cref="IClientPlayer"/> that triggered this <see cref="IPlayerEvent"/>.
/// Gets the <see cref="IClientPlayer" /> that triggered this <see cref="IPlayerEvent" />.
/// </summary>
IClientPlayer ClientPlayer { get; }
/// <summary>
/// Gets the networked <see cref="IInnerPlayerControl"/> that triggered this <see cref="IPlayerEvent"/>.
/// This <see cref="IInnerPlayerControl"/> belongs to the <see cref="IClientPlayer"/>.
/// Gets the networked <see cref="IInnerPlayerControl" /> that triggered this <see cref="IPlayerEvent" />.
/// This <see cref="IInnerPlayerControl" /> belongs to the <see cref="IClientPlayer" />.
/// </summary>
IInnerPlayerControl PlayerControl { get; }
}
}
}
@@ -0,0 +1,15 @@
using Impostor.Api.Innersloth;
namespace Impostor.Api.Events.Player
{
/// <summary>
/// Called whenever a player exits a vent.
/// </summary>
public interface IPlayerExitVentEvent : IPlayerEvent
{
/// <summary>
/// Gets the exited vent.
/// </summary>
public IVent Vent { get; }
}
}
@@ -0,0 +1,6 @@
namespace Impostor.Api.Events.Player
{
public interface IPlayerMovementEvent : IPlayerEvent
{
}
}
@@ -5,7 +5,7 @@ namespace Impostor.Api.Events.Player
public interface IPlayerStartMeetingEvent : IPlayerEvent
{
/// <summary>
/// Gets the player who's body got reported. Is null when the meeting started by Emergency call button
/// Gets the player who's body got reported. Is null when the meeting started by Emergency call button.
/// </summary>
IInnerPlayerControl? Body { get; }
}
@@ -2,16 +2,14 @@ using Impostor.Api.Innersloth;
namespace Impostor.Api.Events.Player
{
/// <summary>
/// Called whenever a player moves to another vent.
/// </summary>
public interface IPlayerVentEvent : IPlayerEvent
{
/// <summary>
/// Gets get the id of the used vent.
/// Gets the vent player moved to.
/// </summary>
public VentLocation VentId { get; }
/// <summary>
/// Gets a value indicating whether the vent was entered or exited.
/// </summary>
public bool VentEnter { get; }
public IVent NewVent { get; }
}
}
@@ -0,0 +1,26 @@
using Impostor.Api.Net.Inner.Objects;
namespace Impostor.Api.Events.Player
{
public enum VoteType : byte
{
HasNotVoted = 255,
Missed = 254,
Skipped = 253,
Dead = 252,
Player = 0,
}
public interface IPlayerVotedEvent : IPlayerEvent
{
/// <summary>
/// Gets the player he voted for.
/// </summary>
IInnerPlayerControl? VotedFor { get; }
/// <summary>
/// Gets the Vote type.
/// </summary>
VoteType VoteType { get; }
}
}
+1 -1
View File
@@ -3,4 +3,4 @@
public interface IEvent
{
}
}
}
+2 -2
View File
@@ -3,8 +3,8 @@
public interface IEventCancelable : IEvent
{
/// <summary>
/// True if the event was cancelled.
/// Gets or sets a value indicating whether the event was cancelled.
/// </summary>
bool IsCancelled { get; set; }
}
}
}
+1 -1
View File
@@ -3,4 +3,4 @@
public interface IEventListener
{
}
}
}
@@ -4,10 +4,10 @@ namespace Impostor.Api.Events
{
public interface IManualEventListener : IEventListener
{
EventPriority Priority { get; set; }
public bool CanExecute<T>();
public ValueTask Execute(IEvent @event);
EventPriority Priority { get; set; }
}
}
}
@@ -16,20 +16,20 @@ namespace Impostor.Api.Events.Managers
where TListener : IEventListener;
/// <summary>
/// Returns true if an event with the type <see cref="TEvent"/> is registered.
/// Returns true if an event with the type <typeparamref name="TEvent" /> is registered.
/// </summary>
/// <returns>True if the <see cref="TEvent"/> is registered.</returns>
/// <returns>True if the <typeparamref name="TEvent" /> is registered.</returns>
/// <typeparam name="TEvent">Type of the event.</typeparam>
bool IsRegistered<TEvent>()
where TEvent : IEvent;
/// <summary>
/// Call all the event listeners for the type <see cref="TEvent"/>.
/// Call all the event listeners for the type <typeparamref name="TEvent" />.
/// </summary>
/// <param name="event">The event argument.</param>
/// <typeparam name="TEvent">Type of the event.</typeparam>
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
ValueTask CallAsync<TEvent>(TEvent @event)
where TEvent : IEvent;
}
}
}
@@ -1,12 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Impostor.Server.Events
namespace Impostor.Api.Events
{
/// <summary>
/// Disposes multiple <see cref="IDisposable"/>.
/// Disposes multiple <see cref="IDisposable" />.
/// </summary>
internal class MultiDisposable : IDisposable
public class MultiDisposable : IDisposable
{
private readonly IEnumerable<IDisposable> _disposables;
@@ -15,6 +16,10 @@ namespace Impostor.Server.Events
_disposables = disposables;
}
public MultiDisposable(params IDisposable[] disposables) : this(disposables.AsEnumerable())
{
}
public void Dispose()
{
foreach (var disposable in _disposables)
@@ -1,24 +0,0 @@
using System;
using System.Runtime.Serialization;
namespace Impostor.Api
{
public class ImpostorCheatException : ImpostorException
{
public ImpostorCheatException()
{
}
protected ImpostorCheatException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
public ImpostorCheatException(string? message) : base(message)
{
}
public ImpostorCheatException(string? message, Exception? innerException) : base(message, innerException)
{
}
}
}
@@ -9,10 +9,6 @@ namespace Impostor.Api
{
}
protected ImpostorConfigException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
public ImpostorConfigException(string? message) : base(message)
{
}
@@ -20,5 +16,9 @@ namespace Impostor.Api
public ImpostorConfigException(string? message, Exception? innerException) : base(message, innerException)
{
}
protected ImpostorConfigException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}
@@ -9,10 +9,6 @@ namespace Impostor.Api
{
}
protected ImpostorException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
public ImpostorException(string? message) : base(message)
{
}
@@ -20,5 +16,9 @@ namespace Impostor.Api
public ImpostorException(string? message, Exception? innerException) : base(message, innerException)
{
}
protected ImpostorException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}
}
@@ -9,10 +9,6 @@ namespace Impostor.Api
{
}
protected ImpostorProtocolException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
public ImpostorProtocolException(string? message) : base(message)
{
}
@@ -20,5 +16,9 @@ namespace Impostor.Api
public ImpostorProtocolException(string? message, Exception? innerException) : base(message, innerException)
{
}
protected ImpostorProtocolException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}
@@ -0,0 +1,19 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace Impostor.Api
{
public static class DictionaryExtensions
{
/// <summary>Returns a read-only <see cref="ReadOnlyDictionary{TKey,TValue}" /> wrapper for the dictionary.</summary>
/// <param name="dictionary">An <see cref="IDictionary{TKey,TValue}" /> to create a <see cref="ReadOnlyDictionary{TKey,TValue}" /> from.</param>
/// <typeparam name="TKey">The type of the keys of <paramref name="dictionary" />.</typeparam>
/// <typeparam name="TValue">The type of the values of <paramref name="dictionary" />.</typeparam>
/// <returns>An object that acts as a read-only wrapper around the <see cref="IDictionary{TKey,TValue}" />.</returns>
public static ReadOnlyDictionary<TKey, TValue> AsReadOnly<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
where TKey : notnull
{
return new ReadOnlyDictionary<TKey, TValue>(dictionary);
}
}
}
@@ -5,7 +5,7 @@ using System.Runtime.CompilerServices;
namespace Impostor.Api
{
/// <summary>
/// Priovides a StreamReader-like api throught extensions
/// Priovides a StreamReader-like api throught extensions.
/// </summary>
public static class SpanReaderExtensions
{
@@ -16,6 +16,13 @@ namespace Impostor.Api
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)]
public static int ReadInt32(this ref ReadOnlySpan<byte> input)
{
@@ -35,9 +42,7 @@ namespace Impostor.Api
{
var original = Advance<float>(ref input);
// BitConverter.Int32BitsToSingle
// Doesn't exist in net 2.0 for some reason
return Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(original));
return BitConverter.Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(original));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -46,18 +51,12 @@ namespace Impostor.Api
return input.ReadByte() != 0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe float Int32BitsToSingle(int value)
{
return *((float*)&value);
}
/// <summary>
/// Advances the position of <see cref="input"/> by the size of <see cref="T"/>.
/// Advances the position of <paramref name="input" /> by the size of <typeparamref name="T" />.
/// </summary>
/// <typeparam name="T">Type that will be read.</typeparam>
/// <param name="input">input "stream"/span.</param>
/// <returns>The original input</returns>
/// <returns>The original input.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe ReadOnlySpan<byte> Advance<T>(ref ReadOnlySpan<byte> input)
where T : unmanaged
@@ -67,4 +66,4 @@ namespace Impostor.Api
return original;
}
}
}
}
@@ -9,4 +9,4 @@ namespace Impostor.Api
return SystemTypeHelpers.Names[(int)type];
}
}
}
}
@@ -39,4 +39,4 @@ namespace Impostor.Api.Games
return game.SendToAsync(writer, player.Client);
}
}
}
}
@@ -8,7 +8,7 @@ namespace Impostor.Api.Games
{
public static int GetGameCount(this IGameManager manager, MapFlags map)
{
return manager.Games.Count(game => map.HasFlag((MapFlags)(1 << game.Options.MapId)));
return manager.Games.Count(game => map.HasFlag((MapFlags)(1 << (byte)game.Options.Map)));
}
}
}
}
+8 -6
View File
@@ -1,4 +1,4 @@
using System;
using System;
using Impostor.Api.Innersloth;
namespace Impostor.Api.Games
@@ -14,13 +14,15 @@ namespace Impostor.Api.Games
public GameCode(string code)
{
Value = GameCodeParser.GameNameToInt(code);
Code = code;
Code = code.ToUpperInvariant();
}
public string Code { get; }
public int Value { get; }
public bool IsInvalid => Value == -1;
public static implicit operator string(GameCode code) => code.Code;
public static implicit operator int(GameCode code) => code.Value;
@@ -48,19 +50,19 @@ namespace Impostor.Api.Games
public static GameCode From(string value) => new GameCode(value);
/// <inheritdoc/>
/// <inheritdoc />
public bool Equals(GameCode other)
{
return Code == other.Code && Value == other.Value;
}
/// <inheritdoc/>
/// <inheritdoc />
public override bool Equals(object? obj)
{
return obj is GameCode other && Equals(other);
}
/// <inheritdoc/>
/// <inheritdoc />
public override int GetHashCode()
{
return HashCode.Combine(Code, Value);
@@ -71,4 +73,4 @@ namespace Impostor.Api.Games
return Code;
}
}
}
}
+2 -2
View File
@@ -41,8 +41,8 @@
/// Custom error by a plugin.
/// </summary>
/// <remarks>
/// A custom message can be set in <see cref="GameJoinResult.Message"/>.
/// A custom message can be set in <see cref="GameJoinResult.Message" />.
/// </remarks>
Custom,
}
}
}
+1 -1
View File
@@ -45,4 +45,4 @@ namespace Impostor.Api.Games
return new GameJoinResult(error);
}
}
}
}
+42 -17
View File
@@ -4,7 +4,6 @@ using System.Threading.Tasks;
using Impostor.Api.Innersloth;
using Impostor.Api.Net;
using Impostor.Api.Net.Inner;
using Impostor.Api.Net.Inner.Objects;
using Impostor.Api.Net.Messages;
namespace Impostor.Api.Games
@@ -25,47 +24,54 @@ namespace Impostor.Api.Games
int PlayerCount { get; }
IClientPlayer Host { get; }
IClientPlayer? Host { get; }
bool IsPublic { get; }
/// <summary>
/// Gets or sets display name on game list.
/// </summary>
string? DisplayName { get; set; }
IDictionary<object, object> Items { get; }
int HostId { get; }
IClientPlayer GetClientPlayer(int clientId);
IClientPlayer? GetClientPlayer(int clientId);
T? FindObjectByNetId<T>(uint netId)
where T : IInnerNetObject;
/// <summary>
/// Adds an <see cref="IPAddress"/> to the ban list of this game.
/// Prevents all future joins from this <see cref="IPAddress"/>.
///
/// This does not kick the player with that <see cref="IPAddress"/> from the lobby.
/// Adds an <see cref="IPAddress" /> to the ban list of this game.
/// Prevents all future joins from this <see cref="IPAddress" />.
/// This does not kick the player with that <see cref="IPAddress" /> from the lobby.
/// </summary>
/// <param name="ipAddress">
/// The <see cref="IPAddress"/> to ban.
/// The <see cref="IPAddress" /> to ban.
/// </param>
void BanIp(IPAddress ipAddress);
/// <summary>
/// Syncs the internal <see cref="GameOptionsData"/> to all players.
/// Syncs the internal <see cref="GameOptionsData" /> to all players.
/// Necessary to do if you modified it, otherwise it won't be used.
/// </summary>
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
ValueTask SyncSettingsAsync();
/// <summary>
/// Sets the specified list as Impostor on all connected players.
/// Sets game's privacy.
/// </summary>
/// <param name="players">List of players to be Impostor.</param>
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
ValueTask SetInfectedAsync(IEnumerable<IInnerPlayerControl> players);
/// <param name="isPublic">Privacy to set.</param>
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
ValueTask SetPrivacyAsync(bool isPublic);
/// <summary>
/// Send the message to all players.
/// </summary>
/// <param name="writer">Message to send.</param>
/// <param name="states">Required limbo state of the player.</param>
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
ValueTask SendToAllAsync(IMessageWriter writer, LimboStates states = LimboStates.NotLimbo);
/// <summary>
@@ -74,7 +80,7 @@ namespace Impostor.Api.Games
/// <param name="writer">Message to send.</param>
/// <param name="senderId">The player to exclude from sending the message.</param>
/// <param name="states">Required limbo state of the player.</param>
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
ValueTask SendToAllExceptAsync(IMessageWriter writer, int senderId, LimboStates states = LimboStates.NotLimbo);
/// <summary>
@@ -82,7 +88,26 @@ namespace Impostor.Api.Games
/// </summary>
/// <param name="writer">Message to send.</param>
/// <param name="id">ID of the client.</param>
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
ValueTask SendToAsync(IMessageWriter writer, int id);
/// <summary>
/// Creates a MessageWriter with GameData header.
/// </summary>
/// <remarks>Use with caution, recommended only for advanced developers.</remarks>
/// <param name="targetNetId">Net id of the InnerNetObject.</param>
/// <param name="callId">Rpc id of the message.</param>
/// <param name="targetClientId">Client id of GameDataTo's target.</param>
/// <param name="type">Message type of the message.</param>
/// <returns>A <see cref="IMessageWriter" /> that you can fill with rpc data and send using <see cref="FinishRpcAsync"/>.</returns>
IMessageWriter StartRpc(uint targetNetId, RpcCalls callId, int? targetClientId, MessageType type = MessageType.Reliable);
/// <summary>
/// Finishes rpc message and sends it to the target.
/// </summary>
/// <param name="writer">Message writer of the rpc.</param>
/// <param name="targetClientId">Id of the receiving client.</param>
/// <returns>A <see cref="ValueTask" /> representing the asynchronous operation.</returns>
ValueTask FinishRpcAsync(IMessageWriter writer, int? targetClientId = null);
}
}
+1 -1
View File
@@ -4,4 +4,4 @@
{
GameCode Create();
}
}
}
@@ -1,4 +1,6 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Impostor.Api.Innersloth;
namespace Impostor.Api.Games.Managers
{
@@ -7,5 +9,13 @@ namespace Impostor.Api.Games.Managers
IEnumerable<IGame> Games { get; }
IGame? Find(GameCode code);
/// <summary>
/// Creates a new game.
/// </summary>
/// <param name="options">Game options.</param>
/// <returns>Created game or null if creation was cancelled by a plugin.</returns>
/// <exception cref="ImpostorException">Thrown when game creation failed.</exception>
ValueTask<IGame?> CreateAsync(GameOptionsData options);
}
}
}
+11 -7
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,15 +15,20 @@
<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" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0" />
<None Include="../../docs/images/logo_64.png" Pack="true" PackagePath="\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0" />
<PackageReference Include="Nullable" Version="1.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
@@ -35,4 +39,4 @@
</PackageReference>
</ItemGroup>
</Project>
</Project>
+1 -1
View File
@@ -4,4 +4,4 @@
{
ChangePrivacy = 1,
}
}
}
+1 -1
View File
@@ -4,4 +4,4 @@
{
DidVote = 0,
}
}
}
@@ -1,6 +1,6 @@
namespace Impostor.Api.Innersloth.Customization
{
public enum ColorType : byte
public enum ColorType
{
Red = 0,
Blue = 1,
@@ -14,5 +14,11 @@
Brown = 9,
Cyan = 10,
Lime = 11,
Maroon = 12,
Rose = 13,
Banana = 14,
Gray = 15,
Tan = 16,
Coral = 17,
}
}
@@ -1,100 +0,0 @@
namespace Impostor.Api.Innersloth.Customization
{
public enum HatType
{
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,
Fedora = 43,
Goggles2 = 44,
Headphones = 45,
MaskHat = 46,
PaperMask = 47,
Security = 48,
StrapHat = 49,
Banana = 50,
Beanie = 51,
Bear = 52,
Cheese = 53,
Cherry = 54,
Egg = 55,
Fedora2 = 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,
Snowman2 = 93,
}
}
@@ -1,18 +0,0 @@
namespace Impostor.Api.Innersloth.Customization
{
public enum PetType
{
NoPet = 0,
Alien = 1,
Crewmate = 2,
Doggy = 3,
Stickmin = 4,
Hamster = 5,
Robot = 6,
Ufo = 7,
Ellie = 8,
Squig = 9,
Bedcrab = 10,
Glitch = 11,
}
}
@@ -0,0 +1,56 @@
using Impostor.Api.Net.Messages;
namespace Impostor.Api.Innersloth.Customization
{
public class PlayerOutfit
{
public ColorType Color { get; internal set; } = (ColorType)(-1);
public string HatId { get; internal set; } = "missing";
public string PetId { get; internal set; } = "missing";
public string SkinId { get; internal set; } = "missing";
public string VisorId { get; internal set; } = "missing";
public string NamePlateId { get; internal set; } = "missing";
public string PlayerName { get; internal set; } = "missing";
public bool IsIncomplete
{
get
{
if (!string.IsNullOrEmpty(PlayerName) && Color != (ColorType)(-1) && HatId != "missing" && PetId != "missing" && SkinId != "missing" && VisorId != "missing")
{
return NamePlateId == "missing";
}
return true;
}
}
public void Serialize(IMessageWriter writer)
{
writer.Write(PlayerName);
writer.WritePacked((int)Color);
writer.Write(HatId);
writer.Write(PetId);
writer.Write(SkinId);
writer.Write(VisorId);
writer.Write(NamePlateId);
}
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();
}
}
}
@@ -0,0 +1,8 @@
namespace Impostor.Api.Innersloth.Customization
{
public enum PlayerOutfitType
{
Default,
Shapeshifted,
}
}
@@ -1,22 +0,0 @@
namespace Impostor.Api.Innersloth.Customization
{
public enum SkinType : byte
{
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,
}
}
+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);
}
}
+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);
}
}
}
}
+13 -6
View File
@@ -6,14 +6,21 @@ namespace Impostor.Api.Innersloth
public enum GameKeywords : uint
{
All = 0,
Other = 1,
Spanish = 2,
English = 256,
SpanishLA = 2,
Brazilian = 2048,
Portuguese = 16,
Korean = 4,
Russian = 8,
Portuguese = 16,
Dutch = 4096,
Filipino = 64,
French = 8192,
German = 16384,
Italian = 32768,
Japanese = 512,
SpanishEU = 1024,
Arabic = 32,
Filipone = 64,
Polish = 128,
English = 256,
Other = 1,
}
}
}
+143 -125
View File
@@ -7,145 +7,135 @@ 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;
public const int LatestVersion = 5;
/// <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 role options.
/// </summary>
public bool IsDefaults { get; set; }
public RoleOptionsData RoleOptions { get; set; } = new RoleOptionsData();
/// <summary>
/// Deserialize a packet/message to a new GameOptionsData object.
/// Gets or sets a value indicating whether the GameOptions are the default ones.
/// </summary>
public bool IsDefaults { get; set; } = true;
/// <summary>
/// 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 +147,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);
@@ -181,31 +171,49 @@ namespace Impostor.Api.Innersloth
writer.Write((uint)VotingTime);
writer.Write((bool)IsDefaults);
if (version > 1)
if (version >= 2)
{
writer.Write((byte)EmergencyCooldown);
}
if (version > 2)
if (version >= 3)
{
writer.Write((bool)ConfirmImpostor);
writer.Write((bool)VisualTasks);
}
if (version > 3)
if (version >= 4)
{
writer.Write((bool)AnonymousVotes);
writer.Write((byte)TaskBarUpdate);
}
if (version > 4)
if (version >= 5)
{
RoleOptions.Serialize(writer);
}
if (version >= 6)
{
// Nothing was changed in V6
}
if (version > 6)
{
throw new ImpostorException($"Unknown GameOptionsData version {Version}.");
}
}
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 +223,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();
@@ -235,24 +243,34 @@ namespace Impostor.Api.Innersloth
IsDefaults = bytes.ReadBoolean();
if (Version > 1)
if (Version >= 2)
{
EmergencyCooldown = bytes.ReadByte();
}
if (Version > 2)
if (Version >= 3)
{
ConfirmImpostor = bytes.ReadBoolean();
VisualTasks = bytes.ReadBoolean();
}
if (Version > 3)
if (Version >= 4)
{
AnonymousVotes = bytes.ReadBoolean();
TaskBarUpdate = (TaskBarUpdate)bytes.ReadByte();
}
if (Version > 4)
if (Version >= 5)
{
RoleOptions = RoleOptionsData.Deserialize(bytes);
}
if (Version >= 6)
{
// Nothing was changed in V6
}
if (Version > 6)
{
throw new ImpostorException($"Unknown GameOptionsData version {Version}.");
}
@@ -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,
}
}
}
+14 -4
View File
@@ -1,10 +1,20 @@
namespace Impostor.Api.Innersloth
{
public class GameVersion
public static class GameVersion
{
public static int GetVersion(int year, int month, int day, int rev = 0)
public static int GetVersion(int year, int month, int day, int revision = 0)
{
return (year * 25000) + (month * 1800) + (day * 50) + rev;
return (year * 25000) + (month * 1800) + (day * 50) + revision;
}
public static void ParseVersion(int version, out int year, out int month, out int day, out int revision)
{
year = version / 25000;
version %= 25000;
month = version / 1800;
version %= 1800;
day = version / 50;
revision = version % 50;
}
}
}
}
+15
View File
@@ -0,0 +1,15 @@
namespace Impostor.Api.Innersloth
{
public interface ITask
{
int Id { get; }
string Name { get; }
TaskTypes Type { get; }
TaskCategories Category { get; }
bool IsVisual { get; }
}
}
+19
View File
@@ -0,0 +1,19 @@
using System.Numerics;
namespace Impostor.Api.Innersloth
{
public interface IVent
{
int Id { get; }
string Name { get; }
Vector2 Position { get; }
IVent? Left { get; }
IVent? Center { get; }
IVent? Right { get; }
}
}
+19
View File
@@ -0,0 +1,19 @@
namespace Impostor.Api.Innersloth
{
public enum Language
{
English,
SpanishLA,
Brazilian,
Portuguese,
Korean,
Russian,
Dutch,
Filipino,
French,
German,
Italian,
Japanese,
SpanishEU,
}
}
+1 -1
View File
@@ -9,4 +9,4 @@ namespace Impostor.Api.Innersloth
MiraHQ = 2,
Polus = 4,
}
}
}
+3 -2
View File
@@ -1,9 +1,10 @@
namespace Impostor.Api.Innersloth
{
public enum MapTypes
public enum MapTypes : byte
{
Skeld = 0,
MiraHQ = 1,
Polus = 2,
Airship = 4,
}
}
}
@@ -0,0 +1,94 @@
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Impostor.Api.Innersloth.Maps.Tasks;
using Impostor.Api.Innersloth.Maps.Vents;
namespace Impostor.Api.Innersloth.Maps
{
public class AirshipData : IMapData
{
private readonly IReadOnlyDictionary<int, IVent> _vents;
private readonly IReadOnlyDictionary<int, ITask> _tasks;
internal AirshipData()
{
var vents = new[]
{
new AirshipVent(this, AirshipVent.Ids.Vault, new Vector2(-12.6322f, 8.4735f), left: AirshipVent.Ids.Cockpit),
new AirshipVent(this, AirshipVent.Ids.Cockpit, new Vector2(-22.099f, -1.512f), left: AirshipVent.Ids.Vault, right: AirshipVent.Ids.ViewingDeck),
new AirshipVent(this, AirshipVent.Ids.ViewingDeck, new Vector2(-15.659f, -11.6991f), left: AirshipVent.Ids.Cockpit),
new AirshipVent(this, AirshipVent.Ids.EngineRoom, new Vector2(0.203f, -2.5361f), left: AirshipVent.Ids.Kitchen, right: AirshipVent.Ids.MainHallBottom),
new AirshipVent(this, AirshipVent.Ids.Kitchen, new Vector2(-2.6019f, -9.338f), left: AirshipVent.Ids.EngineRoom, right: AirshipVent.Ids.MainHallBottom),
new AirshipVent(this, AirshipVent.Ids.MainHallBottom, new Vector2(7.021f, -3.730999f), left: AirshipVent.Ids.EngineRoom, right: AirshipVent.Ids.Kitchen),
new AirshipVent(this, AirshipVent.Ids.GapRight, new Vector2(9.814f, 3.206f), left: AirshipVent.Ids.MainHallTop, right: AirshipVent.Ids.GapLeft),
new AirshipVent(this, AirshipVent.Ids.GapLeft, new Vector2(12.663f, 5.922f), left: AirshipVent.Ids.MainHallTop, right: AirshipVent.Ids.GapRight),
new AirshipVent(this, AirshipVent.Ids.MainHallTop, new Vector2(3.605f, 6.923f), left: AirshipVent.Ids.GapLeft, right: AirshipVent.Ids.GapRight),
new AirshipVent(this, AirshipVent.Ids.Showers, new Vector2(23.9869f, -1.386f), left: AirshipVent.Ids.Records, right: AirshipVent.Ids.CargoBay),
new AirshipVent(this, AirshipVent.Ids.Records, new Vector2(23.2799f, 8.259998f), left: AirshipVent.Ids.Showers, right: AirshipVent.Ids.CargoBay),
new AirshipVent(this, AirshipVent.Ids.CargoBay, new Vector2(30.4409f, -3.577f), left: AirshipVent.Ids.Showers, right: AirshipVent.Ids.Records),
};
Vents = vents.ToDictionary(x => x.Id, x => x).AsReadOnly();
_vents = vents.ToDictionary(x => (int)x.Id, x => (IVent)x).AsReadOnly();
var tasks = new[]
{
new AirshipTask(AirshipTask.Ids.ElectricalFixWiring, TaskTypes.FixWiring, TaskCategories.CommonTask),
new AirshipTask(AirshipTask.Ids.MeetingRoomEnterIDCode, TaskTypes.EnterIdCode, TaskCategories.CommonTask),
new AirshipTask(AirshipTask.Ids.ElectricalCalibrateDistributor, TaskTypes.CalibrateDistributor, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.ElectricalResetBreakers, TaskTypes.ResetBreakers, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.VaultRoomDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.BrigDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.CargoBayDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.GapRoomDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.RecordsDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.CargoBayUnlockSafe, TaskTypes.UnlockSafe, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.VentilationStartFans, TaskTypes.StartFans, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.MainHallEmptyGarbage, TaskTypes.EmptyGarbage, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.MedicalEmptyGarbage, TaskTypes.EmptyGarbage, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.KitchenEmptyGarbage, TaskTypes.EmptyGarbage, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.MainHallDevelopPhotos, TaskTypes.DevelopPhotos, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.CargoBayFuelEngines, TaskTypes.FuelEngines, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.SecurityRewindTapes, TaskTypes.RewindTapes, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.LoungeEmptyGarbage, TaskTypes.EmptyGarbage, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.ShowersEmptyGarbage, TaskTypes.EmptyGarbage, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.VaultRoomPolishRuby, TaskTypes.PolishRuby, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.CockpitStabilizeSteering, TaskTypes.StabilizeSteering, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ArmoryDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.CockpitDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.CommsDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.MedicalDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.ViewingDeckDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
new AirshipTask(AirshipTask.Ids.ElectricalDivertPowerToArmory, TaskTypes.DivertPower, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ElectricalDivertPowerToCockpit, TaskTypes.DivertPower, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ElectricalDivertPowerToGapRoom, TaskTypes.DivertPower, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ElectricalDivertPowerToMainHall, TaskTypes.DivertPower, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ElectricalDivertPowerToMeetingRoom, TaskTypes.DivertPower, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ElectricalDivertPowerToShowers, TaskTypes.DivertPower, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ElectricalDivertPowerToEngine, TaskTypes.DivertPower, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ShowersPickUpTowels, TaskTypes.PickUpTowels, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.LoungeCleanToilet, TaskTypes.CleanToilet, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.VaultRoomDressMannequin, TaskTypes.DressMannequin, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.RecordsSortRecords, TaskTypes.SortRecords, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ArmoryPutAwayPistols, TaskTypes.PutAwayPistols, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ArmoryPutAwayRifles, TaskTypes.PutAwayRifles, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.MainHallDecontaminate, TaskTypes.Decontaminate, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.KitchenMakeBurger, TaskTypes.MakeBurger, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.ShowersFixShower, TaskTypes.FixShower, TaskCategories.ShortTask),
new AirshipTask(AirshipTask.Ids.CleanVent, TaskTypes.VentCleaning, TaskCategories.ShortTask),
};
Tasks = tasks.ToDictionary(x => x.Id, x => x).AsReadOnly();
_tasks = tasks.ToDictionary(x => (int)x.Id, x => (ITask)x).AsReadOnly();
}
public IReadOnlyDictionary<AirshipVent.Ids, AirshipVent> Vents { get; }
IReadOnlyDictionary<int, IVent> IMapData.Vents => _vents;
public IReadOnlyDictionary<AirshipTask.Ids, AirshipTask> Tasks { get; }
IReadOnlyDictionary<int, ITask> IMapData.Tasks => _tasks;
}
}
@@ -0,0 +1,19 @@
using System.Collections.Generic;
namespace Impostor.Api.Innersloth.Maps
{
public interface IMapData
{
public static IReadOnlyDictionary<MapTypes, IMapData> Maps { get; } = new Dictionary<MapTypes, IMapData>
{
[MapTypes.Skeld] = new SkeldData(),
[MapTypes.MiraHQ] = new MiraData(),
[MapTypes.Polus] = new PolusData(),
[MapTypes.Airship] = new AirshipData(),
}.AsReadOnly();
IReadOnlyDictionary<int, IVent> Vents { get; }
IReadOnlyDictionary<int, ITask> Tasks { get; }
}
}
@@ -0,0 +1,77 @@
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Impostor.Api.Innersloth.Maps.Tasks;
using Impostor.Api.Innersloth.Maps.Vents;
namespace Impostor.Api.Innersloth.Maps
{
public class MiraData : IMapData
{
private readonly IReadOnlyDictionary<int, IVent> _vents;
private readonly IReadOnlyDictionary<int, ITask> _tasks;
internal MiraData()
{
var vents = new[]
{
new MiraVent(this, MiraVent.Ids.Balcony, new Vector2(23.77f, -1.94f), left: MiraVent.Ids.Medbay, right: MiraVent.Ids.Cafeteria),
new MiraVent(this, MiraVent.Ids.Cafeteria, new Vector2(23.9f, 7.18f), left: MiraVent.Ids.Admin, right: MiraVent.Ids.Balcony),
new MiraVent(this, MiraVent.Ids.Reactor, new Vector2(0.4800001f, 10.697f), left: MiraVent.Ids.Laboratory, center: MiraVent.Ids.Decontamination, right: MiraVent.Ids.Launchpad),
new MiraVent(this, MiraVent.Ids.Laboratory, new Vector2(11.606f, 13.816f), left: MiraVent.Ids.Reactor, center: MiraVent.Ids.Decontamination, right: MiraVent.Ids.Office),
new MiraVent(this, MiraVent.Ids.Office, new Vector2(13.28f, 20.13f), left: MiraVent.Ids.Laboratory, center: MiraVent.Ids.Admin, right: MiraVent.Ids.Greenhouse),
new MiraVent(this, MiraVent.Ids.Admin, new Vector2(22.39f, 17.23f), left: MiraVent.Ids.Greenhouse, center: MiraVent.Ids.Cafeteria, right: MiraVent.Ids.Office),
new MiraVent(this, MiraVent.Ids.Greenhouse, new Vector2(17.85f, 25.23f), left: MiraVent.Ids.Admin, right: MiraVent.Ids.Office),
new MiraVent(this, MiraVent.Ids.Medbay, new Vector2(15.41f, -1.82f), left: MiraVent.Ids.Balcony, right: MiraVent.Ids.LockerRoom),
new MiraVent(this, MiraVent.Ids.Decontamination, new Vector2(6.83f, 3.145f), left: MiraVent.Ids.Reactor, center: MiraVent.Ids.LockerRoom, right: MiraVent.Ids.Laboratory),
new MiraVent(this, MiraVent.Ids.LockerRoom, new Vector2(4.29f, 0.5299997f), left: MiraVent.Ids.Medbay, center: MiraVent.Ids.Launchpad, right: MiraVent.Ids.Decontamination),
new MiraVent(this, MiraVent.Ids.Launchpad, new Vector2(-6.18f, 3.56f), left: MiraVent.Ids.Reactor, right: MiraVent.Ids.LockerRoom),
};
Vents = vents.ToDictionary(x => x.Id, x => x).AsReadOnly();
_vents = vents.ToDictionary(x => (int)x.Id, x => (IVent)x).AsReadOnly();
var tasks = new[]
{
new MiraTask(MiraTask.Ids.HallwayFixWiring, TaskTypes.FixWiring, TaskCategories.CommonTask),
new MiraTask(MiraTask.Ids.AdminEnterIDCode, TaskTypes.EnterIdCode, TaskCategories.CommonTask),
new MiraTask(MiraTask.Ids.MedbaySubmitScan, TaskTypes.SubmitScan, TaskCategories.LongTask, true),
new MiraTask(MiraTask.Ids.BalconyClearAsteroids, TaskTypes.ClearAsteroids, TaskCategories.LongTask),
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToAdmin, TaskTypes.DivertPower, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToCafeteria, TaskTypes.DivertPower, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToCommunications, TaskTypes.DivertPower, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToLaunchpad, TaskTypes.DivertPower, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToMedbay, TaskTypes.DivertPower, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToOffice, TaskTypes.DivertPower, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.StorageWaterPlants, TaskTypes.WaterPlants, TaskCategories.LongTask),
new MiraTask(MiraTask.Ids.ReactorStartReactor, TaskTypes.StartReactor, TaskCategories.LongTask),
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToGreenhouse, TaskTypes.DivertPower, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.AdminChartCourse, TaskTypes.ChartCourse, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.GreenhouseCleanO2Filter, TaskTypes.Filter, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.LaunchpadFuelEngines, TaskTypes.FuelEngines, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.LaboratoryAssembleArtifact, TaskTypes.AssembleArtifact, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.LaboratorySortSamples, TaskTypes.SortSamples, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.AdminPrimeShields, TaskTypes.PrimeShields, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.CafeteriaEmptyGarbage, TaskTypes.EmptyGarbage, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.BalconyMeasureWeather, TaskTypes.MeasureWeather, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToLaboratory, TaskTypes.DivertPower, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.CafeteriaBuyBeverage, TaskTypes.BuyBeverage, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.OfficeProcessData, TaskTypes.ProcessData, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.LaunchpadRunDiagnostics, TaskTypes.RunDiagnostics, TaskCategories.LongTask),
new MiraTask(MiraTask.Ids.ReactorUnlockManifolds, TaskTypes.UnlockManifolds, TaskCategories.ShortTask),
new MiraTask(MiraTask.Ids.CleanVent, TaskTypes.VentCleaning, TaskCategories.ShortTask),
};
Tasks = tasks.ToDictionary(x => x.Id, x => x).AsReadOnly();
_tasks = tasks.ToDictionary(x => (int)x.Id, x => (ITask)x).AsReadOnly();
}
public IReadOnlyDictionary<MiraVent.Ids, MiraVent> Vents { get; }
IReadOnlyDictionary<int, IVent> IMapData.Vents => _vents;
public IReadOnlyDictionary<MiraTask.Ids, MiraTask> Tasks { get; }
IReadOnlyDictionary<int, ITask> IMapData.Tasks => _tasks;
}
}
@@ -0,0 +1,84 @@
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Impostor.Api.Innersloth.Maps.Tasks;
using Impostor.Api.Innersloth.Maps.Vents;
namespace Impostor.Api.Innersloth.Maps
{
public class PolusData : IMapData
{
private readonly IReadOnlyDictionary<int, IVent> _vents;
private readonly IReadOnlyDictionary<int, ITask> _tasks;
internal PolusData()
{
var vents = new[]
{
new PolusVent(this, PolusVent.Ids.Security, new Vector2(1.929f, -9.558001f), left: PolusVent.Ids.O2, right: PolusVent.Ids.Electrical),
new PolusVent(this, PolusVent.Ids.Electrical, new Vector2(6.9f, -14.41f), left: PolusVent.Ids.O2, right: PolusVent.Ids.Security),
new PolusVent(this, PolusVent.Ids.O2, new Vector2(3.51f, -16.58f), left: PolusVent.Ids.Electrical, right: PolusVent.Ids.Security),
new PolusVent(this, PolusVent.Ids.Communications, new Vector2(12.304f, -18.898f), left: PolusVent.Ids.Storage, right: PolusVent.Ids.Office),
new PolusVent(this, PolusVent.Ids.Office, new Vector2(16.379f, -19.599f), left: PolusVent.Ids.Communications, right: PolusVent.Ids.Storage),
new PolusVent(this, PolusVent.Ids.Admin, new Vector2(20.089f, -25.517f), left: PolusVent.Ids.OutsideAdmin, right: PolusVent.Ids.Lava),
new PolusVent(this, PolusVent.Ids.Laboratory, new Vector2(32.963f, -9.526f), right: PolusVent.Ids.Lava),
new PolusVent(this, PolusVent.Ids.Lava, new Vector2(30.907f, -11.86f), left: PolusVent.Ids.Laboratory, right: PolusVent.Ids.Admin),
new PolusVent(this, PolusVent.Ids.Storage, new Vector2(22f, -12.19f), left: PolusVent.Ids.Communications, right: PolusVent.Ids.Office),
new PolusVent(this, PolusVent.Ids.RightStabilizer, new Vector2(24.02f, -8.39f), left: PolusVent.Ids.LeftStabilizer),
new PolusVent(this, PolusVent.Ids.LeftStabilizer, new Vector2(9.64f, -7.72f), left: PolusVent.Ids.RightStabilizer),
new PolusVent(this, PolusVent.Ids.OutsideAdmin, new Vector2(18.93f, -24.85f), right: PolusVent.Ids.Admin),
};
Vents = vents.ToDictionary(x => x.Id, x => x).AsReadOnly();
_vents = vents.ToDictionary(x => (int)x.Id, x => (IVent)x).AsReadOnly();
var tasks = new[]
{
new PolusTask(PolusTask.Ids.OfficeSwipeCard, TaskTypes.SwipeCard, TaskCategories.CommonTask),
new PolusTask(PolusTask.Ids.DropshipInsertKeys, TaskTypes.InsertKeys, TaskCategories.CommonTask),
new PolusTask(PolusTask.Ids.OfficeScanBoardingPass, TaskTypes.ScanBoardingPass, TaskCategories.CommonTask),
new PolusTask(PolusTask.Ids.ElectricalFixWiring, TaskTypes.FixWiring, TaskCategories.CommonTask),
new PolusTask(PolusTask.Ids.WeaponsDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.OfficeDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.ElectricalDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.SpecimenRoomDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.O2DownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.SpecimenRoomStartReactor, TaskTypes.StartReactor, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.StorageFuelEngines, TaskTypes.FuelEngines, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.BoilerRoomOpenWaterways, TaskTypes.OpenWaterways, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.MedbayInspectSample, TaskTypes.InspectSample, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.BoilerRoomReplaceWaterJug, TaskTypes.ReplaceWaterJug, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.OutsideFixWeatherNodeNode_GI, TaskTypes.ActivateWeatherNodes, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.OutsideFixWeatherNodeNode_IRO, TaskTypes.ActivateWeatherNodes, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.OutsideFixWeatherNodeNode_PD, TaskTypes.ActivateWeatherNodes, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.OutsideFixWeatherNodeNode_TB, TaskTypes.ActivateWeatherNodes, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.CommunicationsRebootWiFi, TaskTypes.RebootWifi, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.O2MonitorTree, TaskTypes.MonitorOxygen, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.SpecimenRoomUnlockManifolds, TaskTypes.UnlockManifolds, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.SpecimenRoomStoreArtifacts, TaskTypes.StoreArtifact, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.O2FillCanisters, TaskTypes.FillCanisters, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.O2EmptyGarbage, TaskTypes.EmptyGarbage, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.DropshipChartCourse, TaskTypes.ChartCourse, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.MedbaySubmitScan, TaskTypes.SubmitScan, TaskCategories.ShortTask, true),
new PolusTask(PolusTask.Ids.WeaponsClearAsteroids, TaskTypes.ClearAsteroids, TaskCategories.ShortTask, true),
new PolusTask(PolusTask.Ids.OutsideFixWeatherNodeNode_CA, TaskTypes.ActivateWeatherNodes, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.OutsideFixWeatherNodeNode_MLG, TaskTypes.ActivateWeatherNodes, TaskCategories.LongTask),
new PolusTask(PolusTask.Ids.LaboratoryAlignTelescope, TaskTypes.AlignTelescope, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.LaboratoryRepairDrill, TaskTypes.RepairDrill, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.LaboratoryRecordTemperature, TaskTypes.RecordTemperature, TaskCategories.ShortTask),
new PolusTask(PolusTask.Ids.OutsideRecordTemperature, TaskTypes.RecordTemperature, TaskCategories.ShortTask),
};
Tasks = tasks.ToDictionary(x => x.Id, x => x).AsReadOnly();
_tasks = tasks.ToDictionary(x => (int)x.Id, x => (ITask)x).AsReadOnly();
}
public IReadOnlyDictionary<PolusVent.Ids, PolusVent> Vents { get; }
IReadOnlyDictionary<int, IVent> IMapData.Vents => _vents;
public IReadOnlyDictionary<PolusTask.Ids, PolusTask> Tasks { get; }
IReadOnlyDictionary<int, ITask> IMapData.Tasks => _tasks;
}
}
@@ -0,0 +1,83 @@
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Impostor.Api.Innersloth.Maps.Tasks;
using Impostor.Api.Innersloth.Maps.Vents;
namespace Impostor.Api.Innersloth.Maps
{
public class SkeldData : IMapData
{
private readonly IReadOnlyDictionary<int, IVent> _vents;
private readonly IReadOnlyDictionary<int, ITask> _tasks;
internal SkeldData()
{
var vents = new[]
{
new SkeldVent(this, SkeldVent.Ids.Admin, new Vector2(2.544f, -9.955201f), left: SkeldVent.Ids.Cafeteria, right: SkeldVent.Ids.RightHallway),
new SkeldVent(this, SkeldVent.Ids.RightHallway, new Vector2(9.384f, -6.438f), left: SkeldVent.Ids.Admin, right: SkeldVent.Ids.Cafeteria),
new SkeldVent(this, SkeldVent.Ids.Cafeteria, new Vector2(4.2588f, -0.276f), left: SkeldVent.Ids.Admin, right: SkeldVent.Ids.RightHallway),
new SkeldVent(this, SkeldVent.Ids.Electrical, new Vector2(-9.7764f, -8.034f), left: SkeldVent.Ids.Security, right: SkeldVent.Ids.Medbay),
new SkeldVent(this, SkeldVent.Ids.UpperEngine, new Vector2(-15.288f, 2.52f), left: SkeldVent.Ids.UpperReactor),
new SkeldVent(this, SkeldVent.Ids.Security, new Vector2(-12.534f, -6.9492f), left: SkeldVent.Ids.Medbay, right: SkeldVent.Ids.Electrical),
new SkeldVent(this, SkeldVent.Ids.Medbay, new Vector2(-10.608f, -4.176f), left: SkeldVent.Ids.Security, right: SkeldVent.Ids.Electrical),
new SkeldVent(this, SkeldVent.Ids.Weapons, new Vector2(8.820001f, 3.324f), right: SkeldVent.Ids.UpperNavigation),
new SkeldVent(this, SkeldVent.Ids.LowerReactor, new Vector2(-20.796f, -6.9528f), left: SkeldVent.Ids.LowerEngine),
new SkeldVent(this, SkeldVent.Ids.LowerEngine, new Vector2(-15.2508f, -13.656f), left: SkeldVent.Ids.LowerReactor),
new SkeldVent(this, SkeldVent.Ids.Shields, new Vector2(9.5232f, -14.3376f), left: SkeldVent.Ids.LowerNavigation),
new SkeldVent(this, SkeldVent.Ids.UpperReactor, new Vector2(-21.876f, -3.0516f), left: SkeldVent.Ids.UpperEngine),
new SkeldVent(this, SkeldVent.Ids.UpperNavigation, new Vector2(16.008f, -3.168f), right: SkeldVent.Ids.Weapons),
new SkeldVent(this, SkeldVent.Ids.LowerNavigation, new Vector2(16.008f, -6.384f), right: SkeldVent.Ids.Shields),
};
Vents = vents.ToDictionary(x => x.Id, x => x).AsReadOnly();
_vents = vents.ToDictionary(x => (int)x.Id, x => (IVent)x).AsReadOnly();
var tasks = new[]
{
new SkeldTask(SkeldTask.Ids.AdminSwipeCard, TaskTypes.SwipeCard, TaskCategories.CommonTask),
new SkeldTask(SkeldTask.Ids.ElectricalFixWiring, TaskTypes.FixWiring, TaskCategories.CommonTask),
new SkeldTask(SkeldTask.Ids.WeaponsClearAsteroids, TaskTypes.ClearAsteroids, TaskCategories.LongTask, true),
new SkeldTask(SkeldTask.Ids.EnginesAlignEngineOutput, TaskTypes.AlignEngineOutput, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.MedbaySubmitScan, TaskTypes.SubmitScan, TaskCategories.LongTask, true),
new SkeldTask(SkeldTask.Ids.MedbayInspectSample, TaskTypes.InspectSample, TaskCategories.LongTask),
new SkeldTask(SkeldTask.Ids.StorageFuelEngines, TaskTypes.FuelEngines, TaskCategories.LongTask),
new SkeldTask(SkeldTask.Ids.ReactorStartReactor, TaskTypes.StartReactor, TaskCategories.LongTask),
new SkeldTask(SkeldTask.Ids.O2EmptyChute, TaskTypes.EmptyChute, TaskCategories.LongTask, true),
new SkeldTask(SkeldTask.Ids.CafeteriaEmptyGarbage, TaskTypes.EmptyGarbage, TaskCategories.LongTask, true),
new SkeldTask(SkeldTask.Ids.CommunicationsDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ElectricalCalibrateDistributor, TaskTypes.CalibrateDistributor, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.NavigationChartCourse, TaskTypes.ChartCourse, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.O2CleanO2Filter, TaskTypes.Filter, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ReactorUnlockManifolds, TaskTypes.UnlockManifolds, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ElectricalDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.NavigationStabilizeSteering, TaskTypes.StabilizeSteering, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.WeaponsDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ShieldsPrimeShields, TaskTypes.PrimeShields, TaskCategories.ShortTask, true),
new SkeldTask(SkeldTask.Ids.CafeteriaDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.NavigationDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToShields, TaskTypes.DivertPower, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToWeapons, TaskTypes.DivertPower, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToCommunications, TaskTypes.DivertPower, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToUpperEngine, TaskTypes.DivertPower, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToO2, TaskTypes.DivertPower, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToNavigation, TaskTypes.DivertPower, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToLowerEngine, TaskTypes.DivertPower, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToSecurity, TaskTypes.DivertPower, TaskCategories.ShortTask),
new SkeldTask(SkeldTask.Ids.CleanVent, TaskTypes.VentCleaning, TaskCategories.ShortTask),
};
Tasks = tasks.ToDictionary(x => x.Id, x => x).AsReadOnly();
_tasks = tasks.ToDictionary(x => (int)x.Id, x => (ITask)x).AsReadOnly();
}
public IReadOnlyDictionary<SkeldVent.Ids, SkeldVent> Vents { get; }
IReadOnlyDictionary<int, IVent> IMapData.Vents => _vents;
public IReadOnlyDictionary<SkeldTask.Ids, SkeldTask> Tasks { get; }
IReadOnlyDictionary<int, ITask> IMapData.Tasks => _tasks;
}
}
@@ -0,0 +1,73 @@
namespace Impostor.Api.Innersloth.Maps.Tasks
{
public class AirshipTask : ITask
{
internal AirshipTask(Ids id, TaskTypes type, TaskCategories category, bool isVisual = false)
{
Id = id;
Name = id.ToString();
Type = type;
Category = category;
IsVisual = isVisual;
}
public enum Ids
{
ElectricalFixWiring = 0,
MeetingRoomEnterIDCode = 1,
ElectricalCalibrateDistributor = 2,
ElectricalResetBreakers = 3,
VaultRoomDownloadData = 4,
BrigDownloadData = 5,
CargoBayDownloadData = 6,
GapRoomDownloadData = 7,
RecordsDownloadData = 8,
CargoBayUnlockSafe = 9,
VentilationStartFans = 10,
MainHallEmptyGarbage = 11,
MedicalEmptyGarbage = 12,
KitchenEmptyGarbage = 13,
MainHallDevelopPhotos = 14,
CargoBayFuelEngines = 15,
SecurityRewindTapes = 16,
LoungeEmptyGarbage = 17,
ShowersEmptyGarbage = 18,
VaultRoomPolishRuby = 19,
CockpitStabilizeSteering = 20,
ArmoryDownloadData = 21,
CockpitDownloadData = 22,
CommsDownloadData = 23,
MedicalDownloadData = 24,
ViewingDeckDownloadData = 25,
ElectricalDivertPowerToArmory = 26,
ElectricalDivertPowerToCockpit = 27,
ElectricalDivertPowerToGapRoom = 28,
ElectricalDivertPowerToMainHall = 29,
ElectricalDivertPowerToMeetingRoom = 30,
ElectricalDivertPowerToShowers = 31,
ElectricalDivertPowerToEngine = 32,
ShowersPickUpTowels = 33,
LoungeCleanToilet = 34,
VaultRoomDressMannequin = 35,
RecordsSortRecords = 36,
ArmoryPutAwayPistols = 37,
ArmoryPutAwayRifles = 38,
MainHallDecontaminate = 39,
KitchenMakeBurger = 40,
ShowersFixShower = 41,
CleanVent = 42,
}
public Ids Id { get; }
int ITask.Id => (int)Id;
public string Name { get; }
public TaskTypes Type { get; }
public TaskCategories Category { get; }
public bool IsVisual { get; }
}
}
@@ -0,0 +1,57 @@
namespace Impostor.Api.Innersloth.Maps.Tasks
{
public class MiraTask : ITask
{
internal MiraTask(Ids id, TaskTypes type, TaskCategories category, bool isVisual = false)
{
Id = id;
Name = id.ToString();
Type = type;
Category = category;
IsVisual = isVisual;
}
public enum Ids
{
HallwayFixWiring = 0,
AdminEnterIDCode = 1,
MedbaySubmitScan = 2,
BalconyClearAsteroids = 3,
ElectricalDivertPowerToAdmin = 4,
ElectricalDivertPowerToCafeteria = 5,
ElectricalDivertPowerToCommunications = 6,
ElectricalDivertPowerToLaunchpad = 7,
ElectricalDivertPowerToMedbay = 8,
ElectricalDivertPowerToOffice = 9,
StorageWaterPlants = 10,
ReactorStartReactor = 11,
ElectricalDivertPowerToGreenhouse = 12,
AdminChartCourse = 13,
GreenhouseCleanO2Filter = 14,
LaunchpadFuelEngines = 15,
LaboratoryAssembleArtifact = 16,
LaboratorySortSamples = 17,
AdminPrimeShields = 18,
CafeteriaEmptyGarbage = 19,
BalconyMeasureWeather = 20,
ElectricalDivertPowerToLaboratory = 21,
CafeteriaBuyBeverage = 22,
OfficeProcessData = 23,
LaunchpadRunDiagnostics = 24,
ReactorUnlockManifolds = 25,
CleanVent = 26,
}
public Ids Id { get; }
int ITask.Id => (int)Id;
public string Name { get; }
public TaskTypes Type { get; }
public TaskCategories Category { get; }
public bool IsVisual { get; }
}
}
@@ -0,0 +1,63 @@
namespace Impostor.Api.Innersloth.Maps.Tasks
{
public class PolusTask : ITask
{
internal PolusTask(Ids id, TaskTypes type, TaskCategories category, bool isVisual = false)
{
Id = id;
Name = id.ToString();
Type = type;
Category = category;
IsVisual = isVisual;
}
public enum Ids
{
OfficeSwipeCard = 0,
DropshipInsertKeys = 1,
OfficeScanBoardingPass = 2,
ElectricalFixWiring = 3,
WeaponsDownloadData = 4,
OfficeDownloadData = 5,
ElectricalDownloadData = 6,
SpecimenRoomDownloadData = 7,
O2DownloadData = 8,
SpecimenRoomStartReactor = 9,
StorageFuelEngines = 10,
BoilerRoomOpenWaterways = 11,
MedbayInspectSample = 12,
BoilerRoomReplaceWaterJug = 13,
OutsideFixWeatherNodeNode_GI = 14,
OutsideFixWeatherNodeNode_IRO = 15,
OutsideFixWeatherNodeNode_PD = 16,
OutsideFixWeatherNodeNode_TB = 17,
CommunicationsRebootWiFi = 18,
O2MonitorTree = 19,
SpecimenRoomUnlockManifolds = 20,
SpecimenRoomStoreArtifacts = 21,
O2FillCanisters = 22,
O2EmptyGarbage = 23,
DropshipChartCourse = 24,
MedbaySubmitScan = 25,
WeaponsClearAsteroids = 26,
OutsideFixWeatherNodeNode_CA = 27,
OutsideFixWeatherNodeNode_MLG = 28,
LaboratoryAlignTelescope = 29,
LaboratoryRepairDrill = 30,
LaboratoryRecordTemperature = 31,
OutsideRecordTemperature = 32,
}
public Ids Id { get; }
int ITask.Id => (int)Id;
public string Name { get; }
public TaskTypes Type { get; }
public TaskCategories Category { get; }
public bool IsVisual { get; }
}
}
@@ -0,0 +1,60 @@
namespace Impostor.Api.Innersloth.Maps.Tasks
{
public class SkeldTask : ITask
{
internal SkeldTask(Ids id, TaskTypes type, TaskCategories category, bool isVisual = false)
{
Id = id;
Name = id.ToString();
Type = type;
Category = category;
IsVisual = isVisual;
}
public enum Ids
{
AdminSwipeCard = 0,
ElectricalFixWiring = 1,
WeaponsClearAsteroids = 2,
EnginesAlignEngineOutput = 3,
MedbaySubmitScan = 4,
MedbayInspectSample = 5,
StorageFuelEngines = 6,
ReactorStartReactor = 7,
O2EmptyChute = 8,
CafeteriaEmptyGarbage = 9,
CommunicationsDownloadData = 10,
ElectricalCalibrateDistributor = 11,
NavigationChartCourse = 12,
O2CleanO2Filter = 13,
ReactorUnlockManifolds = 14,
ElectricalDownloadData = 15,
NavigationStabilizeSteering = 16,
WeaponsDownloadData = 17,
ShieldsPrimeShields = 18,
CafeteriaDownloadData = 19,
NavigationDownloadData = 20,
ElectricalDivertPowerToShields = 21,
ElectricalDivertPowerToWeapons = 22,
ElectricalDivertPowerToCommunications = 23,
ElectricalDivertPowerToUpperEngine = 24,
ElectricalDivertPowerToO2 = 25,
ElectricalDivertPowerToNavigation = 26,
ElectricalDivertPowerToLowerEngine = 27,
ElectricalDivertPowerToSecurity = 28,
CleanVent = 29,
}
public Ids Id { get; }
int ITask.Id => (int)Id;
public string Name { get; }
public TaskTypes Type { get; }
public TaskCategories Category { get; }
public bool IsVisual { get; }
}
}
@@ -0,0 +1,61 @@
using System;
using System.Numerics;
namespace Impostor.Api.Innersloth.Maps.Vents
{
public class AirshipVent : IVent
{
private readonly Lazy<AirshipVent>? _left;
private readonly Lazy<AirshipVent>? _center;
private readonly Lazy<AirshipVent>? _right;
internal AirshipVent(AirshipData data, Ids id, Vector2 position, Ids? left = null, Ids? center = null, Ids? right = null)
{
Id = id;
Name = id.ToString();
Position = position;
_left = left == null ? null : new Lazy<AirshipVent>(() => data.Vents[left.Value]);
_center = center == null ? null : new Lazy<AirshipVent>(() => data.Vents[center.Value]);
_right = right == null ? null : new Lazy<AirshipVent>(() => data.Vents[right.Value]);
}
public enum Ids
{
Vault = 0,
Cockpit = 1,
ViewingDeck = 2,
EngineRoom = 3,
Kitchen = 4,
MainHallBottom = 5,
GapRight = 6,
GapLeft = 7,
MainHallTop = 8,
Showers = 9,
Records = 10,
CargoBay = 11,
}
public Ids Id { get; }
int IVent.Id => (int)Id;
public string Name { get; }
public Vector2 Position { get; }
public AirshipVent? Left => _left?.Value;
IVent? IVent.Left => Left;
public AirshipVent? Center => _center?.Value;
IVent? IVent.Center => Center;
public AirshipVent? Right => _right?.Value;
IVent? IVent.Right => Right;
}
}
@@ -0,0 +1,60 @@
using System;
using System.Numerics;
namespace Impostor.Api.Innersloth.Maps.Vents
{
public class MiraVent : IVent
{
private readonly Lazy<MiraVent>? _left;
private readonly Lazy<MiraVent>? _center;
private readonly Lazy<MiraVent>? _right;
internal MiraVent(MiraData data, Ids id, Vector2 position, Ids? left = null, Ids? center = null, Ids? right = null)
{
Id = id;
Name = id.ToString();
Position = position;
_left = left == null ? null : new Lazy<MiraVent>(() => data.Vents[left.Value]);
_center = center == null ? null : new Lazy<MiraVent>(() => data.Vents[center.Value]);
_right = right == null ? null : new Lazy<MiraVent>(() => data.Vents[right.Value]);
}
public enum Ids
{
Balcony = 1,
Cafeteria = 2,
Reactor = 3,
Laboratory = 4,
Office = 5,
Admin = 6,
Greenhouse = 7,
Medbay = 8,
Decontamination = 9,
LockerRoom = 10,
Launchpad = 11,
}
public Ids Id { get; }
int IVent.Id => (int)Id;
public string Name { get; }
public Vector2 Position { get; }
public MiraVent? Left => _left?.Value;
IVent? IVent.Left => Left;
public MiraVent? Center => _center?.Value;
IVent? IVent.Center => Center;
public MiraVent? Right => _right?.Value;
IVent? IVent.Right => Right;
}
}
@@ -0,0 +1,61 @@
using System;
using System.Numerics;
namespace Impostor.Api.Innersloth.Maps.Vents
{
public class PolusVent : IVent
{
private readonly Lazy<PolusVent>? _left;
private readonly Lazy<PolusVent>? _center;
private readonly Lazy<PolusVent>? _right;
internal PolusVent(PolusData data, Ids id, Vector2 position, Ids? left = null, Ids? center = null, Ids? right = null)
{
Id = id;
Name = id.ToString();
Position = position;
_left = left == null ? null : new Lazy<PolusVent>(() => data.Vents[left.Value]);
_center = center == null ? null : new Lazy<PolusVent>(() => data.Vents[center.Value]);
_right = right == null ? null : new Lazy<PolusVent>(() => data.Vents[right.Value]);
}
public enum Ids
{
Security = 0,
Electrical = 1,
O2 = 2,
Communications = 3,
Office = 4,
Admin = 5,
Laboratory = 6,
Lava = 7,
Storage = 8,
RightStabilizer = 9,
LeftStabilizer = 10,
OutsideAdmin = 11,
}
public Ids Id { get; }
int IVent.Id => (int)Id;
public string Name { get; }
public Vector2 Position { get; }
public PolusVent? Left => _left?.Value;
IVent? IVent.Left => Left;
public PolusVent? Center => _center?.Value;
IVent? IVent.Center => Center;
public PolusVent? Right => _right?.Value;
IVent? IVent.Right => Right;
}
}
@@ -0,0 +1,63 @@
using System;
using System.Numerics;
namespace Impostor.Api.Innersloth.Maps.Vents
{
public class SkeldVent : IVent
{
private readonly Lazy<SkeldVent>? _left;
private readonly Lazy<SkeldVent>? _center;
private readonly Lazy<SkeldVent>? _right;
internal SkeldVent(SkeldData data, Ids id, Vector2 position, Ids? left = null, Ids? center = null, Ids? right = null)
{
Id = id;
Name = id.ToString();
Position = position;
_left = left == null ? null : new Lazy<SkeldVent>(() => data.Vents[left.Value]);
_center = center == null ? null : new Lazy<SkeldVent>(() => data.Vents[center.Value]);
_right = right == null ? null : new Lazy<SkeldVent>(() => data.Vents[right.Value]);
}
public enum Ids
{
Admin = 0,
RightHallway = 1,
Cafeteria = 2,
Electrical = 3,
UpperEngine = 4,
Security = 5,
Medbay = 6,
Weapons = 7,
LowerReactor = 8,
LowerEngine = 9,
Shields = 10,
UpperReactor = 11,
UpperNavigation = 12,
LowerNavigation = 13,
}
public Ids Id { get; }
int IVent.Id => (int)Id;
public string Name { get; }
public Vector2 Position { get; }
public SkeldVent? Left => _left?.Value;
IVent? IVent.Left => Left;
public SkeldVent? Center => _center?.Value;
IVent? IVent.Center => Center;
public SkeldVent? Right => _right?.Value;
IVent? IVent.Right => Right;
}
}
@@ -0,0 +1,50 @@
using System;
using Impostor.Api.Net.Messages;
namespace Impostor.Api.Innersloth
{
public class PlatformSpecificData
{
public PlatformSpecificData(Platforms platform, string platformName, ulong? xboxPlatformId = null, ulong? psnPlatformId = null)
{
Platform = platform;
PlatformName = platformName;
XboxPlatformId = xboxPlatformId;
PsnPlatformId = psnPlatformId;
}
public PlatformSpecificData(IMessageReader reader)
{
Platform = (Platforms)reader.Tag;
PlatformName = reader.ReadString();
XboxPlatformId = Platform == Platforms.Xbox ? reader.ReadUInt64() : null;
PsnPlatformId = Platform == Platforms.Playstation ? reader.ReadUInt64() : null;
}
public Platforms Platform { get; }
public string PlatformName { get; }
public ulong? XboxPlatformId { get; }
public ulong? PsnPlatformId { get; }
public void Serialize(IMessageWriter writer)
{
writer.StartMessage((byte)Platform);
writer.Write(PlatformName);
switch (Platform)
{
case Platforms.Xbox:
writer.Write(XboxPlatformId ?? throw new NullReferenceException($"{nameof(XboxPlatformId)} shouldn't be null when {nameof(Platform)} is Xbox"));
break;
case Platforms.Playstation:
writer.Write(PsnPlatformId ?? throw new NullReferenceException($"{nameof(PsnPlatformId)} shouldn't be null when {nameof(Platform)} is Playstation"));
break;
}
writer.EndMessage();
}
}
}
Loaded 100 of 429 files, more files were not shown because too many files have changed in this diff. Show more