mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-19 15:51:58 +00:00
343 lines
13 KiB
C#
343 lines
13 KiB
C#
using System;
|
|
#if !IL2CPP
|
|
using System.Collections;
|
|
using EHR.Patches;
|
|
#endif
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using AmongUs.Data;
|
|
using EHR.Roles;
|
|
using HarmonyLib;
|
|
using Hazel;
|
|
using InnerNet;
|
|
using UnityEngine;
|
|
|
|
namespace EHR;
|
|
|
|
[HarmonyPatch(typeof(ChatController), nameof(ChatController.Awake))]
|
|
static class ChatControllerAwakePatch
|
|
{
|
|
#if !IL2CPP
|
|
private static SpriteRenderer QuickChatIcon;
|
|
private static SpriteRenderer OpenBanMenuIcon;
|
|
private static SpriteRenderer OpenKeyboardIcon;
|
|
#endif
|
|
|
|
public static readonly Color32 DarkBackgroundColor = new(40, 40, 40, byte.MaxValue);
|
|
|
|
public static void Postfix(ChatController __instance)
|
|
{
|
|
if (AmongUsClient.Instance.AmHost && DataManager.Settings.Multiplayer.ChatMode == QuickChatModes.QuickChatOnly)
|
|
DataManager.Settings.Multiplayer.ChatMode = QuickChatModes.FreeChatOrQuickChat;
|
|
|
|
var chatBubble = __instance.chatBubblePool.Prefab as ChatBubble;
|
|
if (chatBubble == null) return;
|
|
|
|
chatBubble.TextArea.overrideColorTags = false;
|
|
|
|
if (Main.DarkTheme.Value)
|
|
{
|
|
chatBubble.TextArea.color = Color.white;
|
|
chatBubble.Background.color = new(0.1f, 0.1f, 0.1f, 1f);
|
|
|
|
#if !IL2CPP
|
|
__instance.freeChatField.background.color = DarkBackgroundColor;
|
|
|
|
if (!TextBoxPatch.IsInvalidCommand)
|
|
{
|
|
__instance.freeChatField.textArea.compoText.Color(Color.white);
|
|
__instance.freeChatField.textArea.outputText.color = Color.white;
|
|
}
|
|
|
|
__instance.quickChatField.background.color = DarkBackgroundColor;
|
|
__instance.quickChatField.text.color = Color.white;
|
|
|
|
Main.Instance.StartCoroutine(Coroutine());
|
|
#endif
|
|
}
|
|
else
|
|
__instance.freeChatField.textArea.outputText.color = Color.black;
|
|
#if !IL2CPP
|
|
return;
|
|
|
|
IEnumerator Coroutine()
|
|
{
|
|
while (__instance)
|
|
{
|
|
if (__instance.State is ChatControllerState.Open or ChatControllerState.Opening or ChatControllerState.Closing)
|
|
{
|
|
__instance.freeChatField.background.color = DarkBackgroundColor;
|
|
|
|
if (!QuickChatIcon) QuickChatIcon = GameObject.Find("QuickChatIcon")?.transform.GetComponent<SpriteRenderer>();
|
|
if (QuickChatIcon) QuickChatIcon.sprite = Utils.LoadSprite("EHR.Resources.Images.DarkQuickChat.png", 100f);
|
|
|
|
if (!OpenBanMenuIcon) OpenBanMenuIcon = GameObject.Find("OpenBanMenuIcon")?.transform.GetComponent<SpriteRenderer>();
|
|
if (OpenBanMenuIcon) OpenBanMenuIcon.sprite = Utils.LoadSprite("EHR.Resources.Images.DarkReport.png", 100f);
|
|
|
|
if (!OpenKeyboardIcon) OpenKeyboardIcon = GameObject.Find("OpenKeyboardIcon")?.transform.GetComponent<SpriteRenderer>();
|
|
if (OpenKeyboardIcon) OpenKeyboardIcon.sprite = Utils.LoadSprite("EHR.Resources.Images.DarkKeyboard.png", 100f);
|
|
}
|
|
|
|
if (!Main.DarkTheme.Value)
|
|
{
|
|
__instance.freeChatField.textArea.outputText.color = Color.black;
|
|
yield break;
|
|
}
|
|
|
|
yield return null;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
[HarmonyPatch(typeof(UrlFinder), nameof(UrlFinder.TryFindUrl))]
|
|
internal static class UrlFinderPatch
|
|
{
|
|
public static bool Prefix(ref bool __result)
|
|
{
|
|
__result = false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
[HarmonyPatch(typeof(ChatController), nameof(ChatController.ForceClosed))]
|
|
static class ChatControllerForceClosedPatch
|
|
{
|
|
public static bool Prefix()
|
|
{
|
|
return !Utils.TempReviveHostRunning || GameStates.IsEnded || !GameStates.InGame;
|
|
}
|
|
}
|
|
|
|
[HarmonyPatch(typeof(ChatController), nameof(ChatController.SetVisible))]
|
|
static class ChatControllerSetVisiblePatch
|
|
{
|
|
public static bool Prefix([HarmonyArgument(0)] bool visible)
|
|
{
|
|
return visible || !Utils.TempReviveHostRunning || GameStates.IsEnded || !GameStates.InGame;
|
|
}
|
|
}
|
|
|
|
public static class ChatManager
|
|
{
|
|
private const int MaxHistorySize = 20;
|
|
private static readonly List<string> ChatHistory = [];
|
|
|
|
public static void ResetHistory()
|
|
{
|
|
ChatHistory.Clear();
|
|
}
|
|
|
|
private static bool CheckCommand(ref string msg, string command, bool exact = true)
|
|
{
|
|
Utils.CheckServerCommand(ref msg, out _);
|
|
string[] comList = command.Split('|');
|
|
|
|
foreach (string str in comList)
|
|
{
|
|
if (exact)
|
|
{
|
|
if (msg == "/" + str) return true;
|
|
}
|
|
else
|
|
{
|
|
if (msg.StartsWith("/" + str))
|
|
{
|
|
msg = msg.Replace("/" + str, string.Empty);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private static bool CheckName(ref string msg, string command, bool exact = true)
|
|
{
|
|
string[] comList = command.Split('|');
|
|
|
|
foreach (string com in comList)
|
|
{
|
|
if (exact)
|
|
{
|
|
if (msg.Contains(com)) return true;
|
|
}
|
|
else
|
|
{
|
|
int index = msg.IndexOf(com, StringComparison.Ordinal);
|
|
|
|
if (index != -1)
|
|
{
|
|
msg = msg.Remove(index, com.Length);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static void SendMessage(PlayerControl player, string message)
|
|
{
|
|
string playername = player.GetNameWithRole();
|
|
string originalMessage = message.Trim();
|
|
message = message.ToLower().Trim();
|
|
|
|
if (!AmongUsClient.Instance.AmHost || !player.IsAlive() || Silencer.ForSilencer.Contains(player.PlayerId)) return;
|
|
|
|
int operate = message switch
|
|
{
|
|
{ } str when CheckCommand(ref str, "id|guesslist|gl编号|玩家编号|玩家id|id列表|玩家列表|列表|所有id|全部id|shoot|guess|bet|st|gs|bt|猜|赌|sp|jj|tl|trial|审判|判|审|xp|效颦|效|颦|sw|换票|换|swap", false) || CheckName(ref playername, "系统消息", false) => 1,
|
|
{ } str when CheckCommand(ref str, "up|ask|target|vote|chat|check|decree|assume|note|whisper|w|summon|fabricate|select|retribute|imitate|choose|forge|daybreak|jailtalk|jt|reroll", false) => 2,
|
|
{ } str when CheckCommand(ref str, "r|role|m|myrole|n|now") => 4,
|
|
_ => 3
|
|
};
|
|
|
|
switch (operate)
|
|
{
|
|
case 1: // Guessing Command & Such
|
|
{
|
|
Logger.Info("Special Command", "ChatManager");
|
|
if (player.AmOwner) break;
|
|
|
|
LateTask.New(() =>
|
|
{
|
|
if (!ChatCommands.LastSentCommand.ContainsKey(player.PlayerId))
|
|
{
|
|
GuessManager.GuesserMsg(player, message);
|
|
Logger.Info("Delayed Guess", "ChatManager");
|
|
}
|
|
else
|
|
Logger.Info("Delayed Guess was not necessary", "ChatManager");
|
|
}, 0.3f, "Trying Delayed Guess");
|
|
|
|
break;
|
|
}
|
|
case 2: // /up and role ability commands
|
|
case 4: // /r, /n, /m
|
|
{
|
|
Logger.Info($"Command: {message}", "ChatManager");
|
|
break;
|
|
}
|
|
case 3: // In Lobby & Evertything Else
|
|
{
|
|
AddChatHistory(player, originalMessage);
|
|
|
|
if (AmongUsClient.Instance.AmHost)
|
|
TemplateManager.SendTemplateForMessage(originalMessage, player.PlayerId);
|
|
|
|
if (GameStates.IsMeeting && player.Is(CustomRoles.Talkative))
|
|
Talkative.OnMessageSend(player);
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (Options.CurrentGameMode is CustomGameMode.FFA or CustomGameMode.SoloPVP or CustomGameMode.NaturalDisasters or CustomGameMode.Mingle or CustomGameMode.HideAndSeek && GameStates.InGame && !message.StartsWith('/'))
|
|
Main.EnumerateAlivePlayerControls().NotifyPlayers(string.Format(Utils.ColorString(Main.GameModeColors.GetValueOrDefault(Options.CurrentGameMode, new(1,1,1)), Translator.GetString("FFAChatMessageNotify")), player.PlayerId.ColoredPlayerName(), message));
|
|
}
|
|
|
|
public static void AddChatHistory(PlayerControl player, string message)
|
|
{
|
|
var chatEntry = $"{player.PlayerId}: {message}";
|
|
ChatHistory.Add(chatEntry);
|
|
if (ChatHistory.Count > MaxHistorySize) ChatHistory.RemoveAt(0);
|
|
}
|
|
|
|
private static readonly StringBuilder TitleText = new();
|
|
public static void SendPreviousMessagesToAll()
|
|
{
|
|
if (!AmongUsClient.Instance.AmHost || !HudManager.InstanceExists) return;
|
|
|
|
Logger.Info(" Sending Previous Messages To Everyone", "ChatManager");
|
|
|
|
var aapc = Main.CachedAlivePlayerControls();
|
|
if (aapc.Count == 0) return;
|
|
|
|
if (GameStates.CurrentServerType == GameStates.ServerType.Vanilla)
|
|
{
|
|
ClearChat();
|
|
|
|
TitleText.Clear();
|
|
ChatHistory.ForEach(x =>
|
|
{
|
|
string[] split = x.Split(':');
|
|
byte id = byte.Parse(split[0].Trim());
|
|
string msg = string.Join(':', split[1..]).Trim();
|
|
TitleText.Append(id.ColoredPlayerName())
|
|
.Append(':')
|
|
.Append(' ')
|
|
.AppendLine(msg);
|
|
});
|
|
LateTask.New(() => Utils.SendMessage("\n", title: TitleText.ToString().Trim()), 0.2f);
|
|
|
|
return;
|
|
}
|
|
|
|
string[] filtered = ChatHistory.Where(a => Utils.GetPlayerById(Convert.ToByte(a.Split(':')[0].Trim())).IsAlive()).ToArray();
|
|
ChatController chat = HudManager.Instance.Chat;
|
|
var writer = CustomRpcSender.Create("SendPreviousMessagesToAll", SendOption.Reliable);
|
|
var hasValue = false;
|
|
|
|
if (filtered.Length < 20) ClearChat();
|
|
|
|
foreach (string str in filtered)
|
|
{
|
|
string[] entryParts = str.Split(':');
|
|
string senderId = entryParts[0].Trim();
|
|
string senderMessage = entryParts[1].Trim();
|
|
for (var j = 2; j < entryParts.Length; j++) senderMessage += ':' + entryParts[j].Trim();
|
|
|
|
PlayerControl senderPlayer = Utils.GetPlayerById(Convert.ToByte(senderId));
|
|
if (!senderPlayer) continue;
|
|
|
|
chat.AddChat(senderPlayer, senderMessage);
|
|
SendRPC(writer, senderPlayer, senderMessage);
|
|
hasValue = true;
|
|
|
|
if (writer.stream.Length > 500)
|
|
{
|
|
writer.SendMessage();
|
|
writer = CustomRpcSender.Create("SendPreviousMessagesToAll", SendOption.Reliable);
|
|
hasValue = false;
|
|
}
|
|
}
|
|
|
|
hasValue |= ChatUpdatePatch.SendLastMessages(ref writer);
|
|
writer.SendMessage(!hasValue);
|
|
}
|
|
|
|
private static void SendRPC(CustomRpcSender writer, PlayerControl senderPlayer, string senderMessage, int targetClientId = -1)
|
|
{
|
|
if (GameStates.IsLobby && senderPlayer.AmOwner)
|
|
senderMessage = senderMessage.Insert(0, new('\n', PlayerControl.LocalPlayer.name.Count(x => x == '\n')));
|
|
|
|
writer.AutoStartRpc(senderPlayer.NetId, RpcCalls.SendChat, targetClientId)
|
|
.Write(senderMessage)
|
|
.EndRpc();
|
|
}
|
|
|
|
// Base from https://github.com/Rabek009/MoreGamemodes/blob/master/Modules/Utils.cs
|
|
public static void ClearChat(params IReadOnlyList<PlayerControl> targets)
|
|
{
|
|
if (!AmongUsClient.Instance.AmHost) return;
|
|
PlayerControl player = Main.AllAlivePlayerControlsCount == 0 ? PlayerControl.LocalPlayer : Main.CachedAlivePlayerControls().MinBy(x => x.PlayerId);
|
|
if (!player) return;
|
|
if (targets == null || targets.Count == 0 || targets.Count >= Main.AllAlivePlayerControlsCount) SendEmptyMessage(null);
|
|
else targets.Do(SendEmptyMessage);
|
|
return;
|
|
|
|
void SendEmptyMessage(PlayerControl receiver)
|
|
{
|
|
bool toEveryone = !receiver;
|
|
bool toLocalPlayer = !toEveryone && receiver.AmOwner;
|
|
if (HudManager.InstanceExists && (toLocalPlayer || toEveryone)) HudManager.Instance.Chat.AddChat(player, "<size=32767>.");
|
|
if (toLocalPlayer) return;
|
|
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(player.NetId, (byte)RpcCalls.SendChat, SendOption.Reliable, toEveryone ? -1 : receiver.OwnerId);
|
|
writer.Write("<size=32767>.");
|
|
AmongUsClient.Instance.FinishRpcImmediately(writer);
|
|
}
|
|
}
|
|
}
|