using System;
using System.Collections.Generic;
using BrewMonster.Scripts.Task;
using CSNetwork;
using CSNetwork.GPDataType;
using UnityEngine;
using System.Runtime.InteropServices;
using BrewMonster.Network;
using BrewMonster.UI;
using Cysharp.Threading.Tasks;
using System.Threading.Tasks;
namespace BrewMonster
{
// ���� // Contribution info
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct CONTRIB_INFO
{
public int consume_contrib; // �����ѵ� // Consume contribution
public int exp_contrib; // �ɶһ����ɾ���� // Experience contribution
public int cumulate_contrib; // �ۻ�ֵ // Cumulative contribution
// public CONTRIB_INFO()
// {
// consume_contrib = 0;
// exp_contrib = 0;
// cumulate_contrib = 0;
// }
}
public partial class CECHostPlayer
{
private int m_idTradePlayer; // ID of player who is trading with us
private CECTaskInterface m_pTaskInterface;
private int m_iBoothState; // Booth state. 0, none; 1, prepare; 2, open booth; 3, visite other's booth
private CONTRIB_INFO m_contribInfo;
private CECCounter m_TaskCounter = new CECCounter();
private bool m_bTitleDataReady;
private List
m_Titles = new();
public CECTaskInterface GetTaskInterface()
{
return m_pTaskInterface;
}
// Is host player trading ?
public bool IsTrading() { return m_idTradePlayer != 0; }
public CONTRIB_INFO GetContribInfo()
{
return m_contribInfo;
}
public int GetBoothState()
{
return m_iBoothState;
}
public CECShortcutSet GetShortcutSet1(int n) { return m_aSCSets1[n]; }
public CECShortcutSet GetShortcutSet2(int n) { return m_aSCSets2[n]; }
private async UniTaskVoid OnMsgHstTaskData(ECMSG Msg)
{
// decode header to distinguish TASK_DATA vs TASK_VAR_DATA
// if (!(Msg.dwParam2 is cmd_header header))
// {
// Debug.LogError("OnMsgHstTaskData: invalid header");
// return;
// }
int header = Convert.ToInt32(Msg.dwParam2);
byte[] pDataBuf = Msg.dwParam1 as byte[];
if (pDataBuf == null)
{
Debug.LogError("OnMsgHstTaskData: missing payload buffer");
return;
}
if (header == CommandID.TASK_DATA)
{
// Parse aggregated task buffers
cmd_task_data pCmd = cmd_task_data.FromBuffer(pDataBuf);
// cmd_task_data pCmd = GPDataTypeHelper.FromBytes(pDataBuf);
// Release and recreate task interface
m_pTaskInterface = null;
m_pTaskInterface = new CECTaskInterface(this);
var initTask = await m_pTaskInterface.Init(
pCmd.active_list, (int)pCmd.active_list_size,
pCmd.finished_list, (int)pCmd.finished_list_size,
pCmd.finished_time_list, (int)pCmd.finished_time_list_size,
pCmd.finished_count, (int)pCmd.finished_count_size,
pCmd.storage_task, (int)pCmd.storage_task_size);
if (!initTask)
{
Debug.LogError("CECHostPlayer::OnMsgHstTaskData, failed to initialize task interface");
return;
}
m_pTaskInterface.CheckPQEnterWorldInit();
// check if player has equipped goblin (not yet implemented in C#)
// TODO: implement goblin initialization when equipment system is ready
// GET_ALL_DATA end flag tasks were here in C++ (LoadConfigData), omitted in C#
UnityGameSession.LoadConfigData();
// Quest trace lists + minimion: apply SyncTrace once active tasks and templates are ready.
// 任务追踪:在任务数据与模板就绪后调用 SyncTrace 同步追踪列表与小窗。
var pGameUI = EC_Game.GetGameRun()?.GetUIManager()?.GetInGameUIMan();
pGameUI?.OnHostTaskDataInitialized(m_pTaskInterface);
// if (UpdateEquipSkills()) UpdateEquipSkillCoolDown(); // methods not ported yet
}
else if (header == CommandID.TASK_VAR_DATA)
{
// Minimal forwarding; original code passes inner data pointer and size
cmd_task_var_data pCmd = new cmd_task_var_data();
pCmd.ReadBuffer(pDataBuf);
// ASSERT(pCmd);
if(m_pTaskInterface!= null)
OnServerNotify(m_pTaskInterface, pCmd.data, (int)pCmd.size);
else
// ASSERT(m_pTaskInterface);
BMLogger.LogError($" CECHostPlayer::OnMsgHstTaskData: TASK_VAR_DATA received but m_pTaskInterface is null");
}
}
private void OnServerNotify(CECTaskInterface pInterface, byte[] data, int size)
{
TaskClient.OnServerNotify(pInterface, data, (uint)size);
}
private async UniTask TickTask()
{
// Update task
while (true)
{
TaskClient.OnTaskCheckStatus(m_pTaskInterface);
await Task.Delay(1000);
}
}
public bool IsTitleDataReady() { return m_bTitleDataReady; }
// Converted from C++ to C#. Pointer-based parts marked as TODO.
private void OnMsgTitle(ECMSG msg)
{
// TODO: Replace with actual access pattern for your game systems
var gameUI = EC_Game.GetGameRun().GetUIManager().GetInGameUIMan();
int header = Convert.ToInt32(msg.dwParam2);
byte[] pDataBuf = msg.dwParam1 as byte[];
if (header == CommandID.QUERY_TITLE_RE)
{
// Replace unsafe pointer cast with proper C# struct deserialization
// var cmd = msg.dwParam1 as cmd_query_title_re;
var cmd = new cmd_query_title_re();
bool wasRead = cmd.ReadFromBytes(pDataBuf);
if (wasRead)
{
InitTitle(cmd.titlescount, cmd.titles);
// TODO: Original code uses pointer arithmetic:
// (void*)((unsigned short*)(pCmd->titles) + pCmd->titlescount)
// InitTitlePlus(cmd.expirecount, null);
// CECUIHelper.OnQueryTitleRe();
}
}
else if (header == CommandID.CHANGE_CURR_TITLE_RE)
{
// Replace unsafe pointer cast
// var cmd = msg.dwParam1 as cmd_change_curr_title_re;
var cmd = GPDataTypeHelper.FromBytes(pDataBuf);
// if (cmd != null)
{
// TODO: Update current title in UI
// var dlg = gameUI.GetDialog("Win_TitleList") as CDlgTitleList;
// SetCurrentTitle(cmd.titleid);
// dlg?.Update();
}
}
else if (header == CommandID.MODIFY_TITLE_NOFIFY)
{
// Replace unsafe pointer cast
// var cmd = msg.dwParam1 as cmd_modify_title_notify;
var cmd = GPDataTypeHelper.FromBytes(pDataBuf);
// if (cmd != null)
{
bool add = cmd.flag != 0;
if (add)
{
// TODO: Update UI to add title
// CECUIHelper.AddTitle(cmd.id, cmd.expiretime);
// If first title, auto change current title
if (m_Titles.Count == 0)
{
// TODO: Original code calls g_pGame.GetGameSession()
// g_pGame.GetGameSession().c2s_CmdChangeTitle(cmd.id);
// EC_Game.GetGameSession().c2s_CmdChangeTitle(cmd.id);
}
}
// TODO: Update UI to modify title
// ModifyTitle(cmd.id, cmd.expiretime, add);
}
}
}
public void InitTitle(int count, ushort[] id)
{
m_Titles.Clear();
m_bTitleDataReady = true;
// if (id == NULL) return;
for (int i = 0; i < count; ++i)
{
m_Titles.Add(new TITLE(id[i], 0));
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct TITLE
{
public ushort id;
public int expire_time;
public TITLE(ushort _id, int _expire_time)
{
id = _id;
expire_time = _expire_time;
}
// TITLE(unsigned short _id, int _expire_time):id(_id),expire_time(_expire_time){}
// bool operator == (const TITLE& rhs) const {return id == rhs.id;}
};
}
}