Fix MurderPlayer for vanilla clients

In 2023.10.24, vanilla started expecting that CheckMurder is handled on
the server. That is, unless the host is modded, then CheckMurder calls
are handled by the host as before
This commit is contained in:
miniduikboot committed 2023-10-26 23:14:09 +02:00
1 parent 3d60cf58a9
commit 821a2248a7
5 files changed
+48 -9

No files matched your search

@@ -0,0 +1,13 @@
using System;
namespace Impostor.Api.Innersloth
{
[Flags]
public enum MurderResultFlags
{
Succeeded = 1,
FailedError = 2,
FailedProtected = 4,
DecisionByHost = 8,
}
}
@@ -1,18 +1,21 @@
using Impostor.Api.Games;
using Impostor.Api.Net.Inner.Objects;
using Impostor.Api.Innersloth;
namespace Impostor.Api.Net.Messages.Rpcs
{
public static class Rpc12MurderPlayer
{
public static void Serialize(IMessageWriter writer, IInnerPlayerControl target)
public static void Serialize(IMessageWriter writer, IInnerPlayerControl target, MurderResultFlags result)
{
writer.Write(target);
writer.Write((int)result);
}
public static void Deserialize(IMessageReader reader, IGame game, out IInnerPlayerControl? target)
public static void Deserialize(IMessageReader reader, IGame game, out IInnerPlayerControl? target, out MurderResultFlags result)
{
target = reader.ReadNetObject<IInnerPlayerControl>(game);
result = (MurderResultFlags)reader.ReadInt32();
}
}
}
@@ -102,7 +102,7 @@ namespace Impostor.Server.Net.Inner.Objects
((InnerPlayerControl)target).Die(DeathReason.Kill);
using var writer = Game.StartRpc(NetId, RpcCalls.MurderPlayer);
Rpc12MurderPlayer.Serialize(writer, target);
Rpc12MurderPlayer.Serialize(writer, target, MurderResultFlags.Succeeded);
await Game.FinishRpcAsync(writer);
await _eventManager.CallAsync(new PlayerMurderEvent(Game, Game.GetClientPlayer(OwnerId)!, this, target));
@@ -25,12 +25,14 @@ namespace Impostor.Server.Net.Inner.Objects
{
private static readonly byte ColorsCount = (byte)Enum.GetValues<ColorType>().Length;
private readonly Game _game;
private readonly ILogger<InnerPlayerControl> _logger;
private readonly IEventManager _eventManager;
private readonly IDateTimeProvider _dateTimeProvider;
public InnerPlayerControl(ICustomMessageManager<ICustomRpc> customMessageManager, Game game, ILogger<InnerPlayerControl> logger, IServiceProvider serviceProvider, IEventManager eventManager, IDateTimeProvider dateTimeProvider) : base(customMessageManager, game)
{
_game = game;
_logger = logger;
_eventManager = eventManager;
_dateTimeProvider = dateTimeProvider;
@@ -250,8 +252,8 @@ namespace Impostor.Server.Net.Inner.Objects
return false;
}
Rpc12MurderPlayer.Deserialize(reader, Game, out var murdered);
return await HandleMurderPlayer(sender, murdered);
Rpc12MurderPlayer.Deserialize(reader, Game, out var murdered, out var result);
return await HandleMurderPlayer(sender, murdered, result);
}
case RpcCalls.SendChat:
@@ -652,8 +654,6 @@ namespace Impostor.Server.Net.Inner.Objects
}
}
PlayerInfo.LastMurder = _dateTimeProvider.UtcNow - TimeSpan.FromMilliseconds(sender.Client.Connection.AveragePing);
if (target == null || target.PlayerInfo.IsImpostor)
{
if (await sender.Client.ReportCheatAsync(RpcCalls.CheckMurder, "Client tried to murder invalid target"))
@@ -662,12 +662,26 @@ namespace Impostor.Server.Net.Inner.Objects
}
}
PlayerInfo.LastMurder = _dateTimeProvider.UtcNow - TimeSpan.FromMilliseconds(sender.Client.Connection.AveragePing);
IsMurdering = target;
return true;
// Check if host authority mode is on
if (_game.IsHostModded()) {
// Pass the RPC on unharmed, the client will handle it
return true;
}
// TODO check if protected by GA
if (target != null)
{
MurderPlayerAsync(target);
}
return false;
}
private async ValueTask<bool> HandleMurderPlayer(ClientPlayer sender, IInnerPlayerControl? target)
private async ValueTask<bool> HandleMurderPlayer(ClientPlayer sender, IInnerPlayerControl? target, MurderResultFlags result)
{
if (target == null || target.PlayerInfo.IsImpostor)
{
+9
View File
@@ -145,5 +145,14 @@ namespace Impostor.Server.Net.State
.Select(p => p.Client.Connection)
.Where(c => c != null && c.IsConnected)!;
}
internal bool IsHostModded()
{
if (Host == null) {
return false;
} else {
return Host.Client.GameVersion.Revision >= 25;
}
}
}
}