diff --git a/CHANGELOG.md b/CHANGELOG.md index eb1538066..d0371ca76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ ## Changelog +0.9.11: +- @starfi5h: Fix half-growth dark fog bases keep regenerating +- @starfi5h: Fix combat drones doesn't increase ground base threat +- @starfi5h: Fix errors in NgrokManager.IsNgrokActive and SpaceSector.RemoveEnemyWithComponents + 0.9.10: - @fakeboboliu: Support to connect server with WSS by specifying wss:// in the connect Uri - @starfi5h: Sync Logistics Control Panel (I) entry list diff --git a/NebulaModel/Logger/Log.cs b/NebulaModel/Logger/Log.cs index 76afbd0eb..3126a3890 100644 --- a/NebulaModel/Logger/Log.cs +++ b/NebulaModel/Logger/Log.cs @@ -68,8 +68,12 @@ public static void Error(string message) { // ShowError has Unity API and needs to call on the main thread BepInEx.ThreadingHelper.Instance.StartSyncInvoke(() => - UIFatalErrorTip.instance.ShowError("[Nebula Error] " + message, "") - ); + { + // We just want to use the window to show the error message, so leave GameMain.errored as the original value + var tmp = GameMain.errored; + UIFatalErrorTip.instance.ShowError("[Nebula Error] " + message, ""); + GameMain.errored = tmp; + }); return; } UIFatalErrorTip.instance.ShowError("[Nebula Error] " + message, ""); diff --git a/NebulaNetwork/Ngrok/NgrokManager.cs b/NebulaNetwork/Ngrok/NgrokManager.cs index f116c5c1f..03ad36154 100644 --- a/NebulaNetwork/Ngrok/NgrokManager.cs +++ b/NebulaNetwork/Ngrok/NgrokManager.cs @@ -188,13 +188,13 @@ private bool StartNgrok() // This links the process as a child process by attaching a null debugger thus ensuring that the process is killed when its parent dies. _ = new ChildProcessLinker(_ngrokProcess, _ => { - Log.Warn( + Log.WarnInform( "Failed to link Ngrok process to DSP process as a child! (This might result in a left over ngrok process if the DSP process uncleanly killed)"); }); } else { - Log.Error("Failed to start Ngrok process!"); + Log.WarnInform("Failed to start Ngrok process!"); } _ngrokProcess?.BeginOutputReadLine(); @@ -286,7 +286,7 @@ public void StopNgrok() } catch (Exception e) { - Log.Error(e); + Log.WarnInform(e.ToString()); } _ngrokProcess.Close(); _ngrokProcess = null; @@ -301,7 +301,7 @@ public bool IsNgrokActive() } catch (Exception e) { - Log.Error(e); + Log.WarnInform(e.ToString()); return false; } } @@ -310,12 +310,6 @@ public Task GetNgrokAddressAsync() { return Task.Run(() => { - if (!IsNgrokActive()) - { - throw new Exception( - $"Not able to get Ngrok tunnel address because Ngrok is not started (or exited prematurely)! LastErrorCode: {NgrokLastErrorCode} {NgrokLastErrorCodeDesc}"); - } - if (!_ngrokAddressObtainedSource.Task.Wait(TimeSpan.FromSeconds(15))) { throw new TimeoutException( diff --git a/NebulaNetwork/Server.cs b/NebulaNetwork/Server.cs index 523162a4b..aa31d9b8a 100644 --- a/NebulaNetwork/Server.cs +++ b/NebulaNetwork/Server.cs @@ -250,6 +250,7 @@ public void Start() } catch (InvalidOperationException e) { + Log.Warn(e.ToString()); InGamePopup.ShowError("Error", "An error occurred while hosting the game: ".Translate() + e.Message, "Close".Translate()); Stop(); @@ -267,13 +268,22 @@ public void Start() Task.Run(async () => { - if (ngrokManager.IsNgrokActive()) + if (ngrokManager.NgrokEnabled) { - var ip = await ngrokManager.GetNgrokAddressAsync(); - DiscordManager.UpdateRichPresence(ip, updateTimestamp: true); - if (Multiplayer.IsDedicated) + try + { + // Wait up to 15s for ngrok to start, then get the address + var ip = await ngrokManager.GetNgrokAddressAsync(); + DiscordManager.UpdateRichPresence(ip, updateTimestamp: true); + if (Multiplayer.IsDedicated) + { + Log.Info($">> Ngrok address: {ip}"); + } + return; + } + catch (Exception e) { - Log.Info($">> Ngrok address: {ip}"); + Log.Warn(e); } } else diff --git a/NebulaPatcher/Patches/Dynamic/EnemyDFGroundSystem_Patch.cs b/NebulaPatcher/Patches/Dynamic/EnemyDFGroundSystem_Patch.cs index 3bfe4df6f..4b366d01c 100644 --- a/NebulaPatcher/Patches/Dynamic/EnemyDFGroundSystem_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/EnemyDFGroundSystem_Patch.cs @@ -78,31 +78,6 @@ public static bool ExecuteDeferredUnitFormation_Prefix(EnemyDFGroundSystem __ins return true; } - [HarmonyPrefix] - [HarmonyPatch(nameof(EnemyDFGroundSystem.CanEraseBase))] - public static bool CanEraseBase_Prefix(DFGBaseComponent _base, ref bool __result) - { - if (!Multiplayer.IsActive) return true; - - if (_base == null || _base.id == 0) - { - __result = true; - return false; - } - // Skip __instance.builders.buffer[_base.builderId].sp check as it may have different value - var pbuilders = _base.pbuilders; - for (var i = 2; i < pbuilders.Length; i++) - { - if (pbuilders[i].instId > 0) - { - __result = false; - return false; - } - } - __result = true; - return false; - } - [HarmonyPrefix] [HarmonyPatch(nameof(EnemyDFGroundSystem.NotifyEnemyKilled))] public static bool NotifyEnemyKilled_Prefix() @@ -231,4 +206,26 @@ public static void KeyTickLogic_Prefix(EnemyDFGroundSystem __instance) } } + [HarmonyPostfix] + [HarmonyPatch(nameof(EnemyDFGroundSystem.KeyTickLogic))] + public static void KeyTickLogic_Postfix(EnemyDFGroundSystem __instance) + { + if (!Multiplayer.IsActive || Multiplayer.Session.IsServer) return; + + var cursor = __instance.bases.cursor; + var baseBuffer = __instance.bases.buffer; + var enemyPool = __instance.factory.enemyPool; + for (var baseId = 1; baseId < cursor; baseId++) + { + var dfgbaseComponent = baseBuffer[baseId]; + if (dfgbaseComponent == null || dfgbaseComponent.id != baseId) continue; + if (dfgbaseComponent.enemyId != 0 && enemyPool[dfgbaseComponent.enemyId].id == 0) + { + // Note: isInvincible in enemy is used by Nebula client to note if the enemy is pending to get killed + // isInvincible will get set back to true in EnemyDFGroundSystem.KeyTickLogic when base sp > 0 + // So we'll need to set isInvincible = true to let host's incoming KillEnemyFinally packet get executed + enemyPool[dfgbaseComponent.enemyId].isInvincible = true; + } + } + } } diff --git a/NebulaPatcher/Patches/Dynamic/SkillSystem_Patch.cs b/NebulaPatcher/Patches/Dynamic/SkillSystem_Patch.cs index 164205fc7..67eb06f5e 100644 --- a/NebulaPatcher/Patches/Dynamic/SkillSystem_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/SkillSystem_Patch.cs @@ -118,4 +118,25 @@ public static void DamageObject_Prefix(int damage, int slice, ref SkillTarget ta Multiplayer.Session.Network.SendPacketToLocalPlanet(packet); } } + + [HarmonyPrefix] + [HarmonyPatch(nameof(SkillSystem.DamageGroundObjectByLocalCaster))] + public static void DamageGroundObjectByLocalCaster_Prefix(PlanetFactory factory, int damage, int slice, ref SkillTarget target, ref SkillTarget caster) + { + if (caster.type != ETargetType.Craft + || target.type != ETargetType.Enemy + || !Multiplayer.IsActive || Multiplayer.Session.Combat.IsIncomingRequest.Value) return; + + if (factory == GameMain.localPlanet?.factory) // Sync for local planet combat drones + { + target.astroId = caster.astroId = GameMain.localPlanet.astroId; + var packet = new CombatStatDamagePacket(damage, slice, in target, in caster) + { + // Change the caster to player as craft (space fleet) is not sync yet + CasterType = (short)ETargetType.Player, + CasterId = Multiplayer.Session.LocalPlayer.Id + }; + Multiplayer.Session.Network.SendPacketToLocalPlanet(packet); + } + } } diff --git a/NebulaPatcher/Patches/Dynamic/SpaceSector_Patch.cs b/NebulaPatcher/Patches/Dynamic/SpaceSector_Patch.cs index 54e09ed9a..f488f19b0 100644 --- a/NebulaPatcher/Patches/Dynamic/SpaceSector_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/SpaceSector_Patch.cs @@ -53,6 +53,22 @@ public static bool KillEnemyFinal_Prefix(SpaceSector __instance, int enemyId) return false; } + [HarmonyPrefix] + [HarmonyPatch(nameof(SpaceSector.RemoveEnemyWithComponents))] + public static void RemoveEnemyWithComponents_Prefix(SpaceSector __instance, int id) + { + // Fix IndexOutOfRangeException in SpaceSector.RemoveEnemyWithComponents IL_026A + // This is due to combatStats is not sync in client + if (id != 0 && __instance.enemyPool[id].id != 0) + { + if (__instance.enemyPool[id].combatStatId != 0) + { + if (__instance.enemyPool[id].combatStatId >= __instance.skillSystem.combatStats.cursor) + __instance.enemyPool[id].combatStatId = 0; + } + } + } + [HarmonyPrefix] [HarmonyPatch(nameof(SpaceSector.TryCreateNewHive))] public static bool TryCreateNewHive_Prefix(StarData star) diff --git a/NebulaPatcher/Patches/Dynamic/UIFatalErrorTip_Patch.cs b/NebulaPatcher/Patches/Dynamic/UIFatalErrorTip_Patch.cs index 63f0ee53b..3a26fb738 100644 --- a/NebulaPatcher/Patches/Dynamic/UIFatalErrorTip_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/UIFatalErrorTip_Patch.cs @@ -186,7 +186,7 @@ private static void OnCopyClick(int id) } // Nebula only: skip the message after PacketProcessor - if (str.StartsWith("NebulaModel.Packets.PacketProcessor")) + if (str.StartsWith("NebulaModel.Packets.PacketProcessor") || str.StartsWith(" at NebulaModel.Packets.PacketProcessor")) { break; } diff --git a/NebulaPatcher/Patches/Transpilers/DFGBaseComponent_Transpiler.cs b/NebulaPatcher/Patches/Transpilers/DFGBaseComponent_Transpiler.cs index f8501a5e1..36cc454bb 100644 --- a/NebulaPatcher/Patches/Transpilers/DFGBaseComponent_Transpiler.cs +++ b/NebulaPatcher/Patches/Transpilers/DFGBaseComponent_Transpiler.cs @@ -68,8 +68,9 @@ public static IEnumerable UpdateFactoryThreat_Transpiler(IEnume static bool LaunchCondition(DFGBaseComponent @this) { - if (!Multiplayer.IsActive || @this.groundSystem.local_player_alive == true) return @this.groundSystem.local_player_alive; + if (!Multiplayer.IsActive) return @this.groundSystem.local_player_grounded_alive; + // In MP, replace local_player_grounded_alive flag with the following condition var planetId = @this.groundSystem.planet.id; var players = Multiplayer.Session.Combat.Players; for (var i = 0; i < players.Length; i++) diff --git a/version.json b/version.json index 85a05154c..6efe545d0 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "0.9.10", + "version": "0.9.11", "assemblyVersion": { "precision": "build" },