From adb74f628cbe290543aba16493469928bac85343 Mon Sep 17 00:00:00 2001 From: AeonLucid Date: Mon, 19 Dec 2022 02:24:51 +0100 Subject: [PATCH] Fix SyncSettingsAsync --- .../Handlers/GameEventListener.cs | 25 +++++------ .../Objects/GameManager/InnerGameManager.cs | 15 +++++++ src/Impostor.Server/Net/State/Game.Api.cs | 44 ++++++++++++++----- src/Impostor.Server/Net/State/Game.Data.cs | 14 ++++++ 4 files changed, 73 insertions(+), 25 deletions(-) diff --git a/src/Impostor.Plugins.Example/Handlers/GameEventListener.cs b/src/Impostor.Plugins.Example/Handlers/GameEventListener.cs index 1384e8b..39bcb01 100644 --- a/src/Impostor.Plugins.Example/Handlers/GameEventListener.cs +++ b/src/Impostor.Plugins.Example/Handlers/GameEventListener.cs @@ -19,21 +19,16 @@ namespace Impostor.Plugins.Example.Handlers { _logger.LogInformation("Game creation requested by {client}", e.Client == null ? "a plugin" : e.Client.Name); - if (e.Client != null) - { - var gameCode = GameCode.From(e.Client.Name); - - if (!gameCode.IsInvalid) - { - e.GameCode = gameCode; - } - - if (e.Client.Name == "dima") - { - e.IsCancelled = true; - e.Client.DisconnectAsync(DisconnectReason.Custom, "No you dont >:("); - } - } + // TODO: Code below causes the lobby to stop loading and close after 5 secs. + // if (e.Client != null) + // { + // var gameCode = GameCode.From(e.Client.Name); + // + // if (!gameCode.IsInvalid) + // { + // e.GameCode = gameCode; + // } + // } } [EventListener] diff --git a/src/Impostor.Server/Net/Inner/Objects/GameManager/InnerGameManager.cs b/src/Impostor.Server/Net/Inner/Objects/GameManager/InnerGameManager.cs index 27ce592..08891ae 100644 --- a/src/Impostor.Server/Net/Inner/Objects/GameManager/InnerGameManager.cs +++ b/src/Impostor.Server/Net/Inner/Objects/GameManager/InnerGameManager.cs @@ -39,6 +39,21 @@ internal abstract class InnerGameManager : InnerNetObject, IInnerGameManager return logic; } + internal int? GetGameLogicTag(T logic) + where T : GameLogicComponent + { + for (var i = 0; i < LogicComponents.Count; i++) + { + var component = LogicComponents[i]; + if (component == logic) + { + return i; + } + } + + return null; + } + public override ValueTask SerializeAsync(IMessageWriter writer, bool initialState) { throw new System.NotImplementedException(); diff --git a/src/Impostor.Server/Net/State/Game.Api.cs b/src/Impostor.Server/Net/State/Game.Api.cs index f685ca1..ad6c793 100644 --- a/src/Impostor.Server/Net/State/Game.Api.cs +++ b/src/Impostor.Server/Net/State/Game.Api.cs @@ -2,10 +2,13 @@ using System.Threading.Tasks; using Impostor.Api; using Impostor.Api.Games; +using Impostor.Api.Innersloth.GameOptions; using Impostor.Api.Net; using Impostor.Api.Net.Inner; -using Impostor.Api.Net.Messages.Rpcs; +using Impostor.Api.Net.Messages; using Impostor.Hazel; +using Impostor.Server.Net.Inner; +using Impostor.Server.Net.Inner.Objects.GameManager; namespace Impostor.Server.Net.State { @@ -20,24 +23,45 @@ namespace Impostor.Server.Net.State _bannedIps.Add(ipAddress); } - // TODO This no longer does anything, it was replaced by LogicOptions public async ValueTask SyncSettingsAsync() { if (Host?.Character == null) { - throw new ImpostorException("Attempted to set infected when the host was not spawned."); + throw new ImpostorException("Attempted to change settings when the host was not spawned."); } - using (var writer = StartRpc(Host.Character.NetId, RpcCalls.SyncSettings)) + var gameManager = FindObjectByType(); + if (gameManager == null) { - // Someone will probably forget to do this, so we include it here. - // If this is not done, the host will overwrite changes later with the defaults. - Options.IsDefaults = false; - - Rpc02SyncSettings.Serialize(writer, Options); + throw new ImpostorException("Attempted to change options when the game manager was not spawned."); + } - await FinishRpcAsync(writer); + var gameOptionsTag = gameManager.GetGameLogicTag(gameManager.LogicOptions); + if (gameOptionsTag == null) + { + throw new ImpostorException("Attempted to change options when the LogicOptions was not spawned."); } + + // Someone will probably forget to do this, so we include it here. + // If this is not done, the host will overwrite changes later with the defaults. + Options.IsDefaults = false; + + using var writer = MessageWriter.Get(MessageType.Reliable); + + writer.StartMessage(MessageFlags.GameData); + Code.Serialize(writer); + + writer.StartMessage(GameDataTag.DataFlag); + writer.WritePacked(gameManager.NetId); + + writer.StartMessage((byte)gameOptionsTag); + GameOptionsFactory.Serialize(writer, Options); + + writer.EndMessage(); + writer.EndMessage(); + writer.EndMessage(); + + await SendToAllAsync(writer); } public async ValueTask SetPrivacyAsync(bool isPublic) diff --git a/src/Impostor.Server/Net/State/Game.Data.cs b/src/Impostor.Server/Net/State/Game.Data.cs index d08b636..e0a3712 100644 --- a/src/Impostor.Server/Net/State/Game.Data.cs +++ b/src/Impostor.Server/Net/State/Game.Data.cs @@ -60,6 +60,20 @@ namespace Impostor.Server.Net.State return default; } + public T? FindObjectByType() + where T : IInnerNetObject + { + foreach (var netObject in _allObjects) + { + if (netObject is T result) + { + return result; + } + } + + return default; + } + public async ValueTask HandleGameDataAsync(IMessageReader parent, ClientPlayer sender, bool toPlayer) { // Find target player. -- 2.39.5