add handlr input
This commit is contained in:
@@ -1,11 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using BrewMonster.Network;
|
||||
using BrewMonster.Scripts.UI;
|
||||
using BrewMonster.UI;
|
||||
using CSNetwork;
|
||||
using CSNetwork.GPDataType;
|
||||
using CSNetwork.Protocols;
|
||||
|
||||
@@ -207,356 +203,6 @@ namespace BrewMonster.Scripts.Chat
|
||||
return bOK;
|
||||
}
|
||||
|
||||
public static bool HanldeGPChatSystem(chatmessage p, bool bCalledagain)
|
||||
{
|
||||
/*string strMsg = "";
|
||||
switch (p.Srcroleid)
|
||||
{
|
||||
case 1: //CMSG_BIDSTART
|
||||
case 2: //CMSG_BIDEND
|
||||
case 3: //CMSG_BATTLESTART
|
||||
case 4: //CMSG_BATTLEEND
|
||||
case 6: //CMSG_BONUSSEND
|
||||
case 7: //CMSG_SPECIAL
|
||||
{
|
||||
if (!bCalledagain)
|
||||
{
|
||||
List<int, int> pending;
|
||||
if (!OnBattleChatMessage(p, pending))
|
||||
{
|
||||
if (pending.GetSize() > 0)
|
||||
{
|
||||
GetFactionInfo(pending.GetSize(), pending.GetData());
|
||||
m_aPendingProtocols.Add(pProtocol);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!OnBattleChatMessage(p, NULL))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool OnBattleChatMessage(chatmessage p, AArray<int, int> pPendingFactions)
|
||||
{
|
||||
var pGameUI = g_pGame.GetGameRun().GetUIManager().GetInGameUIMan();
|
||||
var pDlgGuildMap = (CDlgGuildMap)pGameUI.GetDialog("Win_GuildMap");
|
||||
|
||||
var info = GlobalData.GetDomainInfos();
|
||||
var pMan = g_pGame.GetFactionMan();
|
||||
|
||||
string strMsg = string.Empty;
|
||||
|
||||
if (pPendingFactions != null)
|
||||
{
|
||||
pPendingFactions.RemoveAll();
|
||||
}
|
||||
|
||||
switch (p.srcroleid)
|
||||
{
|
||||
case 1: // CMSG_BIDSTART
|
||||
{
|
||||
strMsg = pGameUI.GetStringFromTable(4001);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: // CMSG_BIDEND
|
||||
{
|
||||
int group = p.msg.Size / (sizeof(short) + 2 * sizeof(uint));
|
||||
strMsg = pGameUI.GetStringFromTable(4002);
|
||||
|
||||
if (group == 0)
|
||||
break;
|
||||
|
||||
int idFaction = g_pGame.GetGameRun().GetHostPlayer().GetFactionID();
|
||||
|
||||
string strAttacker = "";
|
||||
string strDefender = "";
|
||||
string strAnnounce = "";
|
||||
|
||||
pDlgGuildMap.ClearMessage();
|
||||
|
||||
var o = new OctetsStream(p.msg);
|
||||
|
||||
for (; group > 0; group--)
|
||||
{
|
||||
short id = o.ReadShort();
|
||||
uint owner = o.ReadUInt();
|
||||
uint challenger = o.ReadUInt();
|
||||
|
||||
var finfo = pMan.GetFaction(challenger);
|
||||
|
||||
if ((int)challenger == idFaction)
|
||||
strAttacker = pGameUI.GetStringFromTable(4500);
|
||||
else if (finfo != null)
|
||||
strAttacker = string.Format(pGameUI.GetStringFromTable(4499), finfo.GetName());
|
||||
else if (pPendingFactions != null)
|
||||
pPendingFactions.UniquelyAdd((int)challenger);
|
||||
|
||||
if (string.IsNullOrEmpty(strAttacker))
|
||||
{
|
||||
strMsg = "";
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < info.Count; i++)
|
||||
{
|
||||
if (info[i].id == id)
|
||||
{
|
||||
if (info[i].id_owner != 0)
|
||||
{
|
||||
if (info[i].id_owner == idFaction)
|
||||
strDefender = pGameUI.GetStringFromTable(4500);
|
||||
else
|
||||
{
|
||||
var finfo2 = pMan.GetFaction(info[i].id_owner);
|
||||
|
||||
if (finfo2 != null)
|
||||
strDefender = string.Format(
|
||||
pGameUI.GetStringFromTable(4499),
|
||||
finfo2.GetName());
|
||||
else if (pPendingFactions != null)
|
||||
pPendingFactions.UniquelyAdd(info[i].id_owner);
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(strDefender))
|
||||
{
|
||||
strAnnounce = string.Format(
|
||||
pGameUI.GetStringFromTable(4511),
|
||||
strAttacker,
|
||||
info[i].name);
|
||||
}
|
||||
else
|
||||
{
|
||||
strAnnounce = string.Format(
|
||||
pGameUI.GetStringFromTable(4512),
|
||||
strAttacker,
|
||||
strDefender,
|
||||
info[i].name);
|
||||
}
|
||||
|
||||
if (pPendingFactions == null || pPendingFactions.GetSize() == 0)
|
||||
{
|
||||
pDlgGuildMap.AddMessage(strAnnounce);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
strAttacker = "";
|
||||
strDefender = "";
|
||||
}
|
||||
|
||||
if ((pPendingFactions != null && pPendingFactions.GetSize() > 0) || string.IsNullOrEmpty(strMsg))
|
||||
{
|
||||
pDlgGuildMap.ClearMessage();
|
||||
strMsg = "";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: // CMSG_BATTLESTART
|
||||
{
|
||||
if (p.msg.Size < 2)
|
||||
return false;
|
||||
|
||||
var os = new OctetsStream(p.msg);
|
||||
|
||||
byte id = os.ReadByte();
|
||||
byte result = os.ReadByte();
|
||||
|
||||
for (int i = 0; i < info.Count; i++)
|
||||
{
|
||||
if (info[i].id == id)
|
||||
{
|
||||
strMsg = string.Format(
|
||||
pGameUI.GetStringFromTable(4003),
|
||||
info[i].name);
|
||||
|
||||
strMsg += pGameUI.GetStringFromTable(3900 + result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: // CMSG_BATTLEEND
|
||||
{
|
||||
if (p.msg.Size < 1)
|
||||
return false;
|
||||
|
||||
var os = new OctetsStream(p.msg);
|
||||
|
||||
byte id = os.ReadByte();
|
||||
|
||||
for (int i = 0; i < info.Count; i++)
|
||||
{
|
||||
if (info[i].id == id)
|
||||
{
|
||||
strMsg = string.Format(
|
||||
pGameUI.GetStringFromTable(4004),
|
||||
info[i].name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 6: // CMSG_BONUSSEND
|
||||
{
|
||||
if (p.msg.Size < sizeof(uint) * 3)
|
||||
return false;
|
||||
|
||||
var os = new OctetsStream(p.msg);
|
||||
|
||||
uint money = os.ReadUInt();
|
||||
uint id = os.ReadUInt();
|
||||
uint count = os.ReadUInt();
|
||||
|
||||
var item = CECIvtrItem.CreateItem(id, 0, count);
|
||||
|
||||
strMsg = string.Format(
|
||||
pGameUI.GetStringFromTable(4006),
|
||||
item.GetName(),
|
||||
item.GetCount());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 7: // CMSG_SPECIAL
|
||||
{
|
||||
if (p.msg.Size < sizeof(short))
|
||||
return false;
|
||||
|
||||
var os = new OctetsStream(p.msg);
|
||||
|
||||
short id = os.ReadShort();
|
||||
|
||||
for (int i = 0; i < info.Count; i++)
|
||||
{
|
||||
if (info[i].id == id)
|
||||
{
|
||||
uint fid = info[i].id_owner;
|
||||
|
||||
if (fid > 0)
|
||||
{
|
||||
var finfo = pMan.GetFaction(fid);
|
||||
|
||||
if (finfo != null)
|
||||
{
|
||||
strMsg = string.Format(
|
||||
pGameUI.GetStringFromTable(4007),
|
||||
info[i].name,
|
||||
info[i].name,
|
||||
finfo.GetName());
|
||||
}
|
||||
else if (pPendingFactions != null)
|
||||
{
|
||||
pPendingFactions.UniquelyAdd((int)fid);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
strMsg = string.Format(
|
||||
pGameUI.GetStringFromTable(4005),
|
||||
info[i].name);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((pPendingFactions != null && pPendingFactions.GetSize() > 0) || string.IsNullOrEmpty(strMsg))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
g_pGame.GetGameRun().AddChatMessage(
|
||||
strMsg,
|
||||
ChatChannel.GP_CHAT_BROADCAST,
|
||||
p.srcroleid,
|
||||
null,
|
||||
1,
|
||||
p.emotion);*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*public static void OnTaskChatMessage(byte[] buffer, int size)
|
||||
{
|
||||
const int iNameLen = 20;
|
||||
|
||||
int expectedSize = 4 * 5 + iNameLen * 2;
|
||||
|
||||
if (size < expectedSize)
|
||||
return;
|
||||
|
||||
int offset = 0;
|
||||
|
||||
int self_id = BitConverter.ToInt32(buffer, offset); offset += 4;
|
||||
uint task_id = BitConverter.ToUInt32(buffer, offset); offset += 4;
|
||||
int channel = BitConverter.ToInt32(buffer, offset); offset += 4;
|
||||
int param = BitConverter.ToInt32(buffer, offset); offset += 4;
|
||||
int map_id = BitConverter.ToInt32(buffer, offset); offset += 4;
|
||||
|
||||
// name (UTF16 20 chars)
|
||||
string name = Encoding.Unicode.GetString(buffer, offset, iNameLen * 2);
|
||||
name = name.TrimEnd('\0');
|
||||
|
||||
var pTempl = EC_Game.GetTaskTemplateMan()
|
||||
.GetTaskTemplByID(task_id);
|
||||
|
||||
if (pTempl == null)
|
||||
return;
|
||||
|
||||
var tribute = pTempl.GetTribute();
|
||||
|
||||
if (string.IsNullOrEmpty(tribute))
|
||||
return;
|
||||
|
||||
// register player name
|
||||
EC_Game.GetGameRun().AddPlayerName(self_id, name);
|
||||
|
||||
string strMsg = tribute;
|
||||
|
||||
// replace $name
|
||||
strMsg = strMsg.Replace("$name", $"&{name}&");
|
||||
|
||||
// replace $map
|
||||
string strMap = "";
|
||||
|
||||
var instance = EC_Game.GetGameRun().GetInstance(map_id);
|
||||
|
||||
if (instance != null)
|
||||
strMap = instance.GetName();
|
||||
|
||||
strMsg = strMsg.Replace("$map", strMap);
|
||||
|
||||
EC_Game.GetGameRun().AddChatMessage(strMsg, channel);
|
||||
}*/
|
||||
|
||||
public class AUICTranslate
|
||||
{
|
||||
protected string m_AString = string.Empty;
|
||||
|
||||
@@ -1694,7 +1694,6 @@ namespace CSNetwork
|
||||
|
||||
BitConverter.GetBytes(cmd).CopyTo(bytes, 0);
|
||||
BitConverter.GetBytes(cardId).CopyTo(bytes, 2);
|
||||
Debug.Log($"[Cuong] SendChatData {bytes}");
|
||||
p.Data.Replace(bytes);
|
||||
}
|
||||
}
|
||||
@@ -1743,6 +1742,7 @@ namespace CSNetwork
|
||||
}
|
||||
}
|
||||
EventBus.PublishChannel(pHost.GetCharacterID(), new EventChatMessageOnTopPlayer(pHost.GetCharacterID(), szMsg));
|
||||
EventBus.Publish(new ChatMessageEvent(szMsg, p.Channel));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
|
||||
[SerializeField] private int currentTargetNPCID;
|
||||
CECGameUIMan gameUI;
|
||||
public CECGameUIMan GameUI => gameUI;
|
||||
AUIManager aUIManager;
|
||||
AUIDialog _dlgPlayerOptions;
|
||||
[SerializeField] private DialogScriptTableObject dialogResouce;
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using BrewMonster.Network;
|
||||
using CSNetwork.GPDataType;
|
||||
|
||||
namespace BrewMonster.Scripts.ChatUI
|
||||
{
|
||||
public class ChatCommandProcessor
|
||||
{
|
||||
private struct ChatHistoryEntry
|
||||
{
|
||||
public ChatChannel channel;
|
||||
public float time;
|
||||
public string message;
|
||||
}
|
||||
|
||||
private static List<ChatHistoryEntry> _history = new List<ChatHistoryEntry>();
|
||||
private const int MAX_HISTORY = 10;
|
||||
private static float _lastFarCryTime = 0;
|
||||
private static float _lastSuperFarCryTime = 0;
|
||||
|
||||
public struct ProcessResult
|
||||
{
|
||||
public bool success;
|
||||
public ChatChannel channel;
|
||||
public string message;
|
||||
public string targetPlayer; // For whisper
|
||||
public int itemPack;
|
||||
public int itemSlot;
|
||||
public string errorString;
|
||||
public bool showConfirmation;
|
||||
public int confirmationStringId;
|
||||
}
|
||||
|
||||
public static ProcessResult Process(string text, int itemPack = -1, int itemSlot = -1)
|
||||
{
|
||||
ProcessResult result = new ProcessResult
|
||||
{
|
||||
success = false,
|
||||
channel = ChatChannel.GP_CHAT_LOCAL,
|
||||
message = text,
|
||||
itemPack = itemPack,
|
||||
itemSlot = itemSlot,
|
||||
showConfirmation = false
|
||||
};
|
||||
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// Flood protection
|
||||
float now = Time.time;
|
||||
if (_history.Count > 0)
|
||||
{
|
||||
var last = _history[_history.Count - 1];
|
||||
if (now - last.time <= 1.0f)
|
||||
{
|
||||
result.errorString = GetStringFromTable(272);
|
||||
return result;
|
||||
}
|
||||
|
||||
foreach (var entry in _history)
|
||||
{
|
||||
if (entry.channel != ChatChannel.GP_CHAT_WHISPER &&
|
||||
entry.message == text &&
|
||||
now - entry.time <= 6.0f)
|
||||
{
|
||||
result.errorString = GetStringFromTable(273);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Debug commands
|
||||
if (text == "##debug")
|
||||
{
|
||||
// Toggle console logic here if needed
|
||||
result.success = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
string pszMsg = text;
|
||||
ChatChannel channel = ChatChannel.GP_CHAT_LOCAL;
|
||||
|
||||
if (text.Length >= 2 && text.StartsWith("!!"))
|
||||
{
|
||||
channel = ChatChannel.GP_CHAT_TEAM;
|
||||
pszMsg = text.Substring(2);
|
||||
}
|
||||
else if (text.Length >= 2 && text.StartsWith("!~"))
|
||||
{
|
||||
channel = ChatChannel.GP_CHAT_FACTION;
|
||||
pszMsg = text.Substring(2);
|
||||
}
|
||||
else if (text.Length >= 2 && text.StartsWith("!@"))
|
||||
{
|
||||
channel = ChatChannel.GP_CHAT_FARCRY;
|
||||
pszMsg = text.Substring(2);
|
||||
|
||||
// Requirement check
|
||||
int itemNum = GetPlayerItemCount(12979) + GetPlayerItemCount(36092);
|
||||
if (itemNum < 1 || GetPlayerLevel() < 5)
|
||||
{
|
||||
result.errorString = GetStringFromTable(731);
|
||||
return result;
|
||||
}
|
||||
if (now - _lastFarCryTime <= 1.0f)
|
||||
{
|
||||
result.errorString = GetStringFromTable(730);
|
||||
return result;
|
||||
}
|
||||
|
||||
result.showConfirmation = true;
|
||||
result.confirmationStringId = 732;
|
||||
}
|
||||
else if (text.Length >= 2 && text.StartsWith("!#"))
|
||||
{
|
||||
channel = ChatChannel.GP_CHAT_SUPERFARCRY;
|
||||
pszMsg = text.Substring(2);
|
||||
|
||||
int itemNum = GetPlayerItemCount(27728) + GetPlayerItemCount(27729);
|
||||
if (itemNum < 1)
|
||||
{
|
||||
result.errorString = GetStringFromTable(8531);
|
||||
return result;
|
||||
}
|
||||
if (now - _lastSuperFarCryTime <= 1.0f)
|
||||
{
|
||||
result.errorString = GetStringFromTable(8530);
|
||||
return result;
|
||||
}
|
||||
|
||||
result.showConfirmation = true;
|
||||
result.confirmationStringId = 8532;
|
||||
}
|
||||
else if (text.Length >= 1 && text.StartsWith("$"))
|
||||
{
|
||||
if (HasCountryChannel())
|
||||
{
|
||||
channel = ChatChannel.GP_CHAT_COUNTRY;
|
||||
pszMsg = text.Substring(1);
|
||||
// Add king/money checks if needed
|
||||
}
|
||||
else
|
||||
{
|
||||
channel = ChatChannel.GP_CHAT_TRADE;
|
||||
pszMsg = text.Substring(1);
|
||||
if (GetPlayerLevel() <= 30)
|
||||
{
|
||||
result.errorString = GetStringFromTable(530);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (text.Length >= 1 && text.StartsWith("/"))
|
||||
{
|
||||
string cmdPart = text.Substring(1);
|
||||
int spaceIdx = cmdPart.IndexOf(' ');
|
||||
if (spaceIdx > 0)
|
||||
{
|
||||
result.targetPlayer = cmdPart.Substring(0, spaceIdx);
|
||||
pszMsg = cmdPart.Substring(spaceIdx + 1);
|
||||
channel = ChatChannel.GP_CHAT_WHISPER;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Maybe just showing help or something
|
||||
result.errorString = GetStringFromTable(234);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
channel = HasCountryWarChannel() ? ChatChannel.GP_CHAT_BATTLE : ChatChannel.GP_CHAT_LOCAL;
|
||||
pszMsg = text;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(pszMsg))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
result.success = true;
|
||||
result.channel = channel;
|
||||
result.message = pszMsg;
|
||||
|
||||
// Update history
|
||||
if (_history.Count >= MAX_HISTORY)
|
||||
_history.RemoveAt(0);
|
||||
|
||||
_history.Add(new ChatHistoryEntry { channel = channel, time = now, message = text });
|
||||
|
||||
if (channel == ChatChannel.GP_CHAT_FARCRY) _lastFarCryTime = now;
|
||||
if (channel == ChatChannel.GP_CHAT_SUPERFARCRY) _lastSuperFarCryTime = now;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string GetStringFromTable(int id)
|
||||
{
|
||||
return CECUIManager.Instance?.GetInGameUIMan()?.GetStringFromTable(id) ?? $"[STR_{id}]";
|
||||
}
|
||||
|
||||
private static int GetPlayerItemCount(int tid)
|
||||
{
|
||||
return 0;
|
||||
//return EC_GameRun.Instance?.GetHostPlayer()?.GetPack()?.GetItemTotalNum(tid) ?? 0;
|
||||
}
|
||||
|
||||
private static int GetPlayerLevel()
|
||||
{
|
||||
return 0;
|
||||
//return EC_GameRun.Instance?.GetHostPlayer()?.GetBasicProps()?.iLevel ?? 0;
|
||||
}
|
||||
|
||||
private static bool HasCountryChannel()
|
||||
{
|
||||
return false;
|
||||
//return EC_GameRun.Instance?.GetHostPlayer()?.HasCountryChannel() ?? false;
|
||||
}
|
||||
|
||||
private static bool HasCountryWarChannel()
|
||||
{
|
||||
return false;
|
||||
//return EC_GameRun.Instance?.GetHostPlayer()?.HasCountryWarChannel() ?? false;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a090b5a4bce36b44b6def3542c520d4
|
||||
+308
-208
@@ -1,267 +1,367 @@
|
||||
using UnityEngine;
|
||||
using TMPro;
|
||||
using BrewMonster;
|
||||
using BrewMonster.Network;
|
||||
using CSNetwork.GPDataType;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using BrewMonster.Scripts.Task;
|
||||
using BrewMonster.Network;
|
||||
using BrewMonster.UI;
|
||||
using CSNetwork;
|
||||
|
||||
namespace BrewMonster.Scripts.ChatUI
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles chat input from TMP_InputField and provides task-sharing functionality.
|
||||
/// Converted from CDlgTaskTrace::OnCommand_Chat (DlgTaskTrace.cpp line 888).
|
||||
/// </summary>
|
||||
public class ChatInputHandler : MonoBehaviour
|
||||
{
|
||||
[Header("UI References")]
|
||||
public TMP_InputField inputField; // Ô gõ text
|
||||
public TMP_InputField inputField;
|
||||
|
||||
[Header("Chat Settings")]
|
||||
[Tooltip("Giới hạn số ký tự tối đa cho mỗi tin nhắn chat")]
|
||||
public int maxChatLength = 256;
|
||||
private const int MAX_HISTORY = 10;
|
||||
|
||||
// ===== Constants from C++ source =====
|
||||
private const string INDENTATION = " ";
|
||||
private const int MAX_ITEM_WANTED = 10;
|
||||
private const int MAX_MONSTER_WANTED = 3;
|
||||
private const int MAX_PLAYER_WANTED = MAX_MONSTER_WANTED;
|
||||
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);
|
||||
|
||||
// Giới hạn ký tự trực tiếp trên InputField
|
||||
if (inputField.characterLimit <= 0 || inputField.characterLimit > maxChatLength)
|
||||
inputField.characterLimit = maxChatLength;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
inputField.onSubmit.RemoveListener(OnSubmit);
|
||||
}
|
||||
|
||||
// ===== Khi nhấn Enter =====
|
||||
private void OnSubmit(string text)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
return;
|
||||
|
||||
HandleUserInput(text);
|
||||
OnCommand_speak(text);
|
||||
}
|
||||
|
||||
// ===== Hàm xử lý input (gửi server) =====
|
||||
private void HandleUserInput(string text)
|
||||
// =====================================================
|
||||
// PORT C++: CDlgChat::OnCommand_speak
|
||||
// =====================================================
|
||||
|
||||
private void OnCommand_speak(string text)
|
||||
{
|
||||
// Áp dụng giới hạn ký tự
|
||||
text = TruncateText(text, maxChatLength);
|
||||
string strText = text.Trim();
|
||||
|
||||
// Lọc từ cấm (bad words filter)
|
||||
CECUIManager.Instance?.FilterBadWords(ref text);
|
||||
if (strText.Length <= 0)
|
||||
{
|
||||
ChangeFocus();
|
||||
return;
|
||||
}
|
||||
|
||||
UnityGameSession.SendChatData(
|
||||
(byte)ChatChannel.GP_CHAT_LOCAL,
|
||||
text,
|
||||
0,
|
||||
0
|
||||
);
|
||||
int nPack = -1;
|
||||
int nSlot = -1;
|
||||
|
||||
// reset input
|
||||
inputField.text = "";
|
||||
inputField.ActivateInputField(); // focus lại để tiếp tục gõ
|
||||
}
|
||||
FilterBadWords(ref strText);
|
||||
|
||||
public void Send(string text)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
if (HandleDebugCommand(strText))
|
||||
return;
|
||||
|
||||
HandleUserInput(text);
|
||||
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();
|
||||
}
|
||||
|
||||
// =================================================================
|
||||
// SECTION: OnCommand_Chat - Chia sẻ trạng thái nhiệm vụ lên chat
|
||||
// Converted from CDlgTaskTrace::OnCommand_Chat (DlgTaskTrace.cpp)
|
||||
// =================================================================
|
||||
// =====================================================
|
||||
// DEBUG COMMAND
|
||||
// =====================================================
|
||||
|
||||
/// <summary>
|
||||
/// Builds a chat message describing task progress and sends it to the appropriate channel.
|
||||
/// Gọi hàm này khi người chơi bấm nút "Chia sẻ nhiệm vụ" trên giao diện Task Trace.
|
||||
/// </summary>
|
||||
/// <param name="idTask">ID của nhiệm vụ cần chia sẻ.</param>
|
||||
public void OnCommand_Chat(uint idTask)
|
||||
private bool HandleDebugCommand(string text)
|
||||
{
|
||||
// TODO: Replace with actual EC_Game Unity Wrapper when available
|
||||
// CECHostPlayer pHost = EC_Game.GetGameRun()?.GetHostPlayer();
|
||||
// CECTaskInterface pTask = pHost.GetTaskInterface();
|
||||
// ATaskTempl pTemp = pTask.GetTaskTemplMan().GetTaskTemplByID(idTask);
|
||||
|
||||
// --- MOCK DATA FOR COMPILATION ---
|
||||
bool bActiveTask = true;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
// string strName = pTemp.GetName();
|
||||
string strName = $"[Task_{idTask}]";
|
||||
strName = DeleteColorStr(strName);
|
||||
sb.Append(strName);
|
||||
|
||||
/*
|
||||
// --- Lấy thông tin trạng thái task ---
|
||||
Task_State_info tsi = new Task_State_info();
|
||||
pTask.GetTaskStateInfo(idTask, ref tsi, bActiveTask);
|
||||
|
||||
// --- NPC trao thưởng (nếu có thể hoàn thành task) ---
|
||||
int nANPC = (int)pTemp.GetAwardNPC();
|
||||
if (nANPC > 0 && pTask.CanFinishTask(idTask))
|
||||
...
|
||||
*/
|
||||
|
||||
// --- MOCK LOGIC TO APPEND PROGRESS ---
|
||||
sb.Append(INDENTATION);
|
||||
sb.AppendFormat(GetStringFromTable(248), GetItemName(123), 2, 10); // Mock item progress
|
||||
|
||||
// --- Cắt bớt trailing '\r' ---
|
||||
string strText = sb.ToString().TrimEnd('\r');
|
||||
|
||||
// --- Áp dụng giới hạn ký tự ---
|
||||
strText = TruncateText(strText, maxChatLength);
|
||||
|
||||
// --- Xác định kênh chat: Team nếu có đội, Local nếu không ---
|
||||
byte channel = (byte)ChatChannel.GP_CHAT_LOCAL;
|
||||
|
||||
// --- Gửi lên server ---
|
||||
UnityGameSession.SendChatData(channel, strText, 0, 0);
|
||||
|
||||
Debug.Log($"[ChatInputHandler] OnCommand_Chat: Sent mock task {idTask} to channel {channel}, length={strText.Length}");
|
||||
}
|
||||
|
||||
// =================================================================
|
||||
// SECTION: Helper methods
|
||||
// =================================================================
|
||||
|
||||
/// <summary>
|
||||
/// Cắt chuỗi nếu vượt quá giới hạn ký tự, thêm dấu "..." ở cuối.
|
||||
/// </summary>
|
||||
private static string TruncateText(string text, int maxLength)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text) || maxLength <= 0)
|
||||
return text;
|
||||
|
||||
if (text.Length <= maxLength)
|
||||
return text;
|
||||
|
||||
// Trừ 3 ký tự để chèn "..."
|
||||
if (maxLength > 3)
|
||||
return text.Substring(0, maxLength - 3) + "...";
|
||||
else
|
||||
return text.Substring(0, maxLength);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Xóa các mã màu "^xxxxxx" ra khỏi chuỗi.
|
||||
/// Tương đương CDlgTaskTrace::DeleteColorStr trong C++.
|
||||
/// </summary>
|
||||
private static string DeleteColorStr(string str)
|
||||
{
|
||||
if (string.IsNullOrEmpty(str))
|
||||
return str;
|
||||
|
||||
StringBuilder result = new StringBuilder(str.Length);
|
||||
for (int i = 0; i < str.Length; i++)
|
||||
if (text == "##debug")
|
||||
{
|
||||
if (str[i] == '^' && i + 6 < str.Length)
|
||||
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)
|
||||
{
|
||||
// Kiểm tra 6 ký tự tiếp theo có phải hex không
|
||||
bool isColorCode = true;
|
||||
for (int j = 1; j <= 6; j++)
|
||||
{
|
||||
char c = str[i + j];
|
||||
if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')))
|
||||
{
|
||||
isColorCode = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isColorCode)
|
||||
{
|
||||
i += 6; // bỏ qua 6 ký tự hex
|
||||
continue;
|
||||
}
|
||||
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;
|
||||
}
|
||||
result.Append(str[i]);
|
||||
}
|
||||
return result.ToString();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Format thời gian cho task (tương đương CDlgTask::FormatTime trong C++).
|
||||
/// </summary>
|
||||
private static string FormatTime(int nSec, string format, int totalTime)
|
||||
// =====================================================
|
||||
// SUPER FARCRY (!#)
|
||||
// =====================================================
|
||||
|
||||
private bool CheckSuperFarCryRequirement(string text, float now)
|
||||
{
|
||||
int hours = nSec / 3600;
|
||||
int minutes = (nSec % 3600) / 60;
|
||||
int seconds = nSec % 60;
|
||||
|
||||
string timeStr;
|
||||
if (hours > 0)
|
||||
timeStr = $"{hours:D2}:{minutes:D2}:{seconds:D2}";
|
||||
else
|
||||
timeStr = $"{minutes:D2}:{seconds:D2}";
|
||||
|
||||
if (!string.IsNullOrEmpty(format))
|
||||
if (text.StartsWith("!#"))
|
||||
{
|
||||
try { return string.Format(format, timeStr); }
|
||||
catch { return timeStr; }
|
||||
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 timeStr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lấy string từ bảng String Table (StringFromTable).
|
||||
/// Tương đương pUIMan->GetStringFromTable(id) trong C++.
|
||||
/// </summary>
|
||||
private static string GetStringFromTable(int id)
|
||||
// =====================================================
|
||||
// SPAM PROTECTION
|
||||
// =====================================================
|
||||
|
||||
private bool CheckSpamProtection(string text, float now)
|
||||
{
|
||||
// Sử dụng hệ thống StringTable có sẵn trong project
|
||||
var gameUI = CECUIManager.Instance?.GetInGameUIMan();
|
||||
string result = gameUI?.GetStringFromTable(id);
|
||||
return result ?? $"[STR_{id}]";
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lấy tên NPC theo ID từ ElementDataMan.
|
||||
/// </summary>
|
||||
private static string GetNPCName(int npcId)
|
||||
// =====================================================
|
||||
// PARSE MESSAGE PREFIX
|
||||
// =====================================================
|
||||
|
||||
private void ParseAndSendMessage(string text, int nPack, int nSlot)
|
||||
{
|
||||
// TODO: Kết nối với ElementDataMan của bạn khi đã port xong
|
||||
// var pDataMan = EC_Game.GetElementDataMan();
|
||||
// return pDataMan?.GetNPCName(npcId);
|
||||
return $"NPC_{npcId}";
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lấy tên Monster theo ID từ ElementDataMan.
|
||||
/// </summary>
|
||||
private static string GetMonsterName(int monsterId)
|
||||
// =====================================================
|
||||
// WHISPER
|
||||
// =====================================================
|
||||
|
||||
private void HandleWhisper(string text, int nPack, int nSlot)
|
||||
{
|
||||
// TODO: Kết nối với ElementDataMan của bạn khi đã port xong
|
||||
// var pDataMan = EC_Game.GetElementDataMan();
|
||||
// return pDataMan?.GetMonsterName(monsterId);
|
||||
return $"Monster_{monsterId}";
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lấy tên Item theo ID từ ElementDataMan.
|
||||
/// </summary>
|
||||
private static string GetItemName(int itemId)
|
||||
// =====================================================
|
||||
// SEND CHAT
|
||||
// =====================================================
|
||||
|
||||
private void SendChat(ChatChannel channel, string msg, int pack, int slot)
|
||||
{
|
||||
// TODO: Kết nối với ElementDataMan của bạn khi đã port xong
|
||||
// var pDataMan = EC_Game.GetElementDataMan();
|
||||
// return pDataMan?.GetItemName(itemId);
|
||||
return $"Item_{itemId}";
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user