This commit is contained in:
Ape committed 2026-08-18 21:00:42 +02:00
1 parent f9c9e1a2b6
commit 2e66fb54f9
21 files changed
+617 -148

No files matched your search

+3 -3
View File
@@ -38,13 +38,13 @@ public partial class Main : BasePlugin
public static ConfigEntry<bool> DisableCommandHelper { get; private set; }
public static ConfigEntry<bool> DisableCompatibilityWarning { get; private set; }
public static NormalGameOptionsV10 NormalOptions => GameOptionsManager.Instance != null ? GameOptionsManager.Instance.currentNormalGameOptions : null;
public static HideNSeekGameOptionsV10 HideNSeekOptions => GameOptionsManager.Instance != null ? GameOptionsManager.Instance.currentHideNSeekGameOptions : null;
public static NormalGameOptionsV11 NormalOptions => GameOptionsManager.Instance != null ? GameOptionsManager.Instance.currentNormalGameOptions : null;
public static HideNSeekGameOptionsV11 HideNSeekOptions => GameOptionsManager.Instance != null ? GameOptionsManager.Instance.currentHideNSeekGameOptions : null;
public static MapNames CurrentMap => (MapNames)NormalOptions.MapId;
public static bool HasArgumentException;
public static string CredentialsText;
public const string ModVersion = "v1.9.5";
public const string ModVersion = "v2.0.0";
public static float GameTimer;
public static float AfkTimer;
+1 -1
View File
@@ -18,7 +18,7 @@
<ItemGroup>
<PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.735" ExcludeAssets="runtime;native" />
<PackageReference Include="AmongUs.GameLibs.Steam" Version="2026.6.5" PrivateAssets="all" Condition="'$(Configuration)' == 'Release'"/>
<PackageReference Include="AmongUs.GameLibs.Steam" Version="2026.8.18" PrivateAssets="all" Condition="'$(Configuration)' == 'Release'"/>
<PackageReference Include="AmongUs.GameLibs.Android" Version="2025.10.14" PrivateAssets="all" Condition="'$(Configuration)' == 'Android'"/>
<PackageReference Include="BepInEx.AutoPlugin" Version="1.1.0" PrivateAssets="all" />
+1 -9
View File
@@ -29,7 +29,6 @@ public static class BanManager
private static string TemplatePath = $"{DataPath}/AUR-DATA/Templates.txt";
private static string StartWordsPath = $"{DataPath}/AUR-DATA/Startwords.txt";
public static Dictionary<string, string> Templates = new();
public static List<string> TempBanWhiteList = [];
public static void Init()
{
try
@@ -81,7 +80,7 @@ public static class BanManager
public static void AddBanPlayer(ClientData player)
{
if (!AmongUsClient.Instance.AmHost || player == null) return;
if (!CheckBanList(player?.FriendCode, player?.GetHashedPuid()) && !TempBanWhiteList.Contains(player?.GetHashedPuid()))
if (!CheckBanList(player?.FriendCode, player?.GetHashedPuid()))
{
if (player?.GetHashedPuid() != "" && player?.GetHashedPuid() != null && player?.GetHashedPuid() != "e3b0cb855")
{
@@ -106,13 +105,6 @@ public static class BanManager
Logger.Info($"{player.PlayerName} was in the BanList and has been banned", "BanListBan");
return;
}
if (TempBanWhiteList.Contains(player?.GetHashedPuid()))
{
AmongUsClient.Instance.KickPlayer(player.Id, true);
//This should not happen
Logger.Info($"{player.PlayerName} was in the Temporary BanList", "TempBan");
return;
}
}
public static bool CheckBanList(string code, string hashedpuid = "")
{
+3 -1
View File
@@ -26,6 +26,7 @@ internal static class CommandHelper
new Cmd { Name = new[] { "/sns" }, Prompt = "/sns", Description = Translator.Get("snsDesc"), HasVariable = false },
new Cmd { Name = new[] { "/shiftandseek" }, Prompt = "/shiftandseek", Description = Translator.Get("snsDesc"), HasVariable = false },
new Cmd { Name = new[] { "/sns2" }, Prompt = "/sns2", Description = Translator.Get("snsTwoDesc"), HasVariable = false },
new Cmd { Name = new[] { "/0kc" }, Prompt = "/0kc", Description = Translator.Get("0kcDesc"), HasVariable = false },
new Cmd { Name = new[] { "/0killcooldown" }, Prompt = "/0killcooldown", Description = Translator.Get("0kcDesc"), HasVariable = false },
@@ -82,7 +83,8 @@ internal static class CommandHelper
new Cmd { Name = new[] { "/clearseeker" }, Prompt = "/clearseeker", Description = Translator.Get("clearSeekerDesc"), HasVariable = false },
new Cmd { Name = new[] { "/mapvote" }, Prompt = "/mapvote", Description = Translator.Get("mapVoteDesc"), HasVariable = false },
new Cmd { Name = new[] { "/allmapvote" }, Prompt = "/allmapvote", Description = Translator.Get("allMapVoteDesc"), HasVariable = false }
new Cmd { Name = new[] { "/allmapvote" }, Prompt = "/allmapvote", Description = Translator.Get("allMapVoteDesc"), HasVariable = false },
new Cmd { Name = new[] { "/gmvote" }, Prompt = "/gmvote", Description = Translator.Get("modeVoteDesc"), HasVariable = false }
};
[HarmonyPostfix]
+42 -18
View File
@@ -104,6 +104,8 @@ namespace AmongUsRevamped
public static OptionItem TimeBeforeMapPoll;
public static OptionItem AutomaticAllMapPoll;
public static OptionItem TimeBeforeAllMapPoll;
public static OptionItem AutomaticModePoll;
public static OptionItem TimeBeforeModePoll;
public static OptionItem TabGroupAutostart;
public static OptionItem AutoStartTimer;
@@ -121,6 +123,7 @@ namespace AmongUsRevamped
public static OptionItem TabGroupMisc;
public static OptionItem MapVoteDuration;
public static OptionItem ModeVoteDuration;
public static OptionItem StartCountdown;
public static OptionItem ColorCommandLevel;
public static OptionItem AllowFortegreen;
@@ -149,8 +152,9 @@ namespace AmongUsRevamped
public static OptionItem DisableCloseDoor;
public static OptionItem TabGroupGameplayGeneral;
public static OptionItem ShieldFirstDeath;
public static OptionItem ShieldFirstDeathDuration;
public static OptionItem DisableAnnoyingMeetingCalls;
public static OptionItem ChangeDecontaminationTime;
public static OptionItem DecontaminationTimeOnMiraHQ;
public static OptionItem DecontaminationDoorOpenTimeOnMiraHQ;
@@ -294,6 +298,8 @@ namespace AmongUsRevamped
public static OptionItem TabGroupSNS;
public static OptionItem SNSChatInGame;
public static OptionItem SNSChatInGameExtend;
public static OptionItem SNSChatInGameExtend2;
public static OptionItem SNSChatInGameFast;
public static OptionItem CrewAutoWinsGameAfter;
public static OptionItem MisfiresToSuicide;
public static OptionItem SNSDisableSabotage;
@@ -313,6 +319,7 @@ namespace AmongUsRevamped
public static OptionItem TabGroupPNS;
public static OptionItem PNSChatInGame;
public static OptionItem PNSChatInGameExtend;
public static OptionItem PNSChatInGameFast;
public static OptionItem PNSCrewAutoWinsGameAfter;
public static OptionItem BadMoveTimeToSuicide;
public static OptionItem PNSDisableSabotage;
@@ -410,6 +417,10 @@ namespace AmongUsRevamped
TimeBeforeAllMapPoll = IntegerOptionItem.Create(60157, Translator.Get("timeBeforeMapPoll"), new(10, 300, 5), 10, TabGroup.SystemSettings, false)
.SetValueFormat(OptionFormat.Seconds)
.SetParent(AutomaticAllMapPoll);
AutomaticModePoll = BooleanOptionItem.Create(60158, Translator.Get("automaticModePoll"), false, TabGroup.SystemSettings, false);
TimeBeforeModePoll = IntegerOptionItem.Create(60159, Translator.Get("timeBeforeMapPoll"), new(10, 300, 5), 20, TabGroup.SystemSettings, false)
.SetValueFormat(OptionFormat.Seconds)
.SetParent(AutomaticModePoll);
TabGroupAutostart = TextOptionItem.Create(64425, Translator.Get("tabGroupAutostart"), TabGroup.SystemSettings)
.SetColor(Color.yellow);
@@ -438,7 +449,10 @@ namespace AmongUsRevamped
MapVoteDuration = IntegerOptionItem.Create(60379, Translator.Get("mapVoteDuration"), new(5, 60, 5), 20, TabGroup.SystemSettings, false)
.SetValueFormat(OptionFormat.Seconds)
.SetColor(Color.red);
StartCountdown = IntegerOptionItem.Create(60380, Translator.Get("startCountdown"), new(1, 5, 1), 5, TabGroup.SystemSettings, false)
ModeVoteDuration = IntegerOptionItem.Create(60380, Translator.Get("modeVoteDuration"), new(5, 60, 5), 20, TabGroup.SystemSettings, false)
.SetValueFormat(OptionFormat.Seconds)
.SetColor(Color.red);
StartCountdown = IntegerOptionItem.Create(60381, Translator.Get("startCountdown"), new(1, 5, 1), 5, TabGroup.SystemSettings, false)
.SetValueFormat(OptionFormat.Seconds)
.SetColor(Color.red);
AllowFortegreen = BooleanOptionItem.Create(60382, Translator.Get("allowFortegreen"), false, TabGroup.SystemSettings, false)
@@ -456,36 +470,40 @@ namespace AmongUsRevamped
TabGroupSNS = TextOptionItem.Create(70050, Translator.Get("tabGroupSNS"), TabGroup.GamemodeSettings)
.SetColor(Color.green);
SNSChatInGame = BooleanOptionItem.Create(70051, Translator.Get("snsChatInGame"), false, TabGroup.GamemodeSettings, false);
SNSChatInGameExtend = BooleanOptionItem.Create(70052, Translator.Get("snsChatInGameExtend"), false, TabGroup.GamemodeSettings, false)
SNSChatInGameExtend = BooleanOptionItem.Create(70052, Translator.Get("snsChatInGameExtend"), true, TabGroup.GamemodeSettings, false)
.SetParent(SNSChatInGame);
MisfiresToSuicide = IntegerOptionItem.Create(70053, Translator.Get("misfiresToSuicide"), new(1, 10, 1), 1, TabGroup.GamemodeSettings, false);
CrewAutoWinsGameAfter = IntegerOptionItem.Create(70054, Translator.Get("crewAutoWinsGameAfter"), new(60, 600, 10), 300, TabGroup.GamemodeSettings, false)
SNSChatInGameExtend2 = BooleanOptionItem.Create(70053, Translator.Get("snsChatInGameExtendTwo"), true, TabGroup.GamemodeSettings, false)
.SetParent(SNSChatInGame);
SNSChatInGameFast = BooleanOptionItem.Create(70054, Translator.Get("snsChatInGameFast"), false, TabGroup.GamemodeSettings, false)
.SetParent(SNSChatInGame);
MisfiresToSuicide = IntegerOptionItem.Create(70055, Translator.Get("misfiresToSuicide"), new(1, 10, 1), 1, TabGroup.GamemodeSettings, false);
CrewAutoWinsGameAfter = IntegerOptionItem.Create(70056, Translator.Get("crewAutoWinsGameAfter"), new(60, 600, 10), 300, TabGroup.GamemodeSettings, false)
.SetValueFormat(OptionFormat.Seconds);
SNSDisableSabotage = BooleanOptionItem.Create(70055, Translator.Get("snsDisableSabotage"), true, TabGroup.GamemodeSettings, false)
SNSDisableSabotage = BooleanOptionItem.Create(70057, Translator.Get("snsDisableSabotage"), true, TabGroup.GamemodeSettings, false)
.SetColor(Color.red);
SNSDisableReactor = BooleanOptionItem.Create(70056, Translator.Get("snsDisableReactor"), true, TabGroup.GamemodeSettings, false)
SNSDisableReactor = BooleanOptionItem.Create(70058, Translator.Get("snsDisableReactor"), true, TabGroup.GamemodeSettings, false)
.SetParent(SNSDisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
SNSDisableOxygen = BooleanOptionItem.Create(70057, Translator.Get("snsDisableOxygen"), true, TabGroup.GamemodeSettings, false)
SNSDisableOxygen = BooleanOptionItem.Create(70059, Translator.Get("snsDisableOxygen"), true, TabGroup.GamemodeSettings, false)
.SetParent(SNSDisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
SNSDisableLights = BooleanOptionItem.Create(70058, Translator.Get("snsDisableLights"), true, TabGroup.GamemodeSettings, false)
SNSDisableLights = BooleanOptionItem.Create(70060, Translator.Get("snsDisableLights"), true, TabGroup.GamemodeSettings, false)
.SetParent(SNSDisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
SNSDisableComms = BooleanOptionItem.Create(70059, Translator.Get("snsDisableComms"), true, TabGroup.GamemodeSettings, false)
SNSDisableComms = BooleanOptionItem.Create(70061, Translator.Get("snsDisableComms"), true, TabGroup.GamemodeSettings, false)
.SetParent(SNSDisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
SNSDisableHeli = BooleanOptionItem.Create(70060, Translator.Get("snsDisableHeli"), true, TabGroup.GamemodeSettings, false)
SNSDisableHeli = BooleanOptionItem.Create(70062, Translator.Get("snsDisableHeli"), true, TabGroup.GamemodeSettings, false)
.SetParent(SNSDisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
SNSDisableMushroomMixup = BooleanOptionItem.Create(70061, Translator.Get("snsDisableMushroomMixup"), true, TabGroup.GamemodeSettings, false)
SNSDisableMushroomMixup = BooleanOptionItem.Create(70063, Translator.Get("snsDisableMushroomMixup"), true, TabGroup.GamemodeSettings, false)
.SetParent(SNSDisableSabotage)
.SetColor(new Color32(255, 153, 153, byte.MaxValue));
SNSDisableCloseDoor = BooleanOptionItem.Create(70062, Translator.Get("snsDisableCloseDoor"), true, TabGroup.GamemodeSettings, false)
SNSDisableCloseDoor = BooleanOptionItem.Create(70064, Translator.Get("snsDisableCloseDoor"), true, TabGroup.GamemodeSettings, false)
.SetColor(Color.red);
SNSImpostorsCanVent = BooleanOptionItem.Create(70063, Translator.Get("snsImpostorCanVent"), true, TabGroup.GamemodeSettings, false);
SNSImpostorsCanVent = BooleanOptionItem.Create(70065, Translator.Get("snsImpostorCanVent"), true, TabGroup.GamemodeSettings, false);
TabGroupSpeedrun = TextOptionItem.Create(70075, Translator.Get("tabGroupSpeedrun"), TabGroup.GamemodeSettings)
TabGroupSpeedrun = TextOptionItem.Create(70076, Translator.Get("tabGroupSpeedrun"), TabGroup.GamemodeSettings)
.SetColor(Color.green);
GameAutoEndsAfter = IntegerOptionItem.Create(70077, Translator.Get("gameAutoEndsAfter"), new(0, 600, 10), 300, TabGroup.GamemodeSettings, false)
.SetValueFormat(OptionFormat.Seconds);
@@ -493,8 +511,10 @@ namespace AmongUsRevamped
TabGroupPNS = TextOptionItem.Create(70100, Translator.Get("tabGroupPNS"), TabGroup.GamemodeSettings)
.SetColor(Color.green);
PNSChatInGame = BooleanOptionItem.Create(70102, Translator.Get("snsChatInGame"), false, TabGroup.GamemodeSettings, false);
PNSChatInGameExtend = BooleanOptionItem.Create(70103, Translator.Get("snsChatInGameExtend"), false, TabGroup.GamemodeSettings, false)
PNSChatInGame = BooleanOptionItem.Create(70101, Translator.Get("snsChatInGame"), false, TabGroup.GamemodeSettings, false);
PNSChatInGameExtend = BooleanOptionItem.Create(70102, Translator.Get("snsChatInGameExtend"), false, TabGroup.GamemodeSettings, false)
.SetParent(PNSChatInGame);
PNSChatInGameFast = BooleanOptionItem.Create(70103, Translator.Get("snsChatInGameFast"), false, TabGroup.GamemodeSettings, false)
.SetParent(PNSChatInGame);
BadMoveTimeToSuicide = IntegerOptionItem.Create(70104, Translator.Get("badMoveTimeToSuicide"), new(1, 30, 1), 3, TabGroup.GamemodeSettings, false)
.SetValueFormat(OptionFormat.Seconds);
@@ -554,7 +574,11 @@ namespace AmongUsRevamped
TabGroupGameplayGeneral = TextOptionItem.Create(60564, Translator.Get("tabGroupGameplayGeneral"), TabGroup.ModSettings)
.SetColor(Color.blue);
DisableAnnoyingMeetingCalls = BooleanOptionItem.Create(60565, Translator.Get("disableAnnoyingMeetingCalls"), false, TabGroup.ModSettings, false);
ShieldFirstDeath = BooleanOptionItem.Create(60565, Translator.Get("shieldFirstDeath"), false, TabGroup.ModSettings, false);
ShieldFirstDeathDuration = IntegerOptionItem.Create(60566, Translator.Get("shieldFirstDeathDuration"), new(10, 120, 5), 30, TabGroup.ModSettings, false)
.SetParent(ShieldFirstDeath)
.SetValueFormat(OptionFormat.Seconds);
DisableAnnoyingMeetingCalls = BooleanOptionItem.Create(60567, Translator.Get("disableAnnoyingMeetingCalls"), false, TabGroup.ModSettings, false);
ChangeDecontaminationTime = BooleanOptionItem.Create(60550, Translator.Get("changeDecontaminationTime"), false, TabGroup.ModSettings, false);
DecontaminationTimeOnMiraHQ = FloatOptionItem.Create(60551, Translator.Get("decontaminationTimeOnMiraHQ"), new(0.5f, 10f, 0.25f), 3f, TabGroup.ModSettings, false)
+1 -1
View File
@@ -184,7 +184,7 @@ internal class EACR
goto YesCheat;
}
if (Utils.IsMeeting && MeetingHud.Instance.state != MeetingHud.VoteStates.Animating)
if (Utils.IsMeeting && MeetingHud.Instance.state != MeetingHud.MeetingStates.Animating)
{
Logger.SendInGame($"{player.Data.PlayerName} might have called an invalid sabotage (cheating)");
Logger.Info($" {player.Data.PlayerName} might have called an invalid sabotage (cheating)", "EACR");
+17 -42
View File
@@ -119,54 +119,17 @@ public static class FixedUpdate
}
}
// We check if any SnS Shapshifter is currently nearby their correct target.
// If so, the global Kill Cooldown is set to 1 and all killing actions may proceed.
// If not, the global Kill Cooldown is set to 0.
// While this value is 0, the game stops the kill cooldown from decreasing.
// If the Kill Cooldown value is 0 by default (which it will be at the start of a match), Among Us does not allow kills at all.
// This means most of the time, we can successfully prevent invalid kills.
// The only problem is that if one Shapeshifter is nearby their correct target, while another is not, the second Shapeshifter can kill too.
if (Options.Gamemode.GetValue() == 1 && !Utils.isHideNSeek && !Utils.IsLobby)
{
bool shapeshifterNearTarget = false;
foreach (var p in PlayerControl.AllPlayerControls)
{
if (p.Data == null || p.Data.IsDead || p.shapeshiftTargetPlayerId == byte.MaxValue) continue;
if (p.Data == null || p.Data.IsDead || p.Data.RoleType == RoleTypes.Shapeshifter) continue;
PlayerControl shapeshiftTarget = null;
foreach (var t in PlayerControl.AllPlayerControls)
if (p.protectedByGuardianId == -1)
{
if (t.Data == null || t.Data.IsDead) continue;
if (t.Data.PlayerId == p.shapeshiftTargetPlayerId)
{
shapeshiftTarget = t;
break;
}
}
if (shapeshiftTarget == null) continue;
float distance = Vector2.Distance(p.GetTruePosition(), shapeshiftTarget.GetTruePosition());
if (distance <= 3f)
{
shapeshifterNearTarget = true;
break;
p.RpcProtectPlayer(p, p.cosmetics.ColorId);
}
}
float newCooldown = shapeshifterNearTarget ? 1f : 0f;
if (Main.NormalOptions.KillCooldown != newCooldown)
{
Main.NormalOptions.KillCooldown = newCooldown;
OptionManager.SyncGameOptions();
}
}
}
@@ -246,7 +209,13 @@ class FixedUpdateInGamePatch
case 1: // SnS
if (Utils.InGame) return;
if (Main.NormalOptions.KillCooldown != 1f) Main.NormalOptions.KillCooldown = 1f;
if (Main.NormalOptions.KillCooldown != 2.5f)
{
Main.NormalOptions.KillCooldown = 2.5f;
Main.NormalOptions.roleOptions.SetRoleRate(RoleTypes.Shapeshifter, 3, 100);
Main.NormalOptions.roleOptions.SetRoleRate(RoleTypes.Phantom, 0, 0);
Main.NormalOptions.roleOptions.SetRoleRate(RoleTypes.Viper, 0, 0);
}
break;
case 2: // Speedrun
@@ -254,7 +223,13 @@ class FixedUpdateInGamePatch
case 3: // PnS
if (Utils.InGame) return;
if (Main.NormalOptions.KillCooldown != 1f) Main.NormalOptions.KillCooldown = 1f;
if (Main.NormalOptions.KillCooldown != 1f)
{
Main.NormalOptions.KillCooldown = 1f;
Main.NormalOptions.roleOptions.SetRoleRate(RoleTypes.Shapeshifter, 0, 0);
Main.NormalOptions.roleOptions.SetRoleRate(RoleTypes.Phantom, 3, 100);
Main.NormalOptions.roleOptions.SetRoleRate(RoleTypes.Viper, 0, 0);
}
break;
}
+6
View File
@@ -13,6 +13,12 @@ namespace AmongUsRevamped
{
Logger.Info($" Disconnected due to {reason}/{stringReason}, ping:{__instance.Ping})", "DisconnectManager");
if (!EOSManager.Instance.loginFlowFinished || EOSManager.Instance.authExpiredCallbackTriggered)
{
Logger.Info("Attempted to log in using EOS", "DisconnectManager");
EOSManager.Instance.AdultPermissionsFlow();
}
if (!Options.Rehost.GetBool() || reason == DisconnectReasons.NewConnection || reason == DisconnectReasons.ConnectionLimit || reason == DisconnectReasons.ExitGame) return;
_ = new LateTask(() =>
+85 -1
View File
@@ -42,6 +42,7 @@ public static class Utils
public static bool HandlingGameEnd;
public static byte CustomGameOverReason;
public static bool CanCallMeetings;
public static bool HasMurdered;
public static string ColorString(Color32 color, string str) => $"<#{color.r:x2}{color.g:x2}{color.b:x2}{color.a:x2}>{str}</color>";
public static string ColorToHex(Color32 color) => $"#{color.r:x2}{color.g:x2}{color.b:x2}{color.a:x2}";
@@ -206,9 +207,11 @@ public static class Utils
Main.GameTimer = 0f;
Main.AfkTimer = 0f;
FixedUpdate.Position.Clear();
NormalGameEndChecker.canUpdateWinnerText = true;
MurderPlayerPatch.misfireCount.Clear();
MurderPlayerPatch.killCount.Clear();
HasMurdered = false;
LateTask.Tasks.RemoveAll(x => x.name != "RehostManager");
NormalGameEndChecker.ImpCheckComplete = false;
@@ -240,6 +243,13 @@ public static class Utils
dleksVotes = 0;
HasVoted.Clear();
MapVoteActive = false;
standardVotes = 0;
noKillCooldownVotes = 0;
speedrunVotes = 0;
shiftAndSeekVotes = 0;
poofAndSeekVotes = 0;
ModeVoteActive = false;
}
public static PlayerControl[] AllAlivePlayerControls
@@ -598,7 +608,7 @@ public static class Utils
public static readonly List<byte> HasVoted = [];
public static void MapVote(bool dleks, bool moderator)
{
if (MapVoteActive) return;
if (MapVoteActive || ModeVoteActive) return;
DleksEnabled = dleks;
MapVoteActive = true;
@@ -676,4 +686,78 @@ public static class Utils
MapVoteActive = false;
}, Options.MapVoteDuration.GetInt(), "MapPoll");
}
public static int standardVotes;
public static int noKillCooldownVotes;
public static int speedrunVotes;
public static int shiftAndSeekVotes;
public static int poofAndSeekVotes;
public static bool ModeVoteActive;
public static readonly List<byte> HasModeVoted = [];
public static void ModeVote(bool moderator)
{
if (ModeVoteActive || MapVoteActive) return;
ModeVoteActive = true;
if (moderator) Utils.ModeratorChatCommand("A Gamemode vote is active!\n\nA: None\nB: No Kill Cooldown\nC: Speedrun\nD: SnS\nE: PnS\n\nType /vote 'letter' to vote.", "", false);
else Utils.ChatCommand(DestroyableSingleton<HudManager>.Instance.Chat, "A Gamemode vote is active!\n\nA: None\nB: No Kill Cooldown\nC: Speedrun\nD: SnS\nE: PnS\n\nType /vote 'letter' to vote.", "", false);
new LateTask(() =>
{
int highest = standardVotes;
string winner = "None";
byte modeId = 0;
bool tie = false;
void Check(int votes, string name, byte id)
{
if (votes > highest)
{
highest = votes;
winner = name;
modeId = id;
tie = false;
}
else if (votes == highest)
{
tie = true;
}
}
Check(noKillCooldownVotes, "0 Kill Cooldown", 0);
Check(speedrunVotes, "Speedrun", 2);
Check(shiftAndSeekVotes, "Shift and Seek", 1);
Check(poofAndSeekVotes, "Poof and Seek", 3);
string voteResults = $"Standard: {standardVotes}\n" + $"No Kill Cooldown: {noKillCooldownVotes}\n" + $"Speedrun: {speedrunVotes}\n" + $"Shift and Seek: {shiftAndSeekVotes}\n" + $"Poof and Seek: {poofAndSeekVotes}";
if (highest == 0)
{
ModeratorChatCommand("We have a winner! Just kidding. No one voted.", "", false);
}
else if (tie)
{
ModeratorChatCommand($"Gamemode vote tied. No new mode selected.\n\n{voteResults}", "", false);
}
else
{
ModeratorChatCommand(SendChatPatch.ConvertNum($"Winner: {winner} ({highest})\n\n{voteResults}"), "", false);
Options.Gamemode.SetValue(modeId);
if (winner == "0 Kill Cooldown")
{
Main.NormalOptions.KillCooldown = 0.01f;
}
}
standardVotes = 0;
noKillCooldownVotes = 0;
speedrunVotes = 0;
shiftAndSeekVotes = 0;
poofAndSeekVotes = 0;
HasVoted.Clear();
ModeVoteActive = false;
}, Options.ModeVoteDuration.GetInt(), "ModePoll");
}
}
+183 -16
View File
@@ -420,12 +420,92 @@ internal static class SendChatPatch
}
}
if (text == "/vote a" && Utils.MapVoteActive && !Utils.HasVoted.Contains(PlayerControl.LocalPlayer.Data.PlayerId)) {Utils.skeldVotes++; Utils.HasVoted.Add(PlayerControl.LocalPlayer.Data.PlayerId);}
if (text == "/vote b" && Utils.MapVoteActive && !Utils.HasVoted.Contains(PlayerControl.LocalPlayer.Data.PlayerId)) {Utils.miraVotes++; Utils.HasVoted.Add(PlayerControl.LocalPlayer.Data.PlayerId);}
if (text == "/vote c" && Utils.MapVoteActive && !Utils.HasVoted.Contains(PlayerControl.LocalPlayer.Data.PlayerId)) {Utils.polusVotes++; Utils.HasVoted.Add(PlayerControl.LocalPlayer.Data.PlayerId);}
if (text == "/vote d" && Utils.MapVoteActive && !Utils.HasVoted.Contains(PlayerControl.LocalPlayer.Data.PlayerId)) {Utils.airshipVotes++; Utils.HasVoted.Add(PlayerControl.LocalPlayer.Data.PlayerId);}
if (text == "/vote e" && Utils.MapVoteActive && !Utils.HasVoted.Contains(PlayerControl.LocalPlayer.Data.PlayerId)) {Utils.fungleVotes++; Utils.HasVoted.Add(PlayerControl.LocalPlayer.Data.PlayerId);}
if (text == "/vote f" && Utils.MapVoteActive && !Utils.HasVoted.Contains(PlayerControl.LocalPlayer.Data.PlayerId) && Utils.DleksEnabled) {Utils.dleksVotes++; Utils.HasVoted.Add(PlayerControl.LocalPlayer.Data.PlayerId);}
if (text == "/gmvote")
{
if (Utils.IsLobby)
{
Utils.ModeVote(false);
__instance.freeChatField.textArea.Clear();
__instance.freeChatField.textArea.SetText(string.Empty);
return false;
}
}
if (text == "/vote a")
{
if (Utils.HasVoted.Contains(PlayerControl.LocalPlayer.Data.PlayerId)) return true;
if (Utils.MapVoteActive && !Utils.HasVoted.Contains(PlayerControl.LocalPlayer.Data.PlayerId))
{
Utils.skeldVotes++;
}
if (Utils.ModeVoteActive)
{
Utils.standardVotes++;
}
Utils.HasVoted.Add(PlayerControl.LocalPlayer.Data.PlayerId);
}
if (text == "/vote b")
{
if (Utils.HasVoted.Contains(PlayerControl.LocalPlayer.Data.PlayerId)) return true;
if (Utils.MapVoteActive)
{
Utils.miraVotes++;
}
if (Utils.ModeVoteActive)
{
Utils.noKillCooldownVotes++;
}
Utils.HasVoted.Add(PlayerControl.LocalPlayer.Data.PlayerId);
}
if (text == "/vote c")
{
if (Utils.HasVoted.Contains(PlayerControl.LocalPlayer.Data.PlayerId)) return true;
if (Utils.MapVoteActive)
{
Utils.polusVotes++;
}
if (Utils.ModeVoteActive)
{
Utils.speedrunVotes++;
}
Utils.HasVoted.Add(PlayerControl.LocalPlayer.Data.PlayerId);
}
if (text == "/vote d")
{
if (Utils.HasVoted.Contains(PlayerControl.LocalPlayer.Data.PlayerId)) return true;
if (Utils.MapVoteActive)
{
Utils.airshipVotes++;
}
if (Utils.ModeVoteActive)
{
Utils.shiftAndSeekVotes++;
}
Utils.HasVoted.Add(PlayerControl.LocalPlayer.Data.PlayerId);
}
if (text == "/vote e")
{
if (Utils.HasVoted.Contains(PlayerControl.LocalPlayer.Data.PlayerId)) return true;
if (Utils.MapVoteActive)
{
Utils.fungleVotes++;
}
if (Utils.ModeVoteActive)
{
Utils.poofAndSeekVotes++;
}
Utils.HasVoted.Add(PlayerControl.LocalPlayer.Data.PlayerId);
}
if (text == "/vote f")
{
if (Utils.HasVoted.Contains(PlayerControl.LocalPlayer.Data.PlayerId)) return true;
if (Utils.MapVoteActive && Utils.DleksEnabled)
{
Utils.dleksVotes++;
}
Utils.HasVoted.Add(PlayerControl.LocalPlayer.Data.PlayerId);
}
if (text == "/l" || text == "/lastgame")
{
@@ -451,7 +531,12 @@ internal static class SendChatPatch
if (text == "/sns" || text == "/shiftandseek")
{
Utils.ChatCommand(__instance, "Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nMeetings & Reports = Off", $"Crewmates win by doing tasks or surviving {Options.CrewAutoWinsGameAfter.GetInt()}s\nImpostors win by killing everyone\n{Options.MisfiresToSuicide.GetInt()} wrong kill(s) = suicide", true);
Utils.ChatCommand(__instance, "Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nMeetings & Reports = Off", $"Crewmates win by tasks/surviving {Options.CrewAutoWinsGameAfter.GetInt()}s\nImpostors win by killing\nWrong kills are blocked. Kill animations are off", true);
return false;
}
if (text == "/sns2" || text == "/shiftandseek2")
{
Utils.ChatCommand(__instance, "Correctly killing a target will directly turn them into a ghost and leave no dead body", "", false);
return false;
}
@@ -479,7 +564,7 @@ internal static class SendChatPatch
break;
case 1:
Utils.ChatCommand(__instance, "Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nMeetings & Reports = Off", $"Crewmates win by doing tasks or surviving {Options.CrewAutoWinsGameAfter.GetInt()}s\nImpostors win by killing everyone\n{Options.MisfiresToSuicide.GetInt()} wrong kill(s) = suicide", true);
Utils.ChatCommand(__instance, "Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nMeetings & Reports = Off", $"Crewmates win by tasks/surviving {Options.CrewAutoWinsGameAfter.GetInt()}s\nImpostors win by killing\nWrong kills are blocked. Kill animations are off", true);
break;
case 2:
@@ -771,13 +856,90 @@ public static class RPCHandlerPatch
Utils.MapVote(true, true);
}
}
if (text == "/gmvote")
{
if (Utils.IsLobby)
{
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashMapAndSeekerCmd.GetValue()) return;
Utils.ModeVote(true);
}
}
if (text == "/vote a" && Utils.MapVoteActive && !Utils.HasVoted.Contains(__instance.Data.PlayerId)) {Utils.skeldVotes++; Utils.HasVoted.Add(__instance.Data.PlayerId);}
if (text == "/vote b" && Utils.MapVoteActive && !Utils.HasVoted.Contains(__instance.Data.PlayerId)) {Utils.miraVotes++; Utils.HasVoted.Add(__instance.Data.PlayerId);}
if (text == "/vote c" && Utils.MapVoteActive && !Utils.HasVoted.Contains(__instance.Data.PlayerId)) {Utils.polusVotes++; Utils.HasVoted.Add(__instance.Data.PlayerId);}
if (text == "/vote d" && Utils.MapVoteActive && !Utils.HasVoted.Contains(__instance.Data.PlayerId)) {Utils.airshipVotes++; Utils.HasVoted.Add(__instance.Data.PlayerId);}
if (text == "/vote e" && Utils.MapVoteActive && !Utils.HasVoted.Contains(__instance.Data.PlayerId)) {Utils.fungleVotes++; Utils.HasVoted.Add(__instance.Data.PlayerId);}
if (text == "/vote f" && Utils.MapVoteActive && !Utils.HasVoted.Contains(__instance.Data.PlayerId) && Utils.DleksEnabled) {Utils.dleksVotes++; Utils.HasVoted.Add(__instance.Data.PlayerId);}
if (text == "/vote a")
{
if (Utils.HasVoted.Contains(__instance.Data.PlayerId)) return;
if (Utils.MapVoteActive)
{
Utils.skeldVotes++;
}
if (Utils.ModeVoteActive)
{
Utils.standardVotes++;
}
Utils.HasVoted.Add(__instance.Data.PlayerId);
}
if (text == "/vote b")
{
if (Utils.HasVoted.Contains(__instance.Data.PlayerId)) return;
if (Utils.MapVoteActive)
{
Utils.miraVotes++;
}
if (Utils.ModeVoteActive)
{
Utils.noKillCooldownVotes++;
}
Utils.HasVoted.Add(__instance.Data.PlayerId);
}
if (text == "/vote c")
{
if (Utils.HasVoted.Contains(__instance.Data.PlayerId)) return;
if (Utils.MapVoteActive)
{
Utils.polusVotes++;
}
if (Utils.ModeVoteActive)
{
Utils.speedrunVotes++;
}
Utils.HasVoted.Add(__instance.Data.PlayerId);
}
if (text == "/vote d")
{
if (Utils.HasVoted.Contains(__instance.Data.PlayerId)) return;
if (Utils.MapVoteActive)
{
Utils.airshipVotes++;
}
if (Utils.ModeVoteActive)
{
Utils.shiftAndSeekVotes++;
}
Utils.HasVoted.Add(__instance.Data.PlayerId);
}
if (text == "/vote e")
{
if (Utils.HasVoted.Contains(__instance.Data.PlayerId)) return;
if (Utils.MapVoteActive)
{
Utils.fungleVotes++;
}
if (Utils.ModeVoteActive)
{
Utils.poofAndSeekVotes++;
}
Utils.HasVoted.Add(__instance.Data.PlayerId);
}
if (text == "/vote f")
{
if (Utils.HasVoted.Contains(__instance.Data.PlayerId)) return;
if (Utils.MapVoteActive && Utils.DleksEnabled)
{
Utils.dleksVotes++;
}
Utils.HasVoted.Add(__instance.Data.PlayerId);
}
if (text == "/l" || text == "/lastgame")
{
@@ -800,7 +962,12 @@ public static class RPCHandlerPatch
if (text == "/sns" || text == "/shiftandseek")
{
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashRolesAndGamemodeCmd.GetValue()) return;
Utils.ModeratorChatCommand("Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nMeetings & Reports = Off", $"Crewmates win by doing tasks or surviving {Options.CrewAutoWinsGameAfter.GetInt()}s\nImpostors win by killing everyone\n{Options.MisfiresToSuicide.GetInt()} wrong kill(s) = suicide", true);
Utils.ModeratorChatCommand("Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nMeetings & Reports = Off", $"Crewmates win by tasks/surviving {Options.CrewAutoWinsGameAfter.GetInt()}s\nImpostors win by killing\nWrong kills are blocked. Kill animations are off", true);
}
if (text == "/sns2" || text == "/shiftandseek2")
{
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashRolesAndGamemodeCmd.GetValue()) return;
Utils.ModeratorChatCommand("Correctly killing a target will directly turn them into a ghost and leave no dead body", "", false);
}
if (text == "/sr" || text == "/speedrun")
@@ -828,7 +995,7 @@ public static class RPCHandlerPatch
break;
case 1:
Utils.ModeratorChatCommand("Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nMeetings & Reports = Off", $"Crewmates win by doing tasks or surviving {Options.CrewAutoWinsGameAfter.GetInt()}s\nImpostors win by killing everyone\n{Options.MisfiresToSuicide.GetInt()} wrong kill(s) = suicide", true);
Utils.ModeratorChatCommand("Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nMeetings & Reports = Off", $"Crewmates win by tasks/surviving {Options.CrewAutoWinsGameAfter.GetInt()}s\nImpostors win by killing\nWrong kills are blocked. Kill animations are off", true);
break;
case 2:
+8 -7
View File
@@ -27,10 +27,11 @@ class NormalGameEndChecker
public static bool ImpCheckComplete;
public static string LastWinReason = "";
public static List<PlayerControl> imps = new List<PlayerControl>();
public static string firstDeath;
public static string firstDeathString => firstDeath != null ? $"\n\nFirst death: {firstDeath}" : "";
public static bool Prefix()
{
if (Options.NoGameEnd.GetBool() || Options.Gamemode.GetValue() == 2 || Utils.HandlingGameEnd) return false;
var allPlayers = PlayerControl.AllPlayerControls.ToArray();
@@ -55,14 +56,14 @@ class NormalGameEndChecker
if (Winner == "SnSTimer")
{
LastWinReason = $"Crewmates Win! (Survived {Options.CrewAutoWinsGameAfter.GetInt()}s)\n\n Impostors: " + impostorList;
LastWinReason = $"Crewmates Win! (Survived {Options.CrewAutoWinsGameAfter.GetInt()}s)\n\n Impostors: " + impostorList + firstDeathString;
canUpdateWinnerText = false;
return;
}
if (Winner == "PnSTimer")
{
LastWinReason = $"Crewmates Win! (Survived {Options.CrewAutoWinsGameAfter.GetInt()}s)\n\n Impostors: " + impostorList;
LastWinReason = $"Crewmates Win! (Survived {Options.CrewAutoWinsGameAfter.GetInt()}s)\n\n Impostors: " + impostorList + firstDeathString;
canUpdateWinnerText = false;
return;
}
@@ -76,22 +77,22 @@ class NormalGameEndChecker
if ((Options.Gamemode.GetValue() != 2 && Utils.AliveImpostors == 0) || Winner == "Crewmate")
{
LastWinReason = "Crewmates Win!\n\nImpostors: " + impostorList;
LastWinReason = "Crewmates Win!\n\nImpostors: " + impostorList + firstDeathString;
canUpdateWinnerText = false;
}
else if ((Options.Gamemode.GetValue() != 2 && Utils.AliveImpostors >= Utils.AliveCrewmates) || Winner == "Impostor")
{
LastWinReason = "Impostors Win!\n\nImpostors: " + impostorList;
LastWinReason = "Impostors Win!\n\nImpostors: " + impostorList + firstDeathString;
canUpdateWinnerText = false;
}
else if (GameData.Instance != null && GameData.Instance.TotalTasks > 0 && GameData.Instance.CompletedTasks >= GameData.Instance.TotalTasks || Winner == "CrewmateTasks")
{
LastWinReason = $"Crewmates Win! ({Options.TaskPercentNeededToWin.GetInt()}% tasks completed)\n\nImpostors: " + impostorList;
LastWinReason = $"Crewmates Win! ({Options.TaskPercentNeededToWin.GetInt()}% tasks completed)\n\nImpostors: " + impostorList + firstDeathString;
canUpdateWinnerText = false;
}
else if (Options.Gamemode.GetValue() < 1 || Winner == "ImpostorSabotage")
{
LastWinReason = "Impostors Win! (Sabotage)\n\n Impostors: " + impostorList;
LastWinReason = "Impostors Win! (Sabotage)\n\n Impostors: " + impostorList + firstDeathString;
}
}
}
+45 -4
View File
@@ -19,6 +19,29 @@ internal static class CoShowIntroPatch
foreach (var p in PlayerControl.AllPlayerControls)
{
p.protectedByGuardianId = -1;
if (NormalGameEndChecker.firstDeath != null && NormalGameEndChecker.firstDeath == p.Data.PlayerName && Options.ShieldFirstDeath.GetBool() && Options.Gamemode.GetValue() != 1)
{
if (Main.NormalOptions.roleOptions.TryGetRoleOptions<GuardianAngelRoleOptionsV11>(RoleTypes.GuardianAngel, out var GuardianAngelOptions))
{
var oldGA = GuardianAngelOptions.ImpostorsCanSeeProtect;
var oldGAProt = GuardianAngelOptions.ProtectionDurationSeconds;
GuardianAngelOptions.ProtectionDurationSeconds = Options.ShieldFirstDeathDuration.GetFloat();
GuardianAngelOptions.ImpostorsCanSeeProtect = true;
_ = new LateTask(() =>
{ GuardianAngelOptions.ImpostorsCanSeeProtect = oldGA;
GuardianAngelOptions.ProtectionDurationSeconds = oldGAProt + 6;
OptionManager.SyncGameOptions();
}, Options.ShieldFirstDeathDuration.GetFloat(), "RevertGAProtTime");
}
OptionManager.SyncGameOptions();
p.RpcProtectPlayer(p, p.cosmetics.ColorId);
Logger.Info($" {p.Data.PlayerName} has been granted a shield for {Options.ShieldFirstDeathDuration.GetInt()}s", "RoleInfo");
}
p.cosmetics.nameText.text = p.Data.PlayerName;
MurderPlayerPatch.killCount[p.PlayerId] = 0;
@@ -35,12 +58,28 @@ internal static class CoShowIntroPatch
_ = new LateTask(() =>
{
Utils.CanCallMeetings = true;
}, 33f, "MeetingEnabled");
}, 34f, "MeetingEnabled");
}
if (Options.Gamemode.GetValue() == 1 && Options.SNSChatInGameExtend.GetBool() && !Utils.isHideNSeek)
if (Options.Gamemode.GetValue() == 1 && !Utils.isHideNSeek)
{
Utils.ModeratorChatCommand("Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nMeetings & Reports = Off", $"Crewmates win by doing tasks or surviving {Options.CrewAutoWinsGameAfter.GetInt()}s\nImpostors win by killing everyone\n{Options.MisfiresToSuicide.GetInt()} wrong kill(s) = suicide", true);
if (Main.NormalOptions.roleOptions.TryGetRoleOptions<GuardianAngelRoleOptionsV11>(RoleTypes.GuardianAngel, out var GuardianAngelOptions))
{
GuardianAngelOptions.ProtectionDurationSeconds = 60f;
}
OptionManager.SyncGameOptions();
if (Options.SNSChatInGameExtend.GetBool())
{
Utils.ModeratorChatCommand("Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nMeetings & Reports = Off", $"Crewmates win by tasks/surviving {Options.CrewAutoWinsGameAfter.GetInt()}s\nImpostors win by killing\nWrong kills are blocked. Kill animations are off", true);
}
if (Options.SNSChatInGameExtend2.GetBool())
{
_ = new LateTask(() =>
{
Utils.ChatCommand(DestroyableSingleton<HudManager>.Instance.Chat, "Correctly killing a target will directly turn them into a ghost and leave no dead body", "", false);
}, 6.6f, "SNSChatInGameExtend2");
}
}
if ((GameOptionsManager.Instance.CurrentGameOptions.GetFloat(FloatOptionNames.KillCooldown) == 0.01f))
@@ -59,7 +98,7 @@ internal static class CoShowIntroPatch
{
if (Options.PNSChatInGame.GetBool())
{
Main.NormalOptions.KillCooldown = 13f;
Main.NormalOptions.KillCooldown = 8f;
OptionManager.SyncGameOptions();
_ = new LateTask(() =>
@@ -85,6 +124,8 @@ internal static class CoShowIntroPatch
{
Utils.ModeratorChatCommand($"Poof and Seek:\n\nImpostors can only move while vanished\n Meetings & Reports = Off\nVisibly moving {Options.BadMoveTimeToSuicide.GetInt()}s as Phantom = Suicide", $"Crewmates win by doing tasks or surviving {Options.PNSCrewAutoWinsGameAfter.GetInt()}s\nImpostors win by killing everyone", true);
}
NormalGameEndChecker.firstDeath = "";
}
}
+41 -1
View File
@@ -60,6 +60,13 @@ internal static class OnGameJoinedPatch
Utils.MapVote(true, true);
}, Options.TimeBeforeAllMapPoll.GetInt(), "AutoMapPoll");
}
if (Options.AutomaticModePoll.GetBool())
{
new LateTask(() =>
{
Utils.ModeVote(true);
}, Options.TimeBeforeModePoll.GetInt(), "AutoModePoll");
}
if (Options.Public.GetBool() && DisconnectManager.Rehosting)
{
@@ -114,7 +121,6 @@ class OnPlayerJoinedPatch
}
else
{
if (!BanManager.TempBanWhiteList.Contains(Client.GetHashedPuid())) BanManager.TempBanWhiteList.Add(Client.GetHashedPuid());
AmongUsClient.Instance.KickPlayer(Client.Id, true);
Logger.Info(Translator.Get("invalidFriendCodeBan", Client.PlayerName), "BanInvalidFriendCode");
Logger.SendInGame(Translator.Get("invalidFriendCodeBan", Client.PlayerName));
@@ -205,6 +211,40 @@ public static class ShowLobbyTimer_GameStartManager_Start_Postfix
{
if (__instance == null || !GameData.Instance || !AmongUsClient.Instance || AmongUsClient.Instance.NetworkMode == NetworkModes.LocalGame || !AmongUsClient.Instance.AmHost) return;
// Toes who nose
//Main.NormalOptions.MaxPlayers = 100;
//OptionManager.SyncGameOptions();
HudManager.Instance.ShowLobbyTimer(600);
}
}
[HarmonyPatch(typeof(GameData), nameof(GameData.ShowNotification))]
public static class ShowNotificationPatch
{
static bool Prefix(string playerName, DisconnectReasons reason)
{
switch (reason)
{
case DisconnectReasons.ExitGame:
Logger.Info($" {playerName} left the game. ({reason})", "ShowNotificationPatch");
Logger.SendInGame($" {playerName} left the game. ({reason})");
return false;
case DisconnectReasons.Sanctions:
case DisconnectReasons.Hacking:
Logger.Info($" {playerName} was banned from the game. ({reason})", "ShowNotificationPatch");
Logger.SendInGame($" {playerName} was banned from the game. ({reason})");
return false;
case DisconnectReasons.DuplicateConnectionDetected:
case DisconnectReasons.ClientTimeout:
Logger.Info($" {playerName} was kicked from the game. ({reason})", "ShowNotificationPatch");
Logger.SendInGame($" {playerName} was kicked from the game. ({reason})");
return false;
default:
Logger.Info($" {playerName} disconnected from the game. ({reason})", "ShowNotificationPatch");
return true;
}
}
}
+2 -2
View File
@@ -70,7 +70,7 @@ class MeetingHudStartPatch
PlayerControl player = null;
foreach (var pc in PlayerControl.AllPlayerControls)
{
if (pc.PlayerId == playerState.TargetPlayerId)
if (pc.PlayerId == playerState.PlayerId)
{
player = pc;
break;
@@ -89,7 +89,7 @@ class MeetingHudStartPatch
taskTextMeeting.text = taskText;
taskTextMeeting.gameObject.name = "TaskTextMeeting";
taskTextMeeting.enableWordWrapping = false;
taskTextMeeting.enabled = player.AmOwner || player.PlayerId == playerState.TargetPlayerId;
taskTextMeeting.enabled = player.AmOwner || player.PlayerId == playerState.PlayerId;
}
}
+5
View File
@@ -126,6 +126,11 @@ public static class NumberOption_Initialize
__instance.Increment = 0.05f;
break;
case StringNames.JudgeTaskRequirement:
__instance.Increment = 1f;
__instance.ValidRange = new FloatRange(0f, 100f);
break;
default:
__instance.Increment = 1f;
break;
+113
View File
@@ -1,4 +1,5 @@
using AmongUs.GameOptions;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using System;
using InnerNet;
using UnityEngine;
@@ -149,4 +150,116 @@ internal static class OnGameStartPatch
PastStartScreen = true;
}
// All Patches below are for the speeded up Chat In Game.
// We force the complete intro to skip using 2 patches.
// Some PlayerData related things return null when you do this, so we have to set those all as well.
[HarmonyPatch(typeof(ShhhBehaviour), nameof(ShhhBehaviour.PlayAnimation))]
public static class ShhhBehaviourPlayAnimationPatch
{
static bool Prefix()
{
if (!AmongUsClient.Instance.AmHost) return true;
if ((Options.SNSChatInGameFast.GetBool() && Options.Gamemode.GetValue() == 1) || (Options.PNSChatInGameFast.GetBool() && Options.Gamemode.GetValue() == 3))
{
HudManager.Instance.shhhEmblem.gameObject.SetActive(false);
return false;
}
else return true;
}
}
[HarmonyPatch(typeof(IntroCutscene), nameof(IntroCutscene.CoBegin))]
public static class IntroCutsceneCoBeginPatch
{
public static void Postfix(IntroCutscene __instance, ref Il2CppSystem.Collections.IEnumerator __result)
{
if (!AmongUsClient.Instance.AmHost) return;
if ((Options.SNSChatInGameFast.GetBool() && Options.Gamemode.GetValue() == 1) || (Options.PNSChatInGameFast.GetBool() && Options.Gamemode.GetValue() == 3))
{
__result = SkipIntro(__instance, __result).WrapToIl2Cpp();
}
}
private static System.Collections.IEnumerator SkipIntro(IntroCutscene i, Il2CppSystem.Collections.IEnumerator k)
{
int steps = 0;
while (k.MoveNext() && steps++ < 1024) {}
if (steps >= 1024)
{
if (i != null && i.gameObject != null) i.gameObject.SetActive(false);
}
yield break;
}
}
private static NamePlateViewData meetingNameplate;
[HarmonyPatch(typeof(CosmeticsCache), nameof(CosmeticsCache.GetNameplate))]
public static class CosmeticsCacheGetNameplatePatch
{
public static bool Prefix(ref NamePlateViewData __result)
{
if (!AmongUsClient.Instance.AmHost) return true;
if ((Options.SNSChatInGameFast.GetBool() && Options.Gamemode.GetValue() == 1) || (Options.PNSChatInGameFast.GetBool() && Options.Gamemode.GetValue() == 3))
{
if (MeetingHud.Instance == null) return true;
if (meetingNameplate == null)
{
meetingNameplate = ScriptableObject.CreateInstance<NamePlateViewData>();
meetingNameplate.Image = null;
}
__result = meetingNameplate;
return false;
}
else return true;
}
}
[HarmonyPatch(typeof(CosmeticsCache), nameof(CosmeticsCache.Destroy))]
public static class CosmeticsCacheDestroyPatch
{
public static void Postfix()
{
if (!AmongUsClient.Instance.AmHost) return;
if (meetingNameplate != null) Object.Destroy(meetingNameplate);
meetingNameplate = null;
}
}
[HarmonyPatch(typeof(ShapeshifterPanel), nameof(ShapeshifterPanel.SetPlayer))]
public static class ShapeshifterPanelSetPlayerPatch
{
public static bool Prefix(ShapeshifterPanel __instance, int index, NetworkedPlayerInfo playerInfo, Il2CppSystem.Action onShift)
{
if (__instance == null || playerInfo == null || !AmongUsClient.Instance.AmHost) return true;
if ((Options.SNSChatInGameFast.GetBool() && Options.Gamemode.GetValue() == 1) || (Options.PNSChatInGameFast.GetBool() && Options.Gamemode.GetValue() == 3))
{
__instance.shapeshift = onShift;
__instance.PlayerIcon.SetFlipX(false);
__instance.PlayerIcon.ToggleName(false);
SpriteRenderer[] componentsInChildren = __instance.GetComponentsInChildren<SpriteRenderer>();
foreach (var spriteRenderer in componentsInChildren)
{
spriteRenderer.material.SetInt(PlayerMaterial.MaskLayer, index + 2);
}
__instance.PlayerIcon.SetMaskLayer(index + 2);
__instance.PlayerIcon.UpdateFromEitherPlayerDataOrCache(playerInfo, PlayerOutfitType.Default, PlayerMaterial.MaskType.ComplexUI, false, null);
__instance.NameText.text = playerInfo.PlayerName;
__instance.LevelNumberText.text = ProgressionManager.FormatVisualLevel(playerInfo.PlayerLevel);
return false;
}
else return true;
}
}
}
+28 -17
View File
@@ -51,7 +51,7 @@ internal static class MurderPlayerPatch
public static void Prefix(PlayerControl __instance, [HarmonyArgument(0)] PlayerControl target, [HarmonyArgument(1)] MurderResultFlags resultFlags, ref bool __state)
{
if (!AmongUsClient.Instance.AmHost || !resultFlags.HasFlag(MurderResultFlags.Succeeded)) return;
if (!AmongUsClient.Instance.AmHost) return;
byte playerId = __instance.Data.PlayerId;
@@ -60,11 +60,25 @@ internal static class MurderPlayerPatch
killCount[playerId] = 0;
}
if (resultFlags.HasFlag(MurderResultFlags.Succeeded))
{
killCount[playerId]++;
Logger.Info($" {__instance.Data.PlayerName} killed {target.Data.PlayerName}", "MurderPlayer");
if (string.IsNullOrEmpty(NormalGameEndChecker.firstDeath))
{
NormalGameEndChecker.firstDeath = target.Data.PlayerName;
Utils.HasMurdered = true;
}
killCount[playerId]++;
Logger.Info($" {__instance.Data.PlayerName} killed {target.Data.PlayerName}", "MurderPlayer");
if (Options.Gamemode.GetValue() == 1 && !Utils.isHideNSeek)
{
if (target.Data.PlayerId == __instance.shapeshiftTargetPlayerId) return;
Logger.Info($" {__instance.Data.PlayerName} directly killed {target.Data.PlayerName} in SnS, forcing suicide. (Are they hacking?)", "MurderPlayer");
__instance.RpcSetRole(RoleTypes.ImpostorGhost);
}
}
if ((target == PlayerControl.LocalPlayer || PlayerControl.LocalPlayer.Data.IsDead) && !Main.DisableInfoWhenDead.Value)
if ((target == PlayerControl.LocalPlayer || PlayerControl.LocalPlayer.Data.IsDead) && !Main.DisableInfoWhenDead.Value && resultFlags.HasFlag(MurderResultFlags.Succeeded))
{
foreach (var p in PlayerControl.AllPlayerControls)
{
@@ -82,30 +96,26 @@ internal static class MurderPlayerPatch
//1 = Shift and Seek
if (Options.Gamemode.GetValue() == 1 && !Utils.isHideNSeek)
{
if (!resultFlags.HasFlag(MurderResultFlags.Succeeded)) return;
if (target.Data.PlayerId == __instance.shapeshiftTargetPlayerId)
{
killCount[playerId]++;
Logger.Info($" {__instance.Data.PlayerName} correctly killed {target.Data.PlayerName} ", "SNSKillManager");
target.RpcSetRole(RoleTypes.CrewmateGhost);
if (string.IsNullOrEmpty(NormalGameEndChecker.firstDeath))
{
NormalGameEndChecker.firstDeath = target.Data.PlayerName;
Utils.HasMurdered = true;
}
}
else
{
if (!misfireCount.ContainsKey(playerId))
misfireCount[playerId] = 0;
misfireCount[playerId]++;
if (misfireCount[__instance.Data.PlayerId] >= Options.MisfiresToSuicide.GetFloat())
{
__instance.RpcSetRole(RoleTypes.ImpostorGhost);
Logger.Info($" {__instance.Data.PlayerName} misfired {misfireCount[playerId]} time(s) and suicided", "SNSKillManager");
Logger.SendInGame($" {__instance.Data.PlayerName} misfired {misfireCount[playerId]} time(s) and suicided");
}
Logger.Info($" {__instance.Data.PlayerName} misfired trying to kill {target.Data.PlayerName}. Blocking kill", "SNSKillManager");
}
}
}
}
/*
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.CheckShapeshift))]
internal static class CheckShapeshiftPatch
{
@@ -123,6 +133,7 @@ internal static class CheckShapeshiftPatch
else return true;
}
}
*/
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.CompleteTask))]
class PlayerControlCompleteTaskPatch
+9 -9
View File
@@ -37,14 +37,15 @@
<img src="https://github.com/astra1dev/AUnlocker/assets/90265231/14226f03-a003-4efc-b27b-6df53fb394d6" width=410 height=240>****
‎
# 🎮 Features (v1.9.4):
# 🎮 Features (v2.0.0):
## <b>♠️ Client Side settings:</b>
- Game Master (Spectator)
- Show FPS
- Dark Theme
- Toggle Game Master (Spectator)
- Toggle Show FPS
- Toggle Dark Theme
- Toggle Lobby Music
- Show/Hide Info When Dead
- Toggle Info When Dead
- Toggle Command Helper
## <b>⚙️ Technical settings:</b>
- Advanced AFK Detection system
- Kick/Ban players under/above a certain level
@@ -53,7 +54,7 @@
- Banlist system
- Denyword and Denyname system
- Advanced Moderator system
- To add Admins, Moderators and VIP's, type the user's Friendcode in the designated files located in AUR-DATA
- To add Admins/Moderators/VIP's, type the user's Friendcode in the designated files located in AUR-DATA
- Enable No Game End
- Custom starting countdown
## <b>♻️ Automation settings:</b>
@@ -73,6 +74,7 @@
- % Tasks completed for Crewmates to win
- Enable/Disable any task
- All players have same tasks
- Shield player who died first
- Hide and Seek: Custom Seeker count
## <b>🏆 Custom Gamemodes:</b>
- 0 Kill Cooldown -> Set Kill Cooldown to 0.01
@@ -92,18 +94,15 @@
- Lanuage support: English, Italian, Japanese, Russian, Simplified Chinese, Spanish
- Select a language in Language/YourLanguage.txt
- Preset system for mod settings
- Command Helper
- Creatable and customizable Templates
- Eht Dleks (Reverse Skeld) Map
- Ability to cancel starting countdown
- Improved main menu
- Faster startup time
- Zoom out in lobby or when dead
- See player kill/task count and Role when dead
- Higher and more accurate Option ranges
- Always visible lobby timer
- Access experimental animation test scene
- Manually set multiple Seekers in HnS
- <b>🎉 And this all works in public lobbies!</b>
### Hotkeys
@@ -142,6 +141,7 @@
| /clearseekers | Clears manual Seeker list in HnS |
| /mapvote | Starts a vote for the map. Default maps only |
| /allmapvote | Starts a vote for the map. Includes Eht Dleks |
| /gmvote | Starts a vote for the gamemode |
‎
**Credit to these mods and their developers for their code:**
+12 -4
View File
@@ -56,6 +56,7 @@
"allowFortegreen": "Allow Fortegreen Color",
"noGameEnd": "No Game End",
"mapVoteDuration": "Map Vote Duration",
"modeVoteDuration": "Gamemode Vote Duration",
"tabGroupDeniedWords": "Denied Words",
"enableDeniedWords": "Kick Players Who Say Denied Words",
@@ -64,7 +65,7 @@
"slashColorCmd": "Who Can Use /color",
"slashRolesAndGamemodeCmd": "Who Can Use /r & Templates",
"slashLastGameCmd": "Who Can Use /l & /aur",
"slashMapAndSeekerCmd": "Who Can Use /seeker & /mapvote",
"slashMapAndSeekerCmd": "Who Can Use /seeker & Create Votes",
"slashKickCmd": "Who Can Use /kick & /ckick",
"slashBanCmd": "Who Can Use /ban & /cban",
"slashEndMeetingCmd": "Who Can Use /endmeeting",
@@ -83,6 +84,8 @@
"tabGroupSNS": "Shift and Seek",
"snsChatInGame": "Chat during gameplay (experimental)",
"snsChatInGameExtend": "Send gamemode info after game start",
"snsChatInGameExtendTwo": "Send extended info after game start",
"snsChatInGameFast": "Faster Meeting (experimental+)",
"snsSettingsOverride": "Auto Update Settings",
"cantKillTime": "After Misfiring, Can't kill for",
"misfiresToSuicide": "Suicide After Amount Of Misfires",
@@ -112,6 +115,8 @@
"disableCloseDoor": "Disable Door Sabotages",
"tabGroupGameplayGeneral": "General",
"shieldFirstDeath": "Shield Player Who Died First",
"shieldFirstDeathDuration": "Shield Duration",
"disableAnnoyingMeetingCalls": "Disable Meeting Calls First 30s",
"disableReport": "Disable Body Reports",
"changeDecontaminationTime": "Override Decontamination Time (Standard Only)",
@@ -234,7 +239,7 @@
"disableSubmitScan": "Disable Submit Scan",
"disableUploadData": "Disable Upload Data",
"allCommandsFull": "<b>ALL COMMANDS:</b>\n\n<b>/help</b>\nShow this message.\n<b>/aur, /socials</b>\nSend Among Us Revamped social links.\n\n<b>/r, /gm</b>\nSend current mode description.\n<b>/l, /lastgame</b>\nSend last winner info.\n\n<b>/0kc, /0killcooldown</b>\nSend 0 Kill Cooldown mode description.\n<b>/sns, /shiftandseek</b>\nSend Shift and Seek mode description.\n<b>/pns, /poofandseek</b>\nSend Poof and Seek mode description.\n<b>/sp, /speedrun</b>\nSend Speedrun mode description.\n\n/<b>kick, /ban</b>\nKick or ban a player by name.\n<b>/ckick, /cban</b>\nKick or ban a player by color.\n\n<b>/vip /moderator /admin</b>\nAdd a player as VIP, Moderator, or Admin.\n<b>/removevip, /removemoderator, /removeadmin</b>\nRemove VIP, Moderator, or Admin from a player.\n\n<b>/eg, /endgame</b>\nEnd the current game.\n<b>/em, /endmeeting</b>\nEnd the current meeting.\n<b>/s, /start</b>\nBegin the game starting countdown.\n\n<b>/t {template}</b>\nSend a template from AUR-DATA/templates.txt.\n\n<b>/col, /color, /colour</b>\nSet your color, can be used to bypass limits.\n\n<b>/seeker {name}</b>\nForce someone as Seeker in HnS.\n<b>/seekers</b>\nShow forced seeker list.\n<b>/clearseeker</b>\nClear forced seeker list.\n\n<b>/mapvote</b>\nStarts a map vote containing default maps.\n\n<b>/allmapvote</b>\nStarts a map vote that includes Eht Dleks.",
"allCommandsFull": "<b>ALL COMMANDS:</b>\n\n<b>/help</b>\nShow this message.\n<b>/aur, /socials</b>\nSend Among Us Revamped social links.\n\n<b>/r, /gm</b>\nSend current mode description.\n<b>/l, /lastgame</b>\nSend last winner info.\n\n<b>/0kc, /0killcooldown</b>\nSend 0 Kill Cooldown mode description.\n<b>/sns, /shiftandseek</b>\nSend Shift and Seek mode description.\n<b>/sns2</b>\nSend extended Shift and Seek mode description\n<b>/pns, /poofandseek</b>\nSend Poof and Seek mode description.\n<b>/sp, /speedrun</b>\nSend Speedrun mode description.\n\n/<b>kick, /ban</b>\nKick or ban a player by name.\n<b>/ckick, /cban</b>\nKick or ban a player by color.\n\n<b>/vip /moderator /admin</b>\nAdd a player as VIP, Moderator, or Admin.\n<b>/removevip, /removemoderator, /removeadmin</b>\nRemove VIP, Moderator, or Admin from a player.\n\n<b>/eg, /endgame</b>\nEnd the current game.\n<b>/em, /endmeeting</b>\nEnd the current meeting.\n<b>/s, /start</b>\nBegin the game starting countdown.\n\n<b>/t {template}</b>\nSend a template from AUR-DATA/templates.txt.\n\n<b>/col, /color, /colour</b>\nSet your color, can be used to bypass limits.\n\n<b>/seeker {name}</b>\nForce someone as Seeker in HnS.\n<b>/seekers</b>\nShow forced seeker list.\n<b>/clearseeker</b>\nClear forced seeker list.\n\n<b>/mapvote</b>\nStarts a map vote containing default maps.\n<b>/allmapvote</b>\nStarts a map vote that includes Eht Dleks.\n<b>/gmvote</b>\nStarts a gamemode vote.",
"translationReloaded": "Your file has successfully been reset.\nTo apply all changes, restart your game.",
@@ -262,6 +267,7 @@
"helpDesc": "Show all commands and what they do.",
"snsDesc": "Send Shift and Seek gamemode Description.",
"snsTwoDesc": "Send Shift and Seek extended Description.",
"0kcDesc": "Send 0 Kill Cooldown gamemode Description.",
"SrDesc": "Send Speedrun gamemode Description.",
"pnsDesc": "Send Poof and Seek gamemode Description.",
@@ -291,6 +297,7 @@
"clearSeekerDesc": "Clears the manual Seeker list.",
"mapVoteDesc": "Starts a vote between the 5 core maps.",
"allMapVoteDesc": "Starts a vote between all 6 maps, including Eht Dleks.",
"modeVoteDesc": "Starts a vote between all gamemodes.",
"banWordKick": "{0} was kicked because they sent a word in DeniedWords.txt {1} time(s)",
"startWordKick": "{0} was kicked because they sent a word in StartWords.txt {1} time(s)",
@@ -336,11 +343,12 @@
"automaticMapPoll": "Automatic /mapvote After Rejoining",
"automaticAllMapPoll": "Automatic /allmapvote After Rejoining",
"timeBeforeMapPoll": "Time Before Poll Starts",
"timeBeforeMapPoll": "Time Before Vote Starts",
"automaticModePoll": "Automatic /gmvote After Rejoining",
"pnsDisableSabotage": "Disable PnS Critical Sabotages",
"pnsDisableCloseDoor": "Disable PnS Door Sabotages",
"tabGroupPNS": "Poof and Seek",
"badMoveTimeToSuicide": "Phantom Suicides After Visibly Moving For",
"snsImpostorCanVent": "Impostors can vent"
"snsImpostorCanVent": "Impostors Can Vent"
}
+6 -6
View File
@@ -336,10 +336,10 @@
"automaticMapPoll": "再参加後に /mapvote を自動実行",
"automaticAllMapPoll": "再参加後に /allmapvote を自動実行",
"timeBeforeMapPoll": "投票開始までの待機時間",
"pnsDisableSabotage": "Disable PnS Critical Sabotages",
"pnsDisableCloseDoor": "Disable PnS Door Sabotages",
"tabGroupPNS": "Poof and Seek",
"badMoveTimeToSuicide": "Phantom Suicides After Visibly Moving For",
"snsImpostorCanVent": "Impostors can vent"
"pnsDesc": "Poof and Seekゲームモードの説明を送信します。",
"pnsDisableSabotage": "PnSの重大なサボタージュを無効にする",
"pnsDisableCloseDoor": "PnSのドア閉鎖サボタージュを無効にする",
"tabGroupPNS": "Poof and Seek",
"badMoveTimeToSuicide": "幻象師が明らかに移動した後、自殺するまでの時間",
"snsImpostorCanVent": "インポスターはベントを使用できる"
}
+6 -6
View File
@@ -337,10 +337,10 @@
"automaticAllMapPoll": "Автоматический /allmapvote После Перезахода",
"timeBeforeMapPoll": "Время До Начала Голосования За Карты",
"pnsDisableSabotage": "Disable PnS Critical Sabotages",
"pnsDisableCloseDoor": "Disable PnS Door Sabotages",
"tabGroupPNS": "Poof and Seek",
"badMoveTimeToSuicide": "Phantom Suicides After Visibly Moving For",
"snsImpostorCanVent": "Impostors can vent"
"pnsDisableSabotage": "Выключить Критические Саботажи В Режиме Фантомные Прятки",
"pnsDisableCloseDoor": "Выключить Саботажи Дверей В Режиме Фантомные Прятки",
"tabGroupPNS": "Фантомные Прятки",
"badMoveTimeToSuicide": "Файнтомы Самоубиваются После Видимого Движения После",
"snsImpostorCanVent": "Предатели могут уходить в люк",
"pnsDesc": "Отправляет информацию о Режиме Фантомных Прятках."
}