From 1fdefbb8959dcbe546721ccfefd6df34e68ec935 Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Thu, 22 Jun 2023 20:40:37 +0100 Subject: [PATCH 01/41] add setting to disable text chat input --- QSB/HUD/MultiplayerHUDManager.cs | 2 +- QSB/QSBCore.cs | 2 ++ QSB/default-config.json | 6 ++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/QSB/HUD/MultiplayerHUDManager.cs b/QSB/HUD/MultiplayerHUDManager.cs index 60c4e48e..05e4404f 100644 --- a/QSB/HUD/MultiplayerHUDManager.cs +++ b/QSB/HUD/MultiplayerHUDManager.cs @@ -165,7 +165,7 @@ internal class MultiplayerHUDManager : MonoBehaviour, IAddComponentOnStart var inSuit = Locator.GetPlayerSuit().IsWearingHelmet(); - if (OWInput.IsNewlyPressed(InputLibrary.enter, InputMode.Character) && !_writingMessage && inSuit) + if (OWInput.IsNewlyPressed(InputLibrary.enter, InputMode.Character) && !_writingMessage && inSuit && QSBCore.TextChatInput) { OWInput.ChangeInputMode(InputMode.KeyboardInput); _writingMessage = true; diff --git a/QSB/QSBCore.cs b/QSB/QSBCore.cs index 995e1ec8..1e54438c 100644 --- a/QSB/QSBCore.cs +++ b/QSB/QSBCore.cs @@ -63,6 +63,7 @@ public class QSBCore : ModBehaviour public static bool ShowPlayerNames { get; private set; } public static bool ShipDamage { get; private set; } public static bool ShowExtraHUDElements { get; private set; } + public static bool TextChatInput { get; private set; } public static GameVendor GameVendor { get; private set; } = GameVendor.None; public static bool IsStandalone => GameVendor is GameVendor.Epic or GameVendor.Steam; public static IProfileManager ProfileManager => IsStandalone @@ -263,6 +264,7 @@ public class QSBCore : ModBehaviour ShowPlayerNames = config.GetSettingsValue("showPlayerNames"); ShipDamage = config.GetSettingsValue("shipDamage"); ShowExtraHUDElements = config.GetSettingsValue("showExtraHud"); + TextChatInput = config.GetSettingsValue("textChatInput"); if (IsHost) { diff --git a/QSB/default-config.json b/QSB/default-config.json index 99f11d5f..c80d77fc 100644 --- a/QSB/default-config.json +++ b/QSB/default-config.json @@ -37,6 +37,12 @@ "type": "toggle", "value": true, "tooltip": "Show extra HUD elements, like player status and minimap icons." + }, + "textChatInput": { + "title": "Text Chat Input", + "type": "toggle", + "value": true, + "tooltip": "Disable this if using NomaiVR, or any other mod with conflicting inputs." } } } \ No newline at end of file From 8ae452078b07d195a93087a96cbb39688453704d Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Fri, 23 Jun 2023 19:22:56 +0100 Subject: [PATCH 02/41] fix chat colors being broken on long messages --- QSB/DeathSync/Messages/PlayerDeathMessage.cs | 3 +- QSB/HUD/Messages/ChatMessage.cs | 7 +++-- QSB/HUD/MultiplayerHUDManager.cs | 29 +++++++++++--------- QSB/Player/Messages/PlayerJoinMessage.cs | 3 +- QSB/Player/Messages/PlayerKickMessage.cs | 7 +++-- 5 files changed, 28 insertions(+), 21 deletions(-) diff --git a/QSB/DeathSync/Messages/PlayerDeathMessage.cs b/QSB/DeathSync/Messages/PlayerDeathMessage.cs index 5aedbef6..376f7c09 100644 --- a/QSB/DeathSync/Messages/PlayerDeathMessage.cs +++ b/QSB/DeathSync/Messages/PlayerDeathMessage.cs @@ -5,6 +5,7 @@ using QSB.Messaging; using QSB.Player; using QSB.RespawnSync; using QSB.Utility; +using UnityEngine; namespace QSB.DeathSync.Messages; @@ -41,7 +42,7 @@ public class PlayerDeathMessage : QSBMessage var deathMessage = Necronomicon.GetPhrase(Data, NecronomiconIndex); if (deathMessage != null) { - MultiplayerHUDManager.Instance.WriteMessage($"{string.Format(deathMessage, playerName)}"); + MultiplayerHUDManager.Instance.WriteMessage(string.Format(deathMessage, playerName), Color.grey); } RespawnManager.Instance.OnPlayerDeath(player); diff --git a/QSB/HUD/Messages/ChatMessage.cs b/QSB/HUD/Messages/ChatMessage.cs index a8404ade..e9d25bbc 100644 --- a/QSB/HUD/Messages/ChatMessage.cs +++ b/QSB/HUD/Messages/ChatMessage.cs @@ -4,17 +4,18 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using UnityEngine; namespace QSB.HUD.Messages; -internal class ChatMessage : QSBMessage +internal class ChatMessage : QSBMessage<(string message, Color color)> { - public ChatMessage(string msg) : base(msg) { } + public ChatMessage(string msg, Color color) : base((msg, color)) { } public override void OnReceiveLocal() => OnReceiveRemote(); public override void OnReceiveRemote() { - MultiplayerHUDManager.Instance.WriteMessage(Data); + MultiplayerHUDManager.Instance.WriteMessage(Data.message, Data.color); } } \ No newline at end of file diff --git a/QSB/HUD/MultiplayerHUDManager.cs b/QSB/HUD/MultiplayerHUDManager.cs index 05e4404f..d3886162 100644 --- a/QSB/HUD/MultiplayerHUDManager.cs +++ b/QSB/HUD/MultiplayerHUDManager.cs @@ -71,17 +71,17 @@ internal class MultiplayerHUDManager : MonoBehaviour, IAddComponentOnStart private const float FADE_TIME = 2f; private bool _writingMessage; - private readonly string[] _lines = new string[LINE_COUNT]; + private readonly (string msg, Color color)[] _lines = new (string msg, Color color)[LINE_COUNT]; // this should really be a deque, but eh - private readonly ListStack _messages = new(false); + private readonly ListStack<(string msg, Color color)> _messages = new(false); private float _lastMessageTime; - public void WriteMessage(string message) + public void WriteMessage(string message, Color color) { /* Tricky problem to solve. * - 11 available lines for text to fit onto * - Each line can be max 41 characters - * - Newest messages apepear at the bottom, and get pushed up by newer messages. + * - Newest messages appear at the bottom, and get pushed up by newer messages. * - Messages can use several lines. * * From newest to oldest message, work out how many lines it needs @@ -90,7 +90,7 @@ internal class MultiplayerHUDManager : MonoBehaviour, IAddComponentOnStart _lastMessageTime = Time.time; - _messages.Push(message); + _messages.Push((message, color)); if (_messages.Count > LINE_COUNT) { @@ -101,7 +101,7 @@ internal class MultiplayerHUDManager : MonoBehaviour, IAddComponentOnStart foreach (var msg in _messages.Reverse()) { - var characterCount = msg.Length; + var characterCount = msg.msg.Length; var linesNeeded = Mathf.CeilToInt((float)characterCount / CHAR_COUNT); var chunk = 0; for (var i = linesNeeded - 1; i >= 0; i--) @@ -112,8 +112,8 @@ internal class MultiplayerHUDManager : MonoBehaviour, IAddComponentOnStart continue; } - var chunkString = string.Concat(msg.Skip(CHAR_COUNT * chunk).Take(CHAR_COUNT)); - _lines[currentLineIndex - i] = chunkString; + var chunkString = string.Concat(msg.msg.Skip(CHAR_COUNT * chunk).Take(CHAR_COUNT)); + _lines[currentLineIndex - i] = (chunkString, msg.color); chunk++; } @@ -128,17 +128,20 @@ internal class MultiplayerHUDManager : MonoBehaviour, IAddComponentOnStart var finalText = ""; foreach (var line in _lines) { + var msgColor = ColorUtility.ToHtmlStringRGBA(line.color); + var msg = $"{line.msg}"; + if (line == default) { finalText += Environment.NewLine; } - else if (line.Length == 42) + else if (line.msg.Length == CHAR_COUNT + 1) { - finalText += line; + finalText += msg; } else { - finalText += $"{line}{Environment.NewLine}"; + finalText += $"{msg}{Environment.NewLine}"; } } @@ -183,7 +186,7 @@ internal class MultiplayerHUDManager : MonoBehaviour, IAddComponentOnStart _inputField.text = ""; message = message.Replace("\n", "").Replace("\r", ""); message = $"{QSBPlayerManager.LocalPlayer.Name}: {message}"; - new ChatMessage(message).Send(); + new ChatMessage(message, Color.white).Send(); } if (OWInput.IsNewlyPressed(InputLibrary.escape, InputMode.KeyboardInput) && _writingMessage) @@ -398,7 +401,7 @@ internal class MultiplayerHUDManager : MonoBehaviour, IAddComponentOnStart Destroy(player.HUDBox?.gameObject); Destroy(player.MinimapPlayerMarker); - WriteMessage($"{string.Format(QSBLocalization.Current.PlayerLeftTheGame, player.Name)}"); + WriteMessage(string.Format(QSBLocalization.Current.PlayerLeftTheGame, player.Name), Color.yellow); } private PlanetTrigger CreateTrigger(string parentPath, HUDIcon icon) diff --git a/QSB/Player/Messages/PlayerJoinMessage.cs b/QSB/Player/Messages/PlayerJoinMessage.cs index 6a8bc110..f7af042b 100644 --- a/QSB/Player/Messages/PlayerJoinMessage.cs +++ b/QSB/Player/Messages/PlayerJoinMessage.cs @@ -6,6 +6,7 @@ using QSB.Localization; using QSB.Messaging; using QSB.Utility; using System.Linq; +using UnityEngine; namespace QSB.Player.Messages; @@ -126,7 +127,7 @@ public class PlayerJoinMessage : QSBMessage var player = QSBPlayerManager.GetPlayer(From); player.Name = PlayerName; - MultiplayerHUDManager.Instance.WriteMessage($"{string.Format(QSBLocalization.Current.PlayerJoinedTheGame, player.Name)}"); + MultiplayerHUDManager.Instance.WriteMessage(string.Format(QSBLocalization.Current.PlayerJoinedTheGame, player.Name), Color.green); DebugLog.DebugWrite($"{player} joined. qsbVersion:{QSBVersion}, gameVersion:{GameVersion}, dlcInstalled:{DlcInstalled}", MessageType.Info); } diff --git a/QSB/Player/Messages/PlayerKickMessage.cs b/QSB/Player/Messages/PlayerKickMessage.cs index 7cc62816..84834b5e 100644 --- a/QSB/Player/Messages/PlayerKickMessage.cs +++ b/QSB/Player/Messages/PlayerKickMessage.cs @@ -4,6 +4,7 @@ using QSB.Localization; using QSB.Menus; using QSB.Messaging; using QSB.Utility; +using UnityEngine; namespace QSB.Player.Messages; @@ -35,15 +36,15 @@ internal class PlayerKickMessage : QSBMessage { if (QSBPlayerManager.PlayerExists(PlayerId)) { - MultiplayerHUDManager.Instance.WriteMessage($"{string.Format(QSBLocalization.Current.PlayerWasKicked, QSBPlayerManager.GetPlayer(PlayerId).Name)}"); + MultiplayerHUDManager.Instance.WriteMessage(string.Format(QSBLocalization.Current.PlayerWasKicked, QSBPlayerManager.GetPlayer(PlayerId).Name), Color.red); return; } - MultiplayerHUDManager.Instance.WriteMessage($"{string.Format(QSBLocalization.Current.PlayerWasKicked, PlayerId)}"); + MultiplayerHUDManager.Instance.WriteMessage(string.Format(QSBLocalization.Current.PlayerWasKicked, PlayerId), Color.red); return; } - MultiplayerHUDManager.Instance.WriteMessage($"{string.Format(QSBLocalization.Current.KickedFromServer, Data)}"); + MultiplayerHUDManager.Instance.WriteMessage(string.Format(QSBLocalization.Current.KickedFromServer, Data), Color.red); MenuManager.Instance.OnKicked(Data); NetworkClient.Disconnect(); From e95fc17680fa789b851781e1a389253c0133c647 Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Fri, 23 Jun 2023 19:23:07 +0100 Subject: [PATCH 03/41] Update manifest.json --- QSB/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QSB/manifest.json b/QSB/manifest.json index d81b0959..20357d06 100644 --- a/QSB/manifest.json +++ b/QSB/manifest.json @@ -7,7 +7,7 @@ "body": "- Disable *all* other mods. (Can heavily affect performance)\n- Make sure you are not running any other network-intensive applications." }, "uniqueName": "Raicuparta.QuantumSpaceBuddies", - "version": "0.28.1", + "version": "0.28.2", "owmlVersion": "2.9.0", "dependencies": [ "_nebula.MenuFramework", "JohnCorby.VanillaFix" ], "pathsToPreserve": [ "debugsettings.json" ], From 9f11bc93edaec71decc83bd3f15bc67038d5980e Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Sun, 25 Jun 2023 15:07:48 +0100 Subject: [PATCH 04/41] fix ccu support --- QSB/PoolSync/CustomNomaiRemoteCamera.cs | 2 +- QSB/PoolSync/CustomNomaiRemoteCameraPlatform.cs | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/QSB/PoolSync/CustomNomaiRemoteCamera.cs b/QSB/PoolSync/CustomNomaiRemoteCamera.cs index e867dfa3..9364fcdf 100644 --- a/QSB/PoolSync/CustomNomaiRemoteCamera.cs +++ b/QSB/PoolSync/CustomNomaiRemoteCamera.cs @@ -4,7 +4,7 @@ namespace QSB.PoolSync; internal class CustomNomaiRemoteCamera : MonoBehaviour { - private OWCamera _camera; + public OWCamera _camera; private AudioListener _audioListener; private NomaiViewerImageEffect _viewerImageEffect; private CustomNomaiRemoteCameraPlatform _owningPlatform; diff --git a/QSB/PoolSync/CustomNomaiRemoteCameraPlatform.cs b/QSB/PoolSync/CustomNomaiRemoteCameraPlatform.cs index 0ad8f976..358b53c5 100644 --- a/QSB/PoolSync/CustomNomaiRemoteCameraPlatform.cs +++ b/QSB/PoolSync/CustomNomaiRemoteCameraPlatform.cs @@ -6,6 +6,7 @@ using QSB.Player.Messages; using QSB.Utility; using System.Collections.Generic; using System.Linq; +using System.Reflection; using UnityEngine; namespace QSB.PoolSync; @@ -516,8 +517,16 @@ internal class CustomNomaiRemoteCameraPlatform : NomaiShared private void SwitchToPlayerCamera() { - // does nothing except run CCU's prefix - _oldPlatform.SwitchToPlayerCamera(); + if (QSBCore.Helper.Interaction.ModExists("xen.CommonCameraUtility")) + { + // this is a really fucking dumb fix, but i cannot be + // bothered to rewrite this class to make this work better + var ccuAssembly = QSBCore.Helper.Interaction.TryGetMod("xen.CommonCameraUtility").GetType().Assembly; + var utilClass = ccuAssembly.GetType("CommonCameraUtil.CommonCameraUtil"); + var instance = utilClass.GetField("Instance", BindingFlags.Public | BindingFlags.Static).GetValue(null); + var removeCameraMethod = utilClass.GetMethod("RemoveCamera", BindingFlags.Public | BindingFlags.Instance); + removeCameraMethod.Invoke(instance, new object[] { _slavePlatform._ownedCamera._camera }); + } if (_slavePlatform._visualSector != null) { From ed2b3e49e9a5cbb286952ca61ca9b2940da5599e Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Sun, 25 Jun 2023 15:08:02 +0100 Subject: [PATCH 05/41] Update manifest.json --- QSB/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QSB/manifest.json b/QSB/manifest.json index 20357d06..55aa0efd 100644 --- a/QSB/manifest.json +++ b/QSB/manifest.json @@ -7,7 +7,7 @@ "body": "- Disable *all* other mods. (Can heavily affect performance)\n- Make sure you are not running any other network-intensive applications." }, "uniqueName": "Raicuparta.QuantumSpaceBuddies", - "version": "0.28.2", + "version": "0.28.3", "owmlVersion": "2.9.0", "dependencies": [ "_nebula.MenuFramework", "JohnCorby.VanillaFix" ], "pathsToPreserve": [ "debugsettings.json" ], From 79a0b4e47881cc7f37abe20e25edab36e06d9d6d Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Tue, 4 Jul 2023 20:01:32 +0100 Subject: [PATCH 06/41] update OWML --- QSB/QSB.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QSB/QSB.csproj b/QSB/QSB.csproj index 519e684f..80923879 100644 --- a/QSB/QSB.csproj +++ b/QSB/QSB.csproj @@ -69,7 +69,7 @@ - + From 2ad07641f1dc1e35f829d5effda38e08feaf5102 Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Tue, 4 Jul 2023 20:01:40 +0100 Subject: [PATCH 07/41] make ShipManager public --- QSB/ShipSync/ShipManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QSB/ShipSync/ShipManager.cs b/QSB/ShipSync/ShipManager.cs index 6d7017a2..8bf13d8c 100644 --- a/QSB/ShipSync/ShipManager.cs +++ b/QSB/ShipSync/ShipManager.cs @@ -16,7 +16,7 @@ using UnityEngine; namespace QSB.ShipSync; -internal class ShipManager : WorldObjectManager +public class ShipManager : WorldObjectManager { public override WorldObjectScene WorldObjectScene => WorldObjectScene.SolarSystem; From 7dfbba52c98685d3571c59b4dcef92727d5d6c30 Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Tue, 4 Jul 2023 20:05:49 +0100 Subject: [PATCH 08/41] make OnModStart addon patches work --- QSB/QSBCore.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/QSB/QSBCore.cs b/QSB/QSBCore.cs index 1e54438c..cf8ef47c 100644 --- a/QSB/QSBCore.cs +++ b/QSB/QSBCore.cs @@ -167,6 +167,7 @@ public class QSBCore : ModBehaviour // init again to get addon patches QSBPatchManager.Init(); + QSBPatchManager.DoPatchType(QSBPatchTypes.OnModStart); MenuApi = ModHelper.Interaction.TryGetModApi(ModHelper.Manifest.Dependencies[0]); From fb2eda7b133942be1e53a91f0ef4b2e386162f5b Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Tue, 4 Jul 2023 20:24:00 +0100 Subject: [PATCH 09/41] redo addon patch initialization --- QSB/Patches/QSBPatchManager.cs | 39 ++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/QSB/Patches/QSBPatchManager.cs b/QSB/Patches/QSBPatchManager.cs index 5c678ab8..2ee89973 100644 --- a/QSB/Patches/QSBPatchManager.cs +++ b/QSB/Patches/QSBPatchManager.cs @@ -23,16 +23,43 @@ public static class QSBPatchManager { if (_inited) { - var count = _patchList.Count; + var newPatches = new List(); + foreach (var type in typeof(QSBPatch).GetDerivedTypes()) { - if (!_patchList.Any(x => x.GetType() == type)) + if (!newPatches.Any(x => x.GetType() == type)) { - _patchList.Add((QSBPatch)Activator.CreateInstance(type)); + newPatches.Add((QSBPatch)Activator.CreateInstance(type)); } } - DebugLog.DebugWrite($"Registered {_patchList.Count - count} addon patches.", MessageType.Success); + _patchList.AddRange(newPatches); + + // could do lots of code to make sure all addon patches are done here, + // but the only patche type that will have been used by this point in the + // mod execution is OnModStart + + DebugLog.DebugWrite($"Re-patching block OnModStart for addons", MessageType.Info); + var harmonyInstance = TypeToInstance[QSBPatchTypes.OnModStart]; + foreach (var patch in newPatches) + { + if (patch.Type != QSBPatchTypes.OnModStart) + { + continue; + } + + DebugLog.DebugWrite($" - Patching in {patch.GetType().Name}", MessageType.Info); + try + { + patch.DoPatches(harmonyInstance); + } + catch (Exception ex) + { + DebugLog.ToConsole($"Error while patching {patch.GetType().Name} :\r\n{ex}", MessageType.Error); + } + } + + DebugLog.DebugWrite($"Registered {newPatches.Count()} addon patches.", MessageType.Success); return; } @@ -59,10 +86,10 @@ public static class QSBPatchManager } OnPatchType?.SafeInvoke(type); - //DebugLog.DebugWrite($"Patch block {Enum.GetName(typeof(QSBPatchTypes), type)}", MessageType.Info); + DebugLog.DebugWrite($"Patch block {Enum.GetName(typeof(QSBPatchTypes), type)}", MessageType.Info); foreach (var patch in _patchList.Where(x => x.Type == type && x.PatchVendor.HasFlag(QSBCore.GameVendor))) { - //DebugLog.DebugWrite($" - Patching in {patch.GetType().Name}", MessageType.Info); + DebugLog.DebugWrite($" - Patching in {patch.GetType().Name}", MessageType.Info); try { patch.DoPatches(TypeToInstance[type]); From c6255fbb1531d3f9a287d66ea9786ac1f13e918e Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Tue, 4 Jul 2023 20:24:07 +0100 Subject: [PATCH 10/41] Revert "make OnModStart addon patches work" This reverts commit 7dfbba52c98685d3571c59b4dcef92727d5d6c30. --- QSB/QSBCore.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/QSB/QSBCore.cs b/QSB/QSBCore.cs index cf8ef47c..1e54438c 100644 --- a/QSB/QSBCore.cs +++ b/QSB/QSBCore.cs @@ -167,7 +167,6 @@ public class QSBCore : ModBehaviour // init again to get addon patches QSBPatchManager.Init(); - QSBPatchManager.DoPatchType(QSBPatchTypes.OnModStart); MenuApi = ModHelper.Interaction.TryGetModApi(ModHelper.Manifest.Dependencies[0]); From b6894e5b364624c0dfdee9002b0b06895a7422b8 Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Tue, 4 Jul 2023 20:29:10 +0100 Subject: [PATCH 11/41] fix it --- QSB/Patches/QSBPatchManager.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/QSB/Patches/QSBPatchManager.cs b/QSB/Patches/QSBPatchManager.cs index 2ee89973..969876bd 100644 --- a/QSB/Patches/QSBPatchManager.cs +++ b/QSB/Patches/QSBPatchManager.cs @@ -27,7 +27,8 @@ public static class QSBPatchManager foreach (var type in typeof(QSBPatch).GetDerivedTypes()) { - if (!newPatches.Any(x => x.GetType() == type)) + if (!newPatches.Any(x => x.GetType() == type) + && !_patchList.Any(x => x.GetType() == type)) { newPatches.Add((QSBPatch)Activator.CreateInstance(type)); } @@ -36,7 +37,7 @@ public static class QSBPatchManager _patchList.AddRange(newPatches); // could do lots of code to make sure all addon patches are done here, - // but the only patche type that will have been used by this point in the + // but the only patch type that will have been used by this point in the // mod execution is OnModStart DebugLog.DebugWrite($"Re-patching block OnModStart for addons", MessageType.Info); From 5402bfa3e20bc20f2bf71ee45997fc55c258929a Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Tue, 4 Jul 2023 20:39:08 +0100 Subject: [PATCH 12/41] add null check to SetCurrentFlyer --- QSB/ShipSync/Messages/FlyShipMessage.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QSB/ShipSync/Messages/FlyShipMessage.cs b/QSB/ShipSync/Messages/FlyShipMessage.cs index 3b3adf11..1f55dd3e 100644 --- a/QSB/ShipSync/Messages/FlyShipMessage.cs +++ b/QSB/ShipSync/Messages/FlyShipMessage.cs @@ -57,7 +57,7 @@ internal class FlyShipMessage : QSBMessage if (QSBCore.IsHost) { - ShipTransformSync.LocalInstance.netIdentity.SetOwner(isFlying + ShipTransformSync.LocalInstance?.netIdentity.SetOwner(isFlying ? id : QSBPlayerManager.LocalPlayerId); } From 88d3babe52009b64a069e36f80a20e7a9ec008e6 Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Tue, 4 Jul 2023 20:56:59 +0100 Subject: [PATCH 13/41] make ShipAudioPatches and ShipPatches public --- QSB/ShipSync/Patches/ShipAudioPatches.cs | 2 +- QSB/ShipSync/Patches/ShipPatches.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/QSB/ShipSync/Patches/ShipAudioPatches.cs b/QSB/ShipSync/Patches/ShipAudioPatches.cs index 1e76d57a..51f68517 100644 --- a/QSB/ShipSync/Patches/ShipAudioPatches.cs +++ b/QSB/ShipSync/Patches/ShipAudioPatches.cs @@ -6,7 +6,7 @@ using UnityEngine; namespace QSB.ShipSync.Patches; -internal class ShipAudioPatches : QSBPatch +public class ShipAudioPatches : QSBPatch { public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect; diff --git a/QSB/ShipSync/Patches/ShipPatches.cs b/QSB/ShipSync/Patches/ShipPatches.cs index 5780d389..8eca58c2 100644 --- a/QSB/ShipSync/Patches/ShipPatches.cs +++ b/QSB/ShipSync/Patches/ShipPatches.cs @@ -13,7 +13,7 @@ using UnityEngine; namespace QSB.ShipSync.Patches; [HarmonyPatch] -internal class ShipPatches : QSBPatch +public class ShipPatches : QSBPatch { public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect; From fe97e0f5699e6edad6f703d15418456575112ed4 Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Tue, 4 Jul 2023 20:59:21 +0100 Subject: [PATCH 14/41] add null checks to FlyShipMessage.OnRecieveRemote --- QSB/ShipSync/Messages/FlyShipMessage.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/QSB/ShipSync/Messages/FlyShipMessage.cs b/QSB/ShipSync/Messages/FlyShipMessage.cs index 1f55dd3e..4722b424 100644 --- a/QSB/ShipSync/Messages/FlyShipMessage.cs +++ b/QSB/ShipSync/Messages/FlyShipMessage.cs @@ -40,12 +40,12 @@ internal class FlyShipMessage : QSBMessage if (Data) { QSBPlayerManager.GetPlayer(From)?.AudioController?.PlayOneShot(AudioType.ShipCockpitBuckleUp); - shipCockpitController._interactVolume.DisableInteraction(); + shipCockpitController._interactVolume?.DisableInteraction(); } else { QSBPlayerManager.GetPlayer(From)?.AudioController?.PlayOneShot(AudioType.ShipCockpitUnbuckle); - shipCockpitController._interactVolume.EnableInteraction(); + shipCockpitController._interactVolume?.EnableInteraction(); } } From 6099fa5fd12386f1074cc85361e92969c9027d52 Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Tue, 4 Jul 2023 21:34:29 +0100 Subject: [PATCH 15/41] add another null check --- QSB/ShipSync/Messages/FlyShipMessage.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/QSB/ShipSync/Messages/FlyShipMessage.cs b/QSB/ShipSync/Messages/FlyShipMessage.cs index 4722b424..f73c8a7e 100644 --- a/QSB/ShipSync/Messages/FlyShipMessage.cs +++ b/QSB/ShipSync/Messages/FlyShipMessage.cs @@ -37,6 +37,12 @@ internal class FlyShipMessage : QSBMessage { SetCurrentFlyer(From, Data); var shipCockpitController = ShipManager.Instance.CockpitController; + + if (shipCockpitController == null) + { + return; + } + if (Data) { QSBPlayerManager.GetPlayer(From)?.AudioController?.PlayOneShot(AudioType.ShipCockpitBuckleUp); From 2889bffb1655817bb1f1fe77414f408205a5e01a Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Tue, 4 Jul 2023 21:56:40 +0100 Subject: [PATCH 16/41] add more null checks --- QSB/Audio/Messages/ShipThrusterAudioOneShotMessage.cs | 8 +++++++- QSB/ShipSync/Patches/ShipDetachableModulePatches.cs | 2 +- QSB/ShipSync/Patches/ShipFlameWashPatches.cs | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/QSB/Audio/Messages/ShipThrusterAudioOneShotMessage.cs b/QSB/Audio/Messages/ShipThrusterAudioOneShotMessage.cs index 156e51b2..7b5f45a7 100644 --- a/QSB/Audio/Messages/ShipThrusterAudioOneShotMessage.cs +++ b/QSB/Audio/Messages/ShipThrusterAudioOneShotMessage.cs @@ -13,7 +13,13 @@ public class ShipThrusterAudioOneShotMessage : QSBMessage<(AudioType audioType, public override void OnReceiveRemote() { - var source = ShipManager.Instance.ShipThrusterAudio._rotationalSource; + var source = ShipManager.Instance?.ShipThrusterAudio?._rotationalSource; + + if (source == null) + { + return; + } + source.pitch = Data.pitch; source.PlayOneShot(Data.audioType, Data.volume); } diff --git a/QSB/ShipSync/Patches/ShipDetachableModulePatches.cs b/QSB/ShipSync/Patches/ShipDetachableModulePatches.cs index da1a6231..c11d473e 100644 --- a/QSB/ShipSync/Patches/ShipDetachableModulePatches.cs +++ b/QSB/ShipSync/Patches/ShipDetachableModulePatches.cs @@ -8,7 +8,7 @@ using QSB.WorldSync; namespace QSB.ShipSync.Patches; [HarmonyPatch(typeof(ShipDetachableModule))] -internal class ShipDetachableModulePatches : QSBPatch +public class ShipDetachableModulePatches : QSBPatch { public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect; diff --git a/QSB/ShipSync/Patches/ShipFlameWashPatches.cs b/QSB/ShipSync/Patches/ShipFlameWashPatches.cs index 525c2c38..c988f692 100644 --- a/QSB/ShipSync/Patches/ShipFlameWashPatches.cs +++ b/QSB/ShipSync/Patches/ShipFlameWashPatches.cs @@ -8,7 +8,7 @@ using UnityEngine; namespace QSB.ShipSync.Patches; -internal class ShipFlameWashPatches : QSBPatch +public class ShipFlameWashPatches : QSBPatch { public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect; From fa8f5045e2207caaed54defc747c97de8bff270d Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Wed, 5 Jul 2023 12:44:47 +0100 Subject: [PATCH 17/41] make assetId incrementation automatic --- QSB/QSBNetworkManager.cs | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/QSB/QSBNetworkManager.cs b/QSB/QSBNetworkManager.cs index 735c08b7..8431533b 100644 --- a/QSB/QSBNetworkManager.cs +++ b/QSB/QSBNetworkManager.cs @@ -106,52 +106,52 @@ public class QSBNetworkManager : NetworkManager, IAddComponentOnStart playerPrefab = QSBCore.NetworkAssetBundle.LoadAsset("Assets/Prefabs/NETWORK_Player_Body.prefab"); playerPrefab.GetRequiredComponent().SetValue("_assetId", (uint)1); - ShipPrefab = MakeNewNetworkObject(2, "NetworkShip", typeof(ShipTransformSync)); + ShipPrefab = MakeNewNetworkObject("NetworkShip", typeof(ShipTransformSync)); var shipVector3Sync = ShipPrefab.AddComponent(); var shipThrustSync = ShipPrefab.AddComponent(); shipThrustSync.AccelerationSyncer = shipVector3Sync; spawnPrefabs.Add(ShipPrefab); - _probePrefab = MakeNewNetworkObject(3, "NetworkProbe", typeof(PlayerProbeSync)); + _probePrefab = MakeNewNetworkObject("NetworkProbe", typeof(PlayerProbeSync)); spawnPrefabs.Add(_probePrefab); - OrbPrefab = MakeNewNetworkObject(4, "NetworkOrb", typeof(NomaiOrbTransformSync)); + OrbPrefab = MakeNewNetworkObject("NetworkOrb", typeof(NomaiOrbTransformSync)); spawnPrefabs.Add(OrbPrefab); - AnglerPrefab = MakeNewNetworkObject(5, "NetworkAngler", typeof(AnglerTransformSync)); + AnglerPrefab = MakeNewNetworkObject("NetworkAngler", typeof(AnglerTransformSync)); spawnPrefabs.Add(AnglerPrefab); - JellyfishPrefab = MakeNewNetworkObject(6, "NetworkJellyfish", typeof(JellyfishTransformSync)); + JellyfishPrefab = MakeNewNetworkObject("NetworkJellyfish", typeof(JellyfishTransformSync)); spawnPrefabs.Add(JellyfishPrefab); - OccasionalPrefab = MakeNewNetworkObject(7, "NetworkOccasional", typeof(OccasionalTransformSync)); + OccasionalPrefab = MakeNewNetworkObject("NetworkOccasional", typeof(OccasionalTransformSync)); spawnPrefabs.Add(OccasionalPrefab); - RaftPrefab = MakeNewNetworkObject(8, "NetworkRaft", typeof(RaftTransformSync)); + RaftPrefab = MakeNewNetworkObject("NetworkRaft", typeof(RaftTransformSync)); spawnPrefabs.Add(RaftPrefab); - DoorPrefab = MakeNewNetworkObject(9, "NetworkEclipseDoor", typeof(EclipseDoorVariableSyncer)); + DoorPrefab = MakeNewNetworkObject("NetworkEclipseDoor", typeof(EclipseDoorVariableSyncer)); spawnPrefabs.Add(DoorPrefab); - ElevatorPrefab = MakeNewNetworkObject(10, "NetworkEclipseElevator", typeof(EclipseElevatorVariableSyncer)); + ElevatorPrefab = MakeNewNetworkObject("NetworkEclipseElevator", typeof(EclipseElevatorVariableSyncer)); spawnPrefabs.Add(ElevatorPrefab); - AirlockPrefab = MakeNewNetworkObject(11, "NetworkGhostAirlock", typeof(AirlockVariableSyncer)); + AirlockPrefab = MakeNewNetworkObject("NetworkGhostAirlock", typeof(AirlockVariableSyncer)); spawnPrefabs.Add(AirlockPrefab); - ShipModulePrefab = MakeNewNetworkObject(12, "NetworkShipModule", typeof(ShipModuleTransformSync)); + ShipModulePrefab = MakeNewNetworkObject("NetworkShipModule", typeof(ShipModuleTransformSync)); spawnPrefabs.Add(ShipModulePrefab); - ShipLegPrefab = MakeNewNetworkObject(13, "NetworkShipLeg", typeof(ShipLegTransformSync)); + ShipLegPrefab = MakeNewNetworkObject("NetworkShipLeg", typeof(ShipLegTransformSync)); spawnPrefabs.Add(ShipLegPrefab); - ModelShipPrefab = MakeNewNetworkObject(14, "NetworkModelShip", typeof(ModelShipTransformSync)); + ModelShipPrefab = MakeNewNetworkObject("NetworkModelShip", typeof(ModelShipTransformSync)); var modelShipVector3Syncer = ModelShipPrefab.AddComponent(); var modelShipThrusterVariableSyncer = ModelShipPrefab.AddComponent(); modelShipThrusterVariableSyncer.AccelerationSyncer = modelShipVector3Syncer; spawnPrefabs.Add(ModelShipPrefab); - StationaryProbeLauncherPrefab = MakeNewNetworkObject(15, "NetworkStationaryProbeLauncher", typeof(StationaryProbeLauncherVariableSyncer)); + StationaryProbeLauncherPrefab = MakeNewNetworkObject("NetworkStationaryProbeLauncher", typeof(StationaryProbeLauncherVariableSyncer)); spawnPrefabs.Add(StationaryProbeLauncherPrefab); ConfigureNetworkManager(); @@ -207,11 +207,13 @@ public class QSBNetworkManager : NetworkManager, IAddComponentOnStart } }); + private static int _assetId = 2; + /// create a new network prefab from the network object prefab template. /// this works by calling Unload(false) and then reloading the AssetBundle, /// which makes LoadAsset give you a new resource. /// see https://docs.unity3d.com/Manual/AssetBundles-Native.html. - private static GameObject MakeNewNetworkObject(uint assetId, string name, Type networkBehaviourType) + public static GameObject MakeNewNetworkObject(string name, Type networkBehaviourType) { var bundle = QSBCore.Helper.Assets.LoadBundle("AssetBundles/qsb_empty"); @@ -225,8 +227,11 @@ public class QSBNetworkManager : NetworkManager, IAddComponentOnStart bundle.Unload(false); template.name = name; - template.AddComponent().SetValue("_assetId", assetId); + template.AddComponent().SetValue("_assetId", _assetId); template.AddComponent(networkBehaviourType); + + _assetId++; + return template; } From 37cb95f740546bf09adacd4d637277ddfcfcf388 Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Wed, 5 Jul 2023 12:46:03 +0100 Subject: [PATCH 18/41] add comment --- QSB/QSBNetworkManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QSB/QSBNetworkManager.cs b/QSB/QSBNetworkManager.cs index 8431533b..eb17df72 100644 --- a/QSB/QSBNetworkManager.cs +++ b/QSB/QSBNetworkManager.cs @@ -207,7 +207,7 @@ public class QSBNetworkManager : NetworkManager, IAddComponentOnStart } }); - private static int _assetId = 2; + private static int _assetId = 2; // 1 is the player /// create a new network prefab from the network object prefab template. /// this works by calling Unload(false) and then reloading the AssetBundle, From 6e86ce8dda35d20391c1b16ac85e308df548eb62 Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Wed, 5 Jul 2023 23:08:50 +0100 Subject: [PATCH 19/41] im dumb --- QSB/QSBNetworkManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QSB/QSBNetworkManager.cs b/QSB/QSBNetworkManager.cs index eb17df72..6cb7504b 100644 --- a/QSB/QSBNetworkManager.cs +++ b/QSB/QSBNetworkManager.cs @@ -207,7 +207,7 @@ public class QSBNetworkManager : NetworkManager, IAddComponentOnStart } }); - private static int _assetId = 2; // 1 is the player + private static uint _assetId = 2; // 1 is the player /// create a new network prefab from the network object prefab template. /// this works by calling Unload(false) and then reloading the AssetBundle, From cef539d1787d62cf31bb378204a0ae61ec1ca5e5 Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Thu, 6 Jul 2023 11:59:39 -0700 Subject: [PATCH 20/41] revert transport error translations cuz they were dumb and also incorrect --- QSB/Localization/Translation.cs | 4 +--- QSB/Menus/MenuManager.cs | 2 +- QSB/Translations/en.json | 12 +----------- 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/QSB/Localization/Translation.cs b/QSB/Localization/Translation.cs index b47014a8..4ed59efe 100644 --- a/QSB/Localization/Translation.cs +++ b/QSB/Localization/Translation.cs @@ -1,5 +1,4 @@ -using Mirror; -using System.Collections.Generic; +using System.Collections.Generic; namespace QSB.Localization; @@ -29,7 +28,6 @@ public class Translation public string OK; public string ServerRefusedConnection; public string ClientDisconnectWithError; - public Dictionary TransportErrors; public string QSBVersionMismatch; public string OWVersionMismatch; public string DLCMismatch; diff --git a/QSB/Menus/MenuManager.cs b/QSB/Menus/MenuManager.cs index 0bb1bd42..55166f55 100644 --- a/QSB/Menus/MenuManager.cs +++ b/QSB/Menus/MenuManager.cs @@ -736,7 +736,7 @@ internal class MenuManager : MonoBehaviour, IAddComponentOnStart } }; - OpenInfoPopup(string.Format(QSBLocalization.Current.ClientDisconnectWithError, QSBLocalization.Current.TransportErrors[error], reason), QSBLocalization.Current.OK); + OpenInfoPopup(string.Format(QSBLocalization.Current.ClientDisconnectWithError, reason), QSBLocalization.Current.OK); } SetButtonActive(DisconnectButton, false); diff --git a/QSB/Translations/en.json b/QSB/Translations/en.json index f3ad1b60..a0430021 100644 --- a/QSB/Translations/en.json +++ b/QSB/Translations/en.json @@ -22,17 +22,7 @@ "Connecting": "CONNECTING...", "OK": "OK", "ServerRefusedConnection": "Server refused connection.\n{0}", - "ClientDisconnectWithError": "Client disconnected with error!\n{0}\nMore info: {1}", - "TransportErrors": { - "DnsResolve": "Failed to resolve host name.", - "Refused": "Connection refused.", - "Timeout": "Connection timed out.", - "Congestion": "Congestion on transport.", - "InvalidReceive": "Error receiving message.", - "InvalidSend": "Error sending message.", - "ConnectionClosed": "Connection closed.", - "Unexpected": "Unexpected error." - }, + "ClientDisconnectWithError": "Client disconnected with error!\n{0}", "QSBVersionMismatch": "QSB version does not match. (Client:{0}, Server:{1})", "OWVersionMismatch": "Outer Wilds version does not match. (Client:{0}, Server:{1})", "DLCMismatch": "DLC installation state does not match. (Client:{0}, Server:{1})", From e8e37632037eb523d85bfba8c5653829a274b221 Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Fri, 7 Jul 2023 13:42:05 +0100 Subject: [PATCH 21/41] Update QSB.csproj --- QSB/QSB.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QSB/QSB.csproj b/QSB/QSB.csproj index 80923879..4116a8ac 100644 --- a/QSB/QSB.csproj +++ b/QSB/QSB.csproj @@ -68,7 +68,7 @@ - + From c74d36d714fdc852b1b35ba1652b898796327e0f Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Fri, 7 Jul 2023 19:23:19 +0100 Subject: [PATCH 22/41] improve ListStack --- QSB/HUD/MultiplayerHUDManager.cs | 2 +- QSB/HUD/PlanetTrigger.cs | 4 +-- QSB/Utility/ListStack.cs | 52 ++++++++++++++++++++++++-------- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/QSB/HUD/MultiplayerHUDManager.cs b/QSB/HUD/MultiplayerHUDManager.cs index d3886162..2970b741 100644 --- a/QSB/HUD/MultiplayerHUDManager.cs +++ b/QSB/HUD/MultiplayerHUDManager.cs @@ -94,7 +94,7 @@ internal class MultiplayerHUDManager : MonoBehaviour, IAddComponentOnStart if (_messages.Count > LINE_COUNT) { - _messages.RemoveFirstElementAndShift(); + _messages.PopFromBack(); } var currentLineIndex = 10; diff --git a/QSB/HUD/PlanetTrigger.cs b/QSB/HUD/PlanetTrigger.cs index 339e32a1..a97b12ce 100644 --- a/QSB/HUD/PlanetTrigger.cs +++ b/QSB/HUD/PlanetTrigger.cs @@ -16,7 +16,7 @@ public class PlanetTrigger : SectoredMonoBehaviour } MultiplayerHUDManager.HUDIconStack.Push(Icon); - var top = MultiplayerHUDManager.HUDIconStack.Peek(); + var top = MultiplayerHUDManager.HUDIconStack.PeekFront(); new PlanetMessage(top).Send(); } @@ -28,7 +28,7 @@ public class PlanetTrigger : SectoredMonoBehaviour } MultiplayerHUDManager.HUDIconStack.Remove(Icon); - var top = MultiplayerHUDManager.HUDIconStack.Peek(); + var top = MultiplayerHUDManager.HUDIconStack.PeekFront(); new PlanetMessage(top).Send(); } } diff --git a/QSB/Utility/ListStack.cs b/QSB/Utility/ListStack.cs index 98cd65c9..8a960bca 100644 --- a/QSB/Utility/ListStack.cs +++ b/QSB/Utility/ListStack.cs @@ -4,6 +4,9 @@ using System.Collections.Generic; namespace QSB.Utility; +/// +/// A LIFO collection with List<> functionality. +/// public class ListStack : IEnumerable { private List _items = new(); @@ -12,14 +15,21 @@ public class ListStack : IEnumerable private readonly bool _removeDuplicates; + /// If true, all elements equal to the added item will be removed prior to adding the new element. public ListStack(bool removeDuplicates) { _removeDuplicates = removeDuplicates; } + /// + /// Removes all items from the stack. + /// public void Clear() => _items.Clear(); + /// + /// Pushes an element onto the front of the stack. + /// public void Push(T item) { if (_removeDuplicates && _items.Contains(item)) @@ -30,7 +40,10 @@ public class ListStack : IEnumerable _items.Add(item); } - public T Pop() + /// + /// Pops an element off the front of the stack. + /// + public T PopFromFront() { if (_items.Count > 0) { @@ -42,7 +55,10 @@ public class ListStack : IEnumerable return default; } - public T RemoveFirstElementAndShift() + /// + /// Pops an element off the back of the stack and shifts the entire stack backwards. + /// + public T PopFromBack() { if (_items.Count == 0) { @@ -50,29 +66,39 @@ public class ListStack : IEnumerable } var firstElement = _items[0]; - - if (_items.Count == 0) - { - return firstElement; - } - - // shift list left - // allocates blehhh who cares - _items = _items.GetRange(1, _items.Count - 1); - + _items.RemoveAt(0); return firstElement; } - public T Peek() => _items.Count > 0 + /// + /// Returns the element at the front of the stack. + /// + public T PeekFront() => _items.Count > 0 ? _items[_items.Count - 1] : default; + /// + /// Returns the element at the back of the stack. + /// + public T PeekBack() => _items.Count > 0 + ? _items[0] + : default; + + /// + /// Removes the element at the given index, where 0 is the back of the stack. The stack will shift backwards to fill empty space. + /// public void RemoveAt(int index) => _items.RemoveAt(index); + /// + /// Removes the first occurence (back to front) of an item. + /// public bool Remove(T item) => _items.Remove(item); + /// + /// Removes all elements that match the given predicate. + /// public int RemoveAll(Predicate match) => _items.RemoveAll(match); From 3675ba28fbad3a5dc7640c442d94c344a592daf5 Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Fri, 7 Jul 2023 23:36:08 +0100 Subject: [PATCH 23/41] add custom data per playerinfo --- QSB/Player/PlayerInfo.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/QSB/Player/PlayerInfo.cs b/QSB/Player/PlayerInfo.cs index 5774880d..e90e0cdd 100644 --- a/QSB/Player/PlayerInfo.cs +++ b/QSB/Player/PlayerInfo.cs @@ -11,6 +11,7 @@ using QSB.QuantumSync.WorldObjects; using QSB.ShipSync; using QSB.Tools; using QSB.Utility; +using System.Collections.Generic; using System.Linq; using UnityEngine; @@ -178,5 +179,21 @@ public partial class PlayerInfo HUDBox.OnRespawn(); } + private Dictionary _customData = new(); + + public void SetCustomData(string key, T data) + => _customData[key] = data; + + public T GetCustomData(string key) + { + if (!_customData.ContainsKey(key)) + { + DebugLog.ToConsole($"Custom data for {ToString()} does not contain entry with key {key}!", MessageType.Error); + return default; + } + + return (T)_customData[key]; + } + public override string ToString() => $"{PlayerId}:{GetType().Name} ({Name})"; } From 96f3840b9217e09506de8815151f9b7cd323e150 Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Sat, 8 Jul 2023 00:13:54 +0100 Subject: [PATCH 24/41] Update QSBMessage.cs --- QSB/Messaging/QSBMessage.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QSB/Messaging/QSBMessage.cs b/QSB/Messaging/QSBMessage.cs index 764bc9b2..f52f55b6 100644 --- a/QSB/Messaging/QSBMessage.cs +++ b/QSB/Messaging/QSBMessage.cs @@ -7,7 +7,7 @@ public abstract class QSBMessage /// /// set automatically by Send /// - internal uint From; + protected internal uint From; /// /// (default) uint.MaxValue = send to everyone
/// 0 = send to host From 98354e9a37cbdd3786e5548a4b38af43284e5ce9 Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Sat, 8 Jul 2023 00:21:25 +0100 Subject: [PATCH 25/41] Update DebugLog.cs --- QSB/Utility/DebugLog.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/QSB/Utility/DebugLog.cs b/QSB/Utility/DebugLog.cs index 8c17293a..020f436f 100644 --- a/QSB/Utility/DebugLog.cs +++ b/QSB/Utility/DebugLog.cs @@ -1,8 +1,8 @@ using OWML.Common; using OWML.Logging; +using OWML.Utils; using System.Diagnostics; using System.Linq; -using System.Reflection; using System.Runtime.CompilerServices; #pragma warning disable CS0618 @@ -28,7 +28,20 @@ public static class DebugLog } else { - QSBCore.Helper.Console.WriteLine(message, type, GetCallingType()); + var socket = QSBCore.Helper.Console.GetValue("_socket"); + socket.WriteToSocket(new ModSocketMessage + { + SenderName = "QSB", + SenderType = GetCallingType(), + Type = type, + Message = message + }); + + if (type == MessageType.Fatal) + { + socket.Close(); + Process.GetCurrentProcess().Kill(); + } } } From 756fb161d0d6820ef7b66c6dd2bc6d493bff90cc Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Sat, 8 Jul 2023 10:42:39 +0100 Subject: [PATCH 26/41] remove log message when there is no existing key --- QSB/Player/PlayerInfo.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/QSB/Player/PlayerInfo.cs b/QSB/Player/PlayerInfo.cs index e90e0cdd..d8ef861d 100644 --- a/QSB/Player/PlayerInfo.cs +++ b/QSB/Player/PlayerInfo.cs @@ -188,7 +188,6 @@ public partial class PlayerInfo { if (!_customData.ContainsKey(key)) { - DebugLog.ToConsole($"Custom data for {ToString()} does not contain entry with key {key}!", MessageType.Error); return default; } From b1e38b69095b3f2dc94f9c514dc7f3a337ba6ce8 Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Sat, 8 Jul 2023 14:15:48 +0100 Subject: [PATCH 27/41] more improvements to ListStack --- QSB/Utility/ListStack.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/QSB/Utility/ListStack.cs b/QSB/Utility/ListStack.cs index 8a960bca..58ecd2f3 100644 --- a/QSB/Utility/ListStack.cs +++ b/QSB/Utility/ListStack.cs @@ -102,6 +102,18 @@ public class ListStack : IEnumerable public int RemoveAll(Predicate match) => _items.RemoveAll(match); + /// + /// Returns the index of the given item, where 0 is the back of the stack. + /// + public int IndexOf(T item) + => _items.IndexOf(item); + + public T this[int index] + { + get => _items[index]; + set => _items[index] = value; + } + IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)_items).GetEnumerator(); public IEnumerator GetEnumerator() => ((IEnumerable)_items).GetEnumerator(); } From 4ab15e74e6c3fc71c5d53799ddb36e781aea4f74 Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Sun, 9 Jul 2023 21:19:52 +0100 Subject: [PATCH 28/41] add command intepreter and message scrolling --- QSB/HUD/MultiplayerHUDManager.cs | 40 ++++++++++++++++- QSB/Utility/CommandInterpreter.cs | 74 +++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 QSB/Utility/CommandInterpreter.cs diff --git a/QSB/HUD/MultiplayerHUDManager.cs b/QSB/HUD/MultiplayerHUDManager.cs index 2970b741..fe698ba1 100644 --- a/QSB/HUD/MultiplayerHUDManager.cs +++ b/QSB/HUD/MultiplayerHUDManager.cs @@ -9,6 +9,7 @@ using QSB.WorldSync; using System; using System.Linq; using UnityEngine; +using UnityEngine.InputSystem; using UnityEngine.SceneManagement; using UnityEngine.UI; @@ -157,6 +158,8 @@ internal class MultiplayerHUDManager : MonoBehaviour, IAddComponentOnStart _textChat.GetComponent().alpha = 1; } + ListStack previousMessages = new(true); + private void Update() { if (!QSBWorldSync.AllObjectsReady || _playerList == null) @@ -168,12 +171,39 @@ internal class MultiplayerHUDManager : MonoBehaviour, IAddComponentOnStart var inSuit = Locator.GetPlayerSuit().IsWearingHelmet(); - if (OWInput.IsNewlyPressed(InputLibrary.enter, InputMode.Character) && !_writingMessage && inSuit && QSBCore.TextChatInput) + if ((OWInput.IsNewlyPressed(InputLibrary.enter, InputMode.Character) || (Keyboard.current[Key.Slash].wasPressedThisFrame && OWInput.IsInputMode(InputMode.Character))) + && !_writingMessage && inSuit && QSBCore.TextChatInput) { OWInput.ChangeInputMode(InputMode.KeyboardInput); _writingMessage = true; _inputField.ActivateInputField(); _textChat.GetComponent().alpha = 1; + + if (Keyboard.current[Key.Slash].wasPressedThisFrame) + { + Delay.RunNextFrame(() => _inputField.text = "/"); + } + } + + if (Keyboard.current[Key.UpArrow].wasPressedThisFrame && _writingMessage) + { + var currentText = _inputField.text; + + if (previousMessages.Contains(currentText)) + { + var index = previousMessages.IndexOf(currentText); + + if (index == 0) + { + return; + } + + _inputField.text = previousMessages[index - 1]; + } + else + { + _inputField.text = previousMessages.Last(); + } } if (OWInput.IsNewlyPressed(InputLibrary.enter, InputMode.KeyboardInput) && _writingMessage) @@ -185,6 +215,14 @@ internal class MultiplayerHUDManager : MonoBehaviour, IAddComponentOnStart var message = _inputField.text; _inputField.text = ""; message = message.Replace("\n", "").Replace("\r", ""); + + previousMessages.Push(message); + + if (QSBCore.DebugSettings.DebugMode && CommandInterpreter.InterpretCommand(message)) + { + return; + } + message = $"{QSBPlayerManager.LocalPlayer.Name}: {message}"; new ChatMessage(message, Color.white).Send(); } diff --git a/QSB/Utility/CommandInterpreter.cs b/QSB/Utility/CommandInterpreter.cs new file mode 100644 index 00000000..f402d559 --- /dev/null +++ b/QSB/Utility/CommandInterpreter.cs @@ -0,0 +1,74 @@ +using QSB.HUD; +using QSB.Messaging; +using QSB.ShipSync; +using QSB.ShipSync.Messages; +using QSB.WorldSync; +using System.Linq; +using UnityEngine; + +namespace QSB.Utility; + +public class CommandInterpreter : MonoBehaviour, IAddComponentOnStart +{ + public static bool InterpretCommand(string message) + { + if (message[0] != '/') + { + return false; + } + + var commandParts = message.ToLower().Substring(1).Split(' '); + var command = commandParts[0]; + + switch (command) + { + case "ship": + ShipCommand(commandParts.Skip(1).ToArray()); + break; + default: + MultiplayerHUDManager.Instance.WriteMessage($"Unknown command \"{command}\".", Color.red); + break; + } + + return true; + } + + public static void ShipCommand(string[] arguments) + { + var command = arguments[0]; + + switch (command) + { + case "explode": + MultiplayerHUDManager.Instance.WriteMessage($"Blowing up the ship.", Color.green); + var shipDamageController = Locator.GetShipTransform().GetComponentInChildren(); + shipDamageController.Explode(); + break; + case "repair": + case "damage": + var damage = command == "damage"; + switch (arguments[1]) + { + case "headlight": + var headlight = QSBWorldSync.GetUnityObject(); + headlight.SetDamaged(damage); + break; + default: + break; + } + MultiplayerHUDManager.Instance.WriteMessage($"{(damage ? "Damaging" : "Repairing")} the {arguments[1]}.", Color.green); + break; + case "open-hatch": + QSBWorldSync.GetUnityObject().OpenHatch(); + new HatchMessage(true).Send(); + break; + case "close-hatch": + QSBWorldSync.GetUnityObject().CloseHatch(); + new HatchMessage(false).Send(); + break; + default: + MultiplayerHUDManager.Instance.WriteMessage($"Unknown ship command \"{command}\".", Color.red); + break; + } + } +} From 9ff28dc891b344aa70ef3a241bede7a7f240e419 Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Sun, 9 Jul 2023 21:21:13 +0100 Subject: [PATCH 29/41] Update manifest.json --- QSB/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QSB/manifest.json b/QSB/manifest.json index 55aa0efd..6a4ea52e 100644 --- a/QSB/manifest.json +++ b/QSB/manifest.json @@ -7,7 +7,7 @@ "body": "- Disable *all* other mods. (Can heavily affect performance)\n- Make sure you are not running any other network-intensive applications." }, "uniqueName": "Raicuparta.QuantumSpaceBuddies", - "version": "0.28.3", + "version": "0.29.0", "owmlVersion": "2.9.0", "dependencies": [ "_nebula.MenuFramework", "JohnCorby.VanillaFix" ], "pathsToPreserve": [ "debugsettings.json" ], From b4b48c97b6a75e4f1f5b00700c360135a503751b Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Sun, 9 Jul 2023 14:07:45 -0700 Subject: [PATCH 30/41] update packages in other projects too --- EpicOnlineTransport/EpicOnlineTransport.csproj | 2 +- EpicRerouter/EpicRerouter.csproj | 4 ++-- MirrorWeaver/MirrorWeaver.csproj | 4 ++-- QSB/manifest.json | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/EpicOnlineTransport/EpicOnlineTransport.csproj b/EpicOnlineTransport/EpicOnlineTransport.csproj index 8b101b34..0b7d1d20 100644 --- a/EpicOnlineTransport/EpicOnlineTransport.csproj +++ b/EpicOnlineTransport/EpicOnlineTransport.csproj @@ -8,7 +8,7 @@ License.md - + diff --git a/EpicRerouter/EpicRerouter.csproj b/EpicRerouter/EpicRerouter.csproj index d797329f..a6efdf87 100644 --- a/EpicRerouter/EpicRerouter.csproj +++ b/EpicRerouter/EpicRerouter.csproj @@ -14,7 +14,7 @@ - - + + diff --git a/MirrorWeaver/MirrorWeaver.csproj b/MirrorWeaver/MirrorWeaver.csproj index 8cc6f6c8..f8a45469 100644 --- a/MirrorWeaver/MirrorWeaver.csproj +++ b/MirrorWeaver/MirrorWeaver.csproj @@ -8,8 +8,8 @@ - - + + diff --git a/QSB/manifest.json b/QSB/manifest.json index 6a4ea52e..226ef364 100644 --- a/QSB/manifest.json +++ b/QSB/manifest.json @@ -8,7 +8,7 @@ }, "uniqueName": "Raicuparta.QuantumSpaceBuddies", "version": "0.29.0", - "owmlVersion": "2.9.0", + "owmlVersion": "2.9.3", "dependencies": [ "_nebula.MenuFramework", "JohnCorby.VanillaFix" ], "pathsToPreserve": [ "debugsettings.json" ], "requireLatestVersion": true From 8b23b7bfd4167122892a8a2f2f2ebb96cff9fccf Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Wed, 26 Jul 2023 18:24:43 +0100 Subject: [PATCH 31/41] make development file --- DEVELOPMENT.md | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++ QSB.sln | 5 +-- README.md | 90 +++------------------------------------------- 3 files changed, 106 insertions(+), 87 deletions(-) create mode 100644 DEVELOPMENT.md diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 00000000..064a1536 --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,98 @@ +> :warning: Warning! :warning: +Mod development needs a powerful PC! +Unexpected errors and issues may occur when editing networking code. +Running multiple instances of the game can be very taxing on your computer. +We're not responsible if you push your PC too hard. + +## Prerequisites +- Visual Studio 2022. +- Epic or Steam version of Outer Wilds. +- Keyboard with numpad for in-game debug actions. + +We recommend using the Outer Wilds Mod Manager, but you can use OWML on its own if you want. + +## Cloning and configuration +- Clone QSB's source code. +- Copy the file `DevEnv.template.targets` and rename it to `DevEnv.targets`. +- In `DevEnv.targets`, edit the entry for `` to point to your installation of OWML. This should be the folder named `OWML`. If using the manager, you can find this directory by : + - Legacy Manager : Press the "Mods Directory" button and go up a folder. + - New Manager : Press the "..." button at the top, and select "Show OWML Folder". +- `QSB.sln` should now be ready to open. ***This solution needs to be opened with Visual Studio 2022 or higher!*** + +## Steam +If using the Steam version of Outer Wilds, you will need to create a file to allow you to run multiple instances of the game. +- Navigate to your game install folder. You can find this by right-clicking on the game in Steam, and going `Manage > Browse local files`. +- Create a file named `steam_appid.txt`. +- In this file, write `753640` and save. +This file will override some Steam DRM features and allow the game to be ran multiple times at once. + +## Building +Simply build the solution normally. (`Build > Build Solution` or CTRL-SHIFT-B) + +The files will automatically be copied over to your OWML installation and be ready to play - no DLL copying needed. + +For documentation reasons, here is the build flow : + +- MirrorWeaver is built. +- EpicOnlineTransport is built. +- EpicRerouter is built. +- QSB is built. +- Any `.exe.config` files are removed from the build. +- QSB.dll is processed ("weaved") by MirrorWeaver. This injects all the boilerplate code that Mirror needs to function. +- If needed/possible, any `.dll` or `.exe` files are copied to the Unity project. + +## Debugging +### Debug Actions : + +Hold Q and press : + +- Numpad 1 - Teleport to nearest player. +- Numpad 2 - If holding LeftShift, warp to the dreamworld Vault fire. If not, warp to the Endless Canyon. +- Numpad 3 - Unlock the Sealed Vault. +- Numpad 4 - Damage the ship's electrical system. +- Numpad 5 - Trigger the supernova. +- Numpad 6 - Set the flags for having met Solanum and the Prisoner. +- Numpad 7 - Warp to the Vessel. +- Numpad 8 - Insert the Advanced Warp Core into the Vessel. +- Numpad 9 - If holding LeftShift, load the SolarSystem scene. If not, load the EyeOfTheUniverse scene. +- Numpad 0 - Revive a random dead player. + +### Debug Settings : + +Create a file called `debugsettings.json` in the mod folder. +The template for this file is this : + +```json +{ + "dumpWorldObjects": false, + "instanceIdInLogs": false, + "hookDebugLogs": false, + "avoidTimeSync": false, + "autoStart": false, + "kickEveryone": false, + "disableLoopDeath": false, + "debugMode": false, + "drawGui": false, + "drawLines": false, + "drawLabels": false, + "drawQuantumVisibilityObjects": false, + "drawGhostAI": false, + "greySkybox": false +} +``` + +- dumpWorldObjects - Creates a file with information about the WorldObjects that were created. +- instanceIdInLogs - Appends the game instance id to every log message sent. +- hookDebugLogs - Print Unity logs and warnings. +- avoidTimeSync - Disables the syncing of time. +- autoStart - Host/connect automatically for faster testing. +- kickEveryone - Kick anyone who joins a game. +- disableLoopDeath - Make it so the loop doesn't end when everyone is dead. +- debugMode - Enables debug mode. If this is set to `false`, none of the following settings do anything. +- drawGui - Draws a GUI at the top of the screen that gives information on many things. +- drawLines - Draws gizmo-esque lines around things. Indicates reference sectors/transforms, triggers, etc. LAGGY. +- drawLabels - Draws GUI labels attached to some objects. LAGGY. +- drawQuantumVisibilityObjects - Indicates visibility objects with an orange shape. +- drawGhostAI - Draws debug lines and labels just for the ghosts. +- greySkybox - Turns the skybox grey. Useful in the Eye, where it's pretty dark. + diff --git a/QSB.sln b/QSB.sln index eff33a19..498d8553 100644 --- a/QSB.sln +++ b/QSB.sln @@ -8,6 +8,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2569F98D-F671-42AA-82DE-505B05CDCEF2}" ProjectSection(SolutionItems) = preProject .gitignore = .gitignore + DEVELOPMENT.md = DEVELOPMENT.md LICENSE = LICENSE README.md = README.md TRANSLATING.md = TRANSLATING.md @@ -15,9 +16,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MirrorWeaver", "MirrorWeaver\MirrorWeaver.csproj", "{DA8A467E-15BA-456C-9034-6EB80BAF1FF9}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EpicOnlineTransport", "EpicOnlineTransport\EpicOnlineTransport.csproj", "{971AA4A1-6729-40DE-AADF-2754F1E8783A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EpicOnlineTransport", "EpicOnlineTransport\EpicOnlineTransport.csproj", "{971AA4A1-6729-40DE-AADF-2754F1E8783A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EpicRerouter", "EpicRerouter\EpicRerouter.csproj", "{639EFAEE-C4A1-4DA2-8457-D0472A9F6343}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EpicRerouter", "EpicRerouter\EpicRerouter.csproj", "{639EFAEE-C4A1-4DA2-8457-D0472A9F6343}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/README.md b/README.md index 76fa21a0..1abe708f 100644 --- a/README.md +++ b/README.md @@ -19,13 +19,13 @@ Spoilers within! ### Easy installation (recommended) -- [Install the Outer Wilds Mod Manager](https://github.com/Raicuparta/ow-mod-manager#how-do-i-use-this); +- [Install the Outer Wilds Mod Manager](https://outerwildsmods.com/mod-manager/); - Install Quantum Space Buddies from the mod list displayed in the application; - If you can't get the mod manager to work, follow the instructions for manual installation. ### Manual installation -- [Install OWML](https://github.com/amazingalek/owml#installation); +- [Install OWML](https://github.com/ow-mods/owml#installation); - [Download the latest Quantum Space Buddies release](https://github.com/misternebula/quantum-space-buddies/releases/latest); - Extract the `QSB` directory to the `OWML/Mods` directory; - Run `OWML.Launcher.exe` to start the game. @@ -47,7 +47,7 @@ Spoilers within! ## Frequently Asked Questions ### I keep timing out when trying to connect! -Check the mod settings for "Use KCP Transport". You have to forward port 7777 as TCP/UDP, or use Hamachi. ALL PLAYERS MUST HAVE THIS AS THE SAME VALUE. +Check the mod settings for "Use KCP Transport". You have to forward port 7777 as TCP/UDP, or use Hamachi. ***All players must either be using KCP, or not using KCP.*** ### Requirements - Latest version of OWML. @@ -89,93 +89,13 @@ QSB is a fully synced game. The other players are actually there in the world, a Outer Wilds Online is easier to set up, but much more basic in its features. The other players cannot affect your game, and do not contribute to anything in your save. The loop is entirely per-player. -### Why would someone make this mod? Seems like a lot of effort for no reward. - -Good question. - -Let me know if you find an answer. - -**Update**: a plausible answer is the enjoyment you get seeing/hearing about others playing with their friends :) - ## Translating See [TRANSLATING.md](TRANSLATING.md) -## Development Setup +## Development Setup / Contributing -- [Download the Outer Wilds Mod Manager](https://github.com/raicuparta/ow-mod-manager) and install it anywhere you like; -- Install OWML using the Mod Manager -- Clone QSB's source -- Open the file `DevEnv.targets` in your favorite text editor -- (optional if copying built dlls manually) Edit the entry `` to point to your OWML directory (it is installed inside the Mod Manager directory) -- (optional if no unity project) Edit the entry `` to point to the Assets folder of the QSB unity project -- Open the project solution file `QSB.sln` in Visual Studio 2022 - -If developing with the Steam version of Outer Wilds you can't run multiple instances of the game by default. To do so, create a file called `steam_appid.txt` in your Outer Wilds directory and write `753640` inside it, then run the exe directly. - -A powerful PC is needed for development, due to the high amount of RAM and CPU needed to run 2 or 3 instances of modded Outer Wilds. - -It is also recommended to lower all graphics settings to minimum, be in windowed mode, and lower resolution to roughly a quarter of your monitor space. This lets you run multiple instances of Outer Wilds to quickly test QSB. - -Some debugging options exist to make things easier. These come in the form of actions and settings. -### Debug Actions : - -Hold Q and press : - -- Numpad 1 - Teleport to nearest player. -- Numpad 2 - If holding LeftShift, warp to the dreamworld Vault fire. If not, warp to the Endless Canyon. -- Numpad 3 - Unlock the Sealed Vault. -- Numpad 4 - Damage the ship's electrical system. -- Numpad 5 - Trigger the supernova. -- Numpad 6 - Set the flags for having met Solanum and the Prisoner. -- Numpad 7 - Warp to the Vessel. -- Numpad 8 - Insert the Advanced Warp Core into the Vessel. -- Numpad 9 - If holding LeftShift, load the SolarSystem scene. If not, load the EyeOfTheUniverse scene. -- Numpad 0 - Revive a random dead player. - -### Debug Settings : - -Create a file called `debugsettings.json` in the mod folder. -The template for this file is this : - -``` -{ - "dumpWorldObjects": false, - "instanceIdInLogs": false, - "hookDebugLogs": false, - "avoidTimeSync": false, - "autoStart": false, - "kickEveryone": false, - "disableLoopDeath": false, - "debugMode": false, - "drawGui": false, - "drawLines": false, - "drawLabels": false, - "drawQuantumVisibilityObjects": false, - "drawGhostAI": false, - "greySkybox": false -} -``` - -- dumpWorldObjects - Creates a file with information about the WorldObjects that were created. -- instanceIdInLogs - Appends the game instance id to every log message sent. -- hookDebugLogs - Print Unity logs and warnings. -- avoidTimeSync - Disables the syncing of time. -- autoStart - Host/connect automatically for faster testing. -- kickEveryone - Kick anyone who joins a game. -- disableLoopDeath - Make it so the loop doesn't end when everyone is dead. -- debugMode - Enables debug mode. If this is set to `false`, none of the following settings do anything. -- drawGui - Draws a GUI at the top of the screen that gives information on many things. -- drawLines - Draws gizmo-esque lines around things. Indicates reference sectors/transforms, triggers, etc. LAGGY. -- drawLabels - Draws GUI labels attached to some objects. LAGGY. -- drawQuantumVisibilityObjects - Indicates visibility objects with an orange shape. -- drawGhostAI - Draws debug lines and labels just for the ghosts. -- greySkybox - Turns the skybox grey. Useful in the Eye, where it's pretty dark. - -**Warning : Mod development can lead to unexpected errors in your computer system.** -- **When editing the networking code, mistakes can lead to QSB overwhelming your network connection with excess packets**. -- **Too high RAM usage will lead to Outer Wilds sticking at ~31% loading, then crashing**. -- **There have been instances of graphics cards crashing, and needing to be disabled/re-enabled from Device Manager.** +See [DEVELOPMENT.md](DEVELOPMENT.md) ## Authors and Special Thanks From d27fc9ee6d90fd0c6bb1e285be3d936313ca23a8 Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Wed, 26 Jul 2023 23:54:58 +0100 Subject: [PATCH 32/41] fix authors --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1abe708f..9c6c82af 100644 --- a/README.md +++ b/README.md @@ -101,10 +101,10 @@ See [DEVELOPMENT.md](DEVELOPMENT.md) ### Authors -- [\_nebula](https://github.com/misternebula) - Developer of v0.3.0 onwards -- [JohnCorby](https://github.com/JohnCorby) - Co-developer of v0.13.0 onwards. -- [AmazingAlek](https://github.com/amazingalek) - Developer of v0.1.0 - v0.7.1. -- [Raicuparta](https://github.com/Raicuparta) - Developer of v0.1.0 - v0.2.0. +- [\_nebula](https://github.com/misternebula) - Lead Dev *(v0.3.0 onwards.)* +- [JohnCorby](https://github.com/JohnCorby) - Lead Dev *(v0.13.0 onwards)* +- [AmazingAlek](https://github.com/amazingalek) - Ex-Developer *(v0.1.0 - v0.7.1)* +- [Raicuparta](https://github.com/Raicuparta) - Ex-Developer *(v0.1.0 - v0.2.0)* ### Contributers From e19224c64979804a852cf5ea885fb18f29938cb5 Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Thu, 27 Jul 2023 00:23:24 +0100 Subject: [PATCH 33/41] add qsb abbreviation for resharper --- QSB.sln.DotSettings | 1 + 1 file changed, 1 insertion(+) diff --git a/QSB.sln.DotSettings b/QSB.sln.DotSettings index 5a30abd4..91efc766 100644 --- a/QSB.sln.DotSettings +++ b/QSB.sln.DotSettings @@ -8,6 +8,7 @@ Required Required NEXT_LINE_SHIFTED_2 + QSB True True True From 98e8d6db4b0a115cf86fde53341413a4960e1f5b Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Thu, 27 Jul 2023 00:39:03 +0100 Subject: [PATCH 34/41] don't write messages when not ready --- QSB/HUD/MultiplayerHUDManager.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/QSB/HUD/MultiplayerHUDManager.cs b/QSB/HUD/MultiplayerHUDManager.cs index fe698ba1..22d22dd7 100644 --- a/QSB/HUD/MultiplayerHUDManager.cs +++ b/QSB/HUD/MultiplayerHUDManager.cs @@ -23,6 +23,7 @@ internal class MultiplayerHUDManager : MonoBehaviour, IAddComponentOnStart private Transform _textChat; private InputField _inputField; private Material _markerMaterial; + private bool _ready; public static Sprite UnknownSprite; public static Sprite DeadSprite; @@ -64,6 +65,11 @@ internal class MultiplayerHUDManager : MonoBehaviour, IAddComponentOnStart Interloper = QSBCore.HUDAssetBundle.LoadAsset("Assets/MULTIPLAYER_UI/playerbox_interloper.png"); WhiteHole = QSBCore.HUDAssetBundle.LoadAsset("Assets/MULTIPLAYER_UI/playerbox_whitehole.png"); SpaceSprite = QSBCore.HUDAssetBundle.LoadAsset("Assets/MULTIPLAYER_UI/playerbox_space.png"); + + QSBSceneManager.OnPostSceneLoad += (OWScene old, OWScene newScene) => + { + _ready = false; + }; } private const int LINE_COUNT = 11; @@ -79,6 +85,11 @@ internal class MultiplayerHUDManager : MonoBehaviour, IAddComponentOnStart public void WriteMessage(string message, Color color) { + if (!_ready) + { + return; + } + /* Tricky problem to solve. * - 11 available lines for text to fit onto * - Each line can be max 41 characters @@ -307,6 +318,8 @@ internal class MultiplayerHUDManager : MonoBehaviour, IAddComponentOnStart _lines.Clear(); _messages.Clear(); _textChat.GetComponent().alpha = 0; + + _ready = true; } public void UpdateMinimapMarkers(Minimap minimap) From 1894e4fba6b99f8e32688d43f5a9a4e2701208c2 Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Wed, 26 Jul 2023 16:54:04 -0700 Subject: [PATCH 35/41] revert NH compat stuff --- QSB/DeathSync/RespawnOnDeath.cs | 2 +- QSB/MeteorSync/MeteorManager.cs | 5 +---- QSB/ModelShip/ModelShipManager.cs | 7 ------- QSB/SectorSync/QSBSectorManager.cs | 12 ++++-------- QSB/Syncs/Occasional/OccasionalManager.cs | 5 ----- QSB/WorldSync/QSBWorldSync.cs | 3 +-- 6 files changed, 7 insertions(+), 27 deletions(-) diff --git a/QSB/DeathSync/RespawnOnDeath.cs b/QSB/DeathSync/RespawnOnDeath.cs index e83f5801..865ce8db 100644 --- a/QSB/DeathSync/RespawnOnDeath.cs +++ b/QSB/DeathSync/RespawnOnDeath.cs @@ -239,7 +239,7 @@ public class RespawnOnDeath : MonoBehaviour } var cloak = Locator.GetCloakFieldController(); - // visible stranger and maybe NH disables cloak + // visible stranger disables cloak if (cloak) { cloak._playerInsideCloak = false; diff --git a/QSB/MeteorSync/MeteorManager.cs b/QSB/MeteorSync/MeteorManager.cs index 29c841f8..b93704ab 100644 --- a/QSB/MeteorSync/MeteorManager.cs +++ b/QSB/MeteorSync/MeteorManager.cs @@ -1,7 +1,6 @@ using Cysharp.Threading.Tasks; using QSB.MeteorSync.WorldObjects; using QSB.WorldSync; -using System.Linq; using System.Threading; namespace QSB.MeteorSync; @@ -17,9 +16,7 @@ public class MeteorManager : WorldObjectManager // wait for all late initializers (which includes meteor launchers) to finish await UniTask.WaitUntil(() => LateInitializerManager.isDoneInitializing, cancellationToken: ct); - // NH can make multiple so ensure its the stock whitehole - var whiteHole = QSBWorldSync.GetUnityObjects().First(x => x.GetAstroObjectName() == AstroObject.Name.WhiteHole); - WhiteHoleVolume = whiteHole?.GetComponentInChildren(); + WhiteHoleVolume = QSBWorldSync.GetUnityObject(); QSBWorldSync.Init(); QSBWorldSync.Init(); QSBWorldSync.Init(); diff --git a/QSB/ModelShip/ModelShipManager.cs b/QSB/ModelShip/ModelShipManager.cs index 9561475e..3d8df0df 100644 --- a/QSB/ModelShip/ModelShipManager.cs +++ b/QSB/ModelShip/ModelShipManager.cs @@ -37,13 +37,6 @@ internal class ModelShipManager : WorldObjectManager public override async UniTask BuildWorldObjects(OWScene scene, CancellationToken ct) { - // NH can remove this - var modelShip = QSBWorldSync.GetUnityObject()._modelShipBody; - if (!modelShip) - { - return; - } - if (QSBCore.IsHost) { Instantiate(QSBNetworkManager.singleton.ModelShipPrefab).SpawnWithServerOwnership(); diff --git a/QSB/SectorSync/QSBSectorManager.cs b/QSB/SectorSync/QSBSectorManager.cs index c7025685..21fc185f 100644 --- a/QSB/SectorSync/QSBSectorManager.cs +++ b/QSB/SectorSync/QSBSectorManager.cs @@ -91,15 +91,11 @@ public class QSBSectorManager : WorldObjectManager // time loop spinning ring { - // NH can remove this var TimeLoopRing_Body = GameObject.Find("TimeLoopRing_Body"); - if (TimeLoopRing_Body) - { - var Sector_TimeLoopInterior = GameObject.Find("Sector_TimeLoopInterior").GetComponent(); - // use the same trigger as the parent sector - FakeSector.Create(TimeLoopRing_Body, Sector_TimeLoopInterior, - x => x._triggerRoot = Sector_TimeLoopInterior._triggerRoot); - } + var Sector_TimeLoopInterior = GameObject.Find("Sector_TimeLoopInterior").GetComponent(); + // use the same trigger as the parent sector + FakeSector.Create(TimeLoopRing_Body, Sector_TimeLoopInterior, + x => x._triggerRoot = Sector_TimeLoopInterior._triggerRoot); } // TH elevators diff --git a/QSB/Syncs/Occasional/OccasionalManager.cs b/QSB/Syncs/Occasional/OccasionalManager.cs index a9aa2361..726a861d 100644 --- a/QSB/Syncs/Occasional/OccasionalManager.cs +++ b/QSB/Syncs/Occasional/OccasionalManager.cs @@ -22,11 +22,6 @@ internal class OccasionalManager : WorldObjectManager foreach (var proxy in cannon._realDebrisSectorProxies) { - // NH can remove these - if (!proxy) - { - continue; - } SpawnOccasional(proxy.transform.root.GetAttachedOWRigidbody(), gdBody); } diff --git a/QSB/WorldSync/QSBWorldSync.cs b/QSB/WorldSync/QSBWorldSync.cs index 4305b2b9..a20ef519 100644 --- a/QSB/WorldSync/QSBWorldSync.cs +++ b/QSB/WorldSync/QSBWorldSync.cs @@ -208,8 +208,7 @@ public static class QSBWorldSync { // So objects have time to be deleted, made, whatever // i.e. wait until Start has been called - // TODO: see if this number of frames actually works. TWEAK! - Delay.RunFramesLater(10, () => BuildWorldObjects(loadScene).Forget()); + Delay.RunNextFrame(() => BuildWorldObjects(loadScene).Forget()); } }; From 8aefd0f37f206182717674212c031b9086d316a8 Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Thu, 27 Jul 2023 01:11:09 +0100 Subject: [PATCH 36/41] fix NRE in UpdateElectricalComponent --- QSB/ShipSync/ShipManager.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/QSB/ShipSync/ShipManager.cs b/QSB/ShipSync/ShipManager.cs index 8bf13d8c..90e875b7 100644 --- a/QSB/ShipSync/ShipManager.cs +++ b/QSB/ShipSync/ShipManager.cs @@ -184,6 +184,11 @@ public class ShipManager : WorldObjectManager private void UpdateElectricalComponent() { + if (ShipElectricalComponent == null) + { + return; + } + var electricalSystem = ShipElectricalComponent._electricalSystem; var damaged = ShipElectricalComponent._damaged; From 8742e93c61fe2e45beca76296c56189458a8f331 Mon Sep 17 00:00:00 2001 From: _nebula <41904486+misternebula@users.noreply.github.com> Date: Thu, 27 Jul 2023 01:11:26 +0100 Subject: [PATCH 37/41] Update manifest.json --- QSB/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QSB/manifest.json b/QSB/manifest.json index 226ef364..3ce3c11c 100644 --- a/QSB/manifest.json +++ b/QSB/manifest.json @@ -7,7 +7,7 @@ "body": "- Disable *all* other mods. (Can heavily affect performance)\n- Make sure you are not running any other network-intensive applications." }, "uniqueName": "Raicuparta.QuantumSpaceBuddies", - "version": "0.29.0", + "version": "0.29.1", "owmlVersion": "2.9.3", "dependencies": [ "_nebula.MenuFramework", "JohnCorby.VanillaFix" ], "pathsToPreserve": [ "debugsettings.json" ], From 711e977d0d1f095f053c01b0017771f3660d40fb Mon Sep 17 00:00:00 2001 From: Will Corby Date: Wed, 26 Jul 2023 17:30:58 -0700 Subject: [PATCH 38/41] Update README.md install badge --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 9c6c82af..b1b6ab58 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ ![GitHub release (latest by date)](https://img.shields.io/github/downloads/misternebula/quantum-space-buddies/latest/total?style=flat-square) ![GitHub last commit (branch)](https://img.shields.io/github/last-commit/misternebula/quantum-space-buddies/dev?label=last%20commit%20to%20dev&style=flat-square) +[![Install Quantum Space Buddies](https://img.shields.io/endpoint?url=https%3A%2F%2Fouterwildsmods.com%2Fapi%2FRaicuparta.QuantumSpaceBuddies%2Fbadge.json)](https://outerwildsmods.com/mods/quantumspacebuddies/) + [![Support on Patreon](https://img.shields.io/badge/dynamic/json?style=for-the-badge&color=%23e85b46&label=Patreon&query=data.attributes.patron_count&suffix=%20patrons&url=https%3A%2F%2Fwww.patreon.com%2Fapi%2Fcampaigns%2F8528628&logo=patreon)](https://www.patreon.com/qsb) [![Donate with PayPal](https://img.shields.io/badge/PayPal-Donate%20(nebula)-blue?style=for-the-badge&color=blue&logo=paypal)](https://www.paypal.com/paypalme/nebula2056/5) [![Donate with PayPal](https://img.shields.io/badge/PayPal-Donate%20(johncorby)-blue?style=for-the-badge&color=blue&logo=paypal)](https://www.paypal.com/paypalme/johncorby/5) From 25398f884d7606d48191071e54c0affbf32d5d44 Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Wed, 26 Jul 2023 17:34:32 -0700 Subject: [PATCH 39/41] cool protocol --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b1b6ab58..689f942d 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![GitHub release (latest by date)](https://img.shields.io/github/downloads/misternebula/quantum-space-buddies/latest/total?style=flat-square) ![GitHub last commit (branch)](https://img.shields.io/github/last-commit/misternebula/quantum-space-buddies/dev?label=last%20commit%20to%20dev&style=flat-square) -[![Install Quantum Space Buddies](https://img.shields.io/endpoint?url=https%3A%2F%2Fouterwildsmods.com%2Fapi%2FRaicuparta.QuantumSpaceBuddies%2Fbadge.json)](https://outerwildsmods.com/mods/quantumspacebuddies/) +[![Install Quantum Space Buddies](https://img.shields.io/endpoint?url=https%3A%2F%2Fouterwildsmods.com%2Fapi%2FRaicuparta.QuantumSpaceBuddies%2Fbadge.json)](owmods://install-mod/Raicuparta.QuantumSpaceBuddies) [![Support on Patreon](https://img.shields.io/badge/dynamic/json?style=for-the-badge&color=%23e85b46&label=Patreon&query=data.attributes.patron_count&suffix=%20patrons&url=https%3A%2F%2Fwww.patreon.com%2Fapi%2Fcampaigns%2F8528628&logo=patreon)](https://www.patreon.com/qsb) [![Donate with PayPal](https://img.shields.io/badge/PayPal-Donate%20(nebula)-blue?style=for-the-badge&color=blue&logo=paypal)](https://www.paypal.com/paypalme/nebula2056/5) From fd5a22b478d585cb73f0420632966d951aa928bb Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Wed, 26 Jul 2023 17:35:46 -0700 Subject: [PATCH 40/41] Revert "cool protocol" This reverts commit 25398f884d7606d48191071e54c0affbf32d5d44. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 689f942d..b1b6ab58 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![GitHub release (latest by date)](https://img.shields.io/github/downloads/misternebula/quantum-space-buddies/latest/total?style=flat-square) ![GitHub last commit (branch)](https://img.shields.io/github/last-commit/misternebula/quantum-space-buddies/dev?label=last%20commit%20to%20dev&style=flat-square) -[![Install Quantum Space Buddies](https://img.shields.io/endpoint?url=https%3A%2F%2Fouterwildsmods.com%2Fapi%2FRaicuparta.QuantumSpaceBuddies%2Fbadge.json)](owmods://install-mod/Raicuparta.QuantumSpaceBuddies) +[![Install Quantum Space Buddies](https://img.shields.io/endpoint?url=https%3A%2F%2Fouterwildsmods.com%2Fapi%2FRaicuparta.QuantumSpaceBuddies%2Fbadge.json)](https://outerwildsmods.com/mods/quantumspacebuddies/) [![Support on Patreon](https://img.shields.io/badge/dynamic/json?style=for-the-badge&color=%23e85b46&label=Patreon&query=data.attributes.patron_count&suffix=%20patrons&url=https%3A%2F%2Fwww.patreon.com%2Fapi%2Fcampaigns%2F8528628&logo=patreon)](https://www.patreon.com/qsb) [![Donate with PayPal](https://img.shields.io/badge/PayPal-Donate%20(nebula)-blue?style=for-the-badge&color=blue&logo=paypal)](https://www.paypal.com/paypalme/nebula2056/5) From c424064d0e5bbd2f4b6158776097d7056f2c7f30 Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Wed, 26 Jul 2023 17:35:46 -0700 Subject: [PATCH 41/41] Revert "Update README.md" This reverts commit 711e977d0d1f095f053c01b0017771f3660d40fb. --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index b1b6ab58..9c6c82af 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,6 @@ ![GitHub release (latest by date)](https://img.shields.io/github/downloads/misternebula/quantum-space-buddies/latest/total?style=flat-square) ![GitHub last commit (branch)](https://img.shields.io/github/last-commit/misternebula/quantum-space-buddies/dev?label=last%20commit%20to%20dev&style=flat-square) -[![Install Quantum Space Buddies](https://img.shields.io/endpoint?url=https%3A%2F%2Fouterwildsmods.com%2Fapi%2FRaicuparta.QuantumSpaceBuddies%2Fbadge.json)](https://outerwildsmods.com/mods/quantumspacebuddies/) - [![Support on Patreon](https://img.shields.io/badge/dynamic/json?style=for-the-badge&color=%23e85b46&label=Patreon&query=data.attributes.patron_count&suffix=%20patrons&url=https%3A%2F%2Fwww.patreon.com%2Fapi%2Fcampaigns%2F8528628&logo=patreon)](https://www.patreon.com/qsb) [![Donate with PayPal](https://img.shields.io/badge/PayPal-Donate%20(nebula)-blue?style=for-the-badge&color=blue&logo=paypal)](https://www.paypal.com/paypalme/nebula2056/5) [![Donate with PayPal](https://img.shields.io/badge/PayPal-Donate%20(johncorby)-blue?style=for-the-badge&color=blue&logo=paypal)](https://www.paypal.com/paypalme/johncorby/5)