using System;
-namespace Impostor.Server.Events
+namespace Impostor.Api.Events
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class EventListenerAttribute : Attribute
-namespace Impostor.Server.Events
+namespace Impostor.Api.Events
{
public enum EventPriority
{
-using Impostor.Server.Games;
+using Impostor.Api.Games;
-namespace Impostor.Server.Events
+namespace Impostor.Api.Events
{
/// <summary>
/// Called whenever a new <see cref="IGame"/> is created.
-using Impostor.Server.Games;
+using Impostor.Api.Games;
-namespace Impostor.Server.Events
+namespace Impostor.Api.Events
{
/// <summary>
/// Called whenever a new <see cref="IGame"/> is destroyed.
-using Impostor.Server.Games;
+using Impostor.Api.Games;
-namespace Impostor.Server.Events
+namespace Impostor.Api.Events
{
public interface IGameEvent : IEvent
{
-using Impostor.Server.Games;
-using Impostor.Server.Net;
+using Impostor.Api.Games;
+using Impostor.Api.Net;
-namespace Impostor.Server.Events
+namespace Impostor.Api.Events
{
public class PlayerJoinedGameEvent : IGameEvent
{
-using Impostor.Server.Games;
-using Impostor.Server.Net;
+using Impostor.Api.Games;
+using Impostor.Api.Net;
-namespace Impostor.Server.Events
+namespace Impostor.Api.Events
{
public class PlayerLeftGameEvent : IGameEvent
{
-namespace Impostor.Server.Events
+namespace Impostor.Api.Events
{
public interface IEvent
{
-namespace Impostor.Server.Events
+namespace Impostor.Api.Events
{
public interface IEventCancelable : IEvent
{
-namespace Impostor.Server.Events
+namespace Impostor.Api.Events
{
public interface IEventListener
{
using System;
using System.Threading.Tasks;
-namespace Impostor.Server.Events.Managers
+namespace Impostor.Api.Events.Managers
{
public interface IEventManager
{
using System;
using System.Runtime.Serialization;
-namespace Impostor.Server
+namespace Impostor.Api
{
public class ImpostorException : Exception
{
using System.Linq;
-using Impostor.Server.Games.Managers;
-using Impostor.Shared.Innersloth.Data;
+using Impostor.Api.Games.Managers;
+using Impostor.Api.Innersloth.Data;
-namespace Impostor.Server.Games
+namespace Impostor.Api.Games
{
public static class GameManagerExtensions
{
using System;
-using Impostor.Shared.Innersloth;
+using Impostor.Api.Innersloth;
-namespace Impostor.Server.Games
+namespace Impostor.Api.Games
{
public readonly struct GameCode : IEquatable<GameCode>
{
-namespace Impostor.Server.Games
+namespace Impostor.Api.Games
{
public enum GameJoinError
{
using System;
using System.Diagnostics.CodeAnalysis;
-using Impostor.Server.Net;
+using Impostor.Api.Net;
-namespace Impostor.Server.Games
+namespace Impostor.Api.Games
{
public readonly struct GameJoinResult
{
using System.Collections.Generic;
using System.Net;
-using Impostor.Server.Net;
-using Impostor.Server.Net.Messages;
-using Impostor.Shared.Innersloth;
-using Impostor.Shared.Innersloth.Data;
+using Impostor.Api.Innersloth;
+using Impostor.Api.Innersloth.Data;
+using Impostor.Api.Net;
+using Impostor.Api.Net.Messages;
-namespace Impostor.Server.Games
+namespace Impostor.Api.Games
{
public interface IGame
{
using System.Collections.Generic;
-namespace Impostor.Server.Games.Managers
+namespace Impostor.Api.Games.Managers
{
public interface IGameManager
{
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
- <RootNamespace>Impostor.Server</RootNamespace>
- <Nullable>enable</Nullable>
<DebugType Condition=" '$(Configuration)' == 'Release' ">None</DebugType>
<CodeAnalysisRuleSet>ProjectRules.ruleset</CodeAnalysisRuleSet>
+ <LangVersion>9</LangVersion>
</PropertyGroup>
- <ItemGroup>
- <ProjectReference Include="..\Impostor.Shared\Impostor.Shared.csproj" />
- </ItemGroup>
-
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0-rc.1.20451.14" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0-rc.1.20451.14" />
--- /dev/null
+namespace Impostor.Api.Innersloth.Data
+{
+ public enum AlterGameTags : byte
+ {
+ ChangePrivacy = 1
+ }
+}
\ No newline at end of file
--- /dev/null
+namespace Impostor.Api.Innersloth.Data
+{
+ public enum DisconnectReason
+ {
+ ExitGame = 0,
+ // The game you tried to join is full.
+ // Check with the host to see if you can join next round.
+ GameFull = 1,
+ // The game you tried to join already started.
+ // Check with the host to see if you can join next round.
+ GameStarted = 2,
+ // Could not find the game you're looking for.
+ GameMissing = 3,
+ IncorrectGame = 18,
+ // For these a message can be given, specifying an empty message shows
+ // "An unknown error disconnected you from the server."
+ CustomMessage1 = 4,
+ Custom = 8,
+ // CustomMessage3 = 11,
+ // CustomMessage4 = 12,
+ // CustomMessage5 = 13,
+ // CustomMessage6 = 14,
+ // CustomMessage7 = 15,
+ // You are running an older version of the game.
+ // Please update to play with others.
+ IncorrectVersion = 5,
+ // You cannot rejoin that room.
+ // You were banned
+ Banned = 6,
+ // You can rejoin if the room hasn't started
+ // You were kicked
+ Kicked = 7,
+ // You were banned for hacking.
+ // Please stop.
+ Hacking = 10,
+ Destroy = 16,
+ // You disconnected from the host.
+ // If this happens often, check your WiFi strength.
+ //
+ // You disconnected from the server.
+ // If this happens often, check your network strength.
+ // This may also be a server issue.
+ Error = 17,
+ // The server stopped this game. Possibly due to inactivity.
+ ServerRequest = 19,
+ // The Among Us servers are overloaded.
+ // Sorry! Please try again later!
+ ServerFull = 20,
+ FocusLostBackground = 207,
+ IntentionalLeaving = 208,
+ FocusLost = 209,
+ NewConnection = 210
+ }
+}
\ No newline at end of file
--- /dev/null
+using System;
+
+namespace Impostor.Api.Innersloth.Data
+{
+ [Flags]
+ public enum GameKeywords : uint
+ {
+ All = 0,
+ Other = 1,
+ Spanish = 2,
+ Korean = 4,
+ Russian = 8,
+ Portuguese = 16,
+ Arabic = 32,
+ Filipone = 64,
+ Polish = 128,
+ English = 256
+ }
+}
\ No newline at end of file
--- /dev/null
+namespace Impostor.Api.Innersloth.Data
+{
+ public enum GameStates : byte
+ {
+ NotStarted = 0,
+ Started = 1,
+ Ended = 2,
+ Destroyed = 3
+ }
+}
\ No newline at end of file
--- /dev/null
+using System;
+
+namespace Impostor.Api.Innersloth.Data
+{
+ [Flags]
+ public enum MapFlags
+ {
+ Skeld = 1,
+ MiraHQ = 2,
+ Polus = 4
+ }
+}
\ No newline at end of file
--- /dev/null
+using Impostor.Api.Unity;
+
+namespace Impostor.Api.Innersloth
+{
+ public class FloatRange
+ {
+ private readonly float _min;
+ private readonly float _max;
+
+ public FloatRange(float min, float max)
+ {
+ _min = min;
+ _max = max;
+ }
+
+ public float Width => _max - _min;
+
+ public float Lerp(float v) => Mathf.Lerp(_min, _max, v);
+
+ public float ReverseLerp(float t) => Mathf.Clamp((t - _min) / Width, 0.0f, 1f);
+ }
+}
\ No newline at end of file
--- /dev/null
+using System;
+using System.Buffers.Binary;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace Impostor.Api.Innersloth
+{
+ public static class GameCodeParser
+ {
+ private const string V2 = "QWXRTYLPESDFGHUJKZOCVBINMA";
+ private static readonly int[] V2Map = {
+ 25,
+ 21,
+ 19,
+ 10,
+ 8,
+ 11,
+ 12,
+ 13,
+ 22,
+ 15,
+ 16,
+ 6,
+ 24,
+ 23,
+ 18,
+ 7,
+ 0,
+ 3,
+ 9,
+ 4,
+ 14,
+ 20,
+ 1,
+ 2,
+ 5,
+ 17
+ };
+ private static readonly RNGCryptoServiceProvider Random = new RNGCryptoServiceProvider();
+
+ public static string IntToGameName(int input)
+ {
+ // V2.
+ if (input < -1)
+ {
+ return IntToGameNameV2(input);
+ }
+
+ // V1.
+ Span<byte> code = stackalloc byte[4];
+ BinaryPrimitives.WriteInt32LittleEndian(code, input);
+#if NETSTANDARD2_0
+ return Encoding.UTF8.GetString(code.Slice(0, 4).ToArray());
+#else
+ return Encoding.UTF8.GetString(code.Slice(0, 4));
+#endif
+ }
+
+ private static string IntToGameNameV2(int input)
+ {
+ var a = input & 0x3FF;
+ var b = (input >> 10) & 0xFFFFF;
+
+ return new string(new []
+ {
+ V2[a % 26],
+ V2[a / 26],
+ V2[b % 26],
+ V2[b / 26 % 26],
+ V2[b / (26 * 26) % 26],
+ V2[b / (26 * 26 * 26) % 26]
+ });
+ }
+
+ public static int GameNameToInt(string code)
+ {
+ var upper = code.ToUpperInvariant();
+ if (upper.Any(x => !char.IsLetter(x)))
+ {
+ return -1;
+ }
+
+ var len = code.Length;
+ if (len == 6)
+ {
+ return GameNameToIntV2(upper);
+ }
+
+ if (len == 4)
+ {
+ return code[0] | ((code[1] | ((code[2] | (code[3] << 8)) << 8)) << 8);
+ }
+
+ return -1;
+ }
+
+ private static int GameNameToIntV2(string code)
+ {
+ var a = V2Map[code[0] - 65];
+ var b = V2Map[code[1] - 65];
+ var c = V2Map[code[2] - 65];
+ var d = V2Map[code[3] - 65];
+ var e = V2Map[code[4] - 65];
+ var f = V2Map[code[5] - 65];
+
+ var one = (a + 26 * b) & 0x3FF;
+ var two = (c + 26 * (d + 26 * (e + 26 * f)));
+
+ return (int) (one | ((two << 10) & 0x3FFFFC00) | 0x80000000);
+ }
+
+ public static int GenerateCode(int len)
+ {
+ if (len != 4 && len != 6)
+ {
+ throw new ArgumentException("should be 4 or 6", nameof(len));
+ }
+
+ // Generate random bytes.
+#if NETSTANDARD2_0
+ var data = new byte[len];
+#else
+ Span<byte> data = stackalloc byte[len];
+#endif
+ Random.GetBytes(data);
+
+ // Convert to their char representation.
+ Span<char> dataChar = stackalloc char[len];
+ for (var i = 0; i < len; i++)
+ {
+ dataChar[i] = V2[V2Map[data[i] % 26]];
+ }
+
+#if NETSTANDARD2_0
+ return GameNameToInt(new string(dataChar.ToArray()));
+#else
+ return GameNameToInt(new string(dataChar));
+#endif
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+namespace Impostor.Api.Innersloth.GameData
+{
+ public static class GameDataTag
+ {
+ public const byte DataFlag = 1;
+ public const byte RpcFlag = 2;
+ public const byte SpawnFlag = 4;
+ public const byte DespawnFlag = 5;
+ public const byte SceneChangeFlag = 6;
+ public const byte ReadyFlag = 7;
+ public const byte ChangeSettingsFlag = 8;
+ }
+}
\ No newline at end of file
--- /dev/null
+using System;
+using System.IO;
+using Impostor.Api.Innersloth.Data;
+
+namespace Impostor.Api.Innersloth
+{
+ public class GameOptionsData
+ {
+ public byte Version { get; set; }
+ public byte MaxPlayers { get; set; }
+ public GameKeywords Keywords { get; set; }
+ public byte MapId { get; set; }
+ public float PlayerSpeedMod { get; set; }
+ public float CrewLightMod { get; set; }
+ public float ImpostorLightMod { get; set; }
+ public float KillCooldown { get; set; }
+ public int NumCommonTasks { get; set; }
+ public int NumLongTasks { get; set; }
+ public int NumShortTasks { get; set; }
+ public int NumEmergencyMeetings { get; set; }
+ public int EmergencyCooldown { get; set; }
+ public int NumImpostors { get; set; }
+ public bool GhostsDoTasks { get; set; }
+ public int KillDistance { get; set; }
+ public int DiscussionTime { get; set; }
+ public int VotingTime { get; set; }
+ public bool ConfirmImpostor { get; set; }
+ public bool VisualTasks { get; set; }
+ public bool IsDefaults { get; set; }
+
+ public void Serialize(BinaryWriter writer, byte version)
+ {
+ writer.Write((byte) version);
+ writer.Write((byte) MaxPlayers);
+ writer.Write((uint) Keywords);
+ writer.Write((byte) MapId);
+ writer.Write((float) PlayerSpeedMod);
+ writer.Write((float) CrewLightMod);
+ writer.Write((float) ImpostorLightMod);
+ writer.Write((float) KillCooldown);
+ writer.Write((byte) NumCommonTasks);
+ writer.Write((byte) NumLongTasks);
+ writer.Write((byte) NumShortTasks);
+ writer.Write((int) NumEmergencyMeetings);
+ writer.Write((byte) NumImpostors);
+ writer.Write((byte) KillDistance);
+ writer.Write((uint) DiscussionTime);
+ writer.Write((uint) VotingTime);
+ writer.Write((bool) IsDefaults);
+ if (version > 1)
+ {
+ writer.Write((byte) EmergencyCooldown);
+ }
+
+ if (version > 2)
+ {
+ writer.Write((bool) ConfirmImpostor);
+ writer.Write((bool) VisualTasks);
+ }
+ }
+
+ public static GameOptionsData Deserialize(ReadOnlyMemory<byte> bytes)
+ {
+ // TODO: Remove memory allocation.
+
+ using (var stream = new MemoryStream(bytes.ToArray()))
+ using (var reader = new BinaryReader(stream))
+ {
+ var result = new GameOptionsData();
+
+ result.Version = reader.ReadByte();
+ result.MaxPlayers = reader.ReadByte();
+ result.Keywords = (GameKeywords) reader.ReadUInt32();
+ result.MapId = reader.ReadByte();
+ result.PlayerSpeedMod = reader.ReadSingle();
+ result.CrewLightMod = reader.ReadSingle();
+ result.ImpostorLightMod = reader.ReadSingle();
+ result.KillCooldown = reader.ReadSingle();
+ result.NumCommonTasks = reader.ReadByte();
+ result.NumLongTasks = reader.ReadByte();
+ result.NumShortTasks = reader.ReadByte();
+ result.NumEmergencyMeetings = reader.ReadInt32();
+ result.NumImpostors = reader.ReadByte();
+ result.KillDistance = reader.ReadByte();
+ result.DiscussionTime = reader.ReadInt32();
+ result.VotingTime = reader.ReadInt32();
+ result.IsDefaults = reader.ReadBoolean();
+
+ if (result.Version > 1)
+ {
+ result.EmergencyCooldown = reader.ReadByte();
+ }
+
+ if (result.Version > 2)
+ {
+ result.ConfirmImpostor = reader.ReadBoolean();
+ result.VisualTasks = reader.ReadBoolean();
+ }
+
+ return result;
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+namespace Impostor.Api.Innersloth
+{
+ public class GameVersion
+ {
+ public static int GetVersion(int year, int month, int day, int rev = 0)
+ {
+ return (year * 25000) + (month * 1800) + (day * 50) + rev;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+using System.Collections.Generic;
+using System.IO;
+
+namespace Impostor.Api.Innersloth
+{
+ public class RegionInfo
+ {
+ public RegionInfo(string name, string ping, IReadOnlyList<ServerInfo> servers)
+ {
+ Name = name;
+ Ping = ping;
+ Servers = servers;
+ }
+
+ public string Name { get; }
+ public string Ping { get; }
+ public IReadOnlyList<ServerInfo> Servers { get; }
+
+ public void Serialize(BinaryWriter writer)
+ {
+ writer.Write(0);
+ writer.Write(Name);
+ writer.Write(Ping);
+ writer.Write(Servers.Count);
+
+ foreach (var server in Servers)
+ {
+ server.Serialize(writer);
+ }
+ }
+
+ public static RegionInfo Deserialize(BinaryReader reader)
+ {
+ var unknown = reader.ReadInt32();
+ var name = reader.ReadString();
+ var ping = reader.ReadString();
+ var servers = new List<ServerInfo>();
+ var serverCount = reader.ReadInt32();
+
+ for (var i = 0; i < serverCount; i++)
+ {
+ servers.Add(ServerInfo.Deserialize(reader));
+ }
+
+ return new RegionInfo(name, ping, servers);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+using System.IO;
+using System.Net;
+
+namespace Impostor.Api.Innersloth
+{
+ public class ServerInfo
+ {
+ public string Name { get; }
+ public string Ip { get; }
+ public ushort Port { get; }
+
+ public ServerInfo(string name, string ip, ushort port)
+ {
+ Name = name;
+ Ip = ip;
+ Port = port;
+ }
+
+ public void Serialize(BinaryWriter writer)
+ {
+ writer.Write(Name);
+ writer.Write(IPAddress.Parse(Ip).GetAddressBytes());
+ writer.Write(Port);
+ writer.Write(0);
+ }
+
+ public static ServerInfo Deserialize(BinaryReader reader)
+ {
+ var name = reader.ReadString();
+ var ip = new IPAddress(reader.ReadBytes(4)).ToString();
+ var port = reader.ReadUInt16();
+ var unknown = reader.ReadInt32();
+
+ return new ServerInfo(name, ip, port);
+ }
+ }
+}
\ No newline at end of file
using System;
using System.Threading.Tasks;
-using Impostor.Server.Net.Messages;
+using Impostor.Api.Net.Messages;
-namespace Impostor.Server.Net
+namespace Impostor.Api.Net
{
public static class GameMessageWriterExtensions
{
using System.Collections.Generic;
-namespace Impostor.Server.Net
+namespace Impostor.Api.Net
{
/// <summary>
/// Represents a connected game client.
using System.Threading.Tasks;
-using Impostor.Server.Games;
+using Impostor.Api.Games;
-namespace Impostor.Server.Net
+namespace Impostor.Api.Net
{
/// <summary>
/// Represents a player in <see cref="IGame"/>.
using System.Net;
-using Impostor.Server.Games;
-using Impostor.Server.Net.Messages;
+using Impostor.Api.Games;
+using Impostor.Api.Net.Messages;
-namespace Impostor.Server.Net
+namespace Impostor.Api.Net
{
/// <summary>
/// Represents the connection of the client.
using System;
-namespace Impostor.Server.Net
+namespace Impostor.Api.Net
{
[Flags]
public enum LimboStates
using System.Collections.Generic;
-namespace Impostor.Server.Net.Manager
+namespace Impostor.Api.Net.Manager
{
public interface IClientManager
{
using System.Threading.Tasks;
-namespace Impostor.Server.Net.Messages
+namespace Impostor.Api.Net.Messages
{
/// <summary>
/// Represents the message writer for <see cref="IConnection"/>.
using System.Threading.Tasks;
-using Impostor.Server.Games;
+using Impostor.Api.Games;
-namespace Impostor.Server.Net.Messages
+namespace Impostor.Api.Net.Messages
{
/// <summary>
/// Represents the message writer for <see cref="IGame"/>.
-namespace Impostor.Server.Net.Messages
+namespace Impostor.Api.Net.Messages
{
public interface IMessage
{
using System;
-namespace Impostor.Server.Net.Messages
+namespace Impostor.Api.Net.Messages
{
public interface IMessageReader
{
using System;
using System.Net;
-using Impostor.Server.Games;
+using Impostor.Api.Games;
-namespace Impostor.Server.Net.Messages
+namespace Impostor.Api.Net.Messages
{
/// <summary>
/// Base message writer.
-namespace Impostor.Server.Net.Messages
+namespace Impostor.Api.Net.Messages
{
/// <summary>
/// Specifies how a message should be sent between connections.
using System.Threading.Tasks;
-using Impostor.Server.Events;
+using Impostor.Api.Events;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
-namespace Impostor.Server.Plugins
+namespace Impostor.Api.Plugins
{
public interface IPlugin : IEventListener
{
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
-namespace Impostor.Server.Plugins
+namespace Impostor.Api.Plugins
{
public class PluginBase : IPlugin
{
--- /dev/null
+namespace Impostor.Api.Unity
+{
+ public static class Mathf
+ {
+ /// <summary>
+ /// <para>Clamps the given value between the given minimum float and maximum float values. Returns the given value if it is within the min and max range.</para>
+ /// </summary>
+ /// <param name="value">The floating point value to restrict inside the range defined by the min and max values.</param>
+ /// <param name="min">The minimum floating point value to compare against.</param>
+ /// <param name="max">The maximum floating point value to compare against.</param>
+ /// <returns>
+ /// <para>The float result between the min and max values.</para>
+ /// </returns>
+ public static float Clamp(float value, float min, float max)
+ {
+ if ((double) value < (double) min)
+ value = min;
+ else if ((double) value > (double) max)
+ value = max;
+ return value;
+ }
+
+ /// <summary>
+ /// <para>Clamps value between 0 and 1 and returns value.</para>
+ /// </summary>
+ /// <param name="value"></param>
+ public static float Clamp01(float value)
+ {
+ if ((double) value < 0.0)
+ return 0.0f;
+ return (double) value > 1.0 ? 1f : value;
+ }
+
+ /// <summary>
+ /// <para>Linearly interpolates between a and b by t.</para>
+ /// </summary>
+ /// <param name="a">The start value.</param>
+ /// <param name="b">The end value.</param>
+ /// <param name="t">The interpolation value between the two floats.</param>
+ /// <returns>
+ /// <para>The interpolated float result between the two float values.</para>
+ /// </returns>
+ public static float Lerp(float a, float b, float t) => a + (b - a) * Mathf.Clamp01(t);
+ }
+}
\ No newline at end of file
using Gameloop.Vdf;
using Gameloop.Vdf.Linq;
using Impostor.Patcher.Shared.Events;
-using Impostor.Shared.Innersloth;
+using Impostor.Patcher.Shared.Innersloth;
using ErrorEventArgs = Impostor.Patcher.Shared.Events.ErrorEventArgs;
namespace Impostor.Patcher.Shared
</PropertyGroup>
<ItemGroup>
- <ProjectReference Include="..\..\Impostor.Shared\Impostor.Shared.csproj" />
<PackageReference Include="Gameloop.Vdf" Version="0.6.1" />
</ItemGroup>
--- /dev/null
+using System.Collections.Generic;
+using System.IO;
+
+namespace Impostor.Patcher.Shared.Innersloth
+{
+ public class RegionInfo
+ {
+ public RegionInfo(string name, string ping, IReadOnlyList<ServerInfo> servers)
+ {
+ Name = name;
+ Ping = ping;
+ Servers = servers;
+ }
+
+ public string Name { get; }
+ public string Ping { get; }
+ public IReadOnlyList<ServerInfo> Servers { get; }
+
+ public void Serialize(BinaryWriter writer)
+ {
+ writer.Write(0);
+ writer.Write(Name);
+ writer.Write(Ping);
+ writer.Write(Servers.Count);
+
+ foreach (var server in Servers)
+ {
+ server.Serialize(writer);
+ }
+ }
+
+ public static RegionInfo Deserialize(BinaryReader reader)
+ {
+ var unknown = reader.ReadInt32();
+ var name = reader.ReadString();
+ var ping = reader.ReadString();
+ var servers = new List<ServerInfo>();
+ var serverCount = reader.ReadInt32();
+
+ for (var i = 0; i < serverCount; i++)
+ {
+ servers.Add(ServerInfo.Deserialize(reader));
+ }
+
+ return new RegionInfo(name, ping, servers);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+using System.IO;
+using System.Net;
+
+namespace Impostor.Patcher.Shared.Innersloth
+{
+ public class ServerInfo
+ {
+ public string Name { get; }
+ public string Ip { get; }
+ public ushort Port { get; }
+
+ public ServerInfo(string name, string ip, ushort port)
+ {
+ Name = name;
+ Ip = ip;
+ Port = port;
+ }
+
+ public void Serialize(BinaryWriter writer)
+ {
+ writer.Write(Name);
+ writer.Write(IPAddress.Parse(Ip).GetAddressBytes());
+ writer.Write(Port);
+ writer.Write(0);
+ }
+
+ public static ServerInfo Deserialize(BinaryReader reader)
+ {
+ var name = reader.ReadString();
+ var ip = new IPAddress(reader.ReadBytes(4)).ToString();
+ var port = reader.ReadUInt16();
+ var unknown = reader.ReadInt32();
+
+ return new ServerInfo(name, ip, port);
+ }
+ }
+}
\ No newline at end of file
-using Impostor.Server.Plugins;
+using Impostor.Api.Plugins;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
@page "/"
-@using Impostor.Server.Events
-@using Impostor.Server.Events.Managers
-@using Impostor.Server.Games.Managers
@implements IDisposable
-@implements IEventListener
+@using Impostor.Api.Events.Managers
+@using Impostor.Api.Games.Managers
+@using Impostor.Api.Events
+@implements Impostor.Api.Events.IEventListener
@inject IEventManager EventManager
@inject IGameManager GameManager
-namespace Impostor.Server.Events
+using Impostor.Api.Events;
+
+namespace Impostor.Server.Events
{
internal readonly struct EventHandler
{
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
-using Impostor.Server.Events.Managers;
+using Impostor.Api.Events;
+using Impostor.Api.Events.Managers;
using Microsoft.Extensions.DependencyInjection;
namespace Impostor.Server.Events
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
+using Impostor.Api.Events;
using Microsoft.Extensions.DependencyInjection;
namespace Impostor.Server.Events
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
+using Impostor.Api.Events;
namespace Impostor.Server.Events
{
-using Impostor.Server.Net.Messages;
+using Impostor.Api.Net.Messages;
+using Impostor.Server.Net.Messages;
namespace Impostor.Server.GameData
{
using System.Numerics;
-using Impostor.Server.Net.Messages;
-using Impostor.Shared.Innersloth;
+using Impostor.Api.Innersloth;
+using Impostor.Api.Net.Messages;
using Microsoft.Extensions.Logging;
namespace Impostor.Server.GameData.Objects.Components
-using Impostor.Server.Net.Messages;
+using Impostor.Api.Net.Messages;
+using Impostor.Server.Net.Messages;
namespace Impostor.Server.GameData.Objects.Components
{
using System;
using System.Collections.Generic;
+using Impostor.Api.Net.Messages;
using Impostor.Server.Net.Messages;
namespace Impostor.Server.GameData.Objects.Components
using System;
using System.Collections.Generic;
+using Impostor.Api.Net.Messages;
using Impostor.Server.Net.Messages;
namespace Impostor.Server.GameData.Objects
-using Impostor.Server.Net.Messages;
+using Impostor.Api.Net.Messages;
+using Impostor.Server.Net.Messages;
namespace Impostor.Server.GameData.Objects
{
using System;
using System.Collections.Generic;
+using Impostor.Api.Games;
+using Impostor.Api.Net.Messages;
using Impostor.Server.GameData.Objects.Components;
-using Impostor.Server.Games;
using Impostor.Server.Net.Messages;
namespace Impostor.Server.GameData.Objects
-using Impostor.Server.Games;
+using Impostor.Api.Games;
+using Impostor.Api.Net.Messages;
using Impostor.Server.Net.Messages;
namespace Impostor.Server.GameData.Objects
-using Impostor.Server.Games;
+using Impostor.Api.Games;
+using Impostor.Api.Net.Messages;
using Impostor.Server.Net.Messages;
namespace Impostor.Server.GameData.Objects
using System;
+using Impostor.Api.Games;
+using Impostor.Api.Net.Messages;
using Impostor.Server.GameData.Objects.Components;
-using Impostor.Server.Games;
using Impostor.Server.Net.Messages;
using Microsoft.Extensions.DependencyInjection;
-using Impostor.Server.Games;
+using Impostor.Api.Games;
+using Impostor.Api.Net.Messages;
using Impostor.Server.Net.Messages;
namespace Impostor.Server.GameData.Objects
<ItemGroup>
<ProjectReference Include="..\Impostor.Api\Impostor.Api.csproj" />
<ProjectReference Include="..\Impostor.Hazel\Impostor.Hazel.csproj" />
- <ProjectReference Include="..\Impostor.Shared\Impostor.Shared.csproj" />
</ItemGroup>
<ItemGroup>
using System;
using System.Threading.Tasks;
+using Impostor.Api.Games;
+using Impostor.Api.Innersloth;
+using Impostor.Api.Innersloth.Data;
+using Impostor.Api.Net.Messages;
using Impostor.Server.Data;
-using Impostor.Server.Games;
using Impostor.Server.Net.Hazel;
using Impostor.Server.Net.Manager;
using Impostor.Server.Net.Messages;
-using Impostor.Shared.Innersloth;
-using Impostor.Shared.Innersloth.Data;
using Microsoft.Extensions.Logging;
namespace Impostor.Server.Net
-namespace Impostor.Server.Net
+using Impostor.Api.Net;
+
+namespace Impostor.Server.Net
{
internal abstract partial class ClientBase : IClient
{
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;
+using Impostor.Api.Net.Messages;
using Impostor.Server.Net.Hazel;
using Impostor.Server.Net.Messages;
using Impostor.Server.Net.State;
-namespace Impostor.Server.Net.Hazel
+using Impostor.Api.Net;
+
+namespace Impostor.Server.Net.Hazel
{
internal partial class HazelConnection : IConnection
{
using System.Net;
using System.Threading.Tasks;
using Hazel;
+using Impostor.Api.Net.Messages;
using Impostor.Server.Hazel.Messages;
using Impostor.Server.Net.Hazel.Messages;
using Impostor.Server.Net.Messages;
using System.Buffers.Binary;
using System.Runtime.CompilerServices;
using System.Text;
+using Impostor.Api.Net.Messages;
using Impostor.Server.Net.Messages;
namespace Impostor.Server.Hazel.Messages
using System.Threading.Tasks;
+using Impostor.Api.Net;
+using Impostor.Api.Net.Messages;
using Impostor.Server.Net;
using Impostor.Server.Net.Messages;
using System.Linq;
using System.Threading.Tasks;
using Hazel;
+using Impostor.Api.Net;
+using Impostor.Api.Net.Messages;
using Impostor.Server.Net;
using Impostor.Server.Net.Messages;
using Impostor.Server.Net.State;
using System;
using Hazel;
+using Impostor.Api.Net.Messages;
using Impostor.Server.Hazel.Messages;
using Impostor.Server.Net.Messages;
using System;
using System.Net;
using Hazel;
-using Impostor.Server.Games;
+using Impostor.Api.Games;
+using Impostor.Api.Net.Messages;
using Impostor.Server.Net.Messages;
namespace Impostor.Server.Hazel.Messages
using System.Collections.Generic;
+using Impostor.Api.Net;
+using Impostor.Api.Net.Manager;
namespace Impostor.Server.Net.Manager
{
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
+using Impostor.Api.Innersloth;
+using Impostor.Api.Innersloth.Data;
+using Impostor.Api.Net;
+using Impostor.Api.Net.Messages;
using Impostor.Server.Data;
using Impostor.Server.Net.Factories;
using Impostor.Server.Net.Hazel;
using Impostor.Server.Net.Messages;
-using Impostor.Shared.Innersloth;
-using Impostor.Shared.Innersloth.Data;
using Microsoft.Extensions.Logging;
namespace Impostor.Server.Net.Manager
using System.Collections.Generic;
using System.Linq;
-using Impostor.Server.Games;
-using Impostor.Server.Games.Managers;
+using Impostor.Api.Games;
+using Impostor.Api.Games.Managers;
namespace Impostor.Server.Net.Manager
{
using System.Linq;
using System.Net;
using System.Threading.Tasks;
+using Impostor.Api;
+using Impostor.Api.Events;
+using Impostor.Api.Events.Managers;
+using Impostor.Api.Games;
+using Impostor.Api.Innersloth;
+using Impostor.Api.Innersloth.Data;
using Impostor.Server.Data;
-using Impostor.Server.Events;
-using Impostor.Server.Events.Managers;
-using Impostor.Server.Games;
using Impostor.Server.Net.Redirector;
using Impostor.Server.Net.State;
-using Impostor.Shared.Innersloth;
-using Impostor.Shared.Innersloth.Data;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
-using Impostor.Shared.Innersloth;
+using Impostor.Api.Innersloth;
+using Impostor.Api.Net.Messages;
namespace Impostor.Server.Net.Messages
{
using System;
-using Impostor.Shared.Innersloth.Data;
+using Impostor.Api.Innersloth.Data;
+using Impostor.Api.Net.Messages;
namespace Impostor.Server.Net.Messages
{
-using Impostor.Shared.Innersloth.Data;
+using Impostor.Api.Innersloth.Data;
+using Impostor.Api.Net.Messages;
namespace Impostor.Server.Net.Messages
{
-namespace Impostor.Server.Net.Messages
+using Impostor.Api.Net.Messages;
+
+namespace Impostor.Server.Net.Messages
{
internal static class Message07JoinedGame
{
-using Impostor.Shared.Innersloth.Data;
+using Impostor.Api.Innersloth.Data;
+using Impostor.Api.Net.Messages;
namespace Impostor.Server.Net.Messages
{
-namespace Impostor.Server.Net.Messages
+using Impostor.Api.Net.Messages;
+
+namespace Impostor.Server.Net.Messages
{
internal static class Message11KickPlayer
{
-namespace Impostor.Server.Net.Messages
+using Impostor.Api.Net.Messages;
+
+namespace Impostor.Server.Net.Messages
{
internal static class Message12WaitForHost
{
using System.Net;
+using Impostor.Api.Net.Messages;
namespace Impostor.Server.Net.Messages
{
using System.Collections.Generic;
-using Impostor.Server.Games;
-using Impostor.Shared.Innersloth;
+using Impostor.Api.Games;
+using Impostor.Api.Innersloth;
+using Impostor.Api.Net.Messages;
namespace Impostor.Server.Net.Messages
{
using System.Threading.Tasks;
+using Impostor.Api.Innersloth;
+using Impostor.Api.Innersloth.Data;
+using Impostor.Api.Net.Messages;
using Impostor.Server.Data;
using Impostor.Server.Net.Hazel;
using Impostor.Server.Net.Manager;
using Impostor.Server.Net.Messages;
-using Impostor.Shared.Innersloth;
-using Impostor.Shared.Innersloth.Data;
using Serilog;
using ILogger = Serilog.ILogger;
-using Impostor.Server.Games;
+using Impostor.Api.Games;
+using Impostor.Api.Net;
namespace Impostor.Server.Net.State
{
using System.Threading.Tasks;
+using Impostor.Api.Net;
namespace Impostor.Server.Net.State
{
-using Impostor.Server.Games;
+using Impostor.Api.Games;
+using Impostor.Api.Net;
namespace Impostor.Server.Net.State
{
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
+using Impostor.Api.Innersloth.GameData;
+using Impostor.Api.Net.Messages;
using Impostor.Server.GameData;
using Impostor.Server.GameData.Objects;
-using Impostor.Server.Net.Messages;
-using Impostor.Shared.Innersloth.GameData;
using Microsoft.Extensions.DependencyInjection;
namespace Impostor.Server.Net.State
using System.Threading.Tasks;
-using Impostor.Server.Games;
+using Impostor.Api.Games;
+using Impostor.Api.Innersloth.Data;
+using Impostor.Api.Net;
+using Impostor.Api.Net.Messages;
using Impostor.Server.Net.Messages;
-using Impostor.Shared.Innersloth.Data;
namespace Impostor.Server.Net.State
{
using System.Linq;
+using Impostor.Api.Innersloth.Data;
+using Impostor.Api.Net;
+using Impostor.Api.Net.Messages;
using Impostor.Server.Net.Messages;
-using Impostor.Shared.Innersloth.Data;
namespace Impostor.Server.Net.State
{
using System.Linq;
using System.Threading.Tasks;
-using Impostor.Server.Events;
-using Impostor.Server.Net.Messages;
-using Impostor.Shared.Innersloth.Data;
+using Impostor.Api;
+using Impostor.Api.Events;
+using Impostor.Api.Innersloth.Data;
+using Impostor.Api.Net;
+using Impostor.Api.Net.Messages;
namespace Impostor.Server.Net.State
{
using System.Linq;
using System.Net;
using System.Threading.Tasks;
-using Impostor.Server.Events.Managers;
-using Impostor.Server.Games;
+using Impostor.Api.Events.Managers;
+using Impostor.Api.Games;
+using Impostor.Api.Innersloth;
+using Impostor.Api.Innersloth.Data;
+using Impostor.Api.Net;
+using Impostor.Api.Net.Messages;
using Impostor.Server.Hazel;
using Impostor.Server.Hazel.Messages;
using Impostor.Server.Net.Manager;
using Impostor.Server.Net.Messages;
using Impostor.Server.Net.Redirector;
-using Impostor.Shared.Innersloth;
-using Impostor.Shared.Innersloth.Data;
using Serilog;
using ILogger = Serilog.ILogger;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
+using Impostor.Api.Plugins;
using Microsoft.Extensions.FileSystemGlobbing;
using Microsoft.Extensions.Hosting;
using System;
+using Impostor.Api.Events.Managers;
+using Impostor.Api.Games.Managers;
+using Impostor.Api.Net.Manager;
using Impostor.Server.Data;
using Impostor.Server.Events;
-using Impostor.Server.Events.Managers;
-using Impostor.Server.Games.Managers;
using Impostor.Server.Hazel;
using Impostor.Server.Net;
using Impostor.Server.Net.Factories;
+++ /dev/null
-<Project Sdk="Microsoft.NET.Sdk">
-
- <PropertyGroup>
- <TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
- <DebugType Condition=" '$(Configuration)' == 'Release' ">None</DebugType>
- </PropertyGroup>
-
- <ItemGroup>
- <PackageReference Include="System.Memory" Version="4.5.4" />
- </ItemGroup>
-
-</Project>
+++ /dev/null
-namespace Impostor.Shared.Innersloth.Data
-{
- public enum AlterGameTags : byte
- {
- ChangePrivacy = 1
- }
-}
\ No newline at end of file
+++ /dev/null
-namespace Impostor.Shared.Innersloth.Data
-{
- public enum DisconnectReason
- {
- ExitGame = 0,
- // The game you tried to join is full.
- // Check with the host to see if you can join next round.
- GameFull = 1,
- // The game you tried to join already started.
- // Check with the host to see if you can join next round.
- GameStarted = 2,
- // Could not find the game you're looking for.
- GameMissing = 3,
- IncorrectGame = 18,
- // For these a message can be given, specifying an empty message shows
- // "An unknown error disconnected you from the server."
- CustomMessage1 = 4,
- Custom = 8,
- // CustomMessage3 = 11,
- // CustomMessage4 = 12,
- // CustomMessage5 = 13,
- // CustomMessage6 = 14,
- // CustomMessage7 = 15,
- // You are running an older version of the game.
- // Please update to play with others.
- IncorrectVersion = 5,
- // You cannot rejoin that room.
- // You were banned
- Banned = 6,
- // You can rejoin if the room hasn't started
- // You were kicked
- Kicked = 7,
- // You were banned for hacking.
- // Please stop.
- Hacking = 10,
- Destroy = 16,
- // You disconnected from the host.
- // If this happens often, check your WiFi strength.
- //
- // You disconnected from the server.
- // If this happens often, check your network strength.
- // This may also be a server issue.
- Error = 17,
- // The server stopped this game. Possibly due to inactivity.
- ServerRequest = 19,
- // The Among Us servers are overloaded.
- // Sorry! Please try again later!
- ServerFull = 20,
- FocusLostBackground = 207,
- IntentionalLeaving = 208,
- FocusLost = 209,
- NewConnection = 210
- }
-}
\ No newline at end of file
+++ /dev/null
-using System;
-
-namespace Impostor.Shared.Innersloth.Data
-{
- [Flags]
- public enum GameKeywords : uint
- {
- All = 0,
- Other = 1,
- Spanish = 2,
- Korean = 4,
- Russian = 8,
- Portuguese = 16,
- Arabic = 32,
- Filipone = 64,
- Polish = 128,
- English = 256
- }
-}
\ No newline at end of file
+++ /dev/null
-namespace Impostor.Shared.Innersloth.Data
-{
- public enum GameStates : byte
- {
- NotStarted = 0,
- Started = 1,
- Ended = 2,
- Destroyed = 3
- }
-}
\ No newline at end of file
+++ /dev/null
-using System;
-
-namespace Impostor.Shared.Innersloth.Data
-{
- [Flags]
- public enum MapFlags
- {
- Skeld = 1,
- MiraHQ = 2,
- Polus = 4
- }
-}
\ No newline at end of file
+++ /dev/null
-using Impostor.Shared.Unity;
-
-namespace Impostor.Shared.Innersloth
-{
- public class FloatRange
- {
- private readonly float _min;
- private readonly float _max;
-
- public FloatRange(float min, float max)
- {
- _min = min;
- _max = max;
- }
-
- public float Width => _max - _min;
-
- public float Lerp(float v) => Mathf.Lerp(_min, _max, v);
-
- public float ReverseLerp(float t) => Mathf.Clamp((t - _min) / Width, 0.0f, 1f);
- }
-}
\ No newline at end of file
+++ /dev/null
-using System;
-using System.Buffers.Binary;
-using System.Linq;
-using System.Security.Cryptography;
-using System.Text;
-
-namespace Impostor.Shared.Innersloth
-{
- public static class GameCodeParser
- {
- private const string V2 = "QWXRTYLPESDFGHUJKZOCVBINMA";
- private static readonly int[] V2Map = {
- 25,
- 21,
- 19,
- 10,
- 8,
- 11,
- 12,
- 13,
- 22,
- 15,
- 16,
- 6,
- 24,
- 23,
- 18,
- 7,
- 0,
- 3,
- 9,
- 4,
- 14,
- 20,
- 1,
- 2,
- 5,
- 17
- };
- private static readonly RNGCryptoServiceProvider Random = new RNGCryptoServiceProvider();
-
- public static string IntToGameName(int input)
- {
- // V2.
- if (input < -1)
- {
- return IntToGameNameV2(input);
- }
-
- // V1.
- Span<byte> code = stackalloc byte[4];
- BinaryPrimitives.WriteInt32LittleEndian(code, input);
-#if NETSTANDARD2_0
- return Encoding.UTF8.GetString(code.Slice(0, 4).ToArray());
-#else
- return Encoding.UTF8.GetString(code.Slice(0, 4));
-#endif
- }
-
- private static string IntToGameNameV2(int input)
- {
- var a = input & 0x3FF;
- var b = (input >> 10) & 0xFFFFF;
-
- return new string(new []
- {
- V2[a % 26],
- V2[a / 26],
- V2[b % 26],
- V2[b / 26 % 26],
- V2[b / (26 * 26) % 26],
- V2[b / (26 * 26 * 26) % 26]
- });
- }
-
- public static int GameNameToInt(string code)
- {
- var upper = code.ToUpperInvariant();
- if (upper.Any(x => !char.IsLetter(x)))
- {
- return -1;
- }
-
- var len = code.Length;
- if (len == 6)
- {
- return GameNameToIntV2(upper);
- }
-
- if (len == 4)
- {
- return code[0] | ((code[1] | ((code[2] | (code[3] << 8)) << 8)) << 8);
- }
-
- return -1;
- }
-
- private static int GameNameToIntV2(string code)
- {
- var a = V2Map[code[0] - 65];
- var b = V2Map[code[1] - 65];
- var c = V2Map[code[2] - 65];
- var d = V2Map[code[3] - 65];
- var e = V2Map[code[4] - 65];
- var f = V2Map[code[5] - 65];
-
- var one = (a + 26 * b) & 0x3FF;
- var two = (c + 26 * (d + 26 * (e + 26 * f)));
-
- return (int) (one | ((two << 10) & 0x3FFFFC00) | 0x80000000);
- }
-
- public static int GenerateCode(int len)
- {
- if (len != 4 && len != 6)
- {
- throw new ArgumentException("should be 4 or 6", nameof(len));
- }
-
- // Generate random bytes.
-#if NETSTANDARD2_0
- var data = new byte[len];
-#else
- Span<byte> data = stackalloc byte[len];
-#endif
- Random.GetBytes(data);
-
- // Convert to their char representation.
- Span<char> dataChar = stackalloc char[len];
- for (var i = 0; i < len; i++)
- {
- dataChar[i] = V2[V2Map[data[i] % 26]];
- }
-
-#if NETSTANDARD2_0
- return GameNameToInt(new string(dataChar.ToArray()));
-#else
- return GameNameToInt(new string(dataChar));
-#endif
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-namespace Impostor.Shared.Innersloth.GameData
-{
- public static class GameDataTag
- {
- public const byte DataFlag = 1;
- public const byte RpcFlag = 2;
- public const byte SpawnFlag = 4;
- public const byte DespawnFlag = 5;
- public const byte SceneChangeFlag = 6;
- public const byte ReadyFlag = 7;
- public const byte ChangeSettingsFlag = 8;
- }
-}
\ No newline at end of file
+++ /dev/null
-using System;
-using System.IO;
-using Impostor.Shared.Innersloth.Data;
-
-namespace Impostor.Shared.Innersloth
-{
- public class GameOptionsData
- {
- public byte Version { get; set; }
- public byte MaxPlayers { get; set; }
- public GameKeywords Keywords { get; set; }
- public byte MapId { get; set; }
- public float PlayerSpeedMod { get; set; }
- public float CrewLightMod { get; set; }
- public float ImpostorLightMod { get; set; }
- public float KillCooldown { get; set; }
- public int NumCommonTasks { get; set; }
- public int NumLongTasks { get; set; }
- public int NumShortTasks { get; set; }
- public int NumEmergencyMeetings { get; set; }
- public int EmergencyCooldown { get; set; }
- public int NumImpostors { get; set; }
- public bool GhostsDoTasks { get; set; }
- public int KillDistance { get; set; }
- public int DiscussionTime { get; set; }
- public int VotingTime { get; set; }
- public bool ConfirmImpostor { get; set; }
- public bool VisualTasks { get; set; }
- public bool IsDefaults { get; set; }
-
- public void Serialize(BinaryWriter writer, byte version)
- {
- writer.Write((byte) version);
- writer.Write((byte) MaxPlayers);
- writer.Write((uint) Keywords);
- writer.Write((byte) MapId);
- writer.Write((float) PlayerSpeedMod);
- writer.Write((float) CrewLightMod);
- writer.Write((float) ImpostorLightMod);
- writer.Write((float) KillCooldown);
- writer.Write((byte) NumCommonTasks);
- writer.Write((byte) NumLongTasks);
- writer.Write((byte) NumShortTasks);
- writer.Write((int) NumEmergencyMeetings);
- writer.Write((byte) NumImpostors);
- writer.Write((byte) KillDistance);
- writer.Write((uint) DiscussionTime);
- writer.Write((uint) VotingTime);
- writer.Write((bool) IsDefaults);
- if (version > 1)
- {
- writer.Write((byte) EmergencyCooldown);
- }
-
- if (version > 2)
- {
- writer.Write((bool) ConfirmImpostor);
- writer.Write((bool) VisualTasks);
- }
- }
-
- public static GameOptionsData Deserialize(ReadOnlyMemory<byte> bytes)
- {
- // TODO: Remove memory allocation.
-
- using (var stream = new MemoryStream(bytes.ToArray()))
- using (var reader = new BinaryReader(stream))
- {
- var result = new GameOptionsData();
-
- result.Version = reader.ReadByte();
- result.MaxPlayers = reader.ReadByte();
- result.Keywords = (GameKeywords) reader.ReadUInt32();
- result.MapId = reader.ReadByte();
- result.PlayerSpeedMod = reader.ReadSingle();
- result.CrewLightMod = reader.ReadSingle();
- result.ImpostorLightMod = reader.ReadSingle();
- result.KillCooldown = reader.ReadSingle();
- result.NumCommonTasks = reader.ReadByte();
- result.NumLongTasks = reader.ReadByte();
- result.NumShortTasks = reader.ReadByte();
- result.NumEmergencyMeetings = reader.ReadInt32();
- result.NumImpostors = reader.ReadByte();
- result.KillDistance = reader.ReadByte();
- result.DiscussionTime = reader.ReadInt32();
- result.VotingTime = reader.ReadInt32();
- result.IsDefaults = reader.ReadBoolean();
-
- if (result.Version > 1)
- {
- result.EmergencyCooldown = reader.ReadByte();
- }
-
- if (result.Version > 2)
- {
- result.ConfirmImpostor = reader.ReadBoolean();
- result.VisualTasks = reader.ReadBoolean();
- }
-
- return result;
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-namespace Impostor.Shared.Innersloth
-{
- public class GameVersion
- {
- public static int GetVersion(int year, int month, int day, int rev = 0)
- {
- return (year * 25000) + (month * 1800) + (day * 50) + rev;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-using System.Collections.Generic;
-using System.IO;
-
-namespace Impostor.Shared.Innersloth
-{
- public class RegionInfo
- {
- public RegionInfo(string name, string ping, IReadOnlyList<ServerInfo> servers)
- {
- Name = name;
- Ping = ping;
- Servers = servers;
- }
-
- public string Name { get; }
- public string Ping { get; }
- public IReadOnlyList<ServerInfo> Servers { get; }
-
- public void Serialize(BinaryWriter writer)
- {
- writer.Write(0);
- writer.Write(Name);
- writer.Write(Ping);
- writer.Write(Servers.Count);
-
- foreach (var server in Servers)
- {
- server.Serialize(writer);
- }
- }
-
- public static RegionInfo Deserialize(BinaryReader reader)
- {
- var unknown = reader.ReadInt32();
- var name = reader.ReadString();
- var ping = reader.ReadString();
- var servers = new List<ServerInfo>();
- var serverCount = reader.ReadInt32();
-
- for (var i = 0; i < serverCount; i++)
- {
- servers.Add(ServerInfo.Deserialize(reader));
- }
-
- return new RegionInfo(name, ping, servers);
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-using System.IO;
-using System.Net;
-
-namespace Impostor.Shared.Innersloth
-{
- public class ServerInfo
- {
- public string Name { get; }
- public string Ip { get; }
- public ushort Port { get; }
-
- public ServerInfo(string name, string ip, ushort port)
- {
- Name = name;
- Ip = ip;
- Port = port;
- }
-
- public void Serialize(BinaryWriter writer)
- {
- writer.Write(Name);
- writer.Write(IPAddress.Parse(Ip).GetAddressBytes());
- writer.Write(Port);
- writer.Write(0);
- }
-
- public static ServerInfo Deserialize(BinaryReader reader)
- {
- var name = reader.ReadString();
- var ip = new IPAddress(reader.ReadBytes(4)).ToString();
- var port = reader.ReadUInt16();
- var unknown = reader.ReadInt32();
-
- return new ServerInfo(name, ip, port);
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-namespace Impostor.Shared.Unity
-{
- public static class Mathf
- {
- /// <summary>
- /// <para>Clamps the given value between the given minimum float and maximum float values. Returns the given value if it is within the min and max range.</para>
- /// </summary>
- /// <param name="value">The floating point value to restrict inside the range defined by the min and max values.</param>
- /// <param name="min">The minimum floating point value to compare against.</param>
- /// <param name="max">The maximum floating point value to compare against.</param>
- /// <returns>
- /// <para>The float result between the min and max values.</para>
- /// </returns>
- public static float Clamp(float value, float min, float max)
- {
- if ((double) value < (double) min)
- value = min;
- else if ((double) value > (double) max)
- value = max;
- return value;
- }
-
- /// <summary>
- /// <para>Clamps value between 0 and 1 and returns value.</para>
- /// </summary>
- /// <param name="value"></param>
- public static float Clamp01(float value)
- {
- if ((double) value < 0.0)
- return 0.0f;
- return (double) value > 1.0 ? 1f : value;
- }
-
- /// <summary>
- /// <para>Linearly interpolates between a and b by t.</para>
- /// </summary>
- /// <param name="a">The start value.</param>
- /// <param name="b">The end value.</param>
- /// <param name="t">The interpolation value between the two floats.</param>
- /// <returns>
- /// <para>The interpolated float result between the two float values.</para>
- /// </returns>
- public static float Lerp(float a, float b, float t) => a + (b - a) * Mathf.Clamp01(t);
- }
-}
\ No newline at end of file
+++ /dev/null
-using System;
-using System.Text;
-
-namespace Impostor.Shared.Utils
-{
- public static class HexUtils
- {
- public static string HexDump(byte[] bytes, int bytesPerLine = 16)
- {
- if (bytes == null) return "<null>";
- int bytesLength = bytes.Length;
-
- char[] HexChars = "0123456789ABCDEF".ToCharArray();
-
- int firstHexColumn =
- 8 // 8 characters for the address
- + 3; // 3 spaces
-
- int firstCharColumn = firstHexColumn
- + bytesPerLine * 3 // - 2 digit for the hexadecimal value and 1 space
- + (bytesPerLine - 1) / 8 // - 1 extra space every 8 characters from the 9th
- + 2; // 2 spaces
-
- int lineLength = firstCharColumn
- + bytesPerLine // - characters to show the ascii value
- + Environment.NewLine.Length; // Carriage return and line feed (should normally be 2)
-
- char[] line = (new String(' ', lineLength - Environment.NewLine.Length) + Environment.NewLine).ToCharArray();
- int expectedLines = (bytesLength + bytesPerLine - 1) / bytesPerLine;
- StringBuilder result = new StringBuilder(expectedLines * lineLength);
-
- for (int i = 0; i < bytesLength; i += bytesPerLine)
- {
- line[0] = HexChars[(i >> 28) & 0xF];
- line[1] = HexChars[(i >> 24) & 0xF];
- line[2] = HexChars[(i >> 20) & 0xF];
- line[3] = HexChars[(i >> 16) & 0xF];
- line[4] = HexChars[(i >> 12) & 0xF];
- line[5] = HexChars[(i >> 8) & 0xF];
- line[6] = HexChars[(i >> 4) & 0xF];
- line[7] = HexChars[(i >> 0) & 0xF];
-
- int hexColumn = firstHexColumn;
- int charColumn = firstCharColumn;
-
- for (int j = 0; j < bytesPerLine; j++)
- {
- if (j > 0 && (j & 7) == 0) hexColumn++;
- if (i + j >= bytesLength)
- {
- line[hexColumn] = ' ';
- line[hexColumn + 1] = ' ';
- line[charColumn] = ' ';
- }
- else
- {
- byte b = bytes[i + j];
- line[hexColumn] = HexChars[(b >> 4) & 0xF];
- line[hexColumn + 1] = HexChars[b & 0xF];
- line[charColumn] = (b < 32 ? '·' : (char)b);
- }
- hexColumn += 3;
- charColumn++;
- }
- result.Append(line);
- }
- return result.ToString();
- }
- }
-}
\ No newline at end of file
-using Impostor.Shared.Innersloth;
+using Impostor.Api.Innersloth;
using Xunit;
namespace Impostor.Tests
using Hazel;
+using Impostor.Api.Net.Messages;
using Impostor.Server.Net.Hazel.Messages;
using Impostor.Server.Net.Messages;
using Xunit;
# Visual Studio Version 16
VisualStudioVersion = 16.0.30503.244
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Impostor.Shared", "Impostor.Shared\Impostor.Shared.csproj", "{1D109A96-FADF-41B9-A845-457A7A5C0C5A}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Impostor.Tests", "Impostor.Tests\Impostor.Tests.csproj", "{C1385C67-A7DD-46D2-80F6-FA428B85FB22}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{56DD9707-D811-4056-9E2C-8A9CC2479B07}"
{1B0390AF-A4F3-4FE4-B093-708B0135C0B3}.Release|Any CPU.Build.0 = Release|Any CPU
{1B0390AF-A4F3-4FE4-B093-708B0135C0B3}.Release|x86.ActiveCfg = Release|Any CPU
{1B0390AF-A4F3-4FE4-B093-708B0135C0B3}.Release|x86.Build.0 = Release|Any CPU
- {1D109A96-FADF-41B9-A845-457A7A5C0C5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {1D109A96-FADF-41B9-A845-457A7A5C0C5A}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {1D109A96-FADF-41B9-A845-457A7A5C0C5A}.Debug|x86.ActiveCfg = Debug|Any CPU
- {1D109A96-FADF-41B9-A845-457A7A5C0C5A}.Debug|x86.Build.0 = Debug|Any CPU
- {1D109A96-FADF-41B9-A845-457A7A5C0C5A}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {1D109A96-FADF-41B9-A845-457A7A5C0C5A}.Release|Any CPU.Build.0 = Release|Any CPU
- {1D109A96-FADF-41B9-A845-457A7A5C0C5A}.Release|x86.ActiveCfg = Release|Any CPU
- {1D109A96-FADF-41B9-A845-457A7A5C0C5A}.Release|x86.Build.0 = Release|Any CPU
{C1385C67-A7DD-46D2-80F6-FA428B85FB22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C1385C67-A7DD-46D2-80F6-FA428B85FB22}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C1385C67-A7DD-46D2-80F6-FA428B85FB22}.Debug|x86.ActiveCfg = Debug|Any CPU