mirror of
https://github.com/Impostor/Impostor.git
synced 2026-10-20 01:46:11 +00:00
Added GameData spawn
This commit is contained in:
1 parent
8392fe4237
commit
5f922f5f83
16 files changed
+492
-88
No files matched your search
@@ -0,0 +1,29 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Impostor.Server.GameData
|
||||
{
|
||||
public class GameObject
|
||||
{
|
||||
public GameObject()
|
||||
{
|
||||
Components = new List<object>();
|
||||
}
|
||||
|
||||
protected List<object> Components { get; }
|
||||
|
||||
public List<T> GetComponentsInChildren<T>()
|
||||
{
|
||||
var result = new List<T>();
|
||||
|
||||
foreach (var component in Components)
|
||||
{
|
||||
if (component.GetType().IsAssignableTo(typeof(T)))
|
||||
{
|
||||
result.Add((T) component);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Impostor.Server.Net.Messages;
|
||||
|
||||
namespace Impostor.Server.GameData
|
||||
{
|
||||
public abstract class InnerNetObject : GameObject
|
||||
{
|
||||
public uint NetId { get; set; }
|
||||
|
||||
public int OwnerId { get; set; }
|
||||
|
||||
public SpawnFlags SpawnFlags { get; internal set; }
|
||||
|
||||
public abstract void HandleRpc(byte callId, IMessageReader reader);
|
||||
|
||||
public abstract bool Serialize(IMessageWriter writer, bool initialState);
|
||||
|
||||
public abstract void Deserialize(IMessageReader reader, bool initialState);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using Impostor.Server.Net.Messages;
|
||||
|
||||
namespace Impostor.Server.GameData.Objects.Components
|
||||
{
|
||||
public class InnerCustomNetworkTransform : InnerNetObject
|
||||
{
|
||||
public override void HandleRpc(byte callId, IMessageReader reader)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool Serialize(IMessageWriter writer, bool initialState)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Deserialize(IMessageReader reader, bool initialState)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using Impostor.Server.Net.Messages;
|
||||
|
||||
namespace Impostor.Server.GameData.Objects.Components
|
||||
{
|
||||
public class InnerPlayerPhysics : InnerNetObject
|
||||
{
|
||||
public override void HandleRpc(byte callId, IMessageReader reader)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool Serialize(IMessageWriter writer, bool initialState)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Deserialize(IMessageReader reader, bool initialState)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using Impostor.Server.Net.Messages;
|
||||
|
||||
namespace Impostor.Server.GameData.Objects.Components
|
||||
{
|
||||
public class InnerVoteBanSystem : InnerNetObject
|
||||
{
|
||||
public override void HandleRpc(byte callId, IMessageReader reader)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool Serialize(IMessageWriter writer, bool initialState)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Deserialize(IMessageReader reader, bool initialState)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using Impostor.Server.GameData.Objects.Components;
|
||||
using Impostor.Server.Games;
|
||||
using Impostor.Server.Net.Messages;
|
||||
|
||||
namespace Impostor.Server.GameData.Objects
|
||||
{
|
||||
public class InnerGameData : InnerNetObject
|
||||
{
|
||||
private readonly IGame _game;
|
||||
|
||||
public InnerGameData(IGame game)
|
||||
{
|
||||
_game = game;
|
||||
|
||||
Components.Add(this);
|
||||
Components.Add(new InnerVoteBanSystem());
|
||||
}
|
||||
|
||||
public override void HandleRpc(byte callId, IMessageReader reader)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool Serialize(IMessageWriter writer, bool initialState)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Deserialize(IMessageReader reader, bool initialState)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using Impostor.Server.Games;
|
||||
using Impostor.Server.Net.Messages;
|
||||
|
||||
namespace Impostor.Server.GameData.Objects
|
||||
{
|
||||
public class InnerLobbyBehaviour : InnerNetObject
|
||||
{
|
||||
private readonly IGame _game;
|
||||
|
||||
public InnerLobbyBehaviour(IGame game)
|
||||
{
|
||||
_game = game;
|
||||
|
||||
Components.Add(this);
|
||||
}
|
||||
|
||||
public override void HandleRpc(byte callId, IMessageReader reader)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool Serialize(IMessageWriter writer, bool initialState)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Deserialize(IMessageReader reader, bool initialState)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using Impostor.Server.Games;
|
||||
using Impostor.Server.Net.Messages;
|
||||
|
||||
namespace Impostor.Server.GameData.Objects
|
||||
{
|
||||
public class InnerMeetingHud : InnerNetObject
|
||||
{
|
||||
private readonly IGame _game;
|
||||
|
||||
public InnerMeetingHud(IGame game)
|
||||
{
|
||||
_game = game;
|
||||
|
||||
Components.Add(this);
|
||||
}
|
||||
|
||||
public override void HandleRpc(byte callId, IMessageReader reader)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool Serialize(IMessageWriter writer, bool initialState)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Deserialize(IMessageReader reader, bool initialState)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using Impostor.Server.GameData.Objects.Components;
|
||||
using Impostor.Server.Games;
|
||||
using Impostor.Server.Net.Messages;
|
||||
|
||||
namespace Impostor.Server.GameData.Objects
|
||||
{
|
||||
public class InnerPlayerControl : InnerNetObject
|
||||
{
|
||||
private readonly IGame _game;
|
||||
|
||||
public InnerPlayerControl(IGame game)
|
||||
{
|
||||
_game = game;
|
||||
|
||||
Components.Add(this);
|
||||
Components.Add(new InnerPlayerPhysics());
|
||||
Components.Add(new InnerCustomNetworkTransform());
|
||||
}
|
||||
|
||||
public override void HandleRpc(byte callId, IMessageReader reader)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool Serialize(IMessageWriter writer, bool initialState)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Deserialize(IMessageReader reader, bool initialState)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using Impostor.Server.Games;
|
||||
using Impostor.Server.Net.Messages;
|
||||
|
||||
namespace Impostor.Server.GameData.Objects
|
||||
{
|
||||
public class InnerShipStatus : InnerNetObject
|
||||
{
|
||||
private readonly IGame _game;
|
||||
|
||||
public InnerShipStatus(IGame game)
|
||||
{
|
||||
_game = game;
|
||||
|
||||
Components.Add(this);
|
||||
}
|
||||
|
||||
public override void HandleRpc(byte callId, IMessageReader reader)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool Serialize(IMessageWriter writer, bool initialState)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Deserialize(IMessageReader reader, bool initialState)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace Impostor.Server.GameData
|
||||
{
|
||||
[Flags]
|
||||
public enum SpawnFlags : byte
|
||||
{
|
||||
None = 0,
|
||||
IsClientCharacter = 1,
|
||||
}
|
||||
}
|
||||
@@ -21,16 +21,16 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Impostor.Server.Api\Impostor.Server.Api.csproj"/>
|
||||
<ProjectReference Include="..\Impostor.Server.Hazel\Impostor.Server.Hazel.csproj"/>
|
||||
<ProjectReference Include="..\Impostor.Shared\Impostor.Shared.csproj"/>
|
||||
<ProjectReference Include="..\Impostor.Server.Api\Impostor.Server.Api.csproj" />
|
||||
<ProjectReference Include="..\Impostor.Server.Hazel\Impostor.Server.Hazel.csproj" />
|
||||
<ProjectReference Include="..\Impostor.Shared\Impostor.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="5.0.0-rc.1.20451.7"/>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0-rc.1.20451.14"/>
|
||||
<PackageReference Include="Serilog.Extensions.Hosting" Version="3.1.0"/>
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1"/>
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="5.0.0-rc.1.20451.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0-rc.1.20451.14" />
|
||||
<PackageReference Include="Serilog.Extensions.Hosting" Version="3.1.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using Hazel;
|
||||
using Impostor.Server.Data;
|
||||
using Impostor.Server.Games;
|
||||
using Impostor.Server.Games.Managers;
|
||||
using Impostor.Server.Hazel.Messages;
|
||||
using Impostor.Server.Net.Manager;
|
||||
using Impostor.Server.Net.Messages;
|
||||
using Impostor.Shared.Innersloth;
|
||||
@@ -149,6 +146,8 @@ namespace Impostor.Server.Net
|
||||
|
||||
// Handle packet.
|
||||
var readerCopy = reader.Slice(reader.Position);
|
||||
|
||||
// TODO: Return value, either a bool (to cancel) or a writer (to cancel (null) or modify/overwrite).
|
||||
await Player.Game.HandleGameData(readerCopy, Player, toPlayer);
|
||||
|
||||
// Broadcast packet to all other players.
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
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
|
||||
{
|
||||
internal partial class Game
|
||||
{
|
||||
private static readonly Type[] SpawnableObjects =
|
||||
{
|
||||
typeof(InnerShipStatus), // ShipStatus
|
||||
typeof(InnerMeetingHud),
|
||||
typeof(InnerLobbyBehaviour),
|
||||
typeof(InnerGameData),
|
||||
typeof(InnerPlayerControl),
|
||||
typeof(InnerShipStatus), // HeadQuarters
|
||||
typeof(InnerShipStatus), // PlanetMap
|
||||
typeof(InnerShipStatus), // AprilShipStatus
|
||||
};
|
||||
|
||||
private readonly List<InnerNetObject> _allObjects = new List<InnerNetObject>();
|
||||
private readonly Dictionary<uint, InnerNetObject> _allObjectsFast = new Dictionary<uint, InnerNetObject>();
|
||||
|
||||
public async ValueTask HandleGameData(IMessageReader parent, IClientPlayer sender, bool toPlayer)
|
||||
{
|
||||
// Find target player.
|
||||
IClientPlayer target = null;
|
||||
|
||||
if (toPlayer)
|
||||
{
|
||||
var targetId = parent.ReadPackedInt32();
|
||||
if (!TryGetPlayer(targetId, out target))
|
||||
{
|
||||
// Invalid target.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse GameData messages.
|
||||
while (parent.Position < parent.Length)
|
||||
{
|
||||
var reader = parent.ReadMessage();
|
||||
|
||||
switch (reader.Tag)
|
||||
{
|
||||
case GameDataTag.DataFlag:
|
||||
{
|
||||
var objectNetId = reader.ReadPackedUInt32();
|
||||
Logger.Verbose("> Update {0}", objectNetId);
|
||||
break;
|
||||
}
|
||||
|
||||
case GameDataTag.RpcFlag:
|
||||
{
|
||||
var objectNetId = reader.ReadPackedUInt32();
|
||||
var callId = reader.ReadByte();
|
||||
Logger.Verbose("> RPC {0} {1}", objectNetId, callId);
|
||||
break;
|
||||
}
|
||||
|
||||
case GameDataTag.SpawnFlag:
|
||||
{
|
||||
var objectId = reader.ReadPackedUInt32();
|
||||
if (objectId < SpawnableObjects.Length)
|
||||
{
|
||||
var innerNetObject = (InnerNetObject) ActivatorUtilities.CreateInstance(_serviceProvider, SpawnableObjects[objectId], this);
|
||||
var id = reader.ReadPackedInt32();
|
||||
|
||||
innerNetObject.SpawnFlags = (SpawnFlags) reader.ReadByte();
|
||||
|
||||
var components = innerNetObject.GetComponentsInChildren<InnerNetObject>();
|
||||
var componentsCount = reader.ReadPackedInt32();
|
||||
|
||||
if (componentsCount != components.Count)
|
||||
{
|
||||
Logger.Error(
|
||||
"Children didn't match for spawnable {0}, name {1} ({2} != {3})",
|
||||
objectId,
|
||||
innerNetObject.GetType().Name,
|
||||
componentsCount,
|
||||
components.Count);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (var i = 0; i < componentsCount; i++)
|
||||
{
|
||||
var obj = components[i];
|
||||
|
||||
obj.NetId = reader.ReadPackedUInt32();
|
||||
obj.OwnerId = id;
|
||||
|
||||
if (!AddNetObject(obj))
|
||||
{
|
||||
Logger.Verbose("Failed to AddNetObject.");
|
||||
|
||||
obj.NetId = uint.MaxValue;
|
||||
break;
|
||||
}
|
||||
|
||||
var readerSub = reader.ReadMessage();
|
||||
if (readerSub.Length > 0)
|
||||
{
|
||||
obj.Deserialize(readerSub, true);
|
||||
}
|
||||
}
|
||||
|
||||
if ((innerNetObject.SpawnFlags & SpawnFlags.IsClientCharacter) != SpawnFlags.None)
|
||||
{
|
||||
if (TryGetPlayer(id, out var clientById))
|
||||
{
|
||||
Logger.Verbose("Spawn character");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Verbose("Spawn unowned character");
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
Logger.Error("Couldn't find spawnable object {0}.", objectId);
|
||||
break;
|
||||
}
|
||||
|
||||
case GameDataTag.DespawnFlag:
|
||||
{
|
||||
var objectNetId = reader.ReadPackedUInt32();
|
||||
Logger.Verbose("> Destroy {0}", objectNetId);
|
||||
break;
|
||||
}
|
||||
|
||||
case GameDataTag.SceneChangeFlag:
|
||||
{
|
||||
var clientId = reader.ReadPackedInt32();
|
||||
var targetScene = reader.ReadString();
|
||||
Logger.Verbose("> Scene {0} to {1}", clientId, targetScene);
|
||||
break;
|
||||
}
|
||||
|
||||
case GameDataTag.ReadyFlag:
|
||||
{
|
||||
var clientId = reader.ReadPackedInt32();
|
||||
Logger.Verbose("> IsReady {0}", clientId);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
Logger.Debug("Bad GameData tag {0}", reader.Tag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool AddNetObject(InnerNetObject obj)
|
||||
{
|
||||
if (_allObjectsFast.ContainsKey(obj.NetId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_allObjects.Add(obj);
|
||||
_allObjectsFast.Add(obj.NetId, obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void RemoveNetObject(InnerNetObject obj)
|
||||
{
|
||||
var index = _allObjects.IndexOf(obj);
|
||||
if (index > -1)
|
||||
{
|
||||
_allObjects.RemoveAt(index);
|
||||
}
|
||||
|
||||
_allObjectsFast.Remove(obj.NetId);
|
||||
|
||||
obj.NetId = uint.MaxValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks;
|
||||
using Impostor.Server.Games;
|
||||
using Impostor.Server.Net.Messages;
|
||||
using Impostor.Shared.Innersloth.Data;
|
||||
@@ -195,80 +194,5 @@ namespace Impostor.Server.Net.State
|
||||
|
||||
await BroadcastJoinMessage(packet, true, sender);
|
||||
}
|
||||
|
||||
public async ValueTask HandleGameData(IMessageReader parent, IClientPlayer sender, bool toPlayer)
|
||||
{
|
||||
// Find target player.
|
||||
IClientPlayer target = null;
|
||||
|
||||
if (toPlayer)
|
||||
{
|
||||
var targetId = parent.ReadPackedInt32();
|
||||
if (!TryGetPlayer(targetId, out target))
|
||||
{
|
||||
// Invalid target.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse GameData messages.
|
||||
while (parent.Position < parent.Length)
|
||||
{
|
||||
var reader = parent.ReadMessage();
|
||||
|
||||
switch (reader.Tag)
|
||||
{
|
||||
case GameDataTag.DataFlag:
|
||||
{
|
||||
var objectNetId = reader.ReadPackedUInt32();
|
||||
Logger.Verbose("> Update {0}", objectNetId);
|
||||
break;
|
||||
}
|
||||
|
||||
case GameDataTag.RpcFlag:
|
||||
{
|
||||
var objectNetId = reader.ReadPackedUInt32();
|
||||
var callId = reader.ReadByte();
|
||||
Logger.Verbose("> RPC {0} {1}", objectNetId, callId);
|
||||
break;
|
||||
}
|
||||
|
||||
case GameDataTag.SpawnFlag:
|
||||
{
|
||||
var objectId = reader.ReadPackedUInt32();
|
||||
Logger.Verbose("> Spawn {0}", objectId);
|
||||
break;
|
||||
}
|
||||
|
||||
case GameDataTag.DespawnFlag:
|
||||
{
|
||||
var objectNetId = reader.ReadPackedUInt32();
|
||||
Logger.Verbose("> Destroy {0}", objectNetId);
|
||||
break;
|
||||
}
|
||||
|
||||
case GameDataTag.SceneChangeFlag:
|
||||
{
|
||||
var clientId = reader.ReadPackedInt32();
|
||||
var targetScene = reader.ReadString();
|
||||
Logger.Verbose("> Scene {0} to {1}", clientId, targetScene);
|
||||
break;
|
||||
}
|
||||
|
||||
case GameDataTag.ReadyFlag:
|
||||
{
|
||||
var clientId = reader.ReadPackedInt32();
|
||||
Logger.Verbose("> IsReady {0}", clientId);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
Logger.Debug("Bad GameData tag {0}", reader.Tag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
@@ -19,6 +20,7 @@ namespace Impostor.Server.Net.State
|
||||
{
|
||||
private static readonly ILogger Logger = Log.ForContext<Game>();
|
||||
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IGameManager _gameManager;
|
||||
private readonly IClientManager _clientManager;
|
||||
private readonly IMatchmaker _matchmaker;
|
||||
@@ -26,6 +28,7 @@ namespace Impostor.Server.Net.State
|
||||
private readonly HashSet<IPAddress> _bannedIps;
|
||||
|
||||
public Game(
|
||||
IServiceProvider serviceProvider,
|
||||
IGameManager gameManager,
|
||||
INodeLocator nodeLocator,
|
||||
IPEndPoint publicIp,
|
||||
@@ -34,6 +37,7 @@ namespace Impostor.Server.Net.State
|
||||
IMatchmaker matchmaker,
|
||||
IClientManager clientManager)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
_gameManager = gameManager;
|
||||
_players = new ConcurrentDictionary<int, IClientPlayer>();
|
||||
_bannedIps = new HashSet<IPAddress>();
|
||||
|
||||
Reference in new issue
Block a user