267 lines
9.5 KiB
C#
267 lines
9.5 KiB
C#
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;
|
|
|
|
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
|
|
|
|
[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;
|
|
|
|
// ===== 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 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);
|
|
}
|
|
|
|
// ===== Hàm xử lý input (gửi server) =====
|
|
private void HandleUserInput(string text)
|
|
{
|
|
// Áp dụng giới hạn ký tự
|
|
text = TruncateText(text, maxChatLength);
|
|
|
|
// Lọc từ cấm (bad words filter)
|
|
CECUIManager.Instance?.FilterBadWords(ref text);
|
|
|
|
UnityGameSession.SendChatData(
|
|
(byte)ChatChannel.GP_CHAT_LOCAL,
|
|
text,
|
|
0,
|
|
0
|
|
);
|
|
|
|
// reset input
|
|
inputField.text = "";
|
|
inputField.ActivateInputField(); // focus lại để tiếp tục gõ
|
|
}
|
|
|
|
public void Send(string text)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(text))
|
|
return;
|
|
|
|
HandleUserInput(text);
|
|
}
|
|
|
|
// =================================================================
|
|
// SECTION: OnCommand_Chat - Chia sẻ trạng thái nhiệm vụ lên chat
|
|
// Converted from CDlgTaskTrace::OnCommand_Chat (DlgTaskTrace.cpp)
|
|
// =================================================================
|
|
|
|
/// <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)
|
|
{
|
|
// 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 (str[i] == '^' && i + 6 < str.Length)
|
|
{
|
|
// 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;
|
|
}
|
|
}
|
|
result.Append(str[i]);
|
|
}
|
|
return result.ToString();
|
|
}
|
|
|
|
/// <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)
|
|
{
|
|
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))
|
|
{
|
|
try { return string.Format(format, timeStr); }
|
|
catch { return timeStr; }
|
|
}
|
|
return timeStr;
|
|
}
|
|
|
|
/// <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)
|
|
{
|
|
// 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}]";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Lấy tên NPC theo ID từ ElementDataMan.
|
|
/// </summary>
|
|
private static string GetNPCName(int npcId)
|
|
{
|
|
// 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}";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Lấy tên Monster theo ID từ ElementDataMan.
|
|
/// </summary>
|
|
private static string GetMonsterName(int monsterId)
|
|
{
|
|
// 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}";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Lấy tên Item theo ID từ ElementDataMan.
|
|
/// </summary>
|
|
private static string GetItemName(int itemId)
|
|
{
|
|
// 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}";
|
|
}
|
|
}
|
|
} |