MASSIVE database change, fix million things, add million things

Please don't break the whole mod
This commit is contained in:
Ape committed 2026-01-15 23:18:45 +01:00
1 parent 59384ec415
commit 2e337ce6b8
11 files changed
+324 -49

No files matched your search

+22 -1
View File
@@ -29,7 +29,7 @@ public partial class Main : BasePlugin
public static NormalGameOptionsV10 NormalOptions => GameOptionsManager.Instance != null ? GameOptionsManager.Instance.currentNormalGameOptions : null;
public static bool HasArgumentException;
public static string CredentialsText;
public const string ModVersion = "v1.1.1";
public const string ModVersion = "v1.2.0";
public static float GameTimer;
@@ -84,4 +84,25 @@ public partial class Main : BasePlugin
LateTask.Update(Time.deltaTime);
}
}
public enum ColorToString
{
Red = 0,
Blue = 1,
Green = 2,
Pink = 3,
Orange = 4,
Yellow = 5,
Black = 6,
White = 7,
Purple = 8,
Brown = 9,
Cyan = 10,
Lime = 11,
Maroon = 12,
Rose = 13,
Banana = 14,
Gray = 15,
Tan = 16
}
}
+13 -7
View File
@@ -41,6 +41,9 @@ namespace AmongUsRevamped
public static OptionItem ApplyDenyNameList;
public static OptionItem ApplyModeratorList;
public static OptionItem TabGroupAutomation;
public static OptionItem AutoSendGameInfo;
public static OptionItem AutoRejoinLobby;
public static OptionItem AutoStartTimer;
public static OptionItem WaitAutoStart;
@@ -190,8 +193,8 @@ namespace AmongUsRevamped
.SetColor(Color.green)
.SetHeader(true);
TabGroupMain = TextOptionItem.Create(60000, "Main", TabGroup.SystemSettings)
.SetColor(Color.yellow);
TabGroupMain = TextOptionItem.Create(60000, "Moderation", TabGroup.SystemSettings)
.SetColor(Color.blue);
KickLowLevelPlayer = IntegerOptionItem.Create(60050, "Kick Players Under Level", new(0, 100, 1), 0, TabGroup.SystemSettings, false)
.SetValueFormat(OptionFormat.Level);
@@ -206,18 +209,21 @@ namespace AmongUsRevamped
ApplyDenyNameList = BooleanOptionItem.Create(60120, "Apply DenyName List", true, TabGroup.SystemSettings, false);
ApplyModeratorList = BooleanOptionItem.Create(60121, "Apply Moderator List", true, TabGroup.SystemSettings, false);
TabGroupAutomation = TextOptionItem.Create(60149, "Automation", TabGroup.SystemSettings)
.SetColor(Color.yellow);
AutoSendGameInfo = BooleanOptionItem.Create(60150, "Automatically send winner info", true, TabGroup.SystemSettings, false);
AutoRejoinLobby = BooleanOptionItem.Create(60210, "Auto Rejoin Lobby", false, TabGroup.SystemSettings, false);
AutoStartTimer = IntegerOptionItem.Create(44420, "Countdown For Auto Start", new(1, 600, 1), 5, TabGroup.SystemSettings, false)
AutoStartTimer = IntegerOptionItem.Create(64420, "Countdown For Auto Start", new(1, 600, 1), 5, TabGroup.SystemSettings, false)
.SetValueFormat(OptionFormat.Seconds);
WaitAutoStart = IntegerOptionItem.Create(44421, "Auto Start After", new(10, 600, 10), 300, TabGroup.SystemSettings, false)
WaitAutoStart = IntegerOptionItem.Create(64421, "Auto Start After", new(10, 600, 10), 300, TabGroup.SystemSettings, false)
.SetValueFormat(OptionFormat.Seconds);
PlayerAutoStart = IntegerOptionItem.Create(44422, "Players Needed To Auto Start", new(1, 15, 1), 1, TabGroup.SystemSettings, false);
PlayerAutoStart = IntegerOptionItem.Create(64422, "Players Needed To Auto Start", new(1, 15, 1), 1, TabGroup.SystemSettings, false);
NoGameEnd = BooleanOptionItem.Create(60380, "No Game End", false, TabGroup.SystemSettings, false)
.SetColor(Color.red)
.SetHeader(true);
// Gamemode Settings
TabGroupHNS = TextOptionItem.Create(70000, "Hide and Seek", TabGroup.GamemodeSettings)
.SetColor(Color.green);
@@ -264,7 +270,7 @@ namespace AmongUsRevamped
.SetColor(new Color32(255, 255, 153, byte.MaxValue))
.SetParent(OverrideTaskSettings);
DisableMiraTasks = BooleanOptionItem.Create(23000, "Disable Mira Tasks", false, TabGroup.ModSettings, false)
DisableMiraTasks = BooleanOptionItem.Create(23000, "Disable Mira HQ Tasks", false, TabGroup.ModSettings, false)
.SetColor(new Color32(173, 216, 230, byte.MaxValue))
.SetParent(OverrideTaskSettings);
+2
View File
@@ -40,6 +40,7 @@ public static class FixedUpdate
writer.Write((byte)GameOverReason.ImpostorDisconnect);
AmongUsClient.Instance.FinishEndGame(writer);
Logger.Info($" Crewmates won because the game took longer than {Options.CrewAutoWinsGameAfter.GetInt()}s", "SNSManager");
NormalGameEndChecker.LastWinReason = $"★ Crewmates win! (Timer)\n\nImpostors:\n" + string.Join("\n", NormalGameEndChecker.imps.Select(p => p.Data.PlayerName));
}
}
// 3 = Speedrun
@@ -55,6 +56,7 @@ public static class FixedUpdate
writer.Write((byte)GameOverReason.CrewmatesByVote);
AmongUsClient.Instance.FinishEndGame(writer);
Logger.Info($" No one won because the game took longer than {Options.GameAutoEndsAfter.GetInt()}s", "SpeedrunManager");
NormalGameEndChecker.LastWinReason = $"★ No one wins! (Timer)";
}
}
}
+35 -1
View File
@@ -26,6 +26,8 @@ public static class Utils
public static long TimeStamp => EpochStartSeconds + (long)Stopwatch.Elapsed.TotalSeconds;
public static int allAlivePlayersCount => AllAlivePlayerControls.Count();
public static int AliveCrewmates => AllAlivePlayerControls.Count(pc => !pc.Data.Role.IsImpostor);
public static int AliveImpostors => AllAlivePlayerControls.Count(pc => pc.Data.Role.IsImpostor);
public static bool IsLobby => AmongUsClient.Instance.GameState == InnerNetClient.GameStates.Joined;
public static bool InGame => AmongUsClient.Instance && AmongUsClient.Instance.GameState == InnerNetClient.GameStates.Started;
@@ -198,7 +200,9 @@ public static class Utils
OnGameJoinedPatch.AutoStartCheck = false;
Main.GameTimer = 0f;
MurderPlayerPatch.misfireCount.Clear();
LateTask.Tasks.Clear();
LateTask.Tasks.Clear();
FixedUpdateInGamePatch.ProcessedModerators.Clear();
NormalGameEndChecker.ImpCheckComplete = false;
}
public static PlayerControl[] AllAlivePlayerControls
@@ -222,4 +226,34 @@ public static class Utils
return result;
}
}
public static void ShowLastResult(byte playerId = byte.MaxValue)
{
if (InGame)
{
Logger.SendInGame($"Hi, you're currently in-game. Let's use this command afterwards");
return;
}
if (string.IsNullOrEmpty(NormalGameEndChecker.LastWinReason))
{
Logger.SendInGame($"Your command was canceled due to not having the required info");
return;
}
PlayerControl.LocalPlayer.RpcSendChat($"{NormalGameEndChecker.LastWinReason}");
}
public static bool TryGetColorId(string input, out byte colorId)
{
colorId = 0;
if (Enum.TryParse<Main.ColorToString>(input, true, out var color))
{
colorId = (byte)color;
return true;
}
return false;
}
}
+113 -29
View File
@@ -36,7 +36,16 @@ internal static class SendChatPatch
return false;
}
if (__instance.timeSinceLastMessage < 3f) return false;
if (__instance.timeSinceLastMessage < 3f || OnGameJoinedPatch.WaitingForChat) return false;
if (text == "/l" || text == "/lastgame")
{
Utils.ShowLastResult();
__instance.timeSinceLastMessage = 0.8f;
__instance.freeChatField.textArea.Clear();
__instance.freeChatField.textArea.SetText(string.Empty);
return false;
}
if (text == "/0kc" || text == "/0kcd" || text == "/0killcooldown")
{
@@ -56,6 +65,7 @@ internal static class SendChatPatch
new LateTask(() =>
{
if (!Utils.IsLobby) return;
PlayerControl.LocalPlayer.RpcSendChat($"Crew wins by tasks/surviving {Options.CrewAutoWinsGameAfter.GetInt()}s.\nImp wins by killing Crew.\n1 Wrong kill = Can't kill for {Options.CantKillTime.GetInt()}s.\n{Options.MisfiresToSuicide.GetInt()} Wrong kills = suicide.");
__instance.timeSinceLastMessage = 0.8f;
}, 2.2f, "SNSTutorial2");
@@ -71,46 +81,120 @@ internal static class SendChatPatch
return false;
}
else return true;
}
}
[HarmonyPatch(typeof(PlayerControl), "RpcSendChat")]
public static class PC_RpcSendChat
{
// Banning works by Name and not Id
public static void Prefix(PlayerControl __instance, ref string chatText)
{
if (!AmongUsClient.Instance.AmHost)
return;
bool isKick = chatText.StartsWith("/kick ");
bool isBan = chatText.StartsWith("/ban ");
if (!isKick && !isBan)
return;
if (__instance == PlayerControl.LocalPlayer || Utils.IsPlayerModerator(__instance.Data.FriendCode))
else
{
string kickedPlayerName = chatText.Substring(isBan ? 5 : 6).Trim();
bool isKick = text.StartsWith("/kick ");
bool isBan = text.StartsWith("/ban ");
bool isColorKick = text.StartsWith("/ckick ");
bool isColorBan = text.StartsWith("/cban ");
bool banLog = isBan || isColorBan;
if (!isKick && !isBan && !isColorKick && !isColorBan)
{
Logger.Info($" {PlayerControl.LocalPlayer.Data.PlayerName}: {text}", "SendChat");
return true;
}
string arg = text.Substring(isKick ? 6 : isBan ? 5 : isColorKick ? 7 : isColorBan ? 6 : 0).Trim();
PlayerControl target = null;
foreach (PlayerControl p in PlayerControl.AllPlayerControls)
{
if (p.Data != null && !Utils.IsPlayerModerator(p.Data.FriendCode) && p != PlayerControl.LocalPlayer && p.Data.PlayerName.Equals(kickedPlayerName, StringComparison.OrdinalIgnoreCase))
if (p.Data == null || p == PlayerControl.LocalPlayer) continue;
if ((isKick || isBan) && p.Data.PlayerName.Equals(arg, StringComparison.OrdinalIgnoreCase))
{
target = p;
break;
}
}
if ((isColorKick || isColorBan) && Utils.TryGetColorId(arg, out byte colorId))
{
if (p.Data.DefaultOutfit.ColorId == colorId)
{
target = p;
break;
}
}
}
if (target == null)
return;
if (target != null)
{
AmongUsClient.Instance.KickPlayer(target.Data.ClientId, isBan || isColorBan);
Logger.Info($" {(banLog ? "banned" : "kicked")} {target.Data.PlayerName}", "Kick&BanCommand");
__instance.freeChatField.textArea.Clear();
__instance.freeChatField.textArea.SetText(string.Empty);
}
return false;
}
}
}
AmongUsClient.Instance.KickPlayer(target.Data.ClientId, isBan);
Logger.Info($" {__instance.Data.PlayerName} {(isBan ? "banned" : "kicked")} {target.Data.PlayerName}", "Kick&BanCommand");
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.HandleRpc))]
public static class RPCHandlerPatch
{
public static void Prefix(PlayerControl __instance, byte callId, MessageReader reader)
{
if (!AmongUsClient.Instance.AmHost) return;
var rpcType = (RpcCalls)callId;
MessageReader subReader = MessageReader.Get(reader);
switch (rpcType)
{
case RpcCalls.SendChat:
{
string chatText = subReader.ReadString();
Logger.Info($" {__instance.Data.PlayerName}: {chatText}", "SendChat");
// Banning works by name and color. Commands are seperated incase someone has a color as their name
bool isKick = chatText.StartsWith("/kick ");
bool isBan = chatText.StartsWith("/ban ");
bool isColorKick = chatText.StartsWith("/ckick ");
bool isColorBan = chatText.StartsWith("/cban ");
bool banLog = isBan || isColorBan;
if (!isKick && !isBan && !isColorKick && !isColorBan) return;
if (Utils.IsPlayerModerator(__instance.Data.FriendCode))
{
string arg = chatText.Substring(isKick ? 6 : isBan ? 5 : isColorKick ? 7 : isColorBan ? 6 : 0).Trim();
PlayerControl target = null;
foreach (PlayerControl p in PlayerControl.AllPlayerControls)
{
if (p.Data == null || p == PlayerControl.LocalPlayer || Utils.IsPlayerModerator(p.Data.FriendCode)) continue;
if ((isKick || isBan) && p.Data.PlayerName.Equals(arg, StringComparison.OrdinalIgnoreCase))
{
target = p;
break;
}
if ((isColorKick || isColorBan) && Utils.TryGetColorId(arg, out byte colorId))
{
if (p.Data.DefaultOutfit.ColorId == colorId)
{
target = p;
break;
}
}
}
if (target != null)
{
AmongUsClient.Instance.KickPlayer(target.Data.ClientId, isBan || isColorBan);
Logger.Info($" {__instance.Data.PlayerName} {(banLog ? "banned" : "kicked")} {target.Data.PlayerName}", "Kick&BanCommand");
}
}
break;
}
}
}
}
+1
View File
@@ -52,6 +52,7 @@ namespace AmongUsRevamped
private static void Postfix(VersionShower __instance)
{
Utils.ClearLeftoverData();
NormalGameEndChecker.LastWinReason = "";
Main.CredentialsText = $"<color=#FFD700>Among Us Revamped</color><color=#ffffff> {Main.ModVersion}</color>";
+50
View File
@@ -0,0 +1,50 @@
using System;
using AmongUs.Data;
using Discord;
using HarmonyLib;
namespace AmongUsRevamped;
// Originally from "Town of Us Rewritten", by Det
[HarmonyPatch(typeof(ActivityManager), nameof(ActivityManager.UpdateActivity))]
public class DiscordRPC
{
private static string Lobbycode = "";
private static string Region = "";
public static void Prefix([HarmonyArgument(0)] Activity activity)
{
if (activity == null) return;
var details = $"AmongUsRevamped {Main.ModVersion}";
activity.Details = details;
try
{
if (activity.State != "In Menus")
{
if (!DataManager.Settings.Gameplay.StreamerMode)
{
if (Utils.IsLobby)
{
Lobbycode = GameStartManager.Instance.GameRoomNameCode.text;
Region = Utils.GetRegionName();
}
if (Lobbycode != "" && Region != "") details = $"AmongUsRevamped - {Lobbycode} ({Region})";
}
else
details = $"AmongUsRevamped {Main.ModVersion}";
activity.Details = details;
}
}
catch (Exception ex)
{
Logger.Error("Error in updating discord rpc", "DiscordPatch");
Logger.Exception(ex, "DiscordPatch");
details = $"AmongUsRevamped v{Main.ModVersion}";
activity.Details = details;
}
}
}
+35 -2
View File
@@ -21,12 +21,44 @@ public static class EndGameManagerPatch
[HarmonyPatch(typeof(LogicGameFlowNormal), nameof(LogicGameFlowNormal.CheckEndCriteria))]
class NormalGameEndChecker
{
public static bool ImpCheckComplete;
public static string LastWinReason = "";
public static List<PlayerControl> imps = new List<PlayerControl>();
public static bool Prefix()
{
if (Options.NoGameEnd.GetBool() || Options.Gamemode.GetValue() == 3 || Options.Gamemode.GetValue() == 2 && Main.NormalOptions.NumImpostors*2 < Utils.allAlivePlayersCount ) return false;
else return true;
if (Options.NoGameEnd.GetBool() || Options.Gamemode.GetValue() == 3 || Options.Gamemode.GetValue() == 2 && Main.NormalOptions.NumImpostors*2 < Utils.allAlivePlayersCount) return false;
var allPlayers = PlayerControl.AllPlayerControls.ToArray();
if (!ImpCheckComplete)
{
imps.AddRange(allPlayers.Where(pc => pc.Data.Role.IsImpostor));
ImpCheckComplete = true;
}
if (Utils.AliveImpostors == 0)
{
LastWinReason = $"★ Crewmates win!\n\nImpostors:\n" + string.Join("\n", imps.Select(p => p.Data.PlayerName));
}
else if (Utils.AliveImpostors >= Utils.AliveCrewmates)
{
LastWinReason = $"★ Impostors win!\n\nImpostors:\n★" + string.Join("\n★", imps.Select(p => p.Data.PlayerName));
}
else if (GameData.Instance != null && GameData.Instance.TotalTasks > 0 && GameData.Instance.CompletedTasks >= GameData.Instance.TotalTasks)
{
LastWinReason = $"★ Crewmates win! (Tasks)\n\nImpostors:\n" + string.Join("\n", imps.Select(p => p.Data.PlayerName));
}
else
{
LastWinReason = $"★ Impostors win! (Sabotage)\n\nImpostors:\n★" + string.Join("\n★", imps.Select(p => p.Data.PlayerName));
}
return true;
}
}
[HarmonyPatch(typeof(LogicGameFlowHnS), nameof(LogicGameFlowHnS.CheckEndCriteria))]
class HNSGameEndChecker
{
@@ -36,6 +68,7 @@ class HNSGameEndChecker
else return true;
}
}
[HarmonyPatch(typeof(ControllerManager), nameof(ControllerManager.Update))]
internal class ControllerManagerUpdatePatch
{
+38 -6
View File
@@ -10,17 +10,39 @@ namespace AmongUsRevamped;
[HarmonyPatch(typeof(AmongUsClient), nameof(AmongUsClient.OnGameJoined))]
internal static class OnGameJoinedPatch
{
public static bool WaitingForChat;
public static bool AutoStartCheck;
public static void Postfix(AmongUsClient __instance)
public static void Postfix()
{
if (!AmongUsClient.Instance.AmHost || !Main.AutoStart.Value) return;
if (!AmongUsClient.Instance.AmHost) return;
LateTask.Tasks.Clear();
WaitingForChat = false;
AutoStartCheck = false;
new LateTask(() =>
if (Main.AutoStart.Value)
{
AutoStartCheck = true;
}, Options.WaitAutoStart.GetFloat(), "AutoStartTimer");
LateTask.Tasks.Clear();
new LateTask(() =>
{
AutoStartCheck = true;
}, Options.WaitAutoStart.GetFloat(), "AutoStartTimer");
}
if (Options.AutoSendGameInfo.GetBool() && !string.IsNullOrEmpty(NormalGameEndChecker.LastWinReason))
{
WaitingForChat = true;
new LateTask(() =>
{
Utils.ShowLastResult();
}, 3f, "AutoSendGameInfo");
new LateTask(() =>
{
WaitingForChat = false;
}, 5.2f, "AutoSendGameInfo2");
}
}
}
@@ -80,4 +102,14 @@ class OnPlayerJoinedPatch
}
}
}
}
[HarmonyPatch(typeof(AmongUsClient), nameof(AmongUsClient.OnPlayerLeft))]
class OnPlayerLeftPatch
{
static void Prefix([HarmonyArgument(0)] ClientData client)
{
if (client?.Character == null) return;
FixedUpdateInGamePatch.ProcessedModerators.Remove(client.Character.PlayerId);
}
}
+3
View File
@@ -11,6 +11,9 @@ internal class ApplyCustomImpostorCount
{
if (!AmongUsClient.Instance.AmHost) return;
NormalGameEndChecker.imps.Clear();
NormalGameEndChecker.LastWinReason = "";
// Normal game = Impostor to prevent blocking task win. HNS = Crewmate to prevent Seeker detection range bugging.
if (Main.GM.Value)
{
+12 -3
View File
@@ -9,9 +9,17 @@ namespace AmongUsRevamped;
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.FixedUpdate))]
class FixedUpdateInGamePatch
{
public static readonly HashSet<byte> ProcessedModerators = new HashSet<byte>();
public static void Postfix(PlayerControl __instance)
{
if (__instance == null || __instance.PlayerId == 255) return;
if (Utils.IsPlayerModerator(__instance.Data.FriendCode) && !ProcessedModerators.Contains(__instance.PlayerId))
{
__instance.SetName($"★{__instance.Data.PlayerName}★");
ProcessedModerators.Add(__instance.PlayerId);
}
GameObject g = GameObject.Find("GameSettingsLabel");
@@ -64,9 +72,10 @@ class FixedUpdateInGamePatch
new LateTask(() =>
{
MessageWriter writer = AmongUsClient.Instance.StartEndGame();
writer.Write((byte)GameOverReason.ImpostorsByVote);
AmongUsClient.Instance.FinishEndGame(writer);
NormalGameEndChecker.LastWinReason = $"★ {__instance.Data.PlayerName} Wins! (Completed tasks first)";
MessageWriter writer = AmongUsClient.Instance.StartEndGame();
writer.Write((byte)GameOverReason.ImpostorsByVote);
AmongUsClient.Instance.FinishEndGame(writer);
}, 1f, "SpeedrunSetWinner");
}
}