mirror of
https://github.com/ApeMV/AmongUsRevamped.git
synced 2026-10-20 01:46:28 +00:00
778 lines
35 KiB
C#
778 lines
35 KiB
C#
using Hazel;
|
|
using InnerNet;
|
|
using System;
|
|
using System.IO;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using TMPro;
|
|
|
|
namespace AmongUsRevamped;
|
|
|
|
[HarmonyPatch(typeof(ChatController), nameof(ChatController.Update))]
|
|
internal static class ChatControllerUpdatePatch
|
|
{
|
|
|
|
public static void Postfix(ChatController __instance)
|
|
{
|
|
if (!__instance||!__instance.freeChatField||!__instance.freeChatField.textArea||!__instance.freeChatField.background||__instance.freeChatField.textArea.compoText == null||!__instance.freeChatField.textArea.outputText) return;
|
|
if (!__instance.quickChatField||!__instance.quickChatField.background||__instance.quickChatField.text==null) return;
|
|
|
|
if (Main.DarkTheme.Value)
|
|
{
|
|
__instance.freeChatField.background.color = new Color32(40, 40, 40, byte.MaxValue);
|
|
__instance.freeChatField.textArea.compoText.Color(Color.white);
|
|
__instance.freeChatField.textArea.outputText.color = Color.white;
|
|
|
|
__instance.quickChatField.background.color = new Color32(40, 40, 40, byte.MaxValue);
|
|
__instance.quickChatField.text.color = Color.white;
|
|
}
|
|
else
|
|
{
|
|
__instance.freeChatField.background.color = Color.white;
|
|
__instance.freeChatField.textArea.compoText.Color(Color.black);
|
|
__instance.freeChatField.textArea.outputText.color = Color.black;
|
|
|
|
__instance.quickChatField.background.color = Color.white;
|
|
__instance.quickChatField.text.color = Color.black;
|
|
}
|
|
}
|
|
}
|
|
|
|
[HarmonyPatch(typeof(ChatBubble), nameof(ChatBubble.SetName))]
|
|
internal static class ChatBubbleSetNamePatch
|
|
{
|
|
public static void Postfix(ChatBubble __instance, [HarmonyArgument(2)] bool voted)
|
|
{
|
|
if (!__instance||!__instance.playerInfo||!__instance.playerInfo.Object||!__instance.playerInfo.Object.Data||!__instance.TextArea||!__instance.Background) return;
|
|
|
|
PlayerControl target = __instance.playerInfo.Object;
|
|
|
|
if (Main.DarkTheme.Value)
|
|
{
|
|
__instance.Background.color = new(0.1f, 0.1f, 0.1f, 1f);
|
|
__instance.TextArea.color = Color.white;
|
|
|
|
if (__instance.playerInfo.Object.Data.IsDead && Utils.InGame) __instance.Background.color = new(0.1f, 0.1f, 0.1f, 0.7f);
|
|
}
|
|
}
|
|
}
|
|
|
|
[HarmonyPatch(typeof(ChatController), nameof(ChatController.SendChat))]
|
|
internal static class SendChatPatch
|
|
{
|
|
public static string ConvertNum(string input)
|
|
{
|
|
if (string.IsNullOrEmpty(input)) return input;
|
|
int digitCount = 0;
|
|
|
|
for (int i = 0; i < input.Length; i++)
|
|
{
|
|
if (char.IsDigit(input[i]) && ++digitCount > 5)
|
|
{
|
|
var sb = new System.Text.StringBuilder(input.Length);
|
|
|
|
foreach (char c in input)
|
|
{
|
|
if (char.IsDigit(c))
|
|
sb.Append(Main.CircledDigits[c - '0']);
|
|
else
|
|
sb.Append(c);
|
|
}
|
|
return sb.ToString();
|
|
}
|
|
}
|
|
return input;
|
|
}
|
|
|
|
public static bool Prefix(ChatController __instance)
|
|
{
|
|
string msgtext = __instance.freeChatField.textArea.text.Trim();
|
|
string text = msgtext.ToLower();
|
|
string converted = ConvertNum(msgtext);
|
|
|
|
if (!AmongUsClient.Instance.AmHost) return true;
|
|
|
|
if (text == "/reload")
|
|
{
|
|
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, $"{Translator.Get("translationReloaded")}");
|
|
Translator.Reload();
|
|
__instance.freeChatField.textArea.Clear();
|
|
__instance.freeChatField.textArea.SetText(string.Empty);
|
|
return false;
|
|
}
|
|
|
|
if (text == "/dump")
|
|
{
|
|
Utils.DumpLog();
|
|
__instance.freeChatField.textArea.Clear();
|
|
__instance.freeChatField.textArea.SetText(string.Empty);
|
|
return false;
|
|
}
|
|
if (text == "/help")
|
|
{
|
|
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, $"{Translator.Get("allCommandsFull")}");
|
|
__instance.freeChatField.textArea.Clear();
|
|
__instance.freeChatField.textArea.SetText(string.Empty);
|
|
return false;
|
|
}
|
|
|
|
if (text == "/s" || text == "/start")
|
|
{
|
|
GameStartManager.Instance.BeginGame();
|
|
__instance.freeChatField.textArea.Clear();
|
|
__instance.freeChatField.textArea.SetText(string.Empty);
|
|
return false;
|
|
}
|
|
|
|
if (text == "/eg" || text == "/endgame")
|
|
{
|
|
__instance.freeChatField.textArea.Clear();
|
|
__instance.freeChatField.textArea.SetText(string.Empty);
|
|
|
|
if (!Utils.InGame) return false;
|
|
MessageWriter writer = AmongUsClient.Instance.StartEndGame();
|
|
writer.Write((byte)GameOverReason.ImpostorDisconnect);
|
|
AmongUsClient.Instance.FinishEndGame(writer);
|
|
return false;
|
|
}
|
|
|
|
if (text == "/em" || text == "/endmeeting")
|
|
{
|
|
__instance.freeChatField.textArea.Clear();
|
|
__instance.freeChatField.textArea.SetText(string.Empty);
|
|
|
|
if ( !Utils.InGame || !Utils.IsMeeting) return false;
|
|
MeetingHud.Instance.RpcClose();
|
|
return false;
|
|
}
|
|
|
|
if (text.StartsWith("/vip "))
|
|
{
|
|
PlayerControl target = null;
|
|
string arg = text.Substring(5).Trim();
|
|
|
|
foreach (PlayerControl p in PlayerControl.AllPlayerControls)
|
|
{
|
|
if (p.Data == null || p == PlayerControl.LocalPlayer) continue;
|
|
|
|
if (p.Data.PlayerName.Equals(arg, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
target = p;
|
|
break;
|
|
}
|
|
}
|
|
if (target == null)
|
|
{
|
|
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, Translator.Get("permFail", arg));
|
|
}
|
|
else
|
|
{
|
|
File.AppendAllText(BanManager.VipListPath, "\n" + target.Data.FriendCode);
|
|
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, Translator.Get("vipAdd", target.Data.PlayerName));
|
|
}
|
|
|
|
__instance.freeChatField.textArea.Clear();
|
|
__instance.freeChatField.textArea.SetText(string.Empty);
|
|
return false;
|
|
}
|
|
|
|
if (text.StartsWith("/moderator "))
|
|
{
|
|
PlayerControl target = null;
|
|
string arg = text.Substring(11).Trim();
|
|
|
|
foreach (PlayerControl p in PlayerControl.AllPlayerControls)
|
|
{
|
|
if (p.Data == null || p == PlayerControl.LocalPlayer) continue;
|
|
|
|
if (p.Data.PlayerName.Equals(arg, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
target = p;
|
|
break;
|
|
}
|
|
}
|
|
if (target == null)
|
|
{
|
|
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, Translator.Get("permFail", arg));
|
|
}
|
|
else
|
|
{
|
|
File.AppendAllText(BanManager.ModeratorListPath, "\n" + target.Data.FriendCode);
|
|
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, Translator.Get("moderatorAdd", target.Data.PlayerName));
|
|
}
|
|
|
|
__instance.freeChatField.textArea.Clear();
|
|
__instance.freeChatField.textArea.SetText(string.Empty);
|
|
return false;
|
|
}
|
|
|
|
if (text.StartsWith("/admin "))
|
|
{
|
|
PlayerControl target = null;
|
|
string arg = text.Substring(7).Trim();
|
|
|
|
foreach (PlayerControl p in PlayerControl.AllPlayerControls)
|
|
{
|
|
if (p.Data == null || p == PlayerControl.LocalPlayer) continue;
|
|
|
|
if (p.Data.PlayerName.Equals(arg, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
target = p;
|
|
break;
|
|
}
|
|
}
|
|
if (target == null)
|
|
{
|
|
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, Translator.Get("permFail", arg));
|
|
}
|
|
else
|
|
{
|
|
File.AppendAllText(BanManager.AdminListPath, "\n" + target.Data.FriendCode);
|
|
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, Translator.Get("adminAdd", target.Data.PlayerName));
|
|
}
|
|
|
|
__instance.freeChatField.textArea.Clear();
|
|
__instance.freeChatField.textArea.SetText(string.Empty);
|
|
return false;
|
|
}
|
|
|
|
if (text.StartsWith("/removevip "))
|
|
{
|
|
PlayerControl target = null;
|
|
string arg = text.Substring(11).Trim();
|
|
|
|
foreach (PlayerControl p in PlayerControl.AllPlayerControls)
|
|
{
|
|
if (p.Data == null || p == PlayerControl.LocalPlayer) continue;
|
|
|
|
if (p.Data.PlayerName.Equals(arg, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
target = p;
|
|
break;
|
|
}
|
|
}
|
|
if (target == null)
|
|
{
|
|
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, Translator.Get("permFail", arg));
|
|
}
|
|
else
|
|
{
|
|
File.WriteAllLines(BanManager.VipListPath, File.ReadAllLines(BanManager.VipListPath).Where(x => x.Trim() != target.Data.FriendCode));
|
|
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, Translator.Get("vipRemove", target.Data.PlayerName));
|
|
}
|
|
__instance.freeChatField.textArea.Clear();
|
|
__instance.freeChatField.textArea.SetText(string.Empty);
|
|
return false;
|
|
}
|
|
|
|
if (text.StartsWith("/removemoderator "))
|
|
{
|
|
PlayerControl target = null;
|
|
string arg = text.Substring(17).Trim();
|
|
|
|
foreach (PlayerControl p in PlayerControl.AllPlayerControls)
|
|
{
|
|
if (p.Data == null || p == PlayerControl.LocalPlayer) continue;
|
|
|
|
if (p.Data.PlayerName.Equals(arg, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
target = p;
|
|
break;
|
|
}
|
|
}
|
|
if (target == null)
|
|
{
|
|
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, Translator.Get("permFail", arg));
|
|
}
|
|
else
|
|
{
|
|
File.WriteAllLines(BanManager.ModeratorListPath, File.ReadAllLines(BanManager.ModeratorListPath).Where(x => x.Trim() != target.Data.FriendCode));
|
|
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, Translator.Get("moderatorRemove", target.Data.PlayerName));
|
|
}
|
|
__instance.freeChatField.textArea.Clear();
|
|
__instance.freeChatField.textArea.SetText(string.Empty);
|
|
return false;
|
|
}
|
|
|
|
if (text.StartsWith("/removeadmin "))
|
|
{
|
|
PlayerControl target = null;
|
|
string arg = text.Substring(13).Trim();
|
|
|
|
foreach (PlayerControl p in PlayerControl.AllPlayerControls)
|
|
{
|
|
if (p.Data == null || p == PlayerControl.LocalPlayer) continue;
|
|
|
|
if (p.Data.PlayerName.Equals(arg, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
target = p;
|
|
break;
|
|
}
|
|
}
|
|
if (target == null)
|
|
{
|
|
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, Translator.Get("permFail", arg));
|
|
}
|
|
else
|
|
{
|
|
File.WriteAllLines(BanManager.AdminListPath, File.ReadAllLines(BanManager.AdminListPath).Where(x => x.Trim() != target.Data.FriendCode));
|
|
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, Translator.Get("adminRemove", target.Data.PlayerName));
|
|
}
|
|
__instance.freeChatField.textArea.Clear();
|
|
__instance.freeChatField.textArea.SetText(string.Empty);
|
|
return false;
|
|
}
|
|
|
|
if (__instance.timeSinceLastMessage < 3f || OnGameJoinedPatch.WaitingForChat || AbilityManagement.HandlingRoleMessages) return false;
|
|
|
|
if (text == "/l" || text == "/lastgame")
|
|
{
|
|
if (string.IsNullOrEmpty(NormalGameEndChecker.LastWinReason) || Utils.InGame) return false;
|
|
Utils.ChatCommand(__instance, $"{NormalGameEndChecker.LastWinReason}", "", false);
|
|
return false;
|
|
}
|
|
if (text == "/r jester"){
|
|
Utils.ChatCommand(__instance, "Jester:\n\nThe Jester is a Crewmate who can also win alone by getting voted.", "", false);
|
|
return false;}
|
|
|
|
if (text == "/r mayor"){
|
|
Utils.ChatCommand(__instance, $"Mayor:\n\nThe Mayor is a Crewmate with {Options.ExtraVotesCrewmate.GetInt()} additional vote(s). Use them wisely.", "", false);
|
|
return false;}
|
|
|
|
if (text == "/r tyrant"){
|
|
Utils.ChatCommand(__instance, $"Tyrant:\n\nThe Tyrant is an Impostor with {Options.ExtraVotesImpostor.GetInt()} additional vote(s). Use them wisely.", "", false);
|
|
return false;}
|
|
|
|
if (text == "/r workhorse"){
|
|
Utils.ChatCommand(__instance, $"Workhorse:\n\nThe Workhorse gains {Options.ExtraVotesPerTask.GetInt()} additional vote(s) per completed task. Votes are rounded down.", "", false);
|
|
return false;}
|
|
|
|
if (text == "/r stealer"){
|
|
Utils.ChatCommand(__instance, $"Stealer:\n\nThe Stealer gains {Options.ExtraVotesPerKill.GetInt()} additional vote(s) per killed player. Votes are rounded down.", "", false);
|
|
return false;}
|
|
|
|
if (text == "/r juggernaut"){
|
|
Utils.ChatCommand(__instance, $"Juggernaut:\n\nThe Impostors instantly win if the Juggernaut gains {Options.KillsNeededForJuggernaut.GetInt()} kills.", "", false);
|
|
return false;}
|
|
|
|
if (text == "/r tasker"){
|
|
Utils.ChatCommand(__instance, "Tasker:\n\nThe Crewmates win if the Tasker completes tasks and is alive. The Tasker has more tasks.", "", false);
|
|
return false;}
|
|
|
|
if (text == "/aur" || text == "/socials")
|
|
{
|
|
Utils.ChatCommand(__instance, "AUR socials:\n\ng i t h u b . c o m /\nApeMV/AmongUsRevamped\n\nd i s c o r d . g g /\n83Zhzhyhya", "", false);
|
|
return false;
|
|
}
|
|
|
|
if (text == "/0kc" || text == "/0killcooldown")
|
|
{
|
|
Utils.ChatCommand(__instance, "0 Kill Cooldown:\n\nImpostors have no kill cooldown, Crewmates have low tasks\nThink fast and pay attention!", "", false);
|
|
return false;
|
|
}
|
|
|
|
if (text == "/sns" || text == "/shiftandseek")
|
|
{
|
|
if (Options.MisfiresToSuicide.GetInt() == 1 || Options.CantKillTime.GetInt() == 0)
|
|
{
|
|
Utils.ChatCommand(__instance, "Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nEmergency Meetings = 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);
|
|
}
|
|
else
|
|
{
|
|
Utils.ChatCommand(__instance, "Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nEmergency Meetings = Off", $"Crew wins by tasks/surviving {Options.CrewAutoWinsGameAfter.GetInt()}s\nImp wins by killing\nOne wrong kill = Can't kill for {Options.CantKillTime.GetInt()}s\n{Options.MisfiresToSuicide.GetInt()} wrong kills = suicide", true);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
if (text == "/sr" || text == "/speedrun")
|
|
{
|
|
Utils.ChatCommand(__instance, $"Speedrun:\n\nEveryone is a crewmate. The 1st player to finish tasks wins the game. Game auto ends after {Options.GameAutoEndsAfter.GetInt()}s", "", false);
|
|
return false;
|
|
}
|
|
|
|
if (text == "/r" || text == "/roles")
|
|
{
|
|
switch (Options.Gamemode.GetValue())
|
|
{
|
|
case 0:
|
|
AbilityManagement.SendRoleList(__instance, AbilityManagement.RoleList(), false);
|
|
break;
|
|
|
|
case 1:
|
|
Utils.ChatCommand(__instance, "0 Kill Cooldown:\n\nImpostors have no kill cooldown, Crewmates have low tasks\nThink fast and pay attention!", "", false);
|
|
break;
|
|
|
|
case 2:
|
|
if (Options.MisfiresToSuicide.GetInt() == 1 || Options.CantKillTime.GetInt() == 0)
|
|
{
|
|
Utils.ChatCommand(__instance, "Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nEmergency Meetings = 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);
|
|
}
|
|
else
|
|
{
|
|
Utils.ChatCommand(__instance, "Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nEmergency Meetings = Off", $"Crew wins by tasks/surviving {Options.CrewAutoWinsGameAfter.GetInt()}s\nImp wins by killing\nOne wrong kill = Can't kill for {Options.CantKillTime.GetInt()}s\n{Options.MisfiresToSuicide.GetInt()} wrong kills = suicide", true);
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
Utils.ChatCommand(__instance, $"Speedrun:\n\nEveryone is a crewmate. The 1st player to finish tasks wins the game. Game auto ends after {Options.GameAutoEndsAfter.GetInt()}s", "", false);
|
|
break;
|
|
|
|
}
|
|
__instance.timeSinceLastMessage = 0.8f;
|
|
__instance.freeChatField.textArea.Clear();
|
|
__instance.freeChatField.textArea.SetText(string.Empty);
|
|
return false;
|
|
}
|
|
|
|
if (text.StartsWith("/t "))
|
|
{
|
|
string templateName = text[3..].Trim().ToLower();
|
|
|
|
if (BanManager.Templates.TryGetValue(templateName, out string templateMessage))
|
|
{
|
|
if (templateMessage.Length < 121)
|
|
{
|
|
Utils.ChatCommand(__instance, BanManager.CheckTemplate(templateMessage), "", false);
|
|
}
|
|
else
|
|
{
|
|
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, Translator.Get("tooLongTemplate"));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Logger.Info($"Could not find template '{templateName}'", "TemplateManager");
|
|
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, $"Template '{templateName}' not found.");
|
|
}
|
|
__instance.freeChatField.textArea.Clear();
|
|
__instance.freeChatField.textArea.SetText(string.Empty);
|
|
return false;
|
|
}
|
|
|
|
bool col1 = text.StartsWith("/col ");
|
|
bool col2 = text.StartsWith("/color ");
|
|
bool col3 = text.StartsWith("/colour ");
|
|
|
|
if (col1 || col2 || col3)
|
|
{
|
|
string argCol = text.Substring(col1 ? 5 : col2 ? 7 : col3 ? 8 : 0).Trim();
|
|
|
|
if (Utils.TryGetColorId(argCol, out byte colId) && (col1 || col2 || col3))
|
|
{
|
|
PlayerControl.LocalPlayer.RpcSetColor(colId);
|
|
__instance.freeChatField.textArea.Clear();
|
|
__instance.freeChatField.textArea.SetText(string.Empty);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
else
|
|
{
|
|
|
|
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)
|
|
{
|
|
|
|
//__instance.freeChatField.textArea.SetText(converted);
|
|
//Utils.ChatCommand(__instance, $"{converted}", "", false);
|
|
Logger.Info($" {PlayerControl.LocalPlayer.Data.PlayerName}: {msgtext}", "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 || 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)
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.HandleRpc))]
|
|
public static class RPCHandlerPatch
|
|
{
|
|
public static void Prefix(PlayerControl __instance, [HarmonyArgument(0)] byte callId, [HarmonyArgument(1)] MessageReader reader)
|
|
{
|
|
if (!AmongUsClient.Instance.AmHost) return;
|
|
|
|
var rpcType = (RpcCalls)callId;
|
|
MessageReader subReader = MessageReader.Get(reader);
|
|
|
|
switch (rpcType)
|
|
{
|
|
case RpcCalls.SendChat:
|
|
{
|
|
string msgtext = subReader.ReadString();
|
|
string text = msgtext.ToLower();
|
|
|
|
Logger.Info($" {__instance.Data.PlayerName}: {msgtext}", "SendChat");
|
|
|
|
string[] keywords = Options.AutoKickStartStrength.GetBool() ? new[] { "start", "begin", "commence" } : new[] { "start", "begin", "commence", "s t a r t", "go" };
|
|
|
|
bool c = false;
|
|
|
|
if (Options.AutoKickStartStrength.GetBool())
|
|
{
|
|
c = keywords.Any(k => text.Contains(k));
|
|
}
|
|
else
|
|
{
|
|
c = keywords.Any(k => text == k);
|
|
}
|
|
|
|
if (c && Utils.CheckAccessLevel(__instance.Data.FriendCode) < 1 && Options.AutoKickStart.GetBool() && !Utils.InGame)
|
|
{
|
|
int clientId = __instance.Data.ClientId;
|
|
|
|
if (!Main.SayStartTimes.ContainsKey(clientId))
|
|
Main.SayStartTimes.Add(clientId, 0);
|
|
Main.SayStartTimes[clientId]++;
|
|
|
|
if (Main.SayStartTimes[clientId] >= Options.AutoKickStartTimes.GetInt())
|
|
{
|
|
bool sBan = Options.AutoKickStartAsBan.GetBool();
|
|
AmongUsClient.Instance.KickPlayer(clientId, sBan);
|
|
Logger.Info($" {__instance.Data.PlayerName} was {(sBan ? "banned" : "kicked")} for saying start", "KickAnnoyingKids");
|
|
Logger.SendInGame($" {__instance.Data.PlayerName} was {(sBan ? "banned" : "kicked")} for saying start");
|
|
}
|
|
}
|
|
|
|
BanManager.IsWordBanned(__instance, text);
|
|
|
|
bool col1 = text.StartsWith("/col ");
|
|
bool col2 = text.StartsWith("/color ");
|
|
bool col3 = text.StartsWith("/colour ");
|
|
|
|
if ((col1 || col2 || col3) && !Utils.InGame)
|
|
{
|
|
string argCol = text.Substring(col1 ? 5 : col2 ? 7 : col3 ? 8 : 0).Trim();
|
|
|
|
if (Utils.TryGetColorId(argCol, out byte colId))
|
|
{
|
|
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) >= Options.SlashColorCmd.GetValue())
|
|
{
|
|
if (colId > 17 && !Options.AllowFortegreen.GetBool()) return;
|
|
__instance.RpcSetColor(colId);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Banning works by name and color. Commands are separated incase someone has a color as their name
|
|
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)
|
|
{
|
|
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) >= Options.SlashKickCmd.GetValue())
|
|
{
|
|
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 || p == PlayerControl.LocalPlayer || Utils.CheckAccessLevel(p.Data.FriendCode) >= 1) 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 (banLog && Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashBanCmd.GetValue()) return;
|
|
|
|
if (target != null)
|
|
{
|
|
AmongUsClient.Instance.KickPlayer(target.Data.ClientId, isBan || isColorBan);
|
|
Logger.Info($" {__instance.Data.PlayerName} {(banLog ? "banned" : "kicked")} {target.Data.PlayerName}", "Kick&BanCommand");
|
|
}
|
|
}
|
|
}
|
|
|
|
if (AbilityManagement.HandlingRoleMessages || OnGameJoinedPatch.WaitingForChat || GameStartManagerUpdatePatch.CountingDown) return;
|
|
|
|
if (text == "/eg" || text == "/endgame")
|
|
{
|
|
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashStartAndEndGameCmd.GetValue()) return;
|
|
MessageWriter writer = AmongUsClient.Instance.StartEndGame();
|
|
writer.Write((byte)GameOverReason.ImpostorDisconnect);
|
|
AmongUsClient.Instance.FinishEndGame(writer);
|
|
}
|
|
|
|
if (text == "/em" || text == "/endmeeting")
|
|
{
|
|
if (Utils.IsMeeting)
|
|
{
|
|
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashEndMeetingCmd.GetValue()) return;
|
|
MeetingHud.Instance.RpcClose();
|
|
}
|
|
}
|
|
|
|
if (text == "/s" || text == "/start")
|
|
{
|
|
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashStartAndEndGameCmd.GetValue()) return;
|
|
GameStartManager.Instance.BeginGame();
|
|
}
|
|
|
|
if (text == "/l" || text == "/lastgame")
|
|
{
|
|
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashLastGameCmd.GetValue()) return;
|
|
if (string.IsNullOrEmpty(NormalGameEndChecker.LastWinReason) || Utils.InGame) return;
|
|
Utils.ModeratorChatCommand($"{NormalGameEndChecker.LastWinReason}", "", false);
|
|
}
|
|
|
|
if (text == "/aur" || text == "/socials")
|
|
{
|
|
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashLastGameCmd.GetValue()) return;
|
|
Utils.ModeratorChatCommand("AUR socials:\n\ng i t h u b . c o m /\nApeMV/AmongUsRevamped\n\nd i s c o r d . g g /\n83Zhzhyhya", "", false);
|
|
}
|
|
|
|
if (text == "/0kc" || text == "/0killcooldown")
|
|
{
|
|
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashRolesAndGamemodeCmd.GetValue()) return;
|
|
Utils.ModeratorChatCommand("0 Kill Cooldown:\n\nImpostors have no kill cooldown, Crewmates have low tasks\nThink fast and pay attention!", "", false);
|
|
}
|
|
if (text == "/sns" || text == "/shiftandseek")
|
|
{
|
|
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashRolesAndGamemodeCmd.GetValue()) return;
|
|
|
|
if (Options.MisfiresToSuicide.GetInt() == 1 || Options.CantKillTime.GetInt() == 0)
|
|
{
|
|
Utils.ModeratorChatCommand("Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nEmergency Meetings = 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);
|
|
}
|
|
else
|
|
{
|
|
Utils.ModeratorChatCommand("Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nEmergency Meetings = Off", $"Crew wins by tasks/surviving {Options.CrewAutoWinsGameAfter.GetInt()}s\nImp wins by killing\nOne wrong kill = Can't kill for {Options.CantKillTime.GetInt()}s\n{Options.MisfiresToSuicide.GetInt()} wrong kills = suicide", true);
|
|
}
|
|
}
|
|
|
|
if (text == "/sr" || text == "/speedrun")
|
|
{
|
|
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashRolesAndGamemodeCmd.GetValue()) return;
|
|
Utils.ModeratorChatCommand($"Speedrun:\n\nEveryone is a crewmate. The 1st player to finish tasks wins the game. Game auto ends after {Options.GameAutoEndsAfter.GetInt()}s", "", false);
|
|
}
|
|
|
|
if (text == "/r" || text == "/roles")
|
|
{
|
|
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashRolesAndGamemodeCmd.GetValue()) return;
|
|
switch (Options.Gamemode.GetValue())
|
|
{
|
|
case 0:
|
|
AbilityManagement.SendRoleList(DestroyableSingleton<HudManager>.Instance.Chat, AbilityManagement.RoleList(), true);
|
|
break;
|
|
|
|
case 1:
|
|
Utils.ModeratorChatCommand("0 Kill Cooldown:\n\nImpostors have no kill cooldown, Crewmates have low tasks\nThink fast and pay attention!", "", false);
|
|
break;
|
|
|
|
case 2:
|
|
if (Options.MisfiresToSuicide.GetInt() == 1 || Options.CantKillTime.GetInt() == 0)
|
|
{
|
|
Utils.ModeratorChatCommand("Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nEmergency Meetings = 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);
|
|
}
|
|
else
|
|
{
|
|
Utils.ModeratorChatCommand("Shift and Seek:\n\nImpostors can only kill someone while shapeshifted as them\nEmergency Meetings = Off", $"Crew wins by tasks/surviving {Options.CrewAutoWinsGameAfter.GetInt()}s\nImp wins by killing\nOne wrong kill = Can't kill for {Options.CantKillTime.GetInt()}s\n{Options.MisfiresToSuicide.GetInt()} wrong kills = suicide", true);
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
Utils.ModeratorChatCommand($"Speedrun:\n\nEveryone is a crewmate. The 1st player to finish tasks wins the game. Game auto ends after {Options.GameAutoEndsAfter.GetInt()}s", "", false);
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
if (Utils.CheckAccessLevel(__instance.Data.FriendCode) < Options.SlashRolesAndGamemodeCmd.GetValue()) return;
|
|
|
|
if (text == "/r jester"){
|
|
Utils.ModeratorChatCommand("Jester:\n\nThe Jester is a Crewmate who can also win alone by getting voted.", "", false);}
|
|
|
|
if (text == "/r mayor"){
|
|
Utils.ModeratorChatCommand($"Mayor:\n\nThe Mayor is a Crewmate with {Options.ExtraVotesCrewmate.GetInt()} additional vote(s). Use them wisely.", "", false);}
|
|
|
|
if (text == "/r tyrant"){
|
|
Utils.ModeratorChatCommand($"Tyrant:\n\nThe Tyrant is an Impostor with {Options.ExtraVotesImpostor.GetInt()} additional vote(s). Use them wisely.", "", false);}
|
|
|
|
if (text == "/r workhorse"){
|
|
Utils.ModeratorChatCommand($"Workhorse:\n\nThe Workhorse gains {Options.ExtraVotesPerTask.GetInt()} additional vote(s) per completed task. Votes are rounded down.", "", false);}
|
|
|
|
if (text == "/r stealer"){
|
|
Utils.ModeratorChatCommand($"Stealer:\n\nThe Stealer gains {Options.ExtraVotesPerKill.GetInt()} additional vote(s) per killed player. Votes are rounded down.", "", false);}
|
|
|
|
if (text == "/r juggernaut"){
|
|
Utils.ModeratorChatCommand($"Juggernaut:\n\nThe Impostors instantly win if the Juggernaut gains {Options.KillsNeededForJuggernaut.GetInt()} kills.", "", false);}
|
|
|
|
if (text == "/r tasker"){
|
|
Utils.ModeratorChatCommand("Tasker:\n\nThe Crewmates win if the Tasker completes tasks and is alive. The Tasker has more tasks.", "", false);}
|
|
|
|
if (text.StartsWith("/t "))
|
|
{
|
|
string templateName = text[3..].Trim().ToLower();
|
|
|
|
if (BanManager.Templates.TryGetValue(templateName, out string templateMessage))
|
|
{
|
|
if (templateMessage.Length < 121)
|
|
{
|
|
Utils.ModeratorChatCommand(BanManager.CheckTemplate(templateMessage), "", false);
|
|
}
|
|
else
|
|
{
|
|
HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, Translator.Get("tooLongTemplate"));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} |