This commit is contained in:
Gurge44 committed 2025-05-24 16:52:44 +02:00
1 parent 8b2bdb8d7a
commit df45daff58
8 files changed
+67 -148

No files matched your search

+1 -1
View File
@@ -433,7 +433,7 @@ public static class CaptureTheFlag
var pc2 = id2.GetPlayer();
if (pc2 == null) continue;
hasValue[id1] |= sender.RpcSetRole(pc2, RoleTypes.Phantom, targetClientId);
hasValue[id1] |= sender.RpcSetRole(pc2, RoleTypes.Phantom, targetClientId, changeRoleMap: true);
if (sender.stream.Length > 400)
{
+1 -1
View File
@@ -335,7 +335,7 @@ public static class KingOfTheZones
PlayerTeams.DoIf(
x => x.Key != id && x.Value == team,
// ReSharper disable once AccessToModifiedClosure
x => writer.RpcSetRole(x.Key.GetPlayer(), RoleTypes.Impostor, targetClientId));
x => writer.RpcSetRole(x.Key.GetPlayer(), RoleTypes.Impostor, targetClientId, changeRoleMap: true));
if (writer.stream.Length > 400)
{
+40 -81
View File
@@ -16,6 +16,7 @@ public static class AntiBlackout
public static bool SkipTasks;
private static Dictionary<byte, (bool IsDead, bool Disconnected)> IsDeadCache = [];
private static readonly LogHandler Logger = EHR.Logger.Handler("AntiBlackout");
private static PlayerControl DummyImp;
private static bool IsCached { get; set; }
@@ -45,11 +46,8 @@ public static class AntiBlackout
var players = Main.AllAlivePlayerControls;
if (CheckForEndVotingPatch.TempExiledPlayer != null) players = players.Where(x => x.PlayerId != CheckForEndVotingPatch.TempExiledPlayer.PlayerId).ToArray();
PlayerControl dummyImp = players.MinBy(x => x.PlayerId);
if (dummyImp == null) return;
var hasValue = false;
var sender = CustomRpcSender.Create("AntiBlackout.RevivePlayersAndSetDummyImp", SendOption.Reliable);
DummyImp = players.MinBy(x => x.PlayerId);
if (DummyImp == null) return;
foreach (PlayerControl seer in Main.AllPlayerControls)
{
@@ -57,16 +55,13 @@ public static class AntiBlackout
if (Options.CurrentGameMode is CustomGameMode.Speedrun or CustomGameMode.SoloKombat or CustomGameMode.FFA or CustomGameMode.CaptureTheFlag or CustomGameMode.KingOfTheZones)
{
sender.RpcSetRole(seer, RoleTypes.Impostor, seer.OwnerId, noRpcForSelf: false);
seer.RpcSetRoleDesync(RoleTypes.Impostor, seer.OwnerId);
foreach (PlayerControl target in Main.AllPlayerControls)
{
if (target.PlayerId != seer.PlayerId)
sender.RpcSetRole(target, RoleTypes.Crewmate, seer.OwnerId, noRpcForSelf: false);
target.RpcSetRoleDesync(RoleTypes.Crewmate, seer.OwnerId);
}
hasValue = true;
RestartMessageIfTooLong();
}
else
{
@@ -76,28 +71,12 @@ public static class AntiBlackout
foreach (PlayerControl target in Main.AllPlayerControls)
{
if (seerIsAliveAndHasKillButton)
sender.RpcSetRole(target, target.PlayerId != seer.PlayerId ? RoleTypes.Crewmate : selfRoleType, seer.GetClientId(), noRpcForSelf: false);
target.RpcSetRoleDesync(target.PlayerId != seer.PlayerId ? RoleTypes.Crewmate : selfRoleType, seer.GetClientId());
else
sender.RpcSetRole(target, target.PlayerId == dummyImp.PlayerId ? RoleTypes.Impostor : RoleTypes.Crewmate, seer.GetClientId(), noRpcForSelf: false);
hasValue = true;
RestartMessageIfTooLong();
target.RpcSetRoleDesync(target.PlayerId == DummyImp.PlayerId ? RoleTypes.Impostor : RoleTypes.Crewmate, seer.GetClientId());
}
}
}
sender.SendMessage(!hasValue);
return;
void RestartMessageIfTooLong()
{
if (sender.stream.Length > 400)
{
sender.SendMessage();
sender = CustomRpcSender.Create("AntiBlackout.RevivePlayersAndSetDummyImp", SendOption.Reliable);
hasValue = false;
}
}
}
public static void RestoreIsDead(bool doSend = true, [CallerMemberName] string callerMethodName = "")
@@ -121,7 +100,7 @@ public static class AntiBlackout
if (doSend)
{
SendGameData();
LateTask.New(RestoreIsDeadByExile, 0.3f, "AntiBlackOut_RestoreIsDeadByExile");
LateTask.New(RestoreIsDeadByExile, 0.3f + Utils.CalculatePingDelay(), "AntiBlackOut_RestoreIsDeadByExile");
}
}
@@ -134,6 +113,7 @@ public static class AntiBlackout
{
if (player.Data.IsDead && !player.Data.Disconnected)
{
player.Exiled();
sender.AutoStartRpc(player.NetId, (byte)RpcCalls.Exiled);
sender.EndRpc();
hasValue = true;
@@ -193,10 +173,9 @@ public static class AntiBlackout
public static void SetRealPlayerRoles()
{
if (CustomWinnerHolder.WinnerTeam != CustomWinner.Default) return;
byte[] keys = Main.AllPlayerControls.Select(x => x.PlayerId).Concat(Main.PlayerStates.Keys).Append(byte.MaxValue).Distinct().ToArray();
Dictionary<byte, CustomRpcSender> senders = keys.ToDictionary(x => x, _ => CustomRpcSender.Create("AntiBlackout.SetRealPlayerRoles", SendOption.Reliable));
Dictionary<byte, bool> hasValue = keys.ToDictionary(x => x, _ => false);
var sender = CustomRpcSender.Create("AntiBlackout.SetRealPlayerRoles", SendOption.Reliable);
var hasValue = false;
List<PlayerControl> selfExiled = [];
@@ -205,8 +184,6 @@ public static class AntiBlackout
case CustomGameMode.Standard:
case CustomGameMode.HideAndSeek:
{
StartGameHostPatch.RpcSetRoleReplacer.ResetRoleMapMidGame();
foreach (((byte seerId, byte targetId), (RoleTypes roletype, _)) in StartGameHostPatch.RpcSetRoleReplacer.RoleMap)
{
PlayerControl seer = seerId.GetPlayer();
@@ -232,32 +209,27 @@ public static class AntiBlackout
changedRoleType = roletype is RoleTypes.Impostor or RoleTypes.Shapeshifter or RoleTypes.Phantom ? RoleTypes.ImpostorGhost : RoleTypes.CrewmateGhost;
}
hasValue[seer.PlayerId] = senders[seer.PlayerId].RpcSetRole(target, changedRoleType, seer.OwnerId);
RestartMessageIfTooLong(seer.PlayerId);
target.RpcSetRoleDesync(changedRoleType, seer.OwnerId);
}
foreach (PlayerControl pc in selfExiled)
{
CustomRpcSender sender = senders[byte.MaxValue];
pc.Exiled();
sender.AutoStartRpc(pc.NetId, (byte)RpcCalls.Exiled);
sender.EndRpc();
hasValue[byte.MaxValue] = true;
hasValue = true;
if (!pc.IsModdedClient() && pc.PlayerId == ExileControllerWrapUpPatch.LastExiled?.PlayerId)
{
sender = senders[pc.PlayerId];
sender.AutoStartRpc(pc.NetId, (byte)RpcCalls.MurderPlayer, pc.OwnerId);
sender.WriteNetObject(pc);
sender.Write((int)MurderResultFlags.Succeeded);
sender.EndRpc();
hasValue[pc.PlayerId] = true;
pc.ReactorFlash(0.2f);
}
RestartMessageIfTooLong(byte.MaxValue, pc.PlayerId);
RestartMessageIfTooLong();
}
break;
@@ -272,26 +244,22 @@ public static class AntiBlackout
{
foreach (PlayerControl pc in Main.AllPlayerControls)
{
senders[pc.PlayerId].RpcSetRole(pc, RoleTypes.Crewmate, pc.OwnerId, noRpcForSelf: false);
hasValue[pc.PlayerId] = true;
RestartMessageIfTooLong(pc.PlayerId);
pc.RpcSetRoleDesync(Speedrun.CanKill.Contains(pc.PlayerId) ? RoleTypes.Impostor : RoleTypes.Crewmate, pc.OwnerId);
if (pc.IsModdedClient()) continue;
if (!pc.IsAlive())
{
CustomRpcSender sender = senders[pc.PlayerId];
sender.AutoStartRpc(pc.NetId, (byte)RpcCalls.MurderPlayer, pc.OwnerId);
sender.WriteNetObject(pc);
sender.Write((int)MurderResultFlags.Succeeded);
sender.EndRpc();
hasValue[pc.PlayerId] = true;
hasValue = true;
RestartMessageIfTooLong();
pc.ReactorFlash(0.2f);
}
RestartMessageIfTooLong(pc.PlayerId);
}
break;
@@ -301,65 +269,56 @@ public static class AntiBlackout
case CustomGameMode.CaptureTheFlag:
case CustomGameMode.KingOfTheZones:
{
senders[byte.MaxValue].RpcSetRole(PlayerControl.LocalPlayer, RoleTypes.Crewmate, noRpcForSelf: false);
hasValue[byte.MaxValue] = true;
RestartMessageIfTooLong(byte.MaxValue);
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(DummyImp.NetId, (byte)RpcCalls.SetRole, SendOption.Reliable);
writer.Write((ushort)RoleTypes.Crewmate);
writer.Write(true);
AmongUsClient.Instance.FinishRpcImmediately(writer);
foreach (PlayerControl pc in Main.AllPlayerControls)
{
CustomRpcSender sender = senders[pc.PlayerId];
if (pc.IsAlive())
{
sender.RpcSetRole(pc, RoleTypes.Impostor, pc.OwnerId, noRpcForSelf: false);
hasValue[pc.PlayerId] = true;
}
pc.RpcSetRoleDesync(RoleTypes.Impostor, pc.OwnerId);
else
{
if (pc.IsModdedClient()) continue;
sender.AutoStartRpc(pc.NetId, (byte)RpcCalls.MurderPlayer, pc.OwnerId);
sender.WriteNetObject(pc);
sender.Write((int)MurderResultFlags.Succeeded);
sender.EndRpc();
hasValue[pc.PlayerId] = true;
hasValue = true;
RestartMessageIfTooLong();
pc.ReactorFlash(0.2f);
}
RestartMessageIfTooLong(pc.PlayerId);
}
break;
}
}
foreach (PlayerControl pc in Main.AllPlayerControls)
{
CustomRpcSender sender = senders[pc.PlayerId];
hasValue[pc.PlayerId] |= sender.RpcResetAbilityCooldown(pc);
hasValue[pc.PlayerId] |= sender.SetKillCooldown(pc);
RestartMessageIfTooLong(pc.PlayerId);
}
sender.SendMessage(!hasValue);
senders.Do(x => x.Value.SendMessage(dispose: !hasValue[x.Key]));
LateTask.New(() =>
{
foreach (PlayerControl pc in Main.AllPlayerControls)
{
pc.RpcResetAbilityCooldown();
pc.SetKillCooldown();
}
}, 0.2f, log: false);
return;
void RestartMessageIfTooLong(params List<byte> ids)
void RestartMessageIfTooLong()
{
foreach (var kvp in senders)
if (sender.stream.Length > 400)
{
if (!ids.Contains(kvp.Key)) continue;
if (kvp.Value.stream.Length > 400)
{
kvp.Value.SendMessage();
hasValue[kvp.Key] = false;
}
sender.SendMessage();
sender = CustomRpcSender.Create("AntiBlackout.SetRealPlayerRoles", SendOption.Reliable);
hasValue = false;
}
ids.ForEach(x => senders[x] = CustomRpcSender.Create("AntiBlackout.SetRealPlayerRoles", SendOption.Reliable));
}
}
+22 -1
View File
@@ -370,7 +370,7 @@ public class CustomRpcSender
public static class CustomRpcSenderExtensions
{
public static bool RpcSetRole(this CustomRpcSender sender, PlayerControl player, RoleTypes role, int targetClientId = -1, bool noRpcForSelf = true)
public static bool RpcSetRole(this CustomRpcSender sender, PlayerControl player, RoleTypes role, int targetClientId = -1, bool noRpcForSelf = true, bool changeRoleMap = false)
{
if (AmongUsClient.Instance.ClientId == targetClientId && noRpcForSelf)
{
@@ -383,6 +383,27 @@ public static class CustomRpcSenderExtensions
.Write(true)
.EndRpc();
if (changeRoleMap)
{
try
{
if (targetClientId != -1) ChangeRoleMapForClient(Utils.GetClientById(targetClientId).Character.PlayerId);
else Main.PlayerStates.Keys.Do(ChangeRoleMapForClient);
}
catch (Exception e) { Utils.ThrowException(e); }
void ChangeRoleMapForClient(byte id)
{
(byte, byte) key = (player.PlayerId, id);
if (StartGameHostPatch.RpcSetRoleReplacer.RoleMap.TryGetValue(key, out (RoleTypes RoleType, CustomRoles CustomRole) pair))
{
pair.RoleType = role;
StartGameHostPatch.RpcSetRoleReplacer.RoleMap[key] = pair;
}
}
}
return true;
}
+1 -1
View File
@@ -33,7 +33,7 @@ internal static class GhostRolesManager
IGhostRole instance = CreateGhostRoleInstance(suitableRole);
pc.RpcSetCustomRole(suitableRole);
pc.RpcSetRoleDesync(RoleTypes.GuardianAngel, pc.GetClientId(), true);
pc.RpcSetRoleDesync(RoleTypes.GuardianAngel, pc.GetClientId());
instance.OnAssign(pc);
Main.ResetCamPlayerList.Add(pc.PlayerId);
AssignedGhostRoles[pc.PlayerId] = (suitableRole, instance);
-61
View File
@@ -1433,66 +1433,5 @@ internal static class StartGameHostPatch
}
catch (Exception e) { Utils.ThrowException(e); }
}
public static void ResetRoleMapMidGame()
{
try
{
RoleMap.Clear();
Dictionary<byte, PlayerState>.ValueCollection states = Main.PlayerStates.Values;
foreach (PlayerState targetState in states)
{
try
{
CustomRoles targetMainRole = targetState.MainRole;
RoleTypes selfRoleTypes = GetRoleTypes(targetState);
foreach (PlayerState seerState in states)
{
try
{
byte seerID = seerState.Player.PlayerId;
byte targetID = targetState.Player.PlayerId;
if (seerID == targetID || selfRoleTypes is RoleTypes.Noisemaker)
{
RoleMap[(seerID, targetID)] = (selfRoleTypes, targetMainRole);
continue;
}
CustomRoles seerMainRole = seerState.MainRole;
RoleMap[(seerID, targetID)] = HasDesyncRole(seerState)
? (RoleTypes.Scientist, targetMainRole)
: (IsImpostor(seerState) && IsImpostor(targetState))
? (selfRoleTypes, seerMainRole)
: (RoleTypes.Crewmate, seerMainRole);
bool HasDesyncRole(PlayerState state) => state.Player == null ? state.SubRoles.Contains(CustomRoles.Bloodlust) || state.MainRole.IsDesyncRole() : state.Player.HasDesyncRole();
bool IsImpostor(PlayerState state) => state.Player == null ? !state.SubRoles.Contains(CustomRoles.Bloodlust) && state.MainRole.IsImpostor() : state.Player.IsImpostor();
}
catch (Exception e) { Utils.ThrowException(e); }
}
RoleTypes GetRoleTypes(PlayerState state) =>
state.Player == null
? state.SubRoles switch
{
{ } x when x.Contains(CustomRoles.Bloodlust) => RoleTypes.Impostor,
{ } x when x.Contains(CustomRoles.Nimble) && !targetMainRole.IsDesyncRole() => RoleTypes.Engineer,
{ } x when x.Contains(CustomRoles.Physicist) => RoleTypes.Scientist,
{ } x when x.Contains(CustomRoles.Finder) => RoleTypes.Tracker,
{ } x when x.Contains(CustomRoles.Noisy) => RoleTypes.Noisemaker,
_ => targetMainRole.GetRoleTypes()
}
: state.Player.GetRoleTypes();
}
catch (Exception e) { Utils.ThrowException(e); }
}
}
catch (Exception e) { Utils.ThrowException(e); }
}
}
}
+1 -1
View File
@@ -2157,7 +2157,7 @@ internal static class CoEnterVentPatch
if (!__instance.myPlayer.CanUseVent(id) && Options.CurrentGameMode is CustomGameMode.Standard or CustomGameMode.HideAndSeek && !__instance.myPlayer.Is(CustomRoles.Nimble) && !__instance.myPlayer.Is(CustomRoles.Bloodlust))
LateTask.New(() => __instance.RpcBootFromVent(id), 0.5f, "CannotUseVentBootFromVent");
if (((__instance.myPlayer.Data.Role.Role != RoleTypes.Engineer && !__instance.myPlayer.CanUseImpostorVentButton()) ||
if (((__instance.myPlayer.GetRoleTypes() != RoleTypes.Engineer && !__instance.myPlayer.CanUseImpostorVentButton()) ||
(__instance.myPlayer.Is(CustomRoles.Mayor) && Mayor.MayorUsedButtonCount.TryGetValue(__instance.myPlayer.PlayerId, out int count) && count >= Mayor.MayorNumOfUseButton.GetInt()) ||
(__instance.myPlayer.Is(CustomRoles.Paranoia) && Paranoia.ParaUsedButtonCount.TryGetValue(__instance.myPlayer.PlayerId, out int count2) && count2 >= Options.ParanoiaNumOfUseButton.GetInt()))
&& !__instance.myPlayer.Is(CustomRoles.Nimble) && !__instance.myPlayer.Is(CustomRoles.Bloodlust) && CustomGameMode.Standard.IsActiveOrIntegrated())
+1 -1
View File
@@ -243,7 +243,7 @@ public class Wizard : RoleBase
TaskMode = false;
break;
case false when !pc.IsAlive():
pc.RpcSetRoleDesync(RoleTypes.CrewmateGhost, pc.GetClientId(), true);
pc.RpcSetRoleDesync(RoleTypes.CrewmateGhost, pc.GetClientId());
TaskMode = true;
break;
case false when pc.GetAbilityUseLimit() < 1 && pc.IsAlive():