using UnityEngine; using TMPro; using CSNetwork.GPDataType; using System.Collections.Generic; using BrewMonster.Network; using BrewMonster.UI; using CSNetwork; namespace BrewMonster.Scripts.ChatUI { public class ChatInputHandler : MonoBehaviour { public TMP_InputField inputField; private const int MAX_HISTORY = 10; private struct ChatMsg { public ChatChannel channel; public float time; public string msg; public int pack; public int slot; } private List m_vecHistory = new(); private int m_nCurHistory = 0; private float m_dwTickFarCry = 0; private float m_dwTickFarCry2 = 0; private void Start() { inputField.onSubmit.AddListener(OnSubmit); } private void OnSubmit(string text) { if (string.IsNullOrWhiteSpace(text)) return; OnCommand_speak(text); } // ===================================================== // PORT C++: CDlgChat::OnCommand_speak // ===================================================== private void OnCommand_speak(string text) { string strText = text.Trim(); if (strText.Length <= 0) { //ChangeFocus(); return; } int nPack = -1; int nSlot = -1; FilterBadWords(ref strText); if (HandleDebugCommand(strText)) return; float now = Time.time; if (!CheckFarCryRequirement(strText, now)) return; if (!CheckSuperFarCryRequirement(strText, now)) return; if (!CheckSpamProtection(strText, now)) return; ChatChannel resolvedChannel = ParseAndSendMessage(strText, nPack, nSlot); SaveHistory(resolvedChannel, strText, nPack, nSlot, now); //ChangeFocus(); } // ===================================================== // DEBUG COMMAND // ===================================================== private bool HandleDebugCommand(string text) { if (text == "##debug") { Debug.Log("Toggle debug console"); return true; } return false; } // ===================================================== // FARCRY CHECK (!@) // ===================================================== private bool CheckFarCryRequirement(string text, float now) { if (text.StartsWith("!@")) { int itemNum = GetPlayerItemCount(12979) + GetPlayerItemCount(36092); if (itemNum < 1 || GetPlayerLevel() < 5) { AddChatMessage(CECUIManager.Instance.GameUI.GetStringFromTable(731), ChatChannel.GP_CHAT_MISC); return false; } if (now - m_dwTickFarCry <= 1f) { AddChatMessage(CECUIManager.Instance.GameUI.GetStringFromTable(730), ChatChannel.GP_CHAT_MISC); return false; } } return true; } // ===================================================== // SUPER FARCRY (!#) // ===================================================== private bool CheckSuperFarCryRequirement(string text, float now) { if (text.StartsWith("!#")) { int itemNum = GetPlayerItemCount(27728) + GetPlayerItemCount(27729); if (itemNum < 1) { AddChatMessage(CECUIManager.Instance.GameUI.GetStringFromTable(8531), ChatChannel.GP_CHAT_MISC); return false; } if (now - m_dwTickFarCry2 <= 1f) { AddChatMessage(CECUIManager.Instance.GameUI.GetStringFromTable(8530), ChatChannel.GP_CHAT_MISC); return false; } } return true; } // ===================================================== // SPAM PROTECTION // ===================================================== private bool CheckSpamProtection(string text, float now) { if (m_vecHistory.Count == 0) return true; var last = m_vecHistory[m_vecHistory.Count - 1]; if (now - last.time <= 1f) { AddChatMessage(CECUIManager.Instance.GameUI.GetStringFromTable(272), ChatChannel.GP_CHAT_MISC); return false; } foreach (var cm in m_vecHistory) { if (cm.channel != ChatChannel.GP_CHAT_WHISPER && cm.msg == text && now - cm.time <= 6f) { AddChatMessage(CECUIManager.Instance.GameUI.GetStringFromTable(273), ChatChannel.GP_CHAT_MISC); return false; } } return true; } // ===================================================== // PARSE MESSAGE PREFIX // ===================================================== private ChatChannel ParseAndSendMessage(string text, int nPack, int nSlot) { ChatChannel channel; string pszMsg; if (text.StartsWith("!!")) { channel = ChatChannel.GP_CHAT_TEAM; pszMsg = text.Substring(2); } else if (text.StartsWith("!~")) { channel = ChatChannel.GP_CHAT_FACTION; pszMsg = text.Substring(2); } else if (text.StartsWith("!@")) { channel = ChatChannel.GP_CHAT_FARCRY; pszMsg = text.Substring(2); } else if (text.StartsWith("!#")) { channel = ChatChannel.GP_CHAT_SUPERFARCRY; pszMsg = text.Substring(2); } else if (text.StartsWith("$")) { channel = ChatChannel.GP_CHAT_TRADE; pszMsg = text.Substring(1); } else if (text.StartsWith("/")) { HandleWhisper(text, nPack, nSlot); return ChatChannel.GP_CHAT_WHISPER; } else { channel = ChatChannel.GP_CHAT_LOCAL; pszMsg = text; } SendChat(channel, pszMsg, nPack, nSlot); return channel; } // ===================================================== // WHISPER // ===================================================== private void HandleWhisper(string text, int nPack, int nSlot) { string cmd = text.Substring(1); int spaceIndex = cmd.IndexOf(' '); if (spaceIndex <= 0) { AddChatMessage(CECUIManager.Instance.GameUI.GetStringFromTable(234), ChatChannel.GP_CHAT_MISC); return; } string player = cmd.Substring(0, spaceIndex); string msg = cmd.Substring(spaceIndex + 1); SendPrivateChat(player, msg, nPack, nSlot); } // ===================================================== // SEND CHAT // ===================================================== private void SendChat(ChatChannel channel, string msg, int pack, int slot) { UnityGameSession.SendChatData((byte)channel, msg, pack, slot); } private void SendPrivateChat(string target, string msg, int pack, int slot) { Debug.Log($"Whisper to {target}: {msg}"); } // ===================================================== // HISTORY // ===================================================== private void SaveHistory(ChatChannel channel, string msg, int pack, int slot, float now) { if (m_vecHistory.Count >= MAX_HISTORY) m_vecHistory.RemoveAt(0); m_vecHistory.Add(new ChatMsg { channel = channel, msg = msg, pack = pack, slot = slot, time = now }); m_nCurHistory = m_vecHistory.Count; } // ===================================================== // UTILITIES // ===================================================== private void FilterBadWords(ref string text) { CECUIManager.Instance.FilterBadWords(ref text); } private void AddChatMessage(string msg, ChatChannel channel, int idPlayer = -1, string pszPlayer = "", byte byFlag = 0) { string strModified = msg; // 1. Filter bad words CECUIManager.Instance.FilterBadWords(ref strModified); if (string.IsNullOrEmpty(strModified)) return; // 2. Blacklist check (Placeholder for porting) if (IsPlayerBlacklisted(idPlayer)) return; // 3. Flag handling (Friend chat routing) if (byFlag == 1) // CHANNEL_FRIEND equivalent { // AddFriendMessage(strModified, idPlayer, pszPlayer, ...); // return; } // 4. Formatting with Rich Text string colorHex = GetChannelColorHex(channel); string prefix = GetChannelPrefix(channel); string sender = string.IsNullOrEmpty(pszPlayer) ? "" : $"{pszPlayer}: "; string finalMsg = $"{prefix}{sender}{strModified}"; // 5. Publish event EventBus.Publish(new GameSession.ChatMessageEvent(finalMsg, (byte)channel)); Debug.Log("[Cuong] AddChatMessage" + finalMsg); } private string GetChannelColorHex(ChatChannel channel) { // Simplified mapping based on common PW colors return channel switch { ChatChannel.GP_CHAT_TEAM => "00FFFF", // Cyan ChatChannel.GP_CHAT_FACTION => "00FF00", // Green ChatChannel.GP_CHAT_FARCRY => "FFFF00", // Yellow ChatChannel.GP_CHAT_WHISPER => "FF00FF", // Magenta _ => "FFFFFF" // White }; } private string GetChannelPrefix(ChatChannel channel) { return channel switch { ChatChannel.GP_CHAT_TEAM => "[Team] ", ChatChannel.GP_CHAT_FACTION => "[Faction] ", ChatChannel.GP_CHAT_FARCRY => "[World] ", ChatChannel.GP_CHAT_WHISPER => "[Whisper] ", _ => "" }; } private bool IsPlayerBlacklisted(int idPlayer) => false; // Placeholder private void ChangeFocus() { inputField.text = ""; inputField.ActivateInputField(); } private int GetPlayerItemCount(int id) => 0; private int GetPlayerLevel() => 10; } }