From ae50126729a153ac522418e437f56535826d5922 Mon Sep 17 00:00:00 2001 From: miniduikboot Date: Thu, 20 Jun 2024 18:14:02 +0200 Subject: [PATCH] Spawn PlayerInfo's if host is not authoritive --- src/Impostor.Server/Net/State/Game.Data.cs | 32 +++++++++++++++++-- .../Net/State/Game.Outgoing.cs | 21 ++++++++++++ 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/src/Impostor.Server/Net/State/Game.Data.cs b/src/Impostor.Server/Net/State/Game.Data.cs index af4a4b02..0619c931 100644 --- a/src/Impostor.Server/Net/State/Game.Data.cs +++ b/src/Impostor.Server/Net/State/Game.Data.cs @@ -5,6 +5,7 @@ using Impostor.Api; using Impostor.Api.Innersloth; using Impostor.Api.Net.Inner; using Impostor.Api.Unity; +using Impostor.Hazel; using Impostor.Server.Events.Meeting; using Impostor.Server.Events.Player; using Impostor.Server.Net.Inner; @@ -30,6 +31,8 @@ namespace Impostor.Server.Net.State /// private const int CurrentClient = -3; + private const int ServerOwned = -4; + private static readonly Dictionary SpawnableObjects = new() { [0] = typeof(InnerSkeldShipStatus), @@ -51,7 +54,7 @@ namespace Impostor.Server.Net.State private readonly Dictionary _allObjectsFast = new Dictionary(); - private uint _nextNetId = 1; + private uint _nextNetId = 100000; public T? FindObjectByNetId(uint netId) where T : IInnerNetObject @@ -257,6 +260,31 @@ namespace Impostor.Server.Net.State sender.Scene = scene; _logger.LogTrace("> Scene {0} to {1}", clientId, sender.Scene); + + // If the player is not authoritive, also spawn PlayerInfo + // TODO check if this is the correct location + if (!sender.Client.GameVersion.HasDisableServerAuthorityFlag) + { + var playerInfo = (InnerPlayerInfo)ActivatorUtilities.CreateInstance(_serviceProvider, typeof(InnerPlayerInfo), this); + playerInfo.SpawnFlags = SpawnFlags.None; // TODO?? + playerInfo.NetId = _nextNetId++; + playerInfo.OwnerId = -4; + playerInfo.ClientId = clientId; + playerInfo.PlayerId = 0; // TODO + + if (!AddNetObject(playerInfo)) + { + _logger.LogTrace("Couldn't spawn PlayerInfo"); + playerInfo.NetId = uint.MaxValue; + break; + } + _logger.LogTrace("Spawning PlayerInfo (netId {Netid})", playerInfo.NetId); + await OnSpawnAsync(sender, playerInfo); + var writer = MessageWriter.Get(MessageType.Reliable); + WriteObjectSpawn(writer, playerInfo); + await SendToAllAsync(writer); + } + break; } @@ -314,8 +342,6 @@ namespace Impostor.Server.Net.State private async ValueTask OnSpawnAsync(ClientPlayer sender, InnerNetObject netObj) { - _nextNetId = netObj.NetId + 1; - switch (netObj) { case InnerGameManager innerGameManager: diff --git a/src/Impostor.Server/Net/State/Game.Outgoing.cs b/src/Impostor.Server/Net/State/Game.Outgoing.cs index d2bbe06e..bd6cd999 100644 --- a/src/Impostor.Server/Net/State/Game.Outgoing.cs +++ b/src/Impostor.Server/Net/State/Game.Outgoing.cs @@ -100,5 +100,26 @@ namespace Impostor.Server.Net.State { Message12WaitForHostS2C.Serialize(message, clear, Code, player.Client.Id); } + + private void WriteObjectSpawn(IMessageWriter message, InnerNetObject obj) + { + message.StartMessage(MessageFlags.GameData); + Code.Serialize(message); + message.StartMessage(GameDataTag.SpawnFlag); + message.WritePacked(11u); // TODO don't hardcode + message.WritePacked(obj.OwnerId); + message.Write((byte)obj.SpawnFlags); + var components = obj.GetComponentsInChildren(); + message.WritePacked(components.Count); + foreach (var comp in components) { + message.WritePacked(obj.NetId); + message.StartMessage(1); + comp.SerializeAsync(message, true); + message.EndMessage(); + } + + message.EndMessage(); + message.EndMessage(); + } } }