diff --git a/Gamemodes/CaptureTheFlag.cs b/Gamemodes/CaptureTheFlag.cs index 18d9d0f73..d03909cf2 100644 --- a/Gamemodes/CaptureTheFlag.cs +++ b/Gamemodes/CaptureTheFlag.cs @@ -869,6 +869,8 @@ public static class CaptureTheFlag .SendMessage(); } + bool notify = false; + if (TemporarilyOutPlayers.TryGetValue(__instance.PlayerId, out long endTS)) { if (now >= endTS) @@ -881,7 +883,7 @@ public static class CaptureTheFlag SpawnProtectionTimes[__instance.PlayerId] = Utils.TimeStamp + SpawnProtectionTime.GetInt(); } - if (!notified) Utils.NotifyRoles(SpecifySeer: __instance, SpecifyTarget: __instance, SendOption: SendOption.None); + notify = true; } if (SpawnProtectionTimes.TryGetValue(__instance.PlayerId, out long protectionEndTS)) @@ -889,9 +891,11 @@ public static class CaptureTheFlag if (now >= protectionEndTS) SpawnProtectionTimes.Remove(__instance.PlayerId); - if (!notified) - Utils.NotifyRoles(SpecifySeer: __instance, SpecifyTarget: __instance, SendOption: SendOption.None); + notify = true; } + + if (!notified && notify && PerSecondUpdateScheduler.ShouldRunUpdate(__instance.PlayerId)) + Utils.NotifyRoles(SpecifySeer: __instance, SpecifyTarget: __instance, SendOption: SendOption.None); } } } diff --git a/Modules/CustomRpcSender.cs b/Modules/CustomRpcSender.cs index 7b72ab337..cc2a1cae5 100644 --- a/Modules/CustomRpcSender.cs +++ b/Modules/CustomRpcSender.cs @@ -547,7 +547,7 @@ public static class CustomRpcSenderExtensions sender.checkLength = false; - if (sender.stream.Length + GetSetNameRpcSize(player.NetId, name) > 1100) + if (sender.stream.Length + GetSetNameRpcSize(player.NetId, name) > 1180) { bool packed = sender.packed; sender.SendMessage(); diff --git a/Modules/Debugger.cs b/Modules/Debugger.cs index c0125a886..dd2574007 100644 --- a/Modules/Debugger.cs +++ b/Modules/Debugger.cs @@ -239,6 +239,7 @@ public class CustomLogger private const string UnityTag = "-unity"; + private static string LastAppend; private static CustomLogger PrivateInstance; private float timer = 0.5f; @@ -325,11 +326,18 @@ public class CustomLogger string unityTag = fromUnity && !containsException ? UnityTag : string.Empty; - Builder.Append($""" + string element = $"""
{message}
- """); + """; + + if (LastAppend == element) + element = "+"; + else + LastAppend = element; + + Builder.Append(element); #if DEBUG Finish(false); diff --git a/Modules/GameOptionsSender/PlayerGameOptionsSender.cs b/Modules/GameOptionsSender/PlayerGameOptionsSender.cs index 8d3f01743..8d6a8bb4d 100644 --- a/Modules/GameOptionsSender/PlayerGameOptionsSender.cs +++ b/Modules/GameOptionsSender/PlayerGameOptionsSender.cs @@ -64,13 +64,21 @@ public sealed class PlayerGameOptionsSender(PlayerControl player) : GameOptionsS if (PackedWriterMessages > 0 && PackedWriter != null) { - PackedWriter.EndMessage(); - var capturedWriter = PackedWriter; - DataFlagRateLimiter.Enqueue(() => + try { - AmongUsClient.Instance.SendOrDisconnect(capturedWriter); - capturedWriter.Recycle(); - }, cleanup: capturedWriter.Recycle); + PackedWriter.EndMessage(); + var capturedWriter = PackedWriter; + DataFlagRateLimiter.Enqueue(() => + { + AmongUsClient.Instance.SendOrDisconnect(capturedWriter); + capturedWriter.Recycle(); + }, cleanup: capturedWriter.Recycle); + } + catch + { + try { PackedWriter.Recycle(); } + catch { } + } } PackedWriter = MessageWriter.Get(SendOption.Reliable); @@ -95,15 +103,23 @@ public sealed class PlayerGameOptionsSender(PlayerControl player) : GameOptionsS { if (PackedWriterMessages > 0) { - PackedWriter.EndMessage(); - Logger.Info($"PackedWriter flush queued - Length: {PackedWriter.Length}, Messages: {PackedWriterMessages}", "SendAllImmediately"); - var capturedWriter = PackedWriter; - qa = DataFlagRateLimiter.Enqueue(() => + try { - AmongUsClient.Instance.SendOrDisconnect(capturedWriter); - capturedWriter.Recycle(); - Logger.Info("PackedWriter flush queue finished and sent", "SendAllImmediately"); - }, cleanup: capturedWriter.Recycle); + PackedWriter.EndMessage(); + Logger.Info($"PackedWriter flush queued - Length: {PackedWriter.Length}, Messages: {PackedWriterMessages}", "SendAllImmediately"); + var capturedWriter = PackedWriter; + qa = DataFlagRateLimiter.Enqueue(() => + { + AmongUsClient.Instance.SendOrDisconnect(capturedWriter); + capturedWriter.Recycle(); + Logger.Info("PackedWriter flush queue finished and sent", "SendAllImmediately"); + }, cleanup: capturedWriter.Recycle); + } + catch + { + try { PackedWriter.Recycle(); } + catch { } + } } else { @@ -304,15 +320,23 @@ public sealed class PlayerGameOptionsSender(PlayerControl player) : GameOptionsS if (PackedWriter.Length > 1000 || PackedWriterMessages >= AmongUsClient.Instance.GetMaxMessagePackingLimit()) { - PackedWriter.EndMessage(); - Logger.Info($"PackedWriter flush queued - Length: {PackedWriter.Length}, Messages: {PackedWriterMessages}", "SendOptionsArray"); - var capturedWriter = PackedWriter; - DataFlagRateLimiter.Enqueue(() => + try { - AmongUsClient.Instance.SendOrDisconnect(capturedWriter); - capturedWriter.Recycle(); - Logger.Info("PackedWriter flush queue finished and sent", "SendOptionsArray"); - }, cleanup: capturedWriter.Recycle); + PackedWriter.EndMessage(); + Logger.Info($"PackedWriter flush queued - Length: {PackedWriter.Length}, Messages: {PackedWriterMessages}", "SendOptionsArray"); + var capturedWriter = PackedWriter; + DataFlagRateLimiter.Enqueue(() => + { + AmongUsClient.Instance.SendOrDisconnect(capturedWriter); + capturedWriter.Recycle(); + Logger.Info("PackedWriter flush queue finished and sent", "SendOptionsArray"); + }, cleanup: capturedWriter.Recycle); + } + catch + { + try { PackedWriter.Recycle(); } + catch { } + } PackedWriterMessages = 0; PackedWriter = MessageWriter.Get(SendOption.Reliable); PackedWriter.StartMessage(26); diff --git a/Resources/Lang/en_US.json b/Resources/Lang/en_US.json index e5aa903d6..5839f5584 100644 --- a/Resources/Lang/en_US.json +++ b/Resources/Lang/en_US.json @@ -913,6 +913,7 @@ "Helper": "Helper", "HelperInfo": "Complete Tasks For Others", "HelperInfoLong": "(Crewmates):\\nAs the Helper, whenever you complete a task, a random crewmate will also have one of their tasks completed.", + "Helper.AbilityWorksAfterDeath": "Ability Works After Death", "HelperCompletedTaskForYou": "The {0} completed a task for you!", "Ignitor": "Ignitor", "IgnitorInfo": "Light Candles for High Vision", diff --git a/Roles/Standard/Crewmate/Support/Helper.cs b/Roles/Standard/Crewmate/Support/Helper.cs index 1bd58e735..8507f6269 100644 --- a/Roles/Standard/Crewmate/Support/Helper.cs +++ b/Roles/Standard/Crewmate/Support/Helper.cs @@ -7,11 +7,14 @@ public class Helper : RoleBase { public static bool On; + private static OptionItem AbilityWorksAfterDeath; + public override bool IsEnable => On; public override void SetupCustomOption() { StartSetup(651300) + .AutoSetupOption(ref AbilityWorksAfterDeath, true) .CreateOverrideTasksData(); } @@ -27,6 +30,7 @@ public class Helper : RoleBase public override void OnTaskComplete(PlayerControl pc, int completedTaskCount, int totalTaskCount) { + if (!AbilityWorksAfterDeath.GetBool() && !pc.IsAlive()) return; var randomPlayer = Main.EnumeratePlayerControls().Without(pc).Where(x => x.Is(Team.Crewmate)).Select(x => (pc: x, ts: x.GetTaskState())).Where(x => !x.ts.IsTaskFinished && x.ts.HasTasks).Select(x => x.pc).RandomElement(); #if IL2CPP var incompleteTasks = randomPlayer.myTasks.FindAll((Il2CppSystem.Predicate)(x => !x.IsComplete)); diff --git a/Roles/Standard/Impostor/Support/Blackmailer.cs b/Roles/Standard/Impostor/Support/Blackmailer.cs index 13803d281..9240888b0 100644 --- a/Roles/Standard/Impostor/Support/Blackmailer.cs +++ b/Roles/Standard/Impostor/Support/Blackmailer.cs @@ -63,6 +63,7 @@ internal class Blackmailer : RoleBase public override void AfterMeetingTasks() { + NumBlackmailedThisRound = 0; if (AbilityExpires.GetValue() == 0) BlackmailedPlayerIds.Clear(); } diff --git a/Roles/Standard/Neutral/Benign/Amnesiac.cs b/Roles/Standard/Neutral/Benign/Amnesiac.cs index 8d03c432d..d6c2be24e 100644 --- a/Roles/Standard/Neutral/Benign/Amnesiac.cs +++ b/Roles/Standard/Neutral/Benign/Amnesiac.cs @@ -276,7 +276,16 @@ public class Amnesiac : RoleBase if (HasArrowsToDeadBodies.GetBool()) { var pos = target.Pos(); - Instances.ForEach(x => LateTask.New(() => LocateArrow.Add(x.AmnesiacId, pos), IRandom.Instance.Next(ArrowMinDelay.GetInt(), ArrowMaxDelay.GetInt() + 1), "Amnesiac Arrow")); + Instances.ForEach(x => + { + LateTask.New(() => + { + LocateArrow.Add(x.AmnesiacId, pos); + var pc = x.AmnesiacId.GetPlayer(); + if (!pc || !pc.IsAlive()) return; + Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc); + }, IRandom.Instance.Next(ArrowMinDelay.GetInt(), ArrowMaxDelay.GetInt() + 1), "Amnesiac Arrow"); + }); } }