mirror of
https://github.com/Impostor/Impostor.git
synced 2026-10-20 01:46:11 +00:00
Merge remote-tracking branch 'origin/2021.3.5'
This commit is contained in:
commit
a1c59363a1
17 files changed
+135
-33
No files matched your search
+4
-1
@@ -163,7 +163,7 @@ csharp_new_line_before_open_brace = all
|
||||
csharp_new_line_before_else = true
|
||||
csharp_new_line_before_catch = true
|
||||
csharp_new_line_before_finally = true
|
||||
csharp_new_line_before_members_in_object_initializers = true
|
||||
# csharp_new_line_before_members_in_object_initializers = true TODO seems like Rider/ReSharper has the value inverted, uncomment when its fixed
|
||||
csharp_new_line_before_members_in_anonymous_types = true
|
||||
csharp_new_line_between_query_expression_clauses = true
|
||||
|
||||
@@ -228,3 +228,6 @@ csharp_preserve_single_line_statements = true
|
||||
|
||||
# warning RS0037: PublicAPI.txt is missing '#nullable enable'
|
||||
dotnet_diagnostic.RS0037.severity = none
|
||||
|
||||
# ReSharper properties
|
||||
resharper_trailing_comma_in_multiline_lists = true
|
||||
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace Impostor.Api
|
||||
{
|
||||
public interface IDateTimeProvider
|
||||
{
|
||||
DateTimeOffset UtcNow { get; }
|
||||
}
|
||||
}
|
||||
@@ -24,8 +24,8 @@ namespace Impostor.Server.Net
|
||||
private readonly ClientManager _clientManager;
|
||||
private readonly GameManager _gameManager;
|
||||
|
||||
public Client(ILogger<Client> logger, IOptions<AntiCheatConfig> antiCheatOptions, ClientManager clientManager, GameManager gameManager, string name, IHazelConnection connection, ISet<Mod> mods)
|
||||
: base(name, connection, mods)
|
||||
public Client(ILogger<Client> logger, IOptions<AntiCheatConfig> antiCheatOptions, ClientManager clientManager, GameManager gameManager, string name, int gameVersion, IHazelConnection connection, ISet<Mod> mods)
|
||||
: base(name, gameVersion, connection, mods)
|
||||
{
|
||||
_logger = logger;
|
||||
_antiCheatConfig = antiCheatOptions.Value;
|
||||
|
||||
@@ -16,9 +16,10 @@ namespace Impostor.Server.Net
|
||||
{
|
||||
internal abstract class ClientBase : IClient
|
||||
{
|
||||
protected ClientBase(string name, IHazelConnection connection, ISet<Mod> mods)
|
||||
protected ClientBase(string name, int gameVersion, IHazelConnection connection, ISet<Mod> mods)
|
||||
{
|
||||
Name = name;
|
||||
GameVersion = gameVersion;
|
||||
Connection = connection;
|
||||
Mods = mods;
|
||||
Items = new ConcurrentDictionary<object, object>();
|
||||
@@ -40,6 +41,8 @@ namespace Impostor.Server.Net
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public int GameVersion { get; }
|
||||
|
||||
public ISet<Mod> Mods { get; }
|
||||
|
||||
public Dictionary<int, string> ModIdMap { get; }
|
||||
|
||||
@@ -18,9 +18,9 @@ namespace Impostor.Server.Net.Factories
|
||||
|
||||
public ClientBase Create(IHazelConnection connection, string name, int clientVersion, ISet<Mod> mods)
|
||||
{
|
||||
var client = ActivatorUtilities.CreateInstance<TClient>(_serviceProvider, name, connection, mods);
|
||||
var client = ActivatorUtilities.CreateInstance<TClient>(_serviceProvider, name, clientVersion, connection, mods);
|
||||
connection.Client = client;
|
||||
return client;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@ using Impostor.Api.Net.Messages.Rpcs;
|
||||
using Impostor.Server.Events.Player;
|
||||
using Impostor.Server.Net.Inner.Objects.Components;
|
||||
using Impostor.Server.Net.State;
|
||||
using Impostor.Server.Utils;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
@@ -24,14 +23,14 @@ namespace Impostor.Server.Net.Inner.Objects
|
||||
private readonly ILogger<InnerPlayerControl> _logger;
|
||||
private readonly IEventManager _eventManager;
|
||||
private readonly Game _game;
|
||||
private readonly ServerEnvironment _serverEnvironment;
|
||||
private readonly IDateTimeProvider _dateTimeProvider;
|
||||
|
||||
public InnerPlayerControl(ILogger<InnerPlayerControl> logger, IServiceProvider serviceProvider, IEventManager eventManager, Game game, ServerEnvironment serverEnvironment)
|
||||
public InnerPlayerControl(ILogger<InnerPlayerControl> logger, IServiceProvider serviceProvider, IEventManager eventManager, Game game, IDateTimeProvider dateTimeProvider)
|
||||
{
|
||||
_logger = logger;
|
||||
_eventManager = eventManager;
|
||||
_game = game;
|
||||
_serverEnvironment = serverEnvironment;
|
||||
_dateTimeProvider = dateTimeProvider;
|
||||
|
||||
Physics = ActivatorUtilities.CreateInstance<InnerPlayerPhysics>(serviceProvider, this, _eventManager, _game);
|
||||
NetworkTransform = ActivatorUtilities.CreateInstance<InnerCustomNetworkTransform>(serviceProvider, this, _game);
|
||||
@@ -520,8 +519,7 @@ namespace Impostor.Server.Net.Inner.Objects
|
||||
|
||||
private async ValueTask<bool> HandleMurderPlayer(ClientPlayer sender, IInnerPlayerControl? target)
|
||||
{
|
||||
// TODO record replay with timestamps
|
||||
if (!_serverEnvironment.IsReplay && !PlayerInfo.CanMurder(_game))
|
||||
if (!PlayerInfo.CanMurder(_game, _dateTimeProvider))
|
||||
{
|
||||
if (await sender.Client.ReportCheatAsync(RpcCalls.MurderPlayer, "Client tried to murder too fast"))
|
||||
{
|
||||
@@ -537,7 +535,7 @@ namespace Impostor.Server.Net.Inner.Objects
|
||||
}
|
||||
}
|
||||
|
||||
PlayerInfo.LastMurder = DateTimeOffset.UtcNow;
|
||||
PlayerInfo.LastMurder = _dateTimeProvider.UtcNow;
|
||||
|
||||
if (!target.PlayerInfo.IsDead)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Impostor.Api;
|
||||
using Impostor.Api.Games;
|
||||
using Impostor.Api.Innersloth;
|
||||
using Impostor.Api.Innersloth.Customization;
|
||||
@@ -40,14 +41,14 @@ namespace Impostor.Server.Net.Inner.Objects
|
||||
|
||||
public DateTimeOffset LastMurder { get; set; }
|
||||
|
||||
public bool CanMurder(IGame game)
|
||||
public bool CanMurder(IGame game, IDateTimeProvider dateTimeProvider)
|
||||
{
|
||||
if (!IsImpostor)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return DateTimeOffset.UtcNow.Subtract(LastMurder).TotalSeconds >= game.Options.KillCooldown;
|
||||
return dateTimeProvider.UtcNow.Subtract(LastMurder).TotalSeconds >= game.Options.KillCooldown;
|
||||
}
|
||||
|
||||
public void Serialize(IMessageWriter writer)
|
||||
|
||||
@@ -24,12 +24,13 @@ namespace Impostor.Server.Net.Redirector
|
||||
|
||||
public ClientRedirector(
|
||||
string name,
|
||||
int gameVersion,
|
||||
HazelConnection connection,
|
||||
ISet<Mod> mods,
|
||||
ClientManager clientManager,
|
||||
INodeProvider nodeProvider,
|
||||
INodeLocator nodeLocator)
|
||||
: base(name, connection, mods)
|
||||
: base(name, gameVersion, connection, mods)
|
||||
{
|
||||
_clientManager = clientManager;
|
||||
_nodeProvider = nodeProvider;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Impostor.Api;
|
||||
using Impostor.Api.Events.Managers;
|
||||
using Impostor.Api.Games;
|
||||
using Impostor.Api.Games.Managers;
|
||||
@@ -117,6 +118,7 @@ namespace Impostor.Server
|
||||
.Get<AnnouncementsServerConfig>() ?? new AnnouncementsServerConfig();
|
||||
|
||||
services.AddSingleton<ServerEnvironment>();
|
||||
services.AddSingleton<IDateTimeProvider, RealDateTimeProvider>();
|
||||
|
||||
services.Configure<DebugConfig>(host.Configuration.GetSection(DebugConfig.Section));
|
||||
services.Configure<AntiCheatConfig>(host.Configuration.GetSection(AntiCheatConfig.Section));
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
using Impostor.Api;
|
||||
|
||||
namespace Impostor.Server
|
||||
{
|
||||
public class RealDateTimeProvider : IDateTimeProvider
|
||||
{
|
||||
public DateTimeOffset UtcNow => DateTimeOffset.UtcNow;
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,8 @@ namespace Impostor.Server.Recorder
|
||||
private bool _createdGame;
|
||||
private bool _recordAfter;
|
||||
|
||||
public ClientRecorder(ILogger<Client> logger, IOptions<AntiCheatConfig> antiCheatOptions, ClientManager clientManager, GameManager gameManager, string name, HazelConnection connection, ISet<Mod> mods, PacketRecorder recorder)
|
||||
: base(logger, antiCheatOptions, clientManager, gameManager, name, connection, mods)
|
||||
public ClientRecorder(ILogger<Client> logger, IOptions<AntiCheatConfig> antiCheatOptions, ClientManager clientManager, GameManager gameManager, string name, int gameVersion, HazelConnection connection, ISet<Mod> mods, PacketRecorder recorder)
|
||||
: base(logger, antiCheatOptions, clientManager, gameManager, name, gameVersion, connection, mods)
|
||||
{
|
||||
_recorder = recorder;
|
||||
_isFirst = true;
|
||||
|
||||
@@ -8,6 +8,7 @@ using Impostor.Api.Games;
|
||||
using Impostor.Api.Net.Messages;
|
||||
using Impostor.Server.Config;
|
||||
using Impostor.Server.Net;
|
||||
using Impostor.Server.Utils;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.ObjectPool;
|
||||
@@ -24,6 +25,7 @@ namespace Impostor.Server.Recorder
|
||||
private readonly ILogger<PacketRecorder> _logger;
|
||||
private readonly ObjectPool<PacketSerializationContext> _pool;
|
||||
private readonly Channel<byte[]> _channel;
|
||||
private DateTimeOffset _startTime;
|
||||
|
||||
public PacketRecorder(ILogger<PacketRecorder> logger, IOptions<DebugConfig> options, ObjectPool<PacketSerializationContext> pool)
|
||||
{
|
||||
@@ -42,10 +44,13 @@ namespace Impostor.Server.Recorder
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
_startTime = DateTimeOffset.UtcNow;
|
||||
_logger.LogInformation("PacketRecorder is enabled, writing packets to {0}.", _path);
|
||||
|
||||
var writer = File.Open(_path, FileMode.CreateNew, FileAccess.Write, FileShare.Read);
|
||||
|
||||
await WriteFileHeaderAsync();
|
||||
|
||||
// Handle messages.
|
||||
try
|
||||
{
|
||||
@@ -73,7 +78,7 @@ namespace Impostor.Server.Recorder
|
||||
|
||||
try
|
||||
{
|
||||
WriteHeader(context, RecordedPacketType.Connect);
|
||||
WritePacketHeader(context, RecordedPacketType.Connect);
|
||||
WriteClient(context, client, true);
|
||||
WriteLength(context);
|
||||
|
||||
@@ -93,7 +98,7 @@ namespace Impostor.Server.Recorder
|
||||
|
||||
try
|
||||
{
|
||||
WriteHeader(context, RecordedPacketType.Disconnect);
|
||||
WritePacketHeader(context, RecordedPacketType.Disconnect);
|
||||
WriteClient(context, client, false);
|
||||
context.Writer.Write(reason);
|
||||
WriteLength(context);
|
||||
@@ -114,7 +119,7 @@ namespace Impostor.Server.Recorder
|
||||
|
||||
try
|
||||
{
|
||||
WriteHeader(context, RecordedPacketType.Message);
|
||||
WritePacketHeader(context, RecordedPacketType.Message);
|
||||
WriteClient(context, client, false);
|
||||
WritePacket(context, reader, messageType);
|
||||
WriteLength(context);
|
||||
@@ -135,7 +140,7 @@ namespace Impostor.Server.Recorder
|
||||
|
||||
try
|
||||
{
|
||||
WriteHeader(context, RecordedPacketType.GameCreated);
|
||||
WritePacketHeader(context, RecordedPacketType.GameCreated);
|
||||
WriteClient(context, client, false);
|
||||
WriteGameCode(context, gameCode);
|
||||
WriteLength(context);
|
||||
@@ -148,11 +153,33 @@ namespace Impostor.Server.Recorder
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteHeader(PacketSerializationContext context, RecordedPacketType type)
|
||||
private async Task WriteFileHeaderAsync()
|
||||
{
|
||||
var context = _pool.Get();
|
||||
|
||||
try
|
||||
{
|
||||
context.Writer.Write((uint)ServerReplayVersion.Initial);
|
||||
context.Writer.Write(_startTime.ToUnixTimeMilliseconds());
|
||||
context.Writer.Write(DotnetUtils.GetVersion());
|
||||
|
||||
await WriteAsync(context.Stream);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_pool.Return(context);
|
||||
}
|
||||
}
|
||||
|
||||
private void WritePacketHeader(PacketSerializationContext context, RecordedPacketType type)
|
||||
{
|
||||
// Length placeholder.
|
||||
context.Writer.Write((int) 0);
|
||||
context.Writer.Write((byte) type);
|
||||
context.Writer.Write(0);
|
||||
|
||||
// Timestamp relative to recording start time.
|
||||
context.Writer.Write((uint)(DateTimeOffset.UtcNow - _startTime).TotalMilliseconds);
|
||||
|
||||
context.Writer.Write((byte)type);
|
||||
}
|
||||
|
||||
private static void WriteClient(PacketSerializationContext context, ClientBase client, bool full)
|
||||
@@ -164,18 +191,19 @@ namespace Impostor.Server.Recorder
|
||||
|
||||
if (full)
|
||||
{
|
||||
context.Writer.Write((byte) addressBytes.Length);
|
||||
context.Writer.Write((byte)addressBytes.Length);
|
||||
context.Writer.Write(addressBytes);
|
||||
context.Writer.Write((ushort) address.Port);
|
||||
context.Writer.Write((ushort)address.Port);
|
||||
context.Writer.Write(client.Name);
|
||||
context.Writer.Write(client.GameVersion);
|
||||
}
|
||||
}
|
||||
|
||||
private static void WritePacket(PacketSerializationContext context, IMessageReader reader, MessageType messageType)
|
||||
{
|
||||
context.Writer.Write((byte) messageType);
|
||||
context.Writer.Write((byte) reader.Tag);
|
||||
context.Writer.Write((int) reader.Length);
|
||||
context.Writer.Write((byte)messageType);
|
||||
context.Writer.Write((byte)reader.Tag);
|
||||
context.Writer.Write((int)reader.Length);
|
||||
context.Writer.Write(reader.Buffer, reader.Offset, reader.Length);
|
||||
}
|
||||
|
||||
@@ -189,7 +217,7 @@ namespace Impostor.Server.Recorder
|
||||
var length = context.Stream.Position;
|
||||
|
||||
context.Stream.Position = 0;
|
||||
context.Writer.Write((int) length);
|
||||
context.Writer.Write((int)length);
|
||||
context.Stream.Position = length;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace Impostor.Server.Recorder
|
||||
{
|
||||
/// <summary>
|
||||
/// Version of the server replay data format.
|
||||
/// </summary>
|
||||
public enum ServerReplayVersion
|
||||
{
|
||||
/// <summary>
|
||||
/// Initial version
|
||||
/// </summary>
|
||||
Initial = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Latest version
|
||||
/// </summary>
|
||||
Latest = Initial,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
using Impostor.Api;
|
||||
|
||||
namespace Impostor.Tools.ServerReplay
|
||||
{
|
||||
public class FakeDateTimeProvider : IDateTimeProvider
|
||||
{
|
||||
public DateTimeOffset UtcNow { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Impostor.Api;
|
||||
using Impostor.Api.Events.Managers;
|
||||
using Impostor.Api.Games;
|
||||
using Impostor.Api.Games.Managers;
|
||||
@@ -42,6 +43,7 @@ namespace Impostor.Tools.ServerReplay
|
||||
private static MockGameCodeFactory _gameCodeFactory;
|
||||
private static ClientManager _clientManager;
|
||||
private static GameManager _gameManager;
|
||||
private static FakeDateTimeProvider _fakeDateTimeProvider;
|
||||
|
||||
private static async Task Main(string[] args)
|
||||
{
|
||||
@@ -53,7 +55,7 @@ namespace Impostor.Tools.ServerReplay
|
||||
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
|
||||
foreach (var file in Directory.GetFiles(args[0]))
|
||||
foreach (var file in Directory.GetFiles(args[0], "*.dat"))
|
||||
{
|
||||
// Clear.
|
||||
Connections.Clear();
|
||||
@@ -67,6 +69,7 @@ namespace Impostor.Tools.ServerReplay
|
||||
_gameCodeFactory = _serviceProvider.GetRequiredService<MockGameCodeFactory>();
|
||||
_clientManager = _serviceProvider.GetRequiredService<ClientManager>();
|
||||
_gameManager = _serviceProvider.GetRequiredService<GameManager>();
|
||||
_fakeDateTimeProvider = _serviceProvider.GetRequiredService<FakeDateTimeProvider>();
|
||||
|
||||
await using (var stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
using (var reader = new BinaryReader(stream))
|
||||
@@ -89,6 +92,9 @@ namespace Impostor.Tools.ServerReplay
|
||||
IsReplay = true
|
||||
});
|
||||
|
||||
services.AddSingleton<FakeDateTimeProvider>();
|
||||
services.AddSingleton<IDateTimeProvider>(p => p.GetRequiredService<FakeDateTimeProvider>());
|
||||
|
||||
services.AddLogging(builder =>
|
||||
{
|
||||
builder.ClearProviders();
|
||||
@@ -114,6 +120,17 @@ namespace Impostor.Tools.ServerReplay
|
||||
|
||||
private static async Task ParseSession(BinaryReader reader)
|
||||
{
|
||||
var protocolVersion = (ServerReplayVersion)reader.ReadUInt32();
|
||||
if (protocolVersion < ServerReplayVersion.Initial || protocolVersion > ServerReplayVersion.Latest)
|
||||
{
|
||||
throw new NotSupportedException("Session's protocol version is unsupported");
|
||||
}
|
||||
|
||||
var startTime = _fakeDateTimeProvider.UtcNow = DateTimeOffset.FromUnixTimeMilliseconds(reader.ReadInt64());
|
||||
var serverVersion = reader.ReadString();
|
||||
|
||||
Logger.Information("Loaded session (server: {ServerVersion}, recorded at {StartTime})", serverVersion, startTime);
|
||||
|
||||
while (reader.BaseStream.Position < reader.BaseStream.Length)
|
||||
{
|
||||
var dataLength = reader.ReadInt32();
|
||||
@@ -122,6 +139,7 @@ namespace Impostor.Tools.ServerReplay
|
||||
await using (var stream = new MemoryStream(data))
|
||||
using (var readerInner = new BinaryReader(stream))
|
||||
{
|
||||
_fakeDateTimeProvider.UtcNow = startTime + TimeSpan.FromMilliseconds(readerInner.ReadUInt32());
|
||||
await ParsePacket(readerInner);
|
||||
}
|
||||
}
|
||||
@@ -143,11 +161,12 @@ namespace Impostor.Tools.ServerReplay
|
||||
var addressPort = reader.ReadUInt16();
|
||||
var address = new IPEndPoint(new IPAddress(addressBytes), addressPort);
|
||||
var name = reader.ReadString();
|
||||
var gameVersion = reader.ReadInt32();
|
||||
|
||||
// Create and register connection.
|
||||
var connection = new MockHazelConnection(address);
|
||||
|
||||
await _clientManager.RegisterConnectionAsync(connection, name, 50516550, null);
|
||||
await _clientManager.RegisterConnectionAsync(connection, name, gameVersion, null);
|
||||
|
||||
// Store reference for ourselfs.
|
||||
Connections.Add(clientId, connection);
|
||||
|
||||
Whitespace-only changes.
BIN
Binary file not shown.
Reference in new issue
Block a user