Link player classes internally

This commit is contained in:
AeonLucid committed 2020-10-23 07:19:45 +02:00
1 parent be5a876113
commit dc7ba92fd5
16 files changed
+206 -77

No files matched your search

+6
View File
@@ -3,6 +3,7 @@ using System.Net;
using System.Threading.Tasks;
using Impostor.Api.Innersloth;
using Impostor.Api.Innersloth.Data;
using Impostor.Api.Innersloth.Net;
using Impostor.Api.Net;
using Impostor.Api.Net.Messages;
@@ -32,6 +33,11 @@ namespace Impostor.Api.Games
int HostId { get; }
IClientPlayer GetClientPlayer(int clientId);
T FindObjectByNetId<T>(uint netId)
where T : InnerNetObject;
/// <summary>
/// Send the message to all players.
/// </summary>
+36 -2
View File
@@ -1,4 +1,5 @@
using Impostor.Api.Innersloth.Net;
using Impostor.Api.Games;
using Impostor.Api.Innersloth.Net;
using Impostor.Api.Innersloth.Net.Objects;
namespace Impostor.Api.Innersloth.Data
@@ -8,7 +9,14 @@ namespace Impostor.Api.Innersloth.Data
/// </summary>
public class GameNet
{
public InnerGameData GameData { get; internal set; }
private readonly IGame _game;
public GameNet(IGame game)
{
_game = game;
}
public InnerGameData GameData { get; private set; }
internal void OnSpawn(InnerNetObject netObj)
{
@@ -16,6 +24,23 @@ namespace Impostor.Api.Innersloth.Data
{
GameData = data;
}
else if (netObj is InnerPlayerControl control)
{
// Hook up InnerPlayerControl <-> IClientPlayer.
var clientPlayer = _game.GetClientPlayer(control.OwnerId);
if (clientPlayer != null)
{
clientPlayer.Character = control;
}
// Hook up InnerPlayerControl <-> InnerPlayerControl.PlayerInfo.
control.PlayerInfo = GameData.GetPlayerById(control.PlayerId);
if (control.PlayerInfo == null)
{
GameData.AddPlayer(control);
}
}
}
internal void OnDestroy(InnerNetObject netObj)
@@ -24,6 +49,15 @@ namespace Impostor.Api.Innersloth.Data
{
GameData = null;
}
else if (netObj is InnerPlayerControl control)
{
// Remove InnerPlayerControl <-> IClientPlayer.
var clientPlayer = _game.GetClientPlayer(control.OwnerId);
if (clientPlayer != null)
{
clientPlayer.Character = null;
}
}
}
}
}
@@ -1,4 +1,5 @@
using Impostor.Api.Net.Messages;
using Impostor.Api.Net;
using Impostor.Api.Net.Messages;
namespace Impostor.Api.Innersloth.Net
{
@@ -10,10 +11,10 @@ namespace Impostor.Api.Innersloth.Net
public SpawnFlags SpawnFlags { get; internal set; }
public abstract void HandleRpc(byte callId, IMessageReader reader);
public abstract void HandleRpc(IClientPlayer sender, byte callId, IMessageReader reader);
public abstract bool Serialize(IMessageWriter writer, bool initialState);
public abstract void Deserialize(IMessageReader reader, bool initialState);
public abstract void Deserialize(IClientPlayer sender, IMessageReader reader, bool initialState);
}
}
@@ -1,4 +1,5 @@
using System.Numerics;
using Impostor.Api.Net;
using Impostor.Api.Net.Messages;
using Microsoft.Extensions.Logging;
@@ -43,7 +44,7 @@ namespace Impostor.Api.Innersloth.Net.Objects.Components
return new Vector2(XRange.Lerp(v1), YRange.Lerp(v2));
}
public override void HandleRpc(byte callId, IMessageReader reader)
public override void HandleRpc(IClientPlayer sender, byte callId, IMessageReader reader)
{
if (callId == 0)
{
@@ -74,7 +75,7 @@ namespace Impostor.Api.Innersloth.Net.Objects.Components
return true;
}
public override void Deserialize(IMessageReader reader, bool initialState)
public override void Deserialize(IClientPlayer sender, IMessageReader reader, bool initialState)
{
var sequenceId = reader.ReadUInt16();
@@ -1,10 +1,11 @@
using Impostor.Api.Net.Messages;
using Impostor.Api.Net;
using Impostor.Api.Net.Messages;
namespace Impostor.Api.Innersloth.Net.Objects.Components
{
public class InnerPlayerPhysics : InnerNetObject
{
public override void HandleRpc(byte callId, IMessageReader reader)
public override void HandleRpc(IClientPlayer sender, byte callId, IMessageReader reader)
{
throw new System.NotImplementedException();
}
@@ -14,7 +15,7 @@ namespace Impostor.Api.Innersloth.Net.Objects.Components
throw new System.NotImplementedException();
}
public override void Deserialize(IMessageReader reader, bool initialState)
public override void Deserialize(IClientPlayer sender, IMessageReader reader, bool initialState)
{
throw new System.NotImplementedException();
}
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Impostor.Api.Net;
using Impostor.Api.Net.Messages;
namespace Impostor.Api.Innersloth.Net.Objects.Components
@@ -13,7 +14,7 @@ namespace Impostor.Api.Innersloth.Net.Objects.Components
_votes = new Dictionary<int, int[]>();
}
public override void HandleRpc(byte callId, IMessageReader reader)
public override void HandleRpc(IClientPlayer sender, byte callId, IMessageReader reader)
{
throw new NotImplementedException();
}
@@ -23,7 +24,7 @@ namespace Impostor.Api.Innersloth.Net.Objects.Components
throw new NotImplementedException();
}
public override void Deserialize(IMessageReader reader, bool initialState)
public override void Deserialize(IClientPlayer sender, IMessageReader reader, bool initialState)
{
var votes = _votes;
var unknown = reader.ReadByte();
@@ -15,19 +15,19 @@ namespace Impostor.Api.Innersloth.Net.Objects
public byte PlayerId { get; }
public string PlayerName { get; private set; }
public string PlayerName { get; internal set; }
public byte ColorId { get; private set; }
public byte ColorId { get; internal set; }
public uint HatId { get; private set; }
public uint HatId { get; internal set; }
public uint PetId { get; private set; }
public uint PetId { get; internal set; }
public uint SkinId { get; private set; }
public uint SkinId { get; internal set; }
public bool Disconnected { get; private set; }
public bool Disconnected { get; internal set; }
public bool IsImpostor { get; private set; }
public bool IsImpostor { get; internal set; }
public bool IsDead { get; private set; }
@@ -1,7 +1,9 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using Impostor.Api.Games;
using Impostor.Api.Innersloth.Net.Objects.Components;
using Impostor.Api.Net;
using Impostor.Api.Net.Messages;
namespace Impostor.Api.Innersloth.Net.Objects
@@ -9,12 +11,12 @@ namespace Impostor.Api.Innersloth.Net.Objects
public partial class InnerGameData : InnerNetObject
{
private readonly IGame _game;
private readonly List<PlayerInfo> _allPlayers;
private readonly ConcurrentDictionary<byte, PlayerInfo> _allPlayers;
public InnerGameData(IGame game)
{
_game = game;
_allPlayers = new List<PlayerInfo>();
_allPlayers = new ConcurrentDictionary<byte, PlayerInfo>();
Components.Add(this);
Components.Add(new InnerVoteBanSystem());
@@ -22,22 +24,25 @@ namespace Impostor.Api.Innersloth.Net.Objects
public int PlayerCount => _allPlayers.Count;
public IReadOnlyList<PlayerInfo> Players => _allPlayers;
public IReadOnlyDictionary<byte, PlayerInfo> Players => _allPlayers;
internal void AddPlayer(InnerPlayerControl control)
{
var playerId = control.PlayerId;
var playerInfo = new PlayerInfo(control.PlayerId);
if (_allPlayers.TryAdd(playerId, playerInfo))
{
control.PlayerInfo = playerInfo;
}
}
public PlayerInfo GetPlayerById(byte id)
{
foreach (var player in _allPlayers)
{
if (player.PlayerId == id)
{
return player;
}
}
return null;
return _allPlayers.TryGetValue(id, out var player) ? player : null;
}
public override void HandleRpc(byte callId, IMessageReader reader)
public override void HandleRpc(IClientPlayer sender, byte callId, IMessageReader reader)
{
throw new NotImplementedException();
}
@@ -47,7 +52,7 @@ namespace Impostor.Api.Innersloth.Net.Objects
throw new NotImplementedException();
}
public override void Deserialize(IMessageReader reader, bool initialState)
public override void Deserialize(IClientPlayer sender, IMessageReader reader, bool initialState)
{
if (initialState)
{
@@ -56,8 +61,13 @@ namespace Impostor.Api.Innersloth.Net.Objects
for (var i = 0; i < num; i++)
{
var playerInfo = new PlayerInfo(reader.ReadByte());
playerInfo.Deserialize(reader);
_allPlayers.Add(playerInfo);
if (!_allPlayers.TryAdd(playerInfo.PlayerId, playerInfo))
{
throw new ImpostorException("Failed to add player to InnerGameData.");
}
}
}
else
@@ -1,4 +1,5 @@
using Impostor.Api.Games;
using Impostor.Api.Net;
using Impostor.Api.Net.Messages;
namespace Impostor.Api.Innersloth.Net.Objects
@@ -14,7 +15,7 @@ namespace Impostor.Api.Innersloth.Net.Objects
Components.Add(this);
}
public override void HandleRpc(byte callId, IMessageReader reader)
public override void HandleRpc(IClientPlayer sender, byte callId, IMessageReader reader)
{
throw new System.NotImplementedException();
}
@@ -24,7 +25,7 @@ namespace Impostor.Api.Innersloth.Net.Objects
throw new System.NotImplementedException();
}
public override void Deserialize(IMessageReader reader, bool initialState)
public override void Deserialize(IClientPlayer sender, IMessageReader reader, bool initialState)
{
throw new System.NotImplementedException();
}
@@ -1,6 +1,8 @@
using System;
using System.Linq;
using Impostor.Api.Games;
using Impostor.Api.Innersloth.Data;
using Impostor.Api.Net;
using Impostor.Api.Net.Messages;
namespace Impostor.Api.Innersloth.Net.Objects
@@ -24,18 +26,17 @@ namespace Impostor.Api.Innersloth.Net.Objects
private void PopulateButtons(byte reporter)
{
_playerStates = new PlayerVoteArea[_gameNet.GameData.PlayerCount];
for (var i = 0; i < _playerStates.Length; i++)
{
var player = _gameNet.GameData.Players[i];
var playerVoteArea = _playerStates[i] = new PlayerVoteArea(this, player.PlayerId);
playerVoteArea.SetDead(player.PlayerId == reporter, player.Disconnected || player.IsDead);
}
_playerStates = _gameNet.GameData.Players
.Select(x =>
{
var area = new PlayerVoteArea(this, x.Key);
area.SetDead(x.Value.PlayerId == reporter, x.Value.Disconnected || x.Value.IsDead);
return area;
})
.ToArray();
}
public override void HandleRpc(byte callId, IMessageReader reader)
public override void HandleRpc(IClientPlayer sender, byte callId, IMessageReader reader)
{
throw new NotImplementedException();
}
@@ -45,7 +46,7 @@ namespace Impostor.Api.Innersloth.Net.Objects
throw new NotImplementedException();
}
public override void Deserialize(IMessageReader reader, bool initialState)
public override void Deserialize(IClientPlayer sender, IMessageReader reader, bool initialState)
{
if (initialState)
{
@@ -1,6 +1,7 @@
using System;
using Impostor.Api.Games;
using Impostor.Api.Innersloth.Net.Objects.Components;
using Impostor.Api.Net;
using Impostor.Api.Net.Messages;
using Microsoft.Extensions.DependencyInjection;
@@ -25,9 +26,36 @@ namespace Impostor.Api.Innersloth.Net.Objects
public byte PlayerId { get; private set; }
public override void HandleRpc(byte callId, IMessageReader reader)
public InnerGameData.PlayerInfo PlayerInfo { get; internal set; }
public override void HandleRpc(IClientPlayer sender, byte callId, IMessageReader reader)
{
throw new NotImplementedException();
switch (callId)
{
case 3:
{
var length = reader.ReadPackedInt32();
for (var i = 0; i < length; i++)
{
var playerId = reader.ReadByte();
var player = _game.GameNet.GameData.GetPlayerById(playerId);
player.IsImpostor = true;
}
break;
}
case 6:
{
PlayerInfo.PlayerName = reader.ReadString();
break;
}
default:
break;
}
}
public override bool Serialize(IMessageWriter writer, bool initialState)
@@ -35,7 +63,7 @@ namespace Impostor.Api.Innersloth.Net.Objects
throw new NotImplementedException();
}
public override void Deserialize(IMessageReader reader, bool initialState)
public override void Deserialize(IClientPlayer sender, IMessageReader reader, bool initialState)
{
if (initialState)
{
@@ -1,7 +1,9 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using Impostor.Api.Games;
using Impostor.Api.Innersloth.Net.Objects.Systems;
using Impostor.Api.Innersloth.Net.Objects.Systems.ShipStatus;
using Impostor.Api.Net;
using Impostor.Api.Net.Messages;
namespace Impostor.Api.Innersloth.Net.Objects
@@ -28,18 +30,44 @@ namespace Impostor.Api.Innersloth.Net.Objects
_systems.Add(SystemTypes.Sabotage, new SabotageSystemType(new[]
{
(IActivatable) _systems[SystemTypes.Comms],
(IActivatable) _systems[SystemTypes.Reactor],
(IActivatable) _systems[SystemTypes.LifeSupp],
(IActivatable) _systems[SystemTypes.Electrical],
(IActivatable)_systems[SystemTypes.Comms],
(IActivatable)_systems[SystemTypes.Reactor],
(IActivatable)_systems[SystemTypes.LifeSupp],
(IActivatable)_systems[SystemTypes.Electrical],
}));
Components.Add(this);
}
public override void HandleRpc(byte callId, IMessageReader reader)
public override void HandleRpc(IClientPlayer sender, byte callId, IMessageReader reader)
{
throw new System.NotImplementedException();
switch (callId)
{
case 27:
{
// Close doors.
if (!sender.Character.PlayerInfo.IsImpostor)
{
Console.WriteLine($"OOPS Fake Impostor: {sender.Character.PlayerInfo.PlayerName} did doors");
}
break;
}
case 28:
{
var systemType = (SystemTypes)reader.ReadByte();
var player = _game.FindObjectByNetId<InnerPlayerControl>(reader.ReadPackedUInt32());
var amount = reader.ReadByte();
if (systemType == SystemTypes.Sabotage && !player.PlayerInfo.IsImpostor)
{
Console.WriteLine($"OOPS Fake Impostor: {player.PlayerInfo.PlayerName} did {(SystemTypes) amount}");
}
break;
}
}
}
public override bool Serialize(IMessageWriter writer, bool initialState)
@@ -47,7 +75,7 @@ namespace Impostor.Api.Innersloth.Net.Objects
throw new System.NotImplementedException();
}
public override void Deserialize(IMessageReader reader, bool initialState)
public override void Deserialize(IClientPlayer sender, IMessageReader reader, bool initialState)
{
if (initialState)
{
@@ -67,7 +95,7 @@ namespace Impostor.Api.Innersloth.Net.Objects
foreach (var systemType in SystemTypeHelpers.AllTypes)
{
// TODO: Not sure what is going on here, check.
if ((count & 1 << (int) (systemType & (SystemTypes.ShipTasks | SystemTypes.Doors))) != 0L)
if ((count & 1 << (int)(systemType & (SystemTypes.ShipTasks | SystemTypes.Doors))) != 0L)
{
if (_systems.TryGetValue(systemType, out var system))
{
+3
View File
@@ -1,5 +1,6 @@
using System.Threading.Tasks;
using Impostor.Api.Games;
using Impostor.Api.Innersloth.Net.Objects;
namespace Impostor.Api.Net
{
@@ -23,6 +24,8 @@ namespace Impostor.Api.Net
/// </summary>
LimboStates Limbo { get; set; }
InnerPlayerControl Character { get; set; }
ValueTask KickAsync();
ValueTask BanAsync();
@@ -1,4 +1,5 @@
using System.Threading.Tasks;
using Impostor.Api.Innersloth.Net.Objects;
using Impostor.Api.Net;
namespace Impostor.Server.Net.State
@@ -19,6 +20,9 @@ namespace Impostor.Server.Net.State
/// <inheritdoc />
public LimboStates Limbo { get; set; }
// TODO: Correct visibility to set internal only.
public InnerPlayerControl Character { get; set; }
public bool IsHost => Game?.Host == this;
public string Scene { get; internal set; }
+22 -17
View File
@@ -123,7 +123,7 @@ namespace Impostor.Server.Net.State
var netId = reader.ReadPackedUInt32();
if (_allObjectsFast.TryGetValue(netId, out var obj))
{
obj.Deserialize(reader, false);
obj.Deserialize(sender, reader, false);
}
else
{
@@ -138,8 +138,14 @@ namespace Impostor.Server.Net.State
var netId = reader.ReadPackedUInt32();
if (_allObjectsFast.TryGetValue(netId, out var obj))
{
// Console.WriteLine(reader.ReadByte());
// obj.HandleRpc(reader.ReadByte(), reader);
// TODO: Remove try catch.
try
{
obj.HandleRpc(sender, reader.ReadByte(), reader);
}
catch (NotImplementedException)
{
}
}
else
{
@@ -209,24 +215,12 @@ namespace Impostor.Server.Net.State
var readerSub = reader.ReadMessage();
if (readerSub.Length > 0)
{
obj.Deserialize(readerSub, true);
obj.Deserialize(sender, readerSub, true);
}
GameNet.OnSpawn(obj);
}
if ((innerNetObject.SpawnFlags & SpawnFlags.IsClientCharacter) != SpawnFlags.None)
{
if (TryGetPlayer(ownerClientId, out var clientById))
{
_logger.LogTrace("Spawn character");
}
else
{
_logger.LogTrace("Spawn unowned character");
}
}
continue;
}
@@ -251,7 +245,7 @@ namespace Impostor.Server.Net.State
}
RemoveNetObject(obj);
GameNet.OnSpawn(obj);
GameNet.OnDestroy(obj);
_logger.LogDebug("Destroyed InnerNetObject {0} ({1}), OwnerId {2}", obj.GetType().Name, netId, obj.OwnerId);
}
else
@@ -327,5 +321,16 @@ namespace Impostor.Server.Net.State
obj.NetId = uint.MaxValue;
}
public T FindObjectByNetId<T>(uint netId)
where T : InnerNetObject
{
if (_allObjectsFast.TryGetValue(netId, out var obj))
{
return (T) obj;
}
return null;
}
}
}
+6 -1
View File
@@ -51,7 +51,7 @@ namespace Impostor.Server.Net.State
Code = code;
HostId = -1;
GameState = GameStates.NotStarted;
GameNet = new GameNet();
GameNet = new GameNet(this);
Options = options;
_clientManager = clientManager;
_eventManager = eventManager;
@@ -92,6 +92,11 @@ namespace Impostor.Server.Net.State
return false;
}
public IClientPlayer GetClientPlayer(int clientId)
{
return _players.TryGetValue(clientId, out var clientPlayer) ? clientPlayer : null;
}
public ValueTask EndAsync()
{
return _gameManager.RemoveAsync(Code);