mirror of
https://github.com/Impostor/Impostor.git
synced 2026-10-20 01:46:11 +00:00
Compare commits
57
Commits
v1.3.0
...
pluginmanager
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e857ed555 | ||
|
|
9d31752bf0 | ||
|
|
ced530b83a | ||
|
|
8f1cba8429 | ||
|
|
9009bac883 | ||
|
|
f3460f05bc | ||
|
|
a13fee108f | ||
|
|
adc0e6fe9b | ||
|
|
ce62815dc5 | ||
|
|
b1a0adaa28 | ||
|
|
fe697b1b63 | ||
|
|
55e6d38f9f | ||
|
|
b73a46ff56 | ||
|
|
901deeff59 | ||
|
|
f2126fd4c6 | ||
|
|
9aa6109b3a | ||
|
|
e1a6fdda98 | ||
|
|
283f59b51f | ||
|
|
d47343df08 | ||
|
|
0bb5442a3a | ||
|
|
7ac6c32b5d | ||
|
|
fbd9f12f9e | ||
|
|
f43577b745 | ||
|
|
a56eed2680 | ||
|
|
f0434f071c | ||
|
|
8d27016cb7 | ||
|
|
e941796a4c | ||
|
|
1d66f07906 | ||
|
|
7764987f91 | ||
|
|
bfba4385fd | ||
|
|
f03e72206e | ||
|
|
304b4bb7bf | ||
|
|
970f826dc8 | ||
|
|
4866a350f8 | ||
|
|
13bddeb7bd | ||
|
|
225b56e71f | ||
|
|
60bf6b5f58 | ||
|
|
b5cee48242 | ||
|
|
c750c65481 | ||
|
|
d801a36af8 | ||
|
|
441d9c300c | ||
|
|
7fd68e31e6 | ||
|
|
47aebe7b7b | ||
|
|
66c2434320 | ||
|
|
c01062ed65 | ||
|
|
d5ae007d1c | ||
|
|
16a2b0aac6 | ||
|
|
4c1bd4a578 | ||
|
|
d311150967 | ||
|
|
92e3506f51 | ||
|
|
a63fc40099 | ||
|
|
4f53d3f4e6 | ||
|
|
a39fae3325 | ||
|
|
7c34836d50 | ||
|
|
989b06d04c | ||
|
|
11e87e51db | ||
|
|
b90e5b2c88 |
No files matched your search
@@ -0,0 +1,3 @@
|
||||
[submodule "src/Impostor.Hazel"]
|
||||
path = src/Impostor.Hazel
|
||||
url = https://github.com/Impostor/Impostor.Hazel
|
||||
+2
-2
@@ -11,7 +11,7 @@ WORKDIR /source
|
||||
# Copy csproj and restore.
|
||||
COPY src/Impostor.Server/Impostor.Server.csproj ./src/Impostor.Server/Impostor.Server.csproj
|
||||
COPY src/Impostor.Api/Impostor.Api.csproj ./src/Impostor.Api/Impostor.Api.csproj
|
||||
COPY src/Impostor.Hazel/Impostor.Hazel.csproj ./src/Impostor.Hazel/Impostor.Hazel.csproj
|
||||
COPY src/Impostor.Hazel/Hazel/Hazel.csproj ./src/Impostor.Hazel/Hazel/Hazel.csproj
|
||||
|
||||
RUN case "$TARGETARCH" in \
|
||||
amd64) NETCORE_PLATFORM='linux-x64';; \
|
||||
@@ -21,7 +21,7 @@ RUN case "$TARGETARCH" in \
|
||||
esac && \
|
||||
dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Server/Impostor.Server.csproj && \
|
||||
dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Api/Impostor.Api.csproj && \
|
||||
dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Hazel/Impostor.Hazel.csproj
|
||||
dotnet restore -r "$NETCORE_PLATFORM" ./src/Impostor.Hazel/Hazel/Hazel.csproj
|
||||
|
||||
# Copy everything else.
|
||||
COPY src/. ./src/
|
||||
|
||||
@@ -9,7 +9,8 @@ Impostor is one of the first **Among Us** private servers, written in C#.
|
||||
|-|-|-|-|
|
||||
| 1.1.0 | 2020.09.07 - 2020.09.22 | No | [](https://github.com/Impostor/Impostor/releases/tag/v1.1.0) |
|
||||
| 1.2.2 | 2020.09.22 - 2020.11.17 | No | [](https://github.com/Impostor/Impostor/releases/tag/v1.2.2) |
|
||||
| 1.3.0 | 2021.3.5 | Yes | [](https://ci.appveyor.com/project/Impostor/Impostor/branch/master/artifacts) |
|
||||
| 1.3.0 | 2021.3.5 | No | [](https://github.com/Impostor/Impostor/releases/tag/v1.3.0) |
|
||||
| 1.4.0 | 2021.3.31 - 2021.4.2 | Yes | [](https://ci.appveyor.com/project/Impostor/Impostor/branch/master/artifacts) |
|
||||
|
||||
## Features
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ There are currently two modes to run the Impostor server in. The first way is th
|
||||
- [Windows x64](https://dotnet.microsoft.com/download/dotnet/thank-you/runtime-5.0.0-windows-x64-installer)
|
||||
- [Linux x64](https://docs.microsoft.com/en-us/dotnet/core/install/linux)
|
||||
- [macOS x64](https://dotnet.microsoft.com/download/dotnet/thank-you/runtime-5.0.0-macos-x64-installer)
|
||||
2. Find the [latest dev release](https://ci.appveyor.com/project/Impostor/Impostor/branch/dev/artifacts).
|
||||
2. Find the [latest master release](https://ci.appveyor.com/project/Impostor/Impostor/branch/master/artifacts).
|
||||
3. Download either the Windows or the Linux version.
|
||||
4. Extract the zip.
|
||||
5. Modify `config.json` to your liking. Documentation can be found [here](Server-configuration.md) *(this step is mandatory if you want to expose this server to other devices)*
|
||||
|
||||
+1
-1
@@ -171,7 +171,7 @@ csharp_new_line_between_query_expression_clauses = true
|
||||
csharp_indent_block_contents = true
|
||||
csharp_indent_braces = false
|
||||
csharp_indent_case_contents = true
|
||||
csharp_indent_case_contents_when_block = true
|
||||
csharp_indent_case_contents_when_block = false
|
||||
csharp_indent_switch_labels = true
|
||||
csharp_indent_labels = flush_left
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>1.3.0</VersionPrefix>
|
||||
<VersionPrefix>1.4.0</VersionPrefix>
|
||||
<VersionSuffix>dev</VersionSuffix>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Impostor.Server.Net.Inner;
|
||||
using Impostor.Api.Net.Inner;
|
||||
|
||||
namespace Impostor.Api
|
||||
{
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -2,16 +2,14 @@ using Impostor.Api.Innersloth;
|
||||
|
||||
namespace Impostor.Api.Events.Player
|
||||
{
|
||||
/// <summary>
|
||||
/// Called whenever a player moves to another vent.
|
||||
/// </summary>
|
||||
public interface IPlayerVentEvent : IPlayerEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets get the id of the used vent.
|
||||
/// Gets the vent player moved to.
|
||||
/// </summary>
|
||||
public VentLocation VentId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the vent was entered or exited.
|
||||
/// </summary>
|
||||
public bool VentEnter { get; }
|
||||
public IVent NewVent { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using Impostor.Api.Net.Inner.Objects;
|
||||
|
||||
namespace Impostor.Api.Events.Player
|
||||
{
|
||||
public enum VoteType : sbyte
|
||||
{
|
||||
ForceSkip = -2,
|
||||
Skip = -1,
|
||||
Player = 0,
|
||||
}
|
||||
|
||||
public interface IPlayerVotedEvent : IPlayerEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the player he voted for.
|
||||
/// </summary>
|
||||
IInnerPlayerControl? VotedFor { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Vote type.
|
||||
/// </summary>
|
||||
VoteType VoteType { get; }
|
||||
}
|
||||
}
|
||||
+7
-2
@@ -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" />.
|
||||
/// </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)
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,9 +35,7 @@ namespace Impostor.Api
|
||||
{
|
||||
var original = Advance<float>(ref input);
|
||||
|
||||
// BitConverter.Int32BitsToSingle
|
||||
// Doesn't exist in net 2.0 for some reason
|
||||
return Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(original));
|
||||
return BitConverter.Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(original));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@@ -46,12 +44,6 @@ 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 <paramref name="input" /> by the size of <typeparamref name="T" />.
|
||||
/// </summary>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -90,5 +90,24 @@ namespace Impostor.Api.Games
|
||||
/// <param name="id">ID of the client.</param>
|
||||
/// <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);
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,12 @@ namespace Impostor.Api.Games.Managers
|
||||
|
||||
IGame? Find(GameCode code);
|
||||
|
||||
ValueTask<IGame> CreateAsync(GameOptionsData options);
|
||||
/// <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);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace Impostor.Api.Innersloth.Customization
|
||||
{
|
||||
public enum ColorType : byte
|
||||
public enum ColorType
|
||||
{
|
||||
Red = 0,
|
||||
Blue = 1,
|
||||
|
||||
@@ -97,5 +97,25 @@
|
||||
RamHorns = 92,
|
||||
SnowCrewmate = 93,
|
||||
GeoffHat = 94,
|
||||
DaveCap = 95,
|
||||
EllieRose = 96,
|
||||
SvenHat = 97,
|
||||
BurtHat = 98,
|
||||
EllryMohawk = 99,
|
||||
ThomasMonoc = 100,
|
||||
Wizard = 101,
|
||||
Fredrick = 102,
|
||||
MrMacbeth = 103,
|
||||
ToppatHenry = 104,
|
||||
ToppatEllie = 105,
|
||||
GeoffreyPlumb = 106,
|
||||
AngryEyebrows = 107,
|
||||
ChocolateIce = 108,
|
||||
HeartPin = 109,
|
||||
Ponytail = 110,
|
||||
RubberGlove = 111,
|
||||
UnicornHorn = 112,
|
||||
Zipper = 113,
|
||||
RightHandMan = 114,
|
||||
}
|
||||
}
|
||||
@@ -18,5 +18,8 @@
|
||||
Miner = 13,
|
||||
Winter = 14,
|
||||
Archae = 15,
|
||||
Prisoner = 16,
|
||||
CCC = 17,
|
||||
RightHandMan = 18,
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Impostor.Api.Innersloth
|
||||
{
|
||||
public class MapSpawn
|
||||
{
|
||||
private MapSpawn(float spawnRadius, Vector2 initialSpawnCenter, Vector2 meetingSpawnCenter)
|
||||
{
|
||||
SpawnRadius = spawnRadius;
|
||||
InitialSpawnCenter = initialSpawnCenter;
|
||||
MeetingSpawnCenter = meetingSpawnCenter;
|
||||
}
|
||||
|
||||
public static Dictionary<MapTypes, MapSpawn> Maps { get; } = new Dictionary<MapTypes, MapSpawn>
|
||||
{
|
||||
[MapTypes.Skeld] = new MapSpawn(1.6f, new Vector2(-0.72f, 0.62f), new Vector2(-0.72f, 0.62f)),
|
||||
[MapTypes.MiraHQ] = new MapSpawn(1.55f, new Vector2(-4.4f, 2.2f), new Vector2(24.043f, 1.72f)),
|
||||
[MapTypes.Polus] = new MapSpawn(1f, new Vector2(16.64f, -2.46f), new Vector2(17.726f, -16.286f)),
|
||||
};
|
||||
|
||||
public float SpawnRadius { get; }
|
||||
|
||||
public Vector2 InitialSpawnCenter { get; }
|
||||
|
||||
public Vector2 MeetingSpawnCenter { get; }
|
||||
|
||||
public Vector2 GetSpawnLocation(int playerId, int numPlayer, bool initialSpawn)
|
||||
{
|
||||
var vector = new Vector2(0, 1);
|
||||
vector = Rotate(vector, (playerId - 1) * (360f / numPlayer));
|
||||
vector *= this.SpawnRadius;
|
||||
return (initialSpawn ? this.InitialSpawnCenter : this.MeetingSpawnCenter) + vector + new Vector2(0f, 0.3636f);
|
||||
}
|
||||
|
||||
private static Vector2 Rotate(Vector2 self, float degrees)
|
||||
{
|
||||
var f = 0.017453292f * degrees;
|
||||
var num = (float)Math.Cos(f);
|
||||
var num2 = (float)Math.Sin(f);
|
||||
return new Vector2((self.X * num) - (num2 * self.Y), (self.X * num2) + (num * self.Y));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,5 +5,6 @@
|
||||
Skeld = 0,
|
||||
MiraHQ = 1,
|
||||
Polus = 2,
|
||||
Airship = 4,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Impostor.Api.Innersloth.Maps.Tasks;
|
||||
using Impostor.Api.Innersloth.Maps.Vents;
|
||||
|
||||
namespace Impostor.Api.Innersloth.Maps
|
||||
{
|
||||
public class AirshipData : IMapData
|
||||
{
|
||||
private readonly IReadOnlyDictionary<int, IVent> _vents;
|
||||
private readonly IReadOnlyDictionary<int, ITask> _tasks;
|
||||
|
||||
internal AirshipData()
|
||||
{
|
||||
var vents = new[]
|
||||
{
|
||||
new AirshipVent(this, AirshipVent.Ids.Vault, new Vector2(-12.6322f, 8.4735f), left: AirshipVent.Ids.Cockpit),
|
||||
new AirshipVent(this, AirshipVent.Ids.Cockpit, new Vector2(-22.099f, -1.512f), left: AirshipVent.Ids.Vault, right: AirshipVent.Ids.ViewingDeck),
|
||||
new AirshipVent(this, AirshipVent.Ids.ViewingDeck, new Vector2(-15.659f, -11.6991f), left: AirshipVent.Ids.Cockpit),
|
||||
new AirshipVent(this, AirshipVent.Ids.EngineRoom, new Vector2(0.203f, -2.5361f), left: AirshipVent.Ids.Kitchen, right: AirshipVent.Ids.MainHallBottom),
|
||||
new AirshipVent(this, AirshipVent.Ids.Kitchen, new Vector2(-2.6019f, -9.338f), left: AirshipVent.Ids.EngineRoom, right: AirshipVent.Ids.MainHallBottom),
|
||||
new AirshipVent(this, AirshipVent.Ids.MainHallBottom, new Vector2(7.021f, -3.730999f), left: AirshipVent.Ids.EngineRoom, right: AirshipVent.Ids.Kitchen),
|
||||
new AirshipVent(this, AirshipVent.Ids.GapRight, new Vector2(9.814f, 3.206f), left: AirshipVent.Ids.MainHallTop, right: AirshipVent.Ids.GapLeft),
|
||||
new AirshipVent(this, AirshipVent.Ids.GapLeft, new Vector2(12.663f, 5.922f), left: AirshipVent.Ids.MainHallTop, right: AirshipVent.Ids.GapRight),
|
||||
new AirshipVent(this, AirshipVent.Ids.MainHallTop, new Vector2(3.605f, 6.923f), left: AirshipVent.Ids.GapLeft, right: AirshipVent.Ids.GapRight),
|
||||
new AirshipVent(this, AirshipVent.Ids.Showers, new Vector2(23.9869f, -1.386f), left: AirshipVent.Ids.Records, right: AirshipVent.Ids.CargoBay),
|
||||
new AirshipVent(this, AirshipVent.Ids.Records, new Vector2(23.2799f, 8.259998f), left: AirshipVent.Ids.Showers, right: AirshipVent.Ids.CargoBay),
|
||||
new AirshipVent(this, AirshipVent.Ids.CargoBay, new Vector2(30.4409f, -3.577f), left: AirshipVent.Ids.Showers, right: AirshipVent.Ids.Records),
|
||||
};
|
||||
|
||||
Vents = vents.ToDictionary(x => x.Id, x => x).AsReadOnly();
|
||||
_vents = vents.ToDictionary(x => (int)x.Id, x => (IVent)x).AsReadOnly();
|
||||
|
||||
var tasks = new[]
|
||||
{
|
||||
new AirshipTask(AirshipTask.Ids.ElectricalFixWiring, TaskTypes.FixWiring, TaskCategories.CommonTask),
|
||||
new AirshipTask(AirshipTask.Ids.MeetingRoomEnterIDCode, TaskTypes.EnterIdCode, TaskCategories.CommonTask),
|
||||
new AirshipTask(AirshipTask.Ids.ElectricalResetBreakers, TaskTypes.ResetBreakers, TaskCategories.LongTask),
|
||||
new AirshipTask(AirshipTask.Ids.VaultRoomDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
|
||||
new AirshipTask(AirshipTask.Ids.BrigDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
|
||||
new AirshipTask(AirshipTask.Ids.CargoBayDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
|
||||
new AirshipTask(AirshipTask.Ids.GapRoomDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
|
||||
new AirshipTask(AirshipTask.Ids.RecordsDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
|
||||
new AirshipTask(AirshipTask.Ids.CargoBayUnlockSafe, TaskTypes.UnlockSafe, TaskCategories.LongTask),
|
||||
new AirshipTask(AirshipTask.Ids.VentilationStartFans, TaskTypes.StartFans, TaskCategories.LongTask),
|
||||
new AirshipTask(AirshipTask.Ids.MainHallEmptyGarbage, TaskTypes.EmptyGarbage, TaskCategories.LongTask),
|
||||
new AirshipTask(AirshipTask.Ids.MedicalEmptyGarbage, TaskTypes.EmptyGarbage, TaskCategories.LongTask),
|
||||
new AirshipTask(AirshipTask.Ids.KitchenEmptyGarbage, TaskTypes.EmptyGarbage, TaskCategories.LongTask),
|
||||
new AirshipTask(AirshipTask.Ids.MainHallDevelopPhotos, TaskTypes.DevelopPhotos, TaskCategories.LongTask),
|
||||
new AirshipTask(AirshipTask.Ids.CargoBayFuelEngines, TaskTypes.FuelEngines, TaskCategories.LongTask),
|
||||
new AirshipTask(AirshipTask.Ids.SecurityRewindTapes, TaskTypes.RewindTapes, TaskCategories.LongTask),
|
||||
new AirshipTask(AirshipTask.Ids.VaultRoomPolishRuby, TaskTypes.PolishRuby, TaskCategories.ShortTask),
|
||||
new AirshipTask(AirshipTask.Ids.ElectricalCalibrateDistributor, TaskTypes.CalibrateDistributor, TaskCategories.LongTask),
|
||||
new AirshipTask(AirshipTask.Ids.CockpitStabilizeSteering, TaskTypes.StabilizeSteering, TaskCategories.ShortTask),
|
||||
new AirshipTask(AirshipTask.Ids.ArmoryDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
|
||||
new AirshipTask(AirshipTask.Ids.CockpitDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
|
||||
new AirshipTask(AirshipTask.Ids.CommsDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
|
||||
new AirshipTask(AirshipTask.Ids.MedicalDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
|
||||
new AirshipTask(AirshipTask.Ids.ViewingDeckDownloadData, TaskTypes.UploadData, TaskCategories.LongTask),
|
||||
new AirshipTask(AirshipTask.Ids.ElectricalDivertPowerToArmory, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
new AirshipTask(AirshipTask.Ids.ElectricalDivertPowerToCockpit, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
new AirshipTask(AirshipTask.Ids.ElectricalDivertPowerToGapRoom, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
new AirshipTask(AirshipTask.Ids.ElectricalDivertPowerToMainHall, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
new AirshipTask(AirshipTask.Ids.ElectricalDivertPowerToMeetingRoom, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
new AirshipTask(AirshipTask.Ids.ElectricalDivertPowerToShowers, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
new AirshipTask(AirshipTask.Ids.ElectricalDivertPowerToEngine, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
new AirshipTask(AirshipTask.Ids.ShowersPickUpTowels, TaskTypes.PickUpTowels, TaskCategories.ShortTask),
|
||||
new AirshipTask(AirshipTask.Ids.LoungeCleanToilet, TaskTypes.CleanToilet, TaskCategories.ShortTask),
|
||||
new AirshipTask(AirshipTask.Ids.VaultRoomDressMannequin, TaskTypes.DressMannequin, TaskCategories.ShortTask),
|
||||
new AirshipTask(AirshipTask.Ids.RecordsSortRecords, TaskTypes.SortRecords, TaskCategories.ShortTask),
|
||||
new AirshipTask(AirshipTask.Ids.ArmoryPutAwayPistols, TaskTypes.PutAwayPistols, TaskCategories.ShortTask),
|
||||
new AirshipTask(AirshipTask.Ids.ArmoryPutAwayRifles, TaskTypes.PutAwayRifles, TaskCategories.ShortTask),
|
||||
new AirshipTask(AirshipTask.Ids.MainHallDecontaminate, TaskTypes.Decontaminate, TaskCategories.ShortTask),
|
||||
new AirshipTask(AirshipTask.Ids.KitchenMakeBurger, TaskTypes.MakeBurger, TaskCategories.ShortTask),
|
||||
new AirshipTask(AirshipTask.Ids.ShowersFixShower, TaskTypes.FixShower, TaskCategories.ShortTask),
|
||||
};
|
||||
|
||||
Tasks = tasks.ToDictionary(x => x.Id, x => x).AsReadOnly();
|
||||
_tasks = tasks.ToDictionary(x => (int)x.Id, x => (ITask)x).AsReadOnly();
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<AirshipVent.Ids, AirshipVent> Vents { get; }
|
||||
|
||||
IReadOnlyDictionary<int, IVent> IMapData.Vents => _vents;
|
||||
|
||||
public IReadOnlyDictionary<AirshipTask.Ids, AirshipTask> Tasks { get; }
|
||||
|
||||
IReadOnlyDictionary<int, ITask> IMapData.Tasks => _tasks;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Impostor.Api.Innersloth.Maps
|
||||
{
|
||||
public interface IMapData
|
||||
{
|
||||
public static IReadOnlyDictionary<MapTypes, IMapData> Maps { get; } = new Dictionary<MapTypes, IMapData>
|
||||
{
|
||||
[MapTypes.Skeld] = new SkeldData(),
|
||||
[MapTypes.MiraHQ] = new MiraData(),
|
||||
[MapTypes.Polus] = new PolusData(),
|
||||
[MapTypes.Airship] = new AirshipData(),
|
||||
}.AsReadOnly();
|
||||
|
||||
IReadOnlyDictionary<int, IVent> Vents { get; }
|
||||
|
||||
IReadOnlyDictionary<int, ITask> Tasks { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Impostor.Api.Innersloth.Maps.Tasks;
|
||||
using Impostor.Api.Innersloth.Maps.Vents;
|
||||
|
||||
namespace Impostor.Api.Innersloth.Maps
|
||||
{
|
||||
public class MiraData : IMapData
|
||||
{
|
||||
private readonly IReadOnlyDictionary<int, IVent> _vents;
|
||||
private readonly IReadOnlyDictionary<int, ITask> _tasks;
|
||||
|
||||
internal MiraData()
|
||||
{
|
||||
var vents = new[]
|
||||
{
|
||||
new MiraVent(this, MiraVent.Ids.Balcony, new Vector2(23.77f, -1.94f), left: MiraVent.Ids.Medbay, right: MiraVent.Ids.Cafeteria),
|
||||
new MiraVent(this, MiraVent.Ids.Cafeteria, new Vector2(23.9f, 7.18f), left: MiraVent.Ids.Admin, right: MiraVent.Ids.Balcony),
|
||||
new MiraVent(this, MiraVent.Ids.Reactor, new Vector2(0.4800001f, 10.697f), left: MiraVent.Ids.Laboratory, center: MiraVent.Ids.Decontamination, right: MiraVent.Ids.Launchpad),
|
||||
new MiraVent(this, MiraVent.Ids.Laboratory, new Vector2(11.606f, 13.816f), left: MiraVent.Ids.Reactor, center: MiraVent.Ids.Decontamination, right: MiraVent.Ids.Office),
|
||||
new MiraVent(this, MiraVent.Ids.Office, new Vector2(13.28f, 20.13f), left: MiraVent.Ids.Laboratory, center: MiraVent.Ids.Admin, right: MiraVent.Ids.Greenhouse),
|
||||
new MiraVent(this, MiraVent.Ids.Admin, new Vector2(22.39f, 17.23f), left: MiraVent.Ids.Greenhouse, center: MiraVent.Ids.Cafeteria, right: MiraVent.Ids.Office),
|
||||
new MiraVent(this, MiraVent.Ids.Greenhouse, new Vector2(17.85f, 25.23f), left: MiraVent.Ids.Admin, right: MiraVent.Ids.Office),
|
||||
new MiraVent(this, MiraVent.Ids.Medbay, new Vector2(15.41f, -1.82f), left: MiraVent.Ids.Balcony, right: MiraVent.Ids.LockerRoom),
|
||||
new MiraVent(this, MiraVent.Ids.Decontamination, new Vector2(6.83f, 3.145f), left: MiraVent.Ids.Reactor, center: MiraVent.Ids.LockerRoom, right: MiraVent.Ids.Laboratory),
|
||||
new MiraVent(this, MiraVent.Ids.LockerRoom, new Vector2(4.29f, 0.5299997f), left: MiraVent.Ids.Medbay, center: MiraVent.Ids.Launchpad, right: MiraVent.Ids.Decontamination),
|
||||
new MiraVent(this, MiraVent.Ids.Launchpad, new Vector2(-6.18f, 3.56f), left: MiraVent.Ids.Reactor, right: MiraVent.Ids.LockerRoom),
|
||||
};
|
||||
|
||||
Vents = vents.ToDictionary(x => x.Id, x => x).AsReadOnly();
|
||||
_vents = vents.ToDictionary(x => (int)x.Id, x => (IVent)x).AsReadOnly();
|
||||
|
||||
var tasks = new[]
|
||||
{
|
||||
new MiraTask(MiraTask.Ids.HallwayFixWiring, TaskTypes.FixWiring, TaskCategories.CommonTask),
|
||||
new MiraTask(MiraTask.Ids.AdminEnterIDCode, TaskTypes.EnterIdCode, TaskCategories.CommonTask),
|
||||
new MiraTask(MiraTask.Ids.MedbaySubmitScan, TaskTypes.SubmitScan, TaskCategories.LongTask, true),
|
||||
new MiraTask(MiraTask.Ids.BalconyClearAsteroids, TaskTypes.ClearAsteroids, TaskCategories.LongTask),
|
||||
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToAdmin, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToCafeteria, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToCommunications, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToLaunchpad, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToMedbay, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToOffice, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
new MiraTask(MiraTask.Ids.StorageWaterPlants, TaskTypes.WaterPlants, TaskCategories.LongTask),
|
||||
new MiraTask(MiraTask.Ids.ReactorStartReactor, TaskTypes.StartReactor, TaskCategories.LongTask),
|
||||
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToGreenhouse, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
new MiraTask(MiraTask.Ids.AdminChartCourse, TaskTypes.ChartCourse, TaskCategories.ShortTask),
|
||||
new MiraTask(MiraTask.Ids.GreenhouseCleanO2Filter, TaskTypes.Filter, TaskCategories.ShortTask),
|
||||
new MiraTask(MiraTask.Ids.LaunchpadFuelEngines, TaskTypes.FuelEngines, TaskCategories.ShortTask),
|
||||
new MiraTask(MiraTask.Ids.LaboratoryAssembleArtifact, TaskTypes.AssembleArtifact, TaskCategories.ShortTask),
|
||||
new MiraTask(MiraTask.Ids.LaboratorySortSamples, TaskTypes.SortSamples, TaskCategories.ShortTask),
|
||||
new MiraTask(MiraTask.Ids.AdminPrimeShields, TaskTypes.PrimeShields, TaskCategories.ShortTask),
|
||||
new MiraTask(MiraTask.Ids.CafeteriaEmptyGarbage, TaskTypes.EmptyGarbage, TaskCategories.ShortTask),
|
||||
new MiraTask(MiraTask.Ids.BalconyMeasureWeather, TaskTypes.MeasureWeather, TaskCategories.ShortTask),
|
||||
new MiraTask(MiraTask.Ids.ElectricalDivertPowerToLaboratory, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
new MiraTask(MiraTask.Ids.CafeteriaBuyBeverage, TaskTypes.BuyBeverage, TaskCategories.ShortTask),
|
||||
new MiraTask(MiraTask.Ids.OfficeProcessData, TaskTypes.ProcessData, TaskCategories.ShortTask),
|
||||
new MiraTask(MiraTask.Ids.LaunchpadRunDiagnostics, TaskTypes.RunDiagnostics, TaskCategories.LongTask),
|
||||
new MiraTask(MiraTask.Ids.ReactorUnlockManifolds, TaskTypes.UnlockManifolds, TaskCategories.ShortTask),
|
||||
};
|
||||
|
||||
Tasks = tasks.ToDictionary(x => x.Id, x => x).AsReadOnly();
|
||||
_tasks = tasks.ToDictionary(x => (int)x.Id, x => (ITask)x).AsReadOnly();
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<MiraVent.Ids, MiraVent> Vents { get; }
|
||||
|
||||
IReadOnlyDictionary<int, IVent> IMapData.Vents => _vents;
|
||||
|
||||
public IReadOnlyDictionary<MiraTask.Ids, MiraTask> Tasks { get; }
|
||||
|
||||
IReadOnlyDictionary<int, ITask> IMapData.Tasks => _tasks;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Impostor.Api.Innersloth.Maps.Tasks;
|
||||
using Impostor.Api.Innersloth.Maps.Vents;
|
||||
|
||||
namespace Impostor.Api.Innersloth.Maps
|
||||
{
|
||||
public class PolusData : IMapData
|
||||
{
|
||||
private readonly IReadOnlyDictionary<int, IVent> _vents;
|
||||
private readonly IReadOnlyDictionary<int, ITask> _tasks;
|
||||
|
||||
internal PolusData()
|
||||
{
|
||||
var vents = new[]
|
||||
{
|
||||
new PolusVent(this, PolusVent.Ids.Security, new Vector2(1.929f, -9.558001f), left: PolusVent.Ids.O2, right: PolusVent.Ids.Electrical),
|
||||
new PolusVent(this, PolusVent.Ids.Electrical, new Vector2(6.9f, -14.41f), left: PolusVent.Ids.O2, right: PolusVent.Ids.Security),
|
||||
new PolusVent(this, PolusVent.Ids.O2, new Vector2(3.51f, -16.58f), left: PolusVent.Ids.Electrical, right: PolusVent.Ids.Security),
|
||||
new PolusVent(this, PolusVent.Ids.Communications, new Vector2(12.304f, -18.898f), left: PolusVent.Ids.Storage, right: PolusVent.Ids.Office),
|
||||
new PolusVent(this, PolusVent.Ids.Office, new Vector2(16.379f, -19.599f), left: PolusVent.Ids.Communications, right: PolusVent.Ids.Storage),
|
||||
new PolusVent(this, PolusVent.Ids.Admin, new Vector2(20.089f, -25.517f), left: PolusVent.Ids.OutsideAdmin, right: PolusVent.Ids.Lava),
|
||||
new PolusVent(this, PolusVent.Ids.Laboratory, new Vector2(32.963f, -9.526f), right: PolusVent.Ids.Lava),
|
||||
new PolusVent(this, PolusVent.Ids.Lava, new Vector2(30.907f, -11.86f), left: PolusVent.Ids.Laboratory, right: PolusVent.Ids.Admin),
|
||||
new PolusVent(this, PolusVent.Ids.Storage, new Vector2(22f, -12.19f), left: PolusVent.Ids.Communications, right: PolusVent.Ids.Office),
|
||||
new PolusVent(this, PolusVent.Ids.RightStabilizer, new Vector2(24.02f, -8.39f), left: PolusVent.Ids.LeftStabilizer),
|
||||
new PolusVent(this, PolusVent.Ids.LeftStabilizer, new Vector2(9.64f, -7.72f), left: PolusVent.Ids.RightStabilizer),
|
||||
new PolusVent(this, PolusVent.Ids.OutsideAdmin, new Vector2(18.93f, -24.85f), right: PolusVent.Ids.Admin),
|
||||
};
|
||||
|
||||
Vents = vents.ToDictionary(x => x.Id, x => x).AsReadOnly();
|
||||
_vents = vents.ToDictionary(x => (int)x.Id, x => (IVent)x).AsReadOnly();
|
||||
|
||||
var tasks = new[]
|
||||
{
|
||||
new PolusTask(PolusTask.Ids.OfficeSwipeCard, TaskTypes.SwipeCard, TaskCategories.CommonTask),
|
||||
new PolusTask(PolusTask.Ids.DropshipInsertKeys, TaskTypes.InsertKeys, TaskCategories.CommonTask),
|
||||
new PolusTask(PolusTask.Ids.OfficeScanBoardingPass, TaskTypes.ScanBoardingPass, TaskCategories.CommonTask),
|
||||
new PolusTask(PolusTask.Ids.ElectricalFixWiring, TaskTypes.FixWiring, TaskCategories.CommonTask),
|
||||
new PolusTask(PolusTask.Ids.WeaponsDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
|
||||
new PolusTask(PolusTask.Ids.OfficeDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
|
||||
new PolusTask(PolusTask.Ids.ElectricalDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
|
||||
new PolusTask(PolusTask.Ids.SpecimenRoomDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
|
||||
new PolusTask(PolusTask.Ids.O2DownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
|
||||
new PolusTask(PolusTask.Ids.SpecimenRoomStartReactor, TaskTypes.StartReactor, TaskCategories.LongTask),
|
||||
new PolusTask(PolusTask.Ids.StorageFuelEngines, TaskTypes.FuelEngines, TaskCategories.LongTask),
|
||||
new PolusTask(PolusTask.Ids.BoilerRoomOpenWaterways, TaskTypes.OpenWaterways, TaskCategories.LongTask),
|
||||
new PolusTask(PolusTask.Ids.MedbayInspectSample, TaskTypes.InspectSample, TaskCategories.LongTask),
|
||||
new PolusTask(PolusTask.Ids.BoilerRoomReplaceWaterJug, TaskTypes.ReplaceWaterJug, TaskCategories.LongTask),
|
||||
new PolusTask(PolusTask.Ids.OutsideFixWeatherNodeNode_GI, TaskTypes.ActivateWeatherNodes, TaskCategories.LongTask),
|
||||
new PolusTask(PolusTask.Ids.OutsideFixWeatherNodeNode_IRO, TaskTypes.ActivateWeatherNodes, TaskCategories.LongTask),
|
||||
new PolusTask(PolusTask.Ids.OutsideFixWeatherNodeNode_PD, TaskTypes.ActivateWeatherNodes, TaskCategories.LongTask),
|
||||
new PolusTask(PolusTask.Ids.OutsideFixWeatherNodeNode_TB, TaskTypes.ActivateWeatherNodes, TaskCategories.LongTask),
|
||||
new PolusTask(PolusTask.Ids.CommunicationsRebootWiFi, TaskTypes.RebootWifi, TaskCategories.LongTask),
|
||||
new PolusTask(PolusTask.Ids.O2MonitorTree, TaskTypes.MonitorOxygen, TaskCategories.ShortTask),
|
||||
new PolusTask(PolusTask.Ids.SpecimenRoomUnlockManifolds, TaskTypes.UnlockManifolds, TaskCategories.ShortTask),
|
||||
new PolusTask(PolusTask.Ids.SpecimenRoomStoreArtifacts, TaskTypes.StoreArtifact, TaskCategories.ShortTask),
|
||||
new PolusTask(PolusTask.Ids.O2FillCanisters, TaskTypes.FillCanisters, TaskCategories.ShortTask),
|
||||
new PolusTask(PolusTask.Ids.O2EmptyGarbage, TaskTypes.EmptyGarbage, TaskCategories.ShortTask),
|
||||
new PolusTask(PolusTask.Ids.DropshipChartCourse, TaskTypes.ChartCourse, TaskCategories.ShortTask),
|
||||
new PolusTask(PolusTask.Ids.MedbaySubmitScan, TaskTypes.SubmitScan, TaskCategories.ShortTask, true),
|
||||
new PolusTask(PolusTask.Ids.WeaponsClearAsteroids, TaskTypes.ClearAsteroids, TaskCategories.ShortTask, true),
|
||||
new PolusTask(PolusTask.Ids.OutsideFixWeatherNodeNode_CA, TaskTypes.ActivateWeatherNodes, TaskCategories.LongTask),
|
||||
new PolusTask(PolusTask.Ids.OutsideFixWeatherNodeNode_MLG, TaskTypes.ActivateWeatherNodes, TaskCategories.LongTask),
|
||||
new PolusTask(PolusTask.Ids.LaboratoryAlignTelescope, TaskTypes.AlignTelescope, TaskCategories.ShortTask),
|
||||
new PolusTask(PolusTask.Ids.LaboratoryRepairDrill, TaskTypes.RepairDrill, TaskCategories.ShortTask),
|
||||
new PolusTask(PolusTask.Ids.LaboratoryRecordTemperature, TaskTypes.RecordTemperature, TaskCategories.ShortTask),
|
||||
new PolusTask(PolusTask.Ids.OutsideRecordTemperature, TaskTypes.RecordTemperature, TaskCategories.ShortTask),
|
||||
};
|
||||
|
||||
Tasks = tasks.ToDictionary(x => x.Id, x => x).AsReadOnly();
|
||||
_tasks = tasks.ToDictionary(x => (int)x.Id, x => (ITask)x).AsReadOnly();
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<PolusVent.Ids, PolusVent> Vents { get; }
|
||||
|
||||
IReadOnlyDictionary<int, IVent> IMapData.Vents => _vents;
|
||||
|
||||
public IReadOnlyDictionary<PolusTask.Ids, PolusTask> Tasks { get; }
|
||||
|
||||
IReadOnlyDictionary<int, ITask> IMapData.Tasks => _tasks;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Impostor.Api.Innersloth.Maps.Tasks;
|
||||
using Impostor.Api.Innersloth.Maps.Vents;
|
||||
|
||||
namespace Impostor.Api.Innersloth.Maps
|
||||
{
|
||||
public class SkeldData : IMapData
|
||||
{
|
||||
private readonly IReadOnlyDictionary<int, IVent> _vents;
|
||||
private readonly IReadOnlyDictionary<int, ITask> _tasks;
|
||||
|
||||
internal SkeldData()
|
||||
{
|
||||
var vents = new[]
|
||||
{
|
||||
new SkeldVent(this, SkeldVent.Ids.Admin, new Vector2(2.544f, -9.955201f), left: SkeldVent.Ids.Cafeteria, right: SkeldVent.Ids.RightHallway),
|
||||
new SkeldVent(this, SkeldVent.Ids.RightHallway, new Vector2(9.384f, -6.438f), left: SkeldVent.Ids.Admin, right: SkeldVent.Ids.Cafeteria),
|
||||
new SkeldVent(this, SkeldVent.Ids.Cafeteria, new Vector2(4.2588f, -0.276f), left: SkeldVent.Ids.Admin, right: SkeldVent.Ids.RightHallway),
|
||||
new SkeldVent(this, SkeldVent.Ids.Electrical, new Vector2(-9.7764f, -8.034f), left: SkeldVent.Ids.Security, right: SkeldVent.Ids.Medbay),
|
||||
new SkeldVent(this, SkeldVent.Ids.UpperEngine, new Vector2(-15.288f, 2.52f), left: SkeldVent.Ids.UpperReactor),
|
||||
new SkeldVent(this, SkeldVent.Ids.Security, new Vector2(-12.534f, -6.9492f), left: SkeldVent.Ids.Medbay, right: SkeldVent.Ids.Electrical),
|
||||
new SkeldVent(this, SkeldVent.Ids.Medbay, new Vector2(-10.608f, -4.176f), left: SkeldVent.Ids.Security, right: SkeldVent.Ids.Electrical),
|
||||
new SkeldVent(this, SkeldVent.Ids.Weapons, new Vector2(8.820001f, 3.324f), right: SkeldVent.Ids.UpperNavigation),
|
||||
new SkeldVent(this, SkeldVent.Ids.LowerReactor, new Vector2(-20.796f, -6.9528f), left: SkeldVent.Ids.LowerEngine),
|
||||
new SkeldVent(this, SkeldVent.Ids.LowerEngine, new Vector2(-15.2508f, -13.656f), left: SkeldVent.Ids.LowerReactor),
|
||||
new SkeldVent(this, SkeldVent.Ids.Shields, new Vector2(9.5232f, -14.3376f), left: SkeldVent.Ids.LowerNavigation),
|
||||
new SkeldVent(this, SkeldVent.Ids.UpperReactor, new Vector2(-21.876f, -3.0516f), left: SkeldVent.Ids.UpperEngine),
|
||||
new SkeldVent(this, SkeldVent.Ids.UpperNavigation, new Vector2(16.008f, -3.168f), right: SkeldVent.Ids.Weapons),
|
||||
new SkeldVent(this, SkeldVent.Ids.LowerNavigation, new Vector2(16.008f, -6.384f), right: SkeldVent.Ids.Shields),
|
||||
};
|
||||
|
||||
Vents = vents.ToDictionary(x => x.Id, x => x).AsReadOnly();
|
||||
_vents = vents.ToDictionary(x => (int)x.Id, x => (IVent)x).AsReadOnly();
|
||||
|
||||
var tasks = new[]
|
||||
{
|
||||
new SkeldTask(SkeldTask.Ids.AdminSwipeCard, TaskTypes.SwipeCard, TaskCategories.CommonTask),
|
||||
new SkeldTask(SkeldTask.Ids.ElectricalFixWiring, TaskTypes.FixWiring, TaskCategories.CommonTask),
|
||||
new SkeldTask(SkeldTask.Ids.WeaponsClearAsteroids, TaskTypes.ClearAsteroids, TaskCategories.LongTask, true),
|
||||
new SkeldTask(SkeldTask.Ids.EnginesAlignEngineOutput, TaskTypes.AlignEngineOutput, TaskCategories.ShortTask),
|
||||
new SkeldTask(SkeldTask.Ids.MedbaySubmitScan, TaskTypes.SubmitScan, TaskCategories.LongTask, true),
|
||||
new SkeldTask(SkeldTask.Ids.MedbayInspectSample, TaskTypes.InspectSample, TaskCategories.LongTask),
|
||||
new SkeldTask(SkeldTask.Ids.StorageFuelEngines, TaskTypes.FuelEngines, TaskCategories.LongTask),
|
||||
new SkeldTask(SkeldTask.Ids.ReactorStartReactor, TaskTypes.StartReactor, TaskCategories.LongTask),
|
||||
new SkeldTask(SkeldTask.Ids.O2EmptyChute, TaskTypes.EmptyChute, TaskCategories.LongTask, true),
|
||||
new SkeldTask(SkeldTask.Ids.CafeteriaEmptyGarbage, TaskTypes.EmptyGarbage, TaskCategories.LongTask, true),
|
||||
new SkeldTask(SkeldTask.Ids.CommunicationsDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
|
||||
new SkeldTask(SkeldTask.Ids.ElectricalCalibrateDistributor, TaskTypes.CalibrateDistributor, TaskCategories.ShortTask),
|
||||
new SkeldTask(SkeldTask.Ids.NavigationChartCourse, TaskTypes.ChartCourse, TaskCategories.ShortTask),
|
||||
new SkeldTask(SkeldTask.Ids.O2CleanO2Filter, TaskTypes.Filter, TaskCategories.ShortTask),
|
||||
new SkeldTask(SkeldTask.Ids.ReactorUnlockManifolds, TaskTypes.UnlockManifolds, TaskCategories.ShortTask),
|
||||
new SkeldTask(SkeldTask.Ids.ElectricalDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
|
||||
new SkeldTask(SkeldTask.Ids.NavigationStabilizeSteering, TaskTypes.StabilizeSteering, TaskCategories.ShortTask),
|
||||
new SkeldTask(SkeldTask.Ids.WeaponsDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
|
||||
new SkeldTask(SkeldTask.Ids.ShieldsPrimeShields, TaskTypes.PrimeShields, TaskCategories.ShortTask, true),
|
||||
new SkeldTask(SkeldTask.Ids.CafeteriaDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
|
||||
new SkeldTask(SkeldTask.Ids.NavigationDownloadData, TaskTypes.UploadData, TaskCategories.ShortTask),
|
||||
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToShields, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToWeapons, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToCommunications, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToUpperEngine, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToO2, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToNavigation, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToLowerEngine, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
new SkeldTask(SkeldTask.Ids.ElectricalDivertPowerToSecurity, TaskTypes.DivertPower, TaskCategories.ShortTask),
|
||||
};
|
||||
|
||||
Tasks = tasks.ToDictionary(x => x.Id, x => x).AsReadOnly();
|
||||
_tasks = tasks.ToDictionary(x => (int)x.Id, x => (ITask)x).AsReadOnly();
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<SkeldVent.Ids, SkeldVent> Vents { get; }
|
||||
|
||||
IReadOnlyDictionary<int, IVent> IMapData.Vents => _vents;
|
||||
|
||||
public IReadOnlyDictionary<SkeldTask.Ids, SkeldTask> Tasks { get; }
|
||||
|
||||
IReadOnlyDictionary<int, ITask> IMapData.Tasks => _tasks;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
namespace Impostor.Api.Innersloth.Maps.Tasks
|
||||
{
|
||||
public class AirshipTask : ITask
|
||||
{
|
||||
internal AirshipTask(Ids id, TaskTypes type, TaskCategories category, bool isVisual = false)
|
||||
{
|
||||
Id = id;
|
||||
Name = id.ToString();
|
||||
Type = type;
|
||||
Category = category;
|
||||
IsVisual = isVisual;
|
||||
}
|
||||
|
||||
public enum Ids
|
||||
{
|
||||
ElectricalFixWiring = 0,
|
||||
MeetingRoomEnterIDCode = 1,
|
||||
ElectricalResetBreakers = 2,
|
||||
VaultRoomDownloadData = 3,
|
||||
BrigDownloadData = 4,
|
||||
CargoBayDownloadData = 5,
|
||||
GapRoomDownloadData = 6,
|
||||
RecordsDownloadData = 7,
|
||||
CargoBayUnlockSafe = 8,
|
||||
VentilationStartFans = 9,
|
||||
MainHallEmptyGarbage = 10,
|
||||
MedicalEmptyGarbage = 11,
|
||||
KitchenEmptyGarbage = 12,
|
||||
MainHallDevelopPhotos = 13,
|
||||
CargoBayFuelEngines = 14,
|
||||
SecurityRewindTapes = 15,
|
||||
VaultRoomPolishRuby = 16,
|
||||
ElectricalCalibrateDistributor = 17,
|
||||
CockpitStabilizeSteering = 18,
|
||||
ArmoryDownloadData = 19,
|
||||
CockpitDownloadData = 20,
|
||||
CommsDownloadData = 21,
|
||||
MedicalDownloadData = 22,
|
||||
ViewingDeckDownloadData = 23,
|
||||
ElectricalDivertPowerToArmory = 24,
|
||||
ElectricalDivertPowerToCockpit = 25,
|
||||
ElectricalDivertPowerToGapRoom = 26,
|
||||
ElectricalDivertPowerToMainHall = 27,
|
||||
ElectricalDivertPowerToMeetingRoom = 28,
|
||||
ElectricalDivertPowerToShowers = 29,
|
||||
ElectricalDivertPowerToEngine = 30,
|
||||
ShowersPickUpTowels = 31,
|
||||
LoungeCleanToilet = 32,
|
||||
VaultRoomDressMannequin = 33,
|
||||
RecordsSortRecords = 34,
|
||||
ArmoryPutAwayPistols = 35,
|
||||
ArmoryPutAwayRifles = 36,
|
||||
MainHallDecontaminate = 37,
|
||||
KitchenMakeBurger = 38,
|
||||
ShowersFixShower = 39,
|
||||
}
|
||||
|
||||
public Ids Id { get; }
|
||||
|
||||
int ITask.Id => (int)Id;
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public TaskTypes Type { get; }
|
||||
|
||||
public TaskCategories Category { get; }
|
||||
|
||||
public bool IsVisual { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
namespace Impostor.Api.Innersloth.Maps.Tasks
|
||||
{
|
||||
public class MiraTask : ITask
|
||||
{
|
||||
internal MiraTask(Ids id, TaskTypes type, TaskCategories category, bool isVisual = false)
|
||||
{
|
||||
Id = id;
|
||||
Name = id.ToString();
|
||||
Type = type;
|
||||
Category = category;
|
||||
IsVisual = isVisual;
|
||||
}
|
||||
|
||||
public enum Ids
|
||||
{
|
||||
HallwayFixWiring = 0,
|
||||
AdminEnterIDCode = 1,
|
||||
MedbaySubmitScan = 2,
|
||||
BalconyClearAsteroids = 3,
|
||||
ElectricalDivertPowerToAdmin = 4,
|
||||
ElectricalDivertPowerToCafeteria = 5,
|
||||
ElectricalDivertPowerToCommunications = 6,
|
||||
ElectricalDivertPowerToLaunchpad = 7,
|
||||
ElectricalDivertPowerToMedbay = 8,
|
||||
ElectricalDivertPowerToOffice = 9,
|
||||
StorageWaterPlants = 10,
|
||||
ReactorStartReactor = 11,
|
||||
ElectricalDivertPowerToGreenhouse = 12,
|
||||
AdminChartCourse = 13,
|
||||
GreenhouseCleanO2Filter = 14,
|
||||
LaunchpadFuelEngines = 15,
|
||||
LaboratoryAssembleArtifact = 16,
|
||||
LaboratorySortSamples = 17,
|
||||
AdminPrimeShields = 18,
|
||||
CafeteriaEmptyGarbage = 19,
|
||||
BalconyMeasureWeather = 20,
|
||||
ElectricalDivertPowerToLaboratory = 21,
|
||||
CafeteriaBuyBeverage = 22,
|
||||
OfficeProcessData = 23,
|
||||
LaunchpadRunDiagnostics = 24,
|
||||
ReactorUnlockManifolds = 25,
|
||||
}
|
||||
|
||||
public Ids Id { get; }
|
||||
|
||||
int ITask.Id => (int)Id;
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public TaskTypes Type { get; }
|
||||
|
||||
public TaskCategories Category { get; }
|
||||
|
||||
public bool IsVisual { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
namespace Impostor.Api.Innersloth.Maps.Tasks
|
||||
{
|
||||
public class PolusTask : ITask
|
||||
{
|
||||
internal PolusTask(Ids id, TaskTypes type, TaskCategories category, bool isVisual = false)
|
||||
{
|
||||
Id = id;
|
||||
Name = id.ToString();
|
||||
Type = type;
|
||||
Category = category;
|
||||
IsVisual = isVisual;
|
||||
}
|
||||
|
||||
public enum Ids
|
||||
{
|
||||
OfficeSwipeCard = 0,
|
||||
DropshipInsertKeys = 1,
|
||||
OfficeScanBoardingPass = 2,
|
||||
ElectricalFixWiring = 3,
|
||||
WeaponsDownloadData = 4,
|
||||
OfficeDownloadData = 5,
|
||||
ElectricalDownloadData = 6,
|
||||
SpecimenRoomDownloadData = 7,
|
||||
O2DownloadData = 8,
|
||||
SpecimenRoomStartReactor = 9,
|
||||
StorageFuelEngines = 10,
|
||||
BoilerRoomOpenWaterways = 11,
|
||||
MedbayInspectSample = 12,
|
||||
BoilerRoomReplaceWaterJug = 13,
|
||||
OutsideFixWeatherNodeNode_GI = 14,
|
||||
OutsideFixWeatherNodeNode_IRO = 15,
|
||||
OutsideFixWeatherNodeNode_PD = 16,
|
||||
OutsideFixWeatherNodeNode_TB = 17,
|
||||
CommunicationsRebootWiFi = 18,
|
||||
O2MonitorTree = 19,
|
||||
SpecimenRoomUnlockManifolds = 20,
|
||||
SpecimenRoomStoreArtifacts = 21,
|
||||
O2FillCanisters = 22,
|
||||
O2EmptyGarbage = 23,
|
||||
DropshipChartCourse = 24,
|
||||
MedbaySubmitScan = 25,
|
||||
WeaponsClearAsteroids = 26,
|
||||
OutsideFixWeatherNodeNode_CA = 27,
|
||||
OutsideFixWeatherNodeNode_MLG = 28,
|
||||
LaboratoryAlignTelescope = 29,
|
||||
LaboratoryRepairDrill = 30,
|
||||
LaboratoryRecordTemperature = 31,
|
||||
OutsideRecordTemperature = 32,
|
||||
}
|
||||
|
||||
public Ids Id { get; }
|
||||
|
||||
int ITask.Id => (int)Id;
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public TaskTypes Type { get; }
|
||||
|
||||
public TaskCategories Category { get; }
|
||||
|
||||
public bool IsVisual { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
namespace Impostor.Api.Innersloth.Maps.Tasks
|
||||
{
|
||||
public class SkeldTask : ITask
|
||||
{
|
||||
internal SkeldTask(Ids id, TaskTypes type, TaskCategories category, bool isVisual = false)
|
||||
{
|
||||
Id = id;
|
||||
Name = id.ToString();
|
||||
Type = type;
|
||||
Category = category;
|
||||
IsVisual = isVisual;
|
||||
}
|
||||
|
||||
public enum Ids
|
||||
{
|
||||
AdminSwipeCard = 0,
|
||||
ElectricalFixWiring = 1,
|
||||
WeaponsClearAsteroids = 2,
|
||||
EnginesAlignEngineOutput = 3,
|
||||
MedbaySubmitScan = 4,
|
||||
MedbayInspectSample = 5,
|
||||
StorageFuelEngines = 6,
|
||||
ReactorStartReactor = 7,
|
||||
O2EmptyChute = 8,
|
||||
CafeteriaEmptyGarbage = 9,
|
||||
CommunicationsDownloadData = 10,
|
||||
ElectricalCalibrateDistributor = 11,
|
||||
NavigationChartCourse = 12,
|
||||
O2CleanO2Filter = 13,
|
||||
ReactorUnlockManifolds = 14,
|
||||
ElectricalDownloadData = 15,
|
||||
NavigationStabilizeSteering = 16,
|
||||
WeaponsDownloadData = 17,
|
||||
ShieldsPrimeShields = 18,
|
||||
CafeteriaDownloadData = 19,
|
||||
NavigationDownloadData = 20,
|
||||
ElectricalDivertPowerToShields = 21,
|
||||
ElectricalDivertPowerToWeapons = 22,
|
||||
ElectricalDivertPowerToCommunications = 23,
|
||||
ElectricalDivertPowerToUpperEngine = 24,
|
||||
ElectricalDivertPowerToO2 = 25,
|
||||
ElectricalDivertPowerToNavigation = 26,
|
||||
ElectricalDivertPowerToLowerEngine = 27,
|
||||
ElectricalDivertPowerToSecurity = 28,
|
||||
}
|
||||
|
||||
public Ids Id { get; }
|
||||
|
||||
int ITask.Id => (int)Id;
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public TaskTypes Type { get; }
|
||||
|
||||
public TaskCategories Category { get; }
|
||||
|
||||
public bool IsVisual { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Impostor.Api.Innersloth.Maps.Vents
|
||||
{
|
||||
public class AirshipVent : IVent
|
||||
{
|
||||
private readonly Lazy<AirshipVent>? _left;
|
||||
|
||||
private readonly Lazy<AirshipVent>? _center;
|
||||
|
||||
private readonly Lazy<AirshipVent>? _right;
|
||||
|
||||
internal AirshipVent(AirshipData data, Ids id, Vector2 position, Ids? left = null, Ids? center = null, Ids? right = null)
|
||||
{
|
||||
Id = id;
|
||||
Name = id.ToString();
|
||||
Position = position;
|
||||
|
||||
_left = left == null ? null : new Lazy<AirshipVent>(() => data.Vents[left.Value]);
|
||||
_center = center == null ? null : new Lazy<AirshipVent>(() => data.Vents[center.Value]);
|
||||
_right = right == null ? null : new Lazy<AirshipVent>(() => data.Vents[right.Value]);
|
||||
}
|
||||
|
||||
public enum Ids
|
||||
{
|
||||
Vault = 0,
|
||||
Cockpit = 1,
|
||||
ViewingDeck = 2,
|
||||
EngineRoom = 3,
|
||||
Kitchen = 4,
|
||||
MainHallBottom = 5,
|
||||
GapRight = 6,
|
||||
GapLeft = 7,
|
||||
MainHallTop = 8,
|
||||
Showers = 9,
|
||||
Records = 10,
|
||||
CargoBay = 11,
|
||||
}
|
||||
|
||||
public Ids Id { get; }
|
||||
|
||||
int IVent.Id => (int)Id;
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public Vector2 Position { get; }
|
||||
|
||||
public AirshipVent? Left => _left?.Value;
|
||||
|
||||
IVent? IVent.Left => Left;
|
||||
|
||||
public AirshipVent? Center => _center?.Value;
|
||||
|
||||
IVent? IVent.Center => Center;
|
||||
|
||||
public AirshipVent? Right => _right?.Value;
|
||||
|
||||
IVent? IVent.Right => Right;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Impostor.Api.Innersloth.Maps.Vents
|
||||
{
|
||||
public class MiraVent : IVent
|
||||
{
|
||||
private readonly Lazy<MiraVent>? _left;
|
||||
|
||||
private readonly Lazy<MiraVent>? _center;
|
||||
|
||||
private readonly Lazy<MiraVent>? _right;
|
||||
|
||||
internal MiraVent(MiraData data, Ids id, Vector2 position, Ids? left = null, Ids? center = null, Ids? right = null)
|
||||
{
|
||||
Id = id;
|
||||
Name = id.ToString();
|
||||
Position = position;
|
||||
|
||||
_left = left == null ? null : new Lazy<MiraVent>(() => data.Vents[left.Value]);
|
||||
_center = center == null ? null : new Lazy<MiraVent>(() => data.Vents[center.Value]);
|
||||
_right = right == null ? null : new Lazy<MiraVent>(() => data.Vents[right.Value]);
|
||||
}
|
||||
|
||||
public enum Ids
|
||||
{
|
||||
Balcony = 1,
|
||||
Cafeteria = 2,
|
||||
Reactor = 3,
|
||||
Laboratory = 4,
|
||||
Office = 5,
|
||||
Admin = 6,
|
||||
Greenhouse = 7,
|
||||
Medbay = 8,
|
||||
Decontamination = 9,
|
||||
LockerRoom = 10,
|
||||
Launchpad = 11,
|
||||
}
|
||||
|
||||
public Ids Id { get; }
|
||||
|
||||
int IVent.Id => (int)Id;
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public Vector2 Position { get; }
|
||||
|
||||
public MiraVent? Left => _left?.Value;
|
||||
|
||||
IVent? IVent.Left => Left;
|
||||
|
||||
public MiraVent? Center => _center?.Value;
|
||||
|
||||
IVent? IVent.Center => Center;
|
||||
|
||||
public MiraVent? Right => _right?.Value;
|
||||
|
||||
IVent? IVent.Right => Right;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Impostor.Api.Innersloth.Maps.Vents
|
||||
{
|
||||
public class PolusVent : IVent
|
||||
{
|
||||
private readonly Lazy<PolusVent>? _left;
|
||||
|
||||
private readonly Lazy<PolusVent>? _center;
|
||||
|
||||
private readonly Lazy<PolusVent>? _right;
|
||||
|
||||
internal PolusVent(PolusData data, Ids id, Vector2 position, Ids? left = null, Ids? center = null, Ids? right = null)
|
||||
{
|
||||
Id = id;
|
||||
Name = id.ToString();
|
||||
Position = position;
|
||||
|
||||
_left = left == null ? null : new Lazy<PolusVent>(() => data.Vents[left.Value]);
|
||||
_center = center == null ? null : new Lazy<PolusVent>(() => data.Vents[center.Value]);
|
||||
_right = right == null ? null : new Lazy<PolusVent>(() => data.Vents[right.Value]);
|
||||
}
|
||||
|
||||
public enum Ids
|
||||
{
|
||||
Security = 0,
|
||||
Electrical = 1,
|
||||
O2 = 2,
|
||||
Communications = 3,
|
||||
Office = 4,
|
||||
Admin = 5,
|
||||
Laboratory = 6,
|
||||
Lava = 7,
|
||||
Storage = 8,
|
||||
RightStabilizer = 9,
|
||||
LeftStabilizer = 10,
|
||||
OutsideAdmin = 11,
|
||||
}
|
||||
|
||||
public Ids Id { get; }
|
||||
|
||||
int IVent.Id => (int)Id;
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public Vector2 Position { get; }
|
||||
|
||||
public PolusVent? Left => _left?.Value;
|
||||
|
||||
IVent? IVent.Left => Left;
|
||||
|
||||
public PolusVent? Center => _center?.Value;
|
||||
|
||||
IVent? IVent.Center => Center;
|
||||
|
||||
public PolusVent? Right => _right?.Value;
|
||||
|
||||
IVent? IVent.Right => Right;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Impostor.Api.Innersloth.Maps.Vents
|
||||
{
|
||||
public class SkeldVent : IVent
|
||||
{
|
||||
private readonly Lazy<SkeldVent>? _left;
|
||||
|
||||
private readonly Lazy<SkeldVent>? _center;
|
||||
|
||||
private readonly Lazy<SkeldVent>? _right;
|
||||
|
||||
internal SkeldVent(SkeldData data, Ids id, Vector2 position, Ids? left = null, Ids? center = null, Ids? right = null)
|
||||
{
|
||||
Id = id;
|
||||
Name = id.ToString();
|
||||
Position = position;
|
||||
|
||||
_left = left == null ? null : new Lazy<SkeldVent>(() => data.Vents[left.Value]);
|
||||
_center = center == null ? null : new Lazy<SkeldVent>(() => data.Vents[center.Value]);
|
||||
_right = right == null ? null : new Lazy<SkeldVent>(() => data.Vents[right.Value]);
|
||||
}
|
||||
|
||||
public enum Ids
|
||||
{
|
||||
Admin = 0,
|
||||
RightHallway = 1,
|
||||
Cafeteria = 2,
|
||||
Electrical = 3,
|
||||
UpperEngine = 4,
|
||||
Security = 5,
|
||||
Medbay = 6,
|
||||
Weapons = 7,
|
||||
LowerReactor = 8,
|
||||
LowerEngine = 9,
|
||||
Shields = 10,
|
||||
UpperReactor = 11,
|
||||
UpperNavigation = 12,
|
||||
LowerNavigation = 13,
|
||||
}
|
||||
|
||||
public Ids Id { get; }
|
||||
|
||||
int IVent.Id => (int)Id;
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public Vector2 Position { get; }
|
||||
|
||||
public SkeldVent? Left => _left?.Value;
|
||||
|
||||
IVent? IVent.Left => Left;
|
||||
|
||||
public SkeldVent? Center => _center?.Value;
|
||||
|
||||
IVent? IVent.Center => Center;
|
||||
|
||||
public SkeldVent? Right => _right?.Value;
|
||||
|
||||
IVent? IVent.Right => Right;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace Impostor.Api.Innersloth
|
||||
{
|
||||
public enum Platforms
|
||||
{
|
||||
Unknown = 0,
|
||||
StandaloneEpicPC = 1,
|
||||
StandaloneSteamPC = 2,
|
||||
StandaloneMac = 3,
|
||||
StandaloneWin10 = 4,
|
||||
StandaloneItch = 5,
|
||||
IPhone = 6,
|
||||
Android = 7,
|
||||
Switch = 8,
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
namespace Impostor.Api.Innersloth
|
||||
{
|
||||
public enum ChatType
|
||||
public enum QuickChatModes
|
||||
{
|
||||
FreeChatOrQuickChat = 1,
|
||||
QuickChatOnly = 2,
|
||||
@@ -67,5 +67,39 @@
|
||||
Specimens = 28,
|
||||
|
||||
BoilerRoom = 29,
|
||||
|
||||
VaultRoom = 30,
|
||||
|
||||
Cockpit = 31,
|
||||
|
||||
Armory = 32,
|
||||
|
||||
Kitchen = 33,
|
||||
|
||||
ViewingDeck = 34,
|
||||
|
||||
HallOfPortraits = 35,
|
||||
|
||||
CargoBay = 36,
|
||||
|
||||
Ventilation = 37,
|
||||
|
||||
Showers = 38,
|
||||
|
||||
Engine = 39,
|
||||
|
||||
Brig = 40,
|
||||
|
||||
MeetingRoom = 41,
|
||||
|
||||
Records = 42,
|
||||
|
||||
Lounge = 43,
|
||||
|
||||
GapRoom = 44,
|
||||
|
||||
MainHall = 45,
|
||||
|
||||
Medical = 46,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Impostor.Api.Innersloth
|
||||
{
|
||||
public enum TaskCategories : byte
|
||||
{
|
||||
CommonTask,
|
||||
LongTask,
|
||||
ShortTask,
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Impostor.Api.Innersloth
|
||||
namespace Impostor.Api.Innersloth
|
||||
{
|
||||
public enum TaskTypes : uint
|
||||
{
|
||||
@@ -45,5 +45,22 @@
|
||||
AlignTelescope = 40,
|
||||
RecordTemperature = 41,
|
||||
RebootWifi = 42,
|
||||
PolishRuby = 43,
|
||||
ResetBreakers = 44,
|
||||
Decontaminate = 45,
|
||||
MakeBurger = 46,
|
||||
UnlockSafe = 47,
|
||||
SortRecords = 48,
|
||||
PutAwayPistols = 49,
|
||||
FixShower = 50,
|
||||
CleanToilet = 51,
|
||||
DressMannequin = 52,
|
||||
PickUpTowels = 53,
|
||||
RewindTapes = 54,
|
||||
StartFans = 55,
|
||||
DevelopPhotos = 56,
|
||||
GetBiggolSword = 57,
|
||||
PutAwayRifles = 58,
|
||||
StopCharles = 59,
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
namespace Impostor.Api.Innersloth
|
||||
{
|
||||
public enum VentLocation : uint
|
||||
{
|
||||
// Skeld
|
||||
SkeldAdmin = 0,
|
||||
SkeldRightHallway = 1,
|
||||
SkeldCafeteria = 2,
|
||||
SkeldElectrical = 3,
|
||||
SkeldUpperEngine = 4,
|
||||
SkeldSecurity = 5,
|
||||
SkeldMedbay = 6,
|
||||
SkeldWeapons = 7,
|
||||
SkeldLowerReactor = 8,
|
||||
SkeldLowerEngine = 9,
|
||||
SkeldShields = 10,
|
||||
SkeldUpperReactor = 11,
|
||||
SkeldUpperNavigation = 12,
|
||||
SkeldLowerNavigation = 13,
|
||||
|
||||
// Mira HQ
|
||||
MiraBalcony = 1,
|
||||
MiraCafeteria = 2,
|
||||
MiraReactor = 3,
|
||||
MiraLaboratory = 4,
|
||||
MiraOffice = 5,
|
||||
MiraAdmin = 6,
|
||||
MiraGreenhouse = 7,
|
||||
MiraMedbay = 8,
|
||||
MiraDecontamination = 9,
|
||||
MiraLockerRoom = 10,
|
||||
MiraLaunchpad = 11,
|
||||
|
||||
// Polus
|
||||
PolusSecurity = 0,
|
||||
PolusElectrical = 1,
|
||||
PolusO2 = 2,
|
||||
PolusCommunications = 3,
|
||||
PolusOffice = 4,
|
||||
PolusAdmin = 5,
|
||||
PolusLaboratory = 6,
|
||||
PolusLava = 7,
|
||||
PolusStorage = 8,
|
||||
PolusRightStabilizer = 9,
|
||||
PolusLeftStabilizer = 10,
|
||||
PolusOutsideAdmin = 11,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Impostor.Api.Net.Custom
|
||||
{
|
||||
public interface ICustomMessage
|
||||
{
|
||||
byte Id { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Impostor.Api.Net.Custom
|
||||
{
|
||||
public interface ICustomMessageManager<T>
|
||||
where T : ICustomMessage
|
||||
{
|
||||
bool TryGet(byte id, [MaybeNullWhen(false)] out T message);
|
||||
|
||||
/// <summary>
|
||||
/// Register a custom message.
|
||||
/// </summary>
|
||||
/// <param name="message"><typeparamref name="T"/> message.</param>
|
||||
/// <returns>Disposable that unregisters the message.</returns>
|
||||
IDisposable Register(T message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using System.Threading.Tasks;
|
||||
using Impostor.Api.Net.Messages;
|
||||
|
||||
namespace Impostor.Api.Net.Custom
|
||||
{
|
||||
public interface ICustomRootMessage : ICustomMessage
|
||||
{
|
||||
ValueTask HandleMessageAsync(IClient client, IMessageReader reader, MessageType messageType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System.Threading.Tasks;
|
||||
using Impostor.Api.Net.Inner;
|
||||
using Impostor.Api.Net.Messages;
|
||||
|
||||
namespace Impostor.Api.Net.Custom
|
||||
{
|
||||
public interface ICustomRpc : ICustomMessage
|
||||
{
|
||||
ValueTask<bool> HandleRpcAsync(IInnerNetObject innerNetObject, IClientPlayer sender, IClientPlayer? target, IMessageReader reader);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Threading.Tasks;
|
||||
using Impostor.Api.Innersloth;
|
||||
using Impostor.Api.Net.Messages;
|
||||
using Impostor.Api.Reactor;
|
||||
|
||||
namespace Impostor.Api.Net
|
||||
{
|
||||
@@ -28,11 +27,6 @@ namespace Impostor.Api.Net
|
||||
/// </remarks>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets mods sent by client in modded handshake.
|
||||
/// </summary>
|
||||
ISet<Mod> Mods { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the connection of the client.
|
||||
/// </summary>
|
||||
|
||||
@@ -24,6 +24,11 @@ namespace Impostor.Api.Net
|
||||
/// </summary>
|
||||
IClient? Client { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the average ping of the client.
|
||||
/// </summary>
|
||||
float AveragePing { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Sends a message writer to the connection.
|
||||
/// </summary>
|
||||
@@ -35,7 +40,8 @@ namespace Impostor.Api.Net
|
||||
/// Disconnects the client and invokes the disconnect handler.
|
||||
/// </summary>
|
||||
/// <param name="reason">A reason.</param>
|
||||
/// <param name="writer">A message to send with disconnect packet.</param>
|
||||
/// <returns>Task that must be awaited.</returns>
|
||||
ValueTask DisconnectAsync(string? reason);
|
||||
ValueTask DisconnectAsync(string? reason, IMessageWriter? writer = null);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using Impostor.Api.Net.Inner.Objects;
|
||||
using Impostor.Api.Net.Inner.Objects.ShipStatus;
|
||||
|
||||
namespace Impostor.Api.Net.Inner
|
||||
{
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
namespace Impostor.Api.Net.Inner
|
||||
using Impostor.Api.Games;
|
||||
|
||||
namespace Impostor.Api.Net.Inner
|
||||
{
|
||||
public interface IInnerNetObject
|
||||
{
|
||||
public uint NetId { get; }
|
||||
|
||||
public int OwnerId { get; }
|
||||
|
||||
public IGame Game { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,59 @@
|
||||
namespace Impostor.Api.Net.Inner.Objects
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Impostor.Api.Events.Player;
|
||||
|
||||
namespace Impostor.Api.Net.Inner.Objects
|
||||
{
|
||||
public interface IInnerMeetingHud : IInnerNetObject
|
||||
{
|
||||
public interface IPlayerVoteArea
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the player info of this vote state.
|
||||
/// </summary>
|
||||
IInnerPlayerInfo TargetPlayer { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the player is a dead.
|
||||
/// </summary>
|
||||
bool IsDead { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the player started this meeting.
|
||||
/// </summary>
|
||||
bool DidReport { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the player voted.
|
||||
/// </summary>
|
||||
bool DidVote { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the vote type.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Null when <see cref="DidVote" /> is false.
|
||||
/// </remarks>
|
||||
[MemberNotNullWhen(true, nameof(DidVote))]
|
||||
public VoteType? VoteType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the player voted for.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Null when <see cref="VoteType" /> isn't <see cref="F:Impostor.Api.Events.Player.VoteType.Player"/>.
|
||||
/// </remarks>
|
||||
public IInnerPlayerControl? VotedFor { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets states of players taking part in this meeting.
|
||||
/// </summary>
|
||||
IReadOnlyCollection<IPlayerVoteArea> PlayerStates { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the player that started the meeting.
|
||||
/// </summary>
|
||||
IInnerPlayerInfo? Reporter { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using Impostor.Api.Innersloth;
|
||||
using System.Threading.Tasks;
|
||||
using Impostor.Api.Innersloth;
|
||||
|
||||
namespace Impostor.Api.Net.Inner.Objects
|
||||
{
|
||||
@@ -6,8 +7,14 @@ namespace Impostor.Api.Net.Inner.Objects
|
||||
{
|
||||
uint Id { get; }
|
||||
|
||||
TaskTypes Type { get; }
|
||||
ITask Task { get; }
|
||||
|
||||
bool Complete { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the task as complete.
|
||||
/// </summary>
|
||||
/// <returns>Task that must be awaited.</returns>
|
||||
ValueTask CompleteAsync();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Impostor.Api.Net.Inner.Objects.ShipStatus
|
||||
{
|
||||
public interface IInnerAirshipStatus : IInnerShipStatus
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Impostor.Api.Net.Inner.Objects.ShipStatus
|
||||
{
|
||||
public interface IInnerMiraShipStatus : IInnerShipStatus
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Impostor.Api.Net.Inner.Objects.ShipStatus
|
||||
{
|
||||
public interface IInnerPolusShipStatus : IInnerShipStatus
|
||||
{
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
namespace Impostor.Api.Net.Inner.Objects
|
||||
namespace Impostor.Api.Net.Inner.Objects.ShipStatus
|
||||
{
|
||||
public interface IInnerShipStatus : IInnerNetObject
|
||||
{
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Impostor.Api.Net.Inner.Objects.ShipStatus
|
||||
{
|
||||
public interface IInnerSkeldShipStatus : IInnerShipStatus
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Impostor.Server.Net.Inner
|
||||
namespace Impostor.Api.Net.Inner
|
||||
{
|
||||
public enum RpcCalls : byte
|
||||
{
|
||||
@@ -32,7 +32,7 @@
|
||||
CloseDoorsOfType = 27,
|
||||
RepairSystem = 28,
|
||||
SetTasks = 29,
|
||||
UpdateGameData = 30,
|
||||
CustomRpc = byte.MaxValue,
|
||||
ClimbLadder = 31,
|
||||
UsePlatform = 32,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace Impostor.Api.Net.Messages.Auth
|
||||
{
|
||||
public static class Message01Complete
|
||||
{
|
||||
public static void Serialize(IMessageWriter writer, uint nonce)
|
||||
{
|
||||
writer.WritePacked(nonce);
|
||||
}
|
||||
|
||||
public static void Deserialize(IMessageReader reader, out uint nonce)
|
||||
{
|
||||
nonce = reader.ReadUInt32();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using Impostor.Api.Innersloth;
|
||||
|
||||
namespace Impostor.Api.Net.Messages.Auth
|
||||
{
|
||||
public static class MessageHandshake
|
||||
{
|
||||
public static void Deserialize(IMessageReader reader, out int clientVersion, out Platforms platform, out string clientId)
|
||||
{
|
||||
clientVersion = reader.ReadInt32();
|
||||
platform = (Platforms)reader.ReadByte();
|
||||
clientId = reader.ReadString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace Impostor.Api.Net.Messages.C2S
|
||||
{
|
||||
public static class HandshakeC2S
|
||||
{
|
||||
public static void Deserialize(IMessageReader reader, out int clientVersion, out string name, out uint lastNonceReceived)
|
||||
{
|
||||
clientVersion = reader.ReadInt32();
|
||||
name = reader.ReadString();
|
||||
lastNonceReceived = reader.ReadUInt32();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,12 +15,12 @@ namespace Impostor.Api.Net.Messages.C2S
|
||||
/// Deserialize a packet.
|
||||
/// </summary>
|
||||
/// <param name="reader"><see cref="IMessageReader" /> with <see cref="IMessageReader.Tag" /> 0.</param>
|
||||
/// <param name="chatType">The chat type selected in the client of the player.</param>
|
||||
/// <param name="chatMode">The chat type selected in the client of the player.</param>
|
||||
/// <returns>Deserialized <see cref="GameOptionsData" />.</returns>
|
||||
public static GameOptionsData Deserialize(IMessageReader reader, out ChatType chatType)
|
||||
public static GameOptionsData Deserialize(IMessageReader reader, out QuickChatModes chatMode)
|
||||
{
|
||||
var gameOptionsData = GameOptionsData.DeserializeCreate(reader);
|
||||
chatType = (ChatType)reader.ReadByte();
|
||||
chatMode = (QuickChatModes)reader.ReadByte();
|
||||
|
||||
return gameOptionsData;
|
||||
}
|
||||
|
||||
@@ -10,11 +10,11 @@ namespace Impostor.Api.Net.Messages.C2S
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public static void Deserialize(IMessageReader reader, out GameOptionsData options, out ChatType chatType)
|
||||
public static void Deserialize(IMessageReader reader, out GameOptionsData options, out QuickChatModes chatMode)
|
||||
{
|
||||
reader.ReadPackedInt32(); // Hardcoded 0.
|
||||
options = GameOptionsData.DeserializeCreate(reader);
|
||||
chatType = (ChatType)reader.ReadByte();
|
||||
chatMode = (QuickChatModes)reader.ReadByte();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,13 @@ namespace Impostor.Api.Net.Messages
|
||||
|
||||
public MessageType SendOption { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Copies the contents of this writer into a new array.
|
||||
/// </summary>
|
||||
/// <param name="includeHeader">Whether to include message header in the array.</param>
|
||||
/// <returns>An array containing the data in the current writer.</returns>
|
||||
byte[] ToByteArray(bool includeHeader);
|
||||
|
||||
/// <summary>
|
||||
/// Writes a boolean to the message.
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace Impostor.Api.Net.Messages.Rpcs
|
||||
{
|
||||
public static class Rpc31ClimbLadder
|
||||
{
|
||||
public static void Serialize(IMessageWriter writer, byte ladderId, byte lastClimbLadderSid)
|
||||
{
|
||||
writer.Write(ladderId);
|
||||
writer.Write(lastClimbLadderSid);
|
||||
}
|
||||
|
||||
public static void Deserialize(IMessageReader reader, out byte ladderId, out byte lastClimbLadderSid)
|
||||
{
|
||||
ladderId = reader.ReadByte();
|
||||
lastClimbLadderSid = reader.ReadByte();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace Impostor.Api.Net.Messages.Rpcs
|
||||
{
|
||||
public static class Rpc32UsePlatform
|
||||
{
|
||||
public static void Serialize(IMessageWriter writer)
|
||||
{
|
||||
}
|
||||
|
||||
public static void Deserialize(IMessageReader reader)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using Impostor.Api.Innersloth;
|
||||
|
||||
namespace Impostor.Api.Net.Messages.S2C
|
||||
{
|
||||
public class MessageDisconnect
|
||||
{
|
||||
public static void Serialize(IMessageWriter writer, bool hasReason, DisconnectReason? reason, string? message)
|
||||
{
|
||||
writer.Write(hasReason);
|
||||
|
||||
if (hasReason)
|
||||
{
|
||||
if (reason == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(reason));
|
||||
}
|
||||
|
||||
writer.StartMessage(0);
|
||||
writer.Write((byte)reason);
|
||||
|
||||
if (reason == DisconnectReason.Custom)
|
||||
{
|
||||
if (message == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(message));
|
||||
}
|
||||
|
||||
writer.Write(message);
|
||||
}
|
||||
|
||||
writer.EndMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Deserialize(IMessageReader reader, out bool hasReason, out DisconnectReason? reason, out string? message)
|
||||
{
|
||||
hasReason = reader.ReadBoolean();
|
||||
|
||||
if (hasReason)
|
||||
{
|
||||
var inner = reader.ReadMessage();
|
||||
reason = (DisconnectReason)inner.ReadByte();
|
||||
message = reason == DisconnectReason.Custom ? inner.ReadString() : null;
|
||||
}
|
||||
else
|
||||
{
|
||||
reason = null;
|
||||
message = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Impostor.Api.Plugins
|
||||
{
|
||||
public enum DependencyType
|
||||
{
|
||||
HardDependency,
|
||||
SoftDependency,
|
||||
LoadBefore,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
|
||||
namespace Impostor.Api.Plugins
|
||||
{
|
||||
public interface IPluginInformation
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the unique id of this plugin.
|
||||
/// </summary>
|
||||
string Id { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the human readable name of this plugin.
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the author of this plugin.
|
||||
/// </summary>
|
||||
string Author { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the version of this plugin.
|
||||
/// </summary>
|
||||
string Version { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the optional startup object of this plugin.
|
||||
/// </summary>
|
||||
IPluginStartup? Startup { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instance of this plugin.
|
||||
/// </summary>
|
||||
IPlugin? Instance { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instance type of this plugin.
|
||||
/// </summary>
|
||||
Type PluginType { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Impostor.Api.Plugins
|
||||
{
|
||||
public interface IPluginManager
|
||||
{
|
||||
IReadOnlyList<IPluginInformation> Plugins { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
|
||||
namespace Impostor.Api.Plugins
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
|
||||
public class ImpostorDependencyAttribute : Attribute
|
||||
{
|
||||
public ImpostorDependencyAttribute(string id, DependencyType type)
|
||||
{
|
||||
Id = id;
|
||||
DependencyType = type;
|
||||
}
|
||||
|
||||
public string Id { get; }
|
||||
|
||||
public DependencyType DependencyType { get; }
|
||||
}
|
||||
}
|
||||
@@ -5,20 +5,26 @@ namespace Impostor.Api.Plugins
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class ImpostorPluginAttribute : Attribute
|
||||
{
|
||||
public ImpostorPluginAttribute(string package, string name, string author, string version)
|
||||
public ImpostorPluginAttribute(string id)
|
||||
{
|
||||
Package = package;
|
||||
Id = id;
|
||||
}
|
||||
|
||||
[Obsolete("Use (string id) constructor to avoid redundancy")]
|
||||
public ImpostorPluginAttribute(string id, string name, string author, string version)
|
||||
{
|
||||
Id = id;
|
||||
Name = name;
|
||||
Author = author;
|
||||
Version = version;
|
||||
}
|
||||
|
||||
public string Package { get; }
|
||||
public string Id { get; }
|
||||
|
||||
public string Name { get; }
|
||||
public string? Name { get; }
|
||||
|
||||
public string Author { get; }
|
||||
public string? Author { get; }
|
||||
|
||||
public string Version { get; }
|
||||
public string? Version { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
namespace Impostor.Api.Reactor
|
||||
{
|
||||
public readonly struct Mod
|
||||
{
|
||||
public readonly string Id;
|
||||
public readonly string Version;
|
||||
public readonly PluginSide Side;
|
||||
|
||||
public Mod(string id, string version, PluginSide side)
|
||||
{
|
||||
Id = id;
|
||||
Version = version;
|
||||
Side = side;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Id} ({Version})";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Impostor.Api.Net.Messages;
|
||||
|
||||
namespace Impostor.Api.Reactor
|
||||
{
|
||||
public static class ModList
|
||||
{
|
||||
public static void Deserialize(IMessageReader reader, out ISet<Mod> mods)
|
||||
{
|
||||
var length = reader.ReadPackedInt32();
|
||||
|
||||
mods = new HashSet<Mod>(length);
|
||||
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
var id = reader.ReadString();
|
||||
var version = reader.ReadString();
|
||||
var pluginSide = (PluginSide)reader.ReadByte();
|
||||
|
||||
mods.Add(new Mod(id, version, pluginSide));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Impostor.Api.Net.Messages;
|
||||
|
||||
namespace Impostor.Api.Reactor
|
||||
{
|
||||
public static class ModdedHandshakeC2S
|
||||
{
|
||||
public static void Deserialize(IMessageReader reader, out int clientVersion, out string name, out ISet<Mod>? mods)
|
||||
{
|
||||
clientVersion = reader.ReadInt32();
|
||||
name = reader.ReadString();
|
||||
|
||||
if (reader.Length > reader.Position)
|
||||
{
|
||||
ModList.Deserialize(reader, out mods);
|
||||
}
|
||||
else
|
||||
{
|
||||
mods = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
using Impostor.Api.Net.Messages;
|
||||
|
||||
namespace Impostor.Api.Reactor
|
||||
{
|
||||
public static class ModdedHandshakeS2C
|
||||
{
|
||||
public static void Serialize(IMessageWriter writer, string serverBrand)
|
||||
{
|
||||
writer.StartMessage(byte.MaxValue);
|
||||
writer.Write(serverBrand);
|
||||
writer.EndMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
namespace Impostor.Api.Reactor
|
||||
{
|
||||
/// <summary>
|
||||
/// Plugin side used in modded handshake.
|
||||
/// </summary>
|
||||
public enum PluginSide : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// Required by both sides, reject connection if missing on the other side
|
||||
/// </summary>
|
||||
Both,
|
||||
|
||||
/// <summary>
|
||||
/// Required only by client
|
||||
/// </summary>
|
||||
ClientOnly,
|
||||
|
||||
/// <summary>
|
||||
/// Required only by server
|
||||
/// </summary>
|
||||
ServerOnly,
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Impostor.Api
|
||||
namespace Impostor.Api.Utils
|
||||
{
|
||||
public interface IDateTimeProvider
|
||||
{
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Impostor.Api.Utils
|
||||
{
|
||||
public interface IServerEnvironment
|
||||
{
|
||||
string Version { get; }
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Impostor.Api\Impostor.Api.csproj" />
|
||||
<ProjectReference Include="..\Impostor.Hazel\Impostor.Hazel.csproj" />
|
||||
<ProjectReference Include="..\Impostor.Hazel\Hazel\Hazel.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Submodule
+1
Submodule src/Impostor.Hazel added at 8de027461e.
@@ -1,249 +0,0 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Impostor.Api.Net.Messages;
|
||||
using Serilog;
|
||||
|
||||
namespace Impostor.Hazel
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for all connections.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Connection is the base class for all connections that Hazel can make. It provides common functionality and a
|
||||
/// standard interface to allow connections to be swapped easily.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Any class inheriting from Connection should provide the 3 standard guarantees that Hazel provides:
|
||||
/// <list type="bullet">
|
||||
/// <item>
|
||||
/// <description>Thread Safe</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>Connection Orientated</description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <description>Packet/Message Based</description>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <threadsafety static="true" instance="true"/>
|
||||
public abstract class Connection : IDisposable
|
||||
{
|
||||
private static readonly ILogger Logger = Log.ForContext<Connection>();
|
||||
|
||||
/// <summary>
|
||||
/// Called when a message has been received.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// DataReceived is invoked everytime a message is received from the end point of this connection, the message
|
||||
/// that was received can be found in the <see cref="DataReceivedEventArgs"/> alongside other information from the
|
||||
/// event.
|
||||
/// </para>
|
||||
/// <include file="DocInclude/common.xml" path="docs/item[@name='Event_Thread_Safety_Warning']/*" />
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code language="C#" source="DocInclude/TcpClientExample.cs"/>
|
||||
/// </example>
|
||||
public Func<DataReceivedEventArgs, ValueTask> DataReceived;
|
||||
|
||||
public int TestLagMs = -1;
|
||||
public int TestDropRate = 0;
|
||||
protected int testDropCount = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Called when the end point disconnects or an error occurs.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Disconnected is invoked when the connection is closed due to an exception occuring or because the remote
|
||||
/// end point disconnected. If it was invoked due to an exception occuring then the exception is available
|
||||
/// in the <see cref="DisconnectedEventArgs"/> passed with the event.
|
||||
/// </para>
|
||||
/// <include file="DocInclude/common.xml" path="docs/item[@name='Event_Thread_Safety_Warning']/*" />
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code language="C#" source="DocInclude/TcpClientExample.cs"/>
|
||||
/// </example>
|
||||
public Func<DisconnectedEventArgs, ValueTask> Disconnected;
|
||||
|
||||
/// <summary>
|
||||
/// The remote end point of this Connection.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is the end point that this connection is connected to (i.e. the other device). This returns an abstract
|
||||
/// <see cref="ConnectionEndPoint"/> which can then be cast to an appropriate end point depending on the
|
||||
/// connection type.
|
||||
/// </remarks>
|
||||
public IPEndPoint EndPoint { get; protected set; }
|
||||
|
||||
public IPMode IPMode { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// The traffic statistics about this Connection.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Contains statistics about the number of messages and bytes sent and received by this connection.
|
||||
/// </remarks>
|
||||
public ConnectionStatistics Statistics { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// The state of this connection.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// All implementers should be aware that when this is set to ConnectionState.Connected it will
|
||||
/// release all threads that are blocked on <see cref="WaitOnConnect"/>.
|
||||
/// </remarks>
|
||||
public ConnectionState State
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._state;
|
||||
}
|
||||
|
||||
protected set
|
||||
{
|
||||
this._state = value;
|
||||
this.SetState(value);
|
||||
}
|
||||
}
|
||||
|
||||
protected ConnectionState _state;
|
||||
protected virtual void SetState(ConnectionState state) { }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor that initializes the ConnecitonStatistics object.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This constructor initialises <see cref="Statistics"/> with empty statistics and sets <see cref="State"/> to
|
||||
/// <see cref="ConnectionState.NotConnected"/>.
|
||||
/// </remarks>
|
||||
protected Connection()
|
||||
{
|
||||
this.Statistics = new ConnectionStatistics();
|
||||
this.State = ConnectionState.NotConnected;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a number of bytes to the end point of the connection using the specified <see cref="MessageType"/>.
|
||||
/// </summary>
|
||||
/// <param name="msg">The message to send.</param>
|
||||
/// <remarks>
|
||||
/// <include file="DocInclude/common.xml" path="docs/item[@name='Connection_SendBytes_General']/*" />
|
||||
/// <para>
|
||||
/// The messageType parameter is only a request to use those options and the actual method used to send the
|
||||
/// data is up to the implementation. There are circumstances where this parameter may be ignored but in
|
||||
/// general any implementer should aim to always follow the user's request.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public abstract ValueTask SendAsync(IMessageWriter msg);
|
||||
|
||||
/// <summary>
|
||||
/// Sends a number of bytes to the end point of the connection using the specified <see cref="MessageType"/>.
|
||||
/// </summary>
|
||||
/// <param name="bytes">The bytes of the message to send.</param>
|
||||
/// <param name="messageType">The option specifying how the message should be sent.</param>
|
||||
/// <remarks>
|
||||
/// <include file="DocInclude/common.xml" path="docs/item[@name='Connection_SendBytes_General']/*" />
|
||||
/// <para>
|
||||
/// The messageType parameter is only a request to use those options and the actual method used to send the
|
||||
/// data is up to the implementation. There are circumstances where this parameter may be ignored but in
|
||||
/// general any implementer should aim to always follow the user's request.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public abstract ValueTask SendBytes(byte[] bytes, MessageType messageType = MessageType.Unreliable);
|
||||
|
||||
/// <summary>
|
||||
/// Connects the connection to a server and begins listening.
|
||||
/// This method does not block.
|
||||
/// </summary>
|
||||
/// <param name="bytes">The bytes of data to send in the handshake.</param>
|
||||
public abstract ValueTask ConnectAsync(byte[] bytes = null);
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the DataReceived event.
|
||||
/// </summary>
|
||||
/// <param name="msg">The bytes received.</param>
|
||||
/// <param name="messageType">The <see cref="MessageType"/> the message was received with.</param>
|
||||
/// <remarks>
|
||||
/// Invokes the <see cref="DataReceived"/> event on this connection to alert subscribers a new message has been
|
||||
/// received. The bytes and the send option that the message was sent with should be passed in to give to the
|
||||
/// subscribers.
|
||||
/// </remarks>
|
||||
protected async ValueTask InvokeDataReceived(IMessageReader msg, MessageType messageType)
|
||||
{
|
||||
// Make a copy to avoid race condition between null check and invocation
|
||||
var handler = DataReceived;
|
||||
if (handler != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
await handler(new DataReceivedEventArgs(this, msg, messageType));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error(e, "Invoking data received failed");
|
||||
await Disconnect("Invoking data received failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the Disconnected event.
|
||||
/// </summary>
|
||||
/// <param name="e">The exception, if any, that occurred to cause this.</param>
|
||||
/// <param name="reader">Extra disconnect data</param>
|
||||
/// <remarks>
|
||||
/// Invokes the <see cref="Disconnected"/> event to alert subscribres this connection has been disconnected either
|
||||
/// by the end point or because an error occurred. If an error occurred the error should be passed in in order to
|
||||
/// pass to the subscribers, otherwise null can be passed in.
|
||||
/// </remarks>
|
||||
protected async ValueTask InvokeDisconnected(string e, IMessageReader reader)
|
||||
{
|
||||
// Make a copy to avoid race condition between null check and invocation
|
||||
var handler = Disconnected;
|
||||
if (handler != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
await handler(new DisconnectedEventArgs(e, reader));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error(ex, "Error in InvokeDisconnected");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For times when you want to force the disconnect handler to fire as well as close it.
|
||||
/// If you only want to close it, just use Dispose.
|
||||
/// </summary>
|
||||
public abstract ValueTask Disconnect(string reason, MessageWriter writer = null);
|
||||
|
||||
/// <summary>
|
||||
/// Disposes of this NetworkConnection.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes of this NetworkConnection.
|
||||
/// </summary>
|
||||
/// <param name="disposing">Are we currently disposing?</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
this.DataReceived = null;
|
||||
this.Disconnected = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Impostor.Api.Net.Messages;
|
||||
using Serilog;
|
||||
|
||||
namespace Impostor.Hazel
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for all connection listeners.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// ConnectionListeners are server side objects that listen for clients and create matching server side connections
|
||||
/// for each client in a similar way to TCP does. These connections should be ready for communication immediately.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Each time a client connects the <see cref="NewConnection"/> event will be invoked to alert all subscribers to
|
||||
/// the new connection. A disconnected event is then present on the <see cref="Connection"/> that is passed to the
|
||||
/// subscribers.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <threadsafety static="true" instance="true"/>
|
||||
public abstract class ConnectionListener : IAsyncDisposable
|
||||
{
|
||||
private static readonly ILogger Logger = Log.ForContext<ConnectionListener>();
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when a new client connects.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// NewConnection is invoked each time a client connects to the listener. The
|
||||
/// <see cref="NewConnectionEventArgs"/> contains the new <see cref="Connection"/> for communication with this
|
||||
/// client.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Hazel may or may not store connections so it is your responsibility to keep track and properly Dispose of
|
||||
/// connections to your server.
|
||||
/// </para>
|
||||
/// <include file="DocInclude/common.xml" path="docs/item[@name='Event_Thread_Safety_Warning']/*" />
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code language="C#" source="DocInclude/TcpListenerExample.cs"/>
|
||||
/// </example>
|
||||
public Func<NewConnectionEventArgs, ValueTask> NewConnection;
|
||||
|
||||
/// <summary>
|
||||
/// Makes this connection listener begin listening for connections.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This instructs the listener to begin listening for new clients connecting to the server. When a new client
|
||||
/// connects the <see cref="NewConnection"/> event will be invoked containing the connection to the new client.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// To stop listening you should call <see cref="DisposeAsync()"/>.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <example>
|
||||
/// <code language="C#" source="DocInclude/TcpListenerExample.cs"/>
|
||||
/// </example>
|
||||
public abstract Task StartAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the NewConnection event with the supplied connection.
|
||||
/// </summary>
|
||||
/// <param name="msg">The user sent bytes that were received as part of the handshake.</param>
|
||||
/// <param name="connection">The connection to pass in the arguments.</param>
|
||||
/// <remarks>
|
||||
/// Implementers should call this to invoke the <see cref="NewConnection"/> event before data is received so that
|
||||
/// subscribers do not miss any data that may have been sent immediately after connecting.
|
||||
/// </remarks>
|
||||
internal async Task InvokeNewConnection(IMessageReader msg, Connection connection)
|
||||
{
|
||||
// Make a copy to avoid race condition between null check and invocation
|
||||
var handler = NewConnection;
|
||||
if (handler != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
await handler(new NewConnectionEventArgs(msg, connection));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error(e, "Accepting connection failed");
|
||||
await connection.Disconnect("Accepting connection failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call to dispose of the connection listener.
|
||||
/// </summary>
|
||||
public virtual ValueTask DisposeAsync()
|
||||
{
|
||||
this.NewConnection = null;
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
namespace Impostor.Hazel
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the state a <see cref="Connection"/> is currently in.
|
||||
/// </summary>
|
||||
public enum ConnectionState
|
||||
{
|
||||
/// <summary>
|
||||
/// The Connection has either not been established yet or has been disconnected.
|
||||
/// </summary>
|
||||
NotConnected,
|
||||
|
||||
/// <summary>
|
||||
/// The Connection is currently connecting to an endpoint.
|
||||
/// </summary>
|
||||
Connecting,
|
||||
|
||||
/// <summary>
|
||||
/// The Connection is connected and data can be transfered.
|
||||
/// </summary>
|
||||
Connected,
|
||||
}
|
||||
}
|
||||
@@ -1,566 +0,0 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
|
||||
[assembly: InternalsVisibleTo("Hazel.Tests")]
|
||||
namespace Impostor.Hazel
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds statistics about the traffic through a <see cref="Connection"/>.
|
||||
/// </summary>
|
||||
/// <threadsafety static="true" instance="true"/>
|
||||
public class ConnectionStatistics
|
||||
{
|
||||
private const int ExpectedMTU = 1200;
|
||||
|
||||
/// <summary>
|
||||
/// The total number of messages sent.
|
||||
/// </summary>
|
||||
public int MessagesSent
|
||||
{
|
||||
get
|
||||
{
|
||||
return UnreliableMessagesSent + ReliableMessagesSent + FragmentedMessagesSent + AcknowledgementMessagesSent + HelloMessagesSent;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of messages sent larger than 576 bytes. This is smaller than most default MTUs.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is the number of unreliable messages that were sent from the <see cref="Connection"/>, incremented
|
||||
/// each time that LogUnreliableSend is called by the Connection. Messages that caused an error are not
|
||||
/// counted and messages are only counted once all other operations in the send are complete.
|
||||
/// </remarks>
|
||||
public int FragmentableMessagesSent
|
||||
{
|
||||
get
|
||||
{
|
||||
return fragmentableMessagesSent;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of messages sent larger than 576 bytes.
|
||||
/// </summary>
|
||||
int fragmentableMessagesSent;
|
||||
|
||||
/// <summary>
|
||||
/// The number of unreliable messages sent.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is the number of unreliable messages that were sent from the <see cref="Connection"/>, incremented
|
||||
/// each time that LogUnreliableSend is called by the Connection. Messages that caused an error are not
|
||||
/// counted and messages are only counted once all other operations in the send are complete.
|
||||
/// </remarks>
|
||||
public int UnreliableMessagesSent
|
||||
{
|
||||
get
|
||||
{
|
||||
return unreliableMessagesSent;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of unreliable messages sent.
|
||||
/// </summary>
|
||||
int unreliableMessagesSent;
|
||||
|
||||
/// <summary>
|
||||
/// The number of reliable messages sent.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is the number of reliable messages that were sent from the <see cref="Connection"/>, incremented
|
||||
/// each time that LogReliableSend is called by the Connection. Messages that caused an error are not
|
||||
/// counted and messages are only counted once all other operations in the send are complete.
|
||||
/// </remarks>
|
||||
public int ReliableMessagesSent
|
||||
{
|
||||
get
|
||||
{
|
||||
return reliableMessagesSent;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of unreliable messages sent.
|
||||
/// </summary>
|
||||
int reliableMessagesSent;
|
||||
|
||||
/// <summary>
|
||||
/// The number of fragmented messages sent.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is the number of fragmented messages that were sent from the <see cref="Connection"/>, incremented
|
||||
/// each time that LogFragmentedSend is called by the Connection. Messages that caused an error are not
|
||||
/// counted and messages are only counted once all other operations in the send are complete.
|
||||
/// </remarks>
|
||||
public int FragmentedMessagesSent
|
||||
{
|
||||
get
|
||||
{
|
||||
return fragmentedMessagesSent;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of fragmented messages sent.
|
||||
/// </summary>
|
||||
int fragmentedMessagesSent;
|
||||
|
||||
/// <summary>
|
||||
/// The number of acknowledgement messages sent.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is the number of acknowledgements that were sent from the <see cref="Connection"/>, incremented
|
||||
/// each time that LogAcknowledgementSend is called by the Connection. Messages that caused an error are not
|
||||
/// counted and messages are only counted once all other operations in the send are complete.
|
||||
/// </remarks>
|
||||
public int AcknowledgementMessagesSent
|
||||
{
|
||||
get
|
||||
{
|
||||
return acknowledgementMessagesSent;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of acknowledgement messages sent.
|
||||
/// </summary>
|
||||
int acknowledgementMessagesSent;
|
||||
|
||||
/// <summary>
|
||||
/// The number of hello messages sent.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is the number of hello messages that were sent from the <see cref="Connection"/>, incremented
|
||||
/// each time that LogHelloSend is called by the Connection. Messages that caused an error are not
|
||||
/// counted and messages are only counted once all other operations in the send are complete.
|
||||
/// </remarks>
|
||||
public int HelloMessagesSent
|
||||
{
|
||||
get
|
||||
{
|
||||
return helloMessagesSent;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of hello messages sent.
|
||||
/// </summary>
|
||||
int helloMessagesSent;
|
||||
|
||||
/// <summary>
|
||||
/// The number of bytes of data sent.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This is the number of bytes of data (i.e. user bytes) that were sent from the <see cref="Connection"/>,
|
||||
/// accumulated each time that LogSend is called by the Connection. Messages that caused an error are not
|
||||
/// counted and messages are only counted once all other operations in the send are complete.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// For the number of bytes including protocol bytes see <see cref="TotalBytesSent"/>.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public long DataBytesSent
|
||||
{
|
||||
get
|
||||
{
|
||||
return Interlocked.Read(ref dataBytesSent);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of bytes of data sent.
|
||||
/// </summary>
|
||||
long dataBytesSent;
|
||||
|
||||
/// <summary>
|
||||
/// The number of bytes sent in total.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This is the total number of bytes (the data bytes plus protocol bytes) that were sent from the
|
||||
/// <see cref="Connection"/>, accumulated each time that LogSend is called by the Connection. Messages that
|
||||
/// caused an error are not counted and messages are only counted once all other operations in the send are
|
||||
/// complete.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// For the number of data bytes excluding protocol bytes see <see cref="DataBytesSent"/>.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public long TotalBytesSent
|
||||
{
|
||||
get
|
||||
{
|
||||
return Interlocked.Read(ref totalBytesSent);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of bytes sent in total.
|
||||
/// </summary>
|
||||
long totalBytesSent;
|
||||
|
||||
/// <summary>
|
||||
/// The total number of messages received.
|
||||
/// </summary>
|
||||
public int MessagesReceived
|
||||
{
|
||||
get
|
||||
{
|
||||
return UnreliableMessagesReceived + ReliableMessagesReceived + FragmentedMessagesReceived + AcknowledgementMessagesReceived + helloMessagesReceived;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of unreliable messages received.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is the number of unreliable messages that were received by the <see cref="Connection"/>, incremented
|
||||
/// each time that LogUnreliableReceive is called by the Connection. Messages are counted before the receive event is invoked.
|
||||
/// </remarks>
|
||||
public int UnreliableMessagesReceived
|
||||
{
|
||||
get
|
||||
{
|
||||
return unreliableMessagesReceived;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of unreliable messages received.
|
||||
/// </summary>
|
||||
int unreliableMessagesReceived;
|
||||
|
||||
/// <summary>
|
||||
/// The number of reliable messages received.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is the number of reliable messages that were received by the <see cref="Connection"/>, incremented
|
||||
/// each time that LogReliableReceive is called by the Connection. Messages are counted before the receive event is invoked.
|
||||
/// </remarks>
|
||||
public int ReliableMessagesReceived
|
||||
{
|
||||
get
|
||||
{
|
||||
return reliableMessagesReceived;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of reliable messages received.
|
||||
/// </summary>
|
||||
int reliableMessagesReceived;
|
||||
|
||||
/// <summary>
|
||||
/// The number of fragmented messages received.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is the number of fragmented messages that were received by the <see cref="Connection"/>, incremented
|
||||
/// each time that LogFragmentedReceive is called by the Connection. Messages are counted before the receive event is invoked.
|
||||
/// </remarks>
|
||||
public int FragmentedMessagesReceived
|
||||
{
|
||||
get
|
||||
{
|
||||
return fragmentedMessagesReceived;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of fragmented messages received.
|
||||
/// </summary>
|
||||
int fragmentedMessagesReceived;
|
||||
|
||||
/// <summary>
|
||||
/// The number of acknowledgement messages received.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is the number of acknowledgement messages that were received by the <see cref="Connection"/>, incremented
|
||||
/// each time that LogAcknowledgemntReceive is called by the Connection. Messages are counted before the receive event is invoked.
|
||||
/// </remarks>
|
||||
public int AcknowledgementMessagesReceived
|
||||
{
|
||||
get
|
||||
{
|
||||
return acknowledgementMessagesReceived;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of acknowledgement messages received.
|
||||
/// </summary>
|
||||
int acknowledgementMessagesReceived;
|
||||
|
||||
/// <summary>
|
||||
/// The number of ping messages received.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is the number of hello messages that were received by the <see cref="Connection"/>, incremented
|
||||
/// each time that LogHelloReceive is called by the Connection. Messages are counted before the receive event is invoked.
|
||||
/// </remarks>
|
||||
public int PingMessagesReceived
|
||||
{
|
||||
get
|
||||
{
|
||||
return pingMessagesReceived;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of hello messages received.
|
||||
/// </summary>
|
||||
int pingMessagesReceived;
|
||||
|
||||
/// <summary>
|
||||
/// The number of hello messages received.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is the number of hello messages that were received by the <see cref="Connection"/>, incremented
|
||||
/// each time that LogHelloReceive is called by the Connection. Messages are counted before the receive event is invoked.
|
||||
/// </remarks>
|
||||
public int HelloMessagesReceived
|
||||
{
|
||||
get
|
||||
{
|
||||
return helloMessagesReceived;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of hello messages received.
|
||||
/// </summary>
|
||||
int helloMessagesReceived;
|
||||
|
||||
/// <summary>
|
||||
/// The number of bytes of data received.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This is the number of bytes of data (i.e. user bytes) that were received by the <see cref="Connection"/>,
|
||||
/// accumulated each time that LogReceive is called by the Connection. Messages are counted before the receive
|
||||
/// event is invoked.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// For the number of bytes including protocol bytes see <see cref="TotalBytesReceived"/>.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public long DataBytesReceived
|
||||
{
|
||||
get
|
||||
{
|
||||
return Interlocked.Read(ref dataBytesReceived);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of bytes of data received.
|
||||
/// </summary>
|
||||
long dataBytesReceived;
|
||||
|
||||
/// <summary>
|
||||
/// The number of bytes received in total.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This is the total number of bytes (the data bytes plus protocol bytes) that were received by the
|
||||
/// <see cref="Connection"/>, accumulated each time that LogReceive is called by the Connection. Messages are
|
||||
/// counted before the receive event is invoked.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// For the number of data bytes excluding protocol bytes see <see cref="DataBytesReceived"/>.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public long TotalBytesReceived
|
||||
{
|
||||
get
|
||||
{
|
||||
return Interlocked.Read(ref totalBytesReceived);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The number of bytes received in total.
|
||||
/// </summary>
|
||||
long totalBytesReceived;
|
||||
|
||||
public int MessagesResent { get { return messagesResent; } }
|
||||
int messagesResent;
|
||||
|
||||
/// <summary>
|
||||
/// Logs the sending of an unreliable data packet in the statistics.
|
||||
/// </summary>
|
||||
/// <param name="dataLength">The number of bytes of data sent.</param>
|
||||
/// <param name="totalLength">The total number of bytes sent.</param>
|
||||
/// <remarks>
|
||||
/// This should be called after the data has been sent and should only be called for data that is sent sucessfully.
|
||||
/// </remarks>
|
||||
internal void LogUnreliableSend(int dataLength, int totalLength)
|
||||
{
|
||||
Interlocked.Increment(ref unreliableMessagesSent);
|
||||
Interlocked.Add(ref dataBytesSent, dataLength);
|
||||
Interlocked.Add(ref totalBytesSent, totalLength);
|
||||
|
||||
if (totalLength > ExpectedMTU)
|
||||
{
|
||||
Interlocked.Increment(ref fragmentableMessagesSent);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs the sending of a reliable data packet in the statistics.
|
||||
/// </summary>
|
||||
/// <param name="dataLength">The number of bytes of data sent.</param>
|
||||
/// <param name="totalLength">The total number of bytes sent.</param>
|
||||
/// <remarks>
|
||||
/// This should be called after the data has been sent and should only be called for data that is sent sucessfully.
|
||||
/// </remarks>
|
||||
internal void LogReliableSend(int dataLength, int totalLength)
|
||||
{
|
||||
Interlocked.Increment(ref reliableMessagesSent);
|
||||
Interlocked.Add(ref dataBytesSent, dataLength);
|
||||
Interlocked.Add(ref totalBytesSent, totalLength);
|
||||
|
||||
if (totalLength > ExpectedMTU)
|
||||
{
|
||||
Interlocked.Increment(ref fragmentableMessagesSent);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs the sending of a fragmented data packet in the statistics.
|
||||
/// </summary>
|
||||
/// <param name="dataLength">The number of bytes of data sent.</param>
|
||||
/// <param name="totalLength">The total number of bytes sent.</param>
|
||||
/// <remarks>
|
||||
/// This should be called after the data has been sent and should only be called for data that is sent sucessfully.
|
||||
/// </remarks>
|
||||
internal void LogFragmentedSend(int dataLength, int totalLength)
|
||||
{
|
||||
Interlocked.Increment(ref fragmentedMessagesSent);
|
||||
Interlocked.Add(ref dataBytesSent, dataLength);
|
||||
Interlocked.Add(ref totalBytesSent, totalLength);
|
||||
|
||||
if (totalLength > ExpectedMTU)
|
||||
{
|
||||
Interlocked.Increment(ref fragmentableMessagesSent);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs the sending of a acknowledgement data packet in the statistics.
|
||||
/// </summary>
|
||||
/// <param name="totalLength">The total number of bytes sent.</param>
|
||||
/// <remarks>
|
||||
/// This should be called after the data has been sent and should only be called for data that is sent sucessfully.
|
||||
/// </remarks>
|
||||
internal void LogAcknowledgementSend(int totalLength)
|
||||
{
|
||||
Interlocked.Increment(ref acknowledgementMessagesSent);
|
||||
Interlocked.Add(ref totalBytesSent, totalLength);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs the sending of a hellp data packet in the statistics.
|
||||
/// </summary>
|
||||
/// <param name="totalLength">The total number of bytes sent.</param>
|
||||
/// <remarks>
|
||||
/// This should be called after the data has been sent and should only be called for data that is sent sucessfully.
|
||||
/// </remarks>
|
||||
internal void LogHelloSend(int totalLength)
|
||||
{
|
||||
Interlocked.Increment(ref helloMessagesSent);
|
||||
Interlocked.Add(ref totalBytesSent, totalLength);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs the receiving of an unreliable data packet in the statistics.
|
||||
/// </summary>
|
||||
/// <param name="dataLength">The number of bytes of data received.</param>
|
||||
/// <param name="totalLength">The total number of bytes received.</param>
|
||||
/// <remarks>
|
||||
/// This should be called before the received event is invoked so it is up to date for subscribers to that event.
|
||||
/// </remarks>
|
||||
internal void LogUnreliableReceive(int dataLength, int totalLength)
|
||||
{
|
||||
Interlocked.Increment(ref unreliableMessagesReceived);
|
||||
Interlocked.Add(ref dataBytesReceived, dataLength);
|
||||
Interlocked.Add(ref totalBytesReceived, totalLength);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs the receiving of a reliable data packet in the statistics.
|
||||
/// </summary>
|
||||
/// <param name="dataLength">The number of bytes of data received.</param>
|
||||
/// <param name="totalLength">The total number of bytes received.</param>
|
||||
/// <remarks>
|
||||
/// This should be called before the received event is invoked so it is up to date for subscribers to that event.
|
||||
/// </remarks>
|
||||
internal void LogReliableReceive(int dataLength, int totalLength)
|
||||
{
|
||||
Interlocked.Increment(ref reliableMessagesReceived);
|
||||
Interlocked.Add(ref dataBytesReceived, dataLength);
|
||||
Interlocked.Add(ref totalBytesReceived, totalLength);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs the receiving of a fragmented data packet in the statistics.
|
||||
/// </summary>
|
||||
/// <param name="dataLength">The number of bytes of data received.</param>
|
||||
/// <param name="totalLength">The total number of bytes received.</param>
|
||||
/// <remarks>
|
||||
/// This should be called before the received event is invoked so it is up to date for subscribers to that event.
|
||||
/// </remarks>
|
||||
internal void LogFragmentedReceive(int dataLength, int totalLength)
|
||||
{
|
||||
Interlocked.Increment(ref fragmentedMessagesReceived);
|
||||
Interlocked.Add(ref dataBytesReceived, dataLength);
|
||||
Interlocked.Add(ref totalBytesReceived, totalLength);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs the receiving of an acknowledgement data packet in the statistics.
|
||||
/// </summary>
|
||||
/// <param name="totalLength">The total number of bytes received.</param>
|
||||
/// <remarks>
|
||||
/// This should be called before the received event is invoked so it is up to date for subscribers to that event.
|
||||
/// </remarks>
|
||||
internal void LogAcknowledgementReceive(int totalLength)
|
||||
{
|
||||
Interlocked.Increment(ref acknowledgementMessagesReceived);
|
||||
Interlocked.Add(ref totalBytesReceived, totalLength);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs the receiving of a hello data packet in the statistics.
|
||||
/// </summary>
|
||||
/// <param name="totalLength">The total number of bytes received.</param>
|
||||
/// <remarks>
|
||||
/// This should be called before the received event is invoked so it is up to date for subscribers to that event.
|
||||
/// </remarks>
|
||||
internal void LogPingReceive(int totalLength)
|
||||
{
|
||||
Interlocked.Increment(ref pingMessagesReceived);
|
||||
Interlocked.Add(ref totalBytesReceived, totalLength);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs the receiving of a hello data packet in the statistics.
|
||||
/// </summary>
|
||||
/// <param name="totalLength">The total number of bytes received.</param>
|
||||
/// <remarks>
|
||||
/// This should be called before the received event is invoked so it is up to date for subscribers to that event.
|
||||
/// </remarks>
|
||||
internal void LogHelloReceive(int totalLength)
|
||||
{
|
||||
Interlocked.Increment(ref helloMessagesReceived);
|
||||
Interlocked.Add(ref totalBytesReceived, totalLength);
|
||||
}
|
||||
|
||||
internal void LogMessageResent()
|
||||
{
|
||||
Interlocked.Increment(ref messagesResent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
using Impostor.Api.Net.Messages;
|
||||
|
||||
namespace Impostor.Hazel
|
||||
{
|
||||
public struct DataReceivedEventArgs
|
||||
{
|
||||
public readonly Connection Sender;
|
||||
|
||||
/// <summary>
|
||||
/// The bytes received from the client.
|
||||
/// </summary>
|
||||
public readonly IMessageReader Message;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Type"/> the data was sent with.
|
||||
/// </summary>
|
||||
public readonly MessageType Type;
|
||||
|
||||
public DataReceivedEventArgs(Connection sender, IMessageReader msg, MessageType type)
|
||||
{
|
||||
this.Sender = sender;
|
||||
this.Message = msg;
|
||||
this.Type = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
using System;
|
||||
using Impostor.Api.Net.Messages;
|
||||
|
||||
namespace Impostor.Hazel
|
||||
{
|
||||
public class DisconnectedEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Optional disconnect reason. May be null.
|
||||
/// </summary>
|
||||
public readonly string Reason;
|
||||
|
||||
/// <summary>
|
||||
/// Optional data sent with a disconnect message. May be null.
|
||||
/// You must not recycle this. If you need the message outside of a callback, you should copy it.
|
||||
/// </summary>
|
||||
public readonly IMessageReader Message;
|
||||
|
||||
public DisconnectedEventArgs(string reason, IMessageReader message)
|
||||
{
|
||||
this.Reason = reason;
|
||||
this.Message = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.ObjectPool;
|
||||
|
||||
namespace Impostor.Hazel.Extensions
|
||||
{
|
||||
public static class ServiceProviderExtensions
|
||||
{
|
||||
public static void AddHazel(this IServiceCollection services)
|
||||
{
|
||||
services.TryAddSingleton<ObjectPoolProvider>(new DefaultObjectPoolProvider());
|
||||
|
||||
services.AddSingleton(serviceProvider =>
|
||||
{
|
||||
var provider = serviceProvider.GetRequiredService<ObjectPoolProvider>();
|
||||
var policy = ActivatorUtilities.CreateInstance<MessageReaderPolicy>(serviceProvider);
|
||||
return provider.Create(policy);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Impostor.Hazel
|
||||
{
|
||||
/// <summary>
|
||||
/// Wrapper for exceptions thrown from Hazel.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class HazelException : Exception
|
||||
{
|
||||
internal HazelException(string msg) : base (msg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
internal HazelException(string msg, Exception e) : base (msg, e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
namespace Impostor.Hazel
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the IP version that a connection or listener will use.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If you wand a client to connect or be able to connect using IPv6 then you should use <see cref="IPv4AndIPv6"/>,
|
||||
/// this sets the underlying sockets to use IPv6 but still allow IPv4 sockets to connect for backwards compatability
|
||||
/// and hence it is the default IPMode in most cases.
|
||||
/// </remarks>
|
||||
public enum IPMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Instruction to use IPv4 only, IPv6 connections will not be able to connect.
|
||||
/// </summary>
|
||||
IPv4,
|
||||
|
||||
/// <summary>
|
||||
/// Instruction to use IPv6 only, IPv4 connections will not be able to connect. IPv4 addresses can be connected
|
||||
/// by converting to IPv6 addresses.
|
||||
/// </summary>
|
||||
IPv6
|
||||
}
|
||||
}
|
||||
Loaded 100 of 210 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user