367 lines
11 KiB
C#
367 lines
11 KiB
C#
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<ChatMsg> 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;
|
|
|
|
ParseAndSendMessage(strText, nPack, nSlot);
|
|
|
|
SaveHistory(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 void 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;
|
|
}
|
|
else
|
|
{
|
|
channel = ChatChannel.GP_CHAT_LOCAL;
|
|
pszMsg = text;
|
|
}
|
|
|
|
SendChat(channel, pszMsg, nPack, nSlot);
|
|
}
|
|
|
|
// =====================================================
|
|
// 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(string msg, int pack, int slot, float now)
|
|
{
|
|
if (m_vecHistory.Count >= MAX_HISTORY)
|
|
m_vecHistory.RemoveAt(0);
|
|
|
|
m_vecHistory.Add(new ChatMsg
|
|
{
|
|
channel = ChatChannel.GP_CHAT_LOCAL,
|
|
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 = $"<color=#{colorHex}>{prefix}{sender}{strModified}</color>";
|
|
|
|
// 5. Publish event
|
|
EventBus.Publish(new GameSession.ChatMessageEvent(finalMsg, (byte)channel));
|
|
|
|
Debug.Log(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;
|
|
}
|
|
} |