From e124f2fab12e8a09066a06c4b2421b29f6c4e389 Mon Sep 17 00:00:00 2001 From: HungDK <> Date: Tue, 16 Dec 2025 11:02:28 +0700 Subject: [PATCH] Implement write task struct data logic --- .../Scripts/Task/TaskTempl.Struct.cs | 102 ++++++++++++++++-- 1 file changed, 92 insertions(+), 10 deletions(-) diff --git a/Assets/PerfectWorld/Scripts/Task/TaskTempl.Struct.cs b/Assets/PerfectWorld/Scripts/Task/TaskTempl.Struct.cs index 9929273a4d..6dc02a28a2 100644 --- a/Assets/PerfectWorld/Scripts/Task/TaskTempl.Struct.cs +++ b/Assets/PerfectWorld/Scripts/Task/TaskTempl.Struct.cs @@ -100,8 +100,23 @@ namespace BrewMonster.Scripts.Task [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.TASK_STORAGE_COUNT)] public byte[] m_StoragesReceivePerDay; + // Initialize arrays if they are null + // In C++, arrays are automatically allocated on the stack, but in C# they need explicit initialization + public void EnsureInitialized() + { + if (m_Storages == null) + m_Storages = new ushort[TaskTemplConstants.TASK_STORAGE_COUNT * TaskTemplConstants.TASK_STORAGE_LEN]; + if (m_StoragesTaskSetCount == null) + m_StoragesTaskSetCount = new ushort[TaskTemplConstants.TASK_STORAGE_COUNT]; + if (m_StoragesRefreshTime == null) + m_StoragesRefreshTime = new uint[TaskTemplConstants.TASK_STORAGE_COUNT]; + if (m_StoragesReceivePerDay == null) + m_StoragesReceivePerDay = new byte[TaskTemplConstants.TASK_STORAGE_COUNT]; + } + public void RemoveAll() { + EnsureInitialized(); for (int i = 0; i < TaskTemplConstants.TASK_STORAGE_COUNT; i++) { for (int j = 0; j < TaskTemplConstants.TASK_STORAGE_LEN; j++) @@ -117,6 +132,11 @@ namespace BrewMonster.Scripts.Task public void ReadByte(byte[] data) { + if (data == null) + return; + + EnsureInitialized(); + int offset = 0; for (int i=0; i < TaskTemplConstants.TASK_STORAGE_COUNT; i++) { @@ -436,8 +456,58 @@ namespace BrewMonster.Scripts.Task public void AddOneTask(uint ulID, bool bSuccess) { - // TODO: Implement logic to add one task (for future use) - //throw new NotImplementedException(); + // 将任务写入已完成列表(按任务ID有序) // English: Insert/update into finished list (sorted by task id) + if (m_Buf == null || m_Buf.Length != TaskInterfaceConstants.TASK_FINISHED_LIST_BUF_SIZE) + { + m_Buf = new byte[TaskInterfaceConstants.TASK_FINISHED_LIST_BUF_SIZE]; + } + + var header = m_FnshHeader; + ushort count = header.m_uTaskCount; + if (count >= TaskInterfaceConstants.TASK_FINISHED_LIST_MAX_LEN) return; + + int entrySize = Marshal.SizeOf(); // should be 4 + int pos = GetTaskPos(ulID); + + byte mask = (byte)(bSuccess ? 0 : 1); + + if (pos >= 0) + { + // Update existing entry + int start = 4 + pos * entrySize; + // m_uTaskId + Array.Copy(BitConverter.GetBytes((ushort)ulID), 0, m_Buf, start, 2); + // m_Buf (mask + reserved bits) + m_Buf[start + 2] = (byte)((m_Buf[start + 2] & 0xFE) | (mask & 0x1)); + // m_FnshedCount: keep at least 1 + if (m_Buf[start + 3] == 0) m_Buf[start + 3] = 1; + return; + } + + // Find insertion index to keep sorted order + int insert = 0; + for (; insert < count; insert++) + { + ushort existingId = BitConverter.ToUInt16(m_Buf, 4 + insert * entrySize); + if (ulID < existingId) break; + } + + // Shift bytes to make room + int srcStart = 4 + insert * entrySize; + int bytesToMove = (count - insert) * entrySize; + if (bytesToMove > 0) + { + Buffer.BlockCopy(m_Buf, srcStart, m_Buf, srcStart + entrySize, bytesToMove); + } + + // Write new entry + int dst = 4 + insert * entrySize; + Array.Copy(BitConverter.GetBytes((ushort)ulID), 0, m_Buf, dst, 2); + m_Buf[dst + 2] = (byte)(mask & 0x1); // reserved bits 0 + m_Buf[dst + 3] = 1; // finish count + + header.m_uTaskCount = (ushort)(count + 1); + m_FnshHeader = header; } public void RemoveTask(uint ulID) @@ -461,22 +531,34 @@ namespace BrewMonster.Scripts.Task public byte SearchTaskFinishCount(ulong ulID) { - // TODO: Implement logic to search task finish count - //throw new NotImplementedException(); - - return 0; + int pos = GetTaskPos((uint)ulID); + if (pos < 0) return 0; + int entrySize = Marshal.SizeOf(); + int start = 4 + pos * entrySize; + return m_Buf[start + 3]; // m_FnshedCount } public void ResetFinishCount(ulong ulID) { - // TODO: Implement logic to reset finish count - //throw new NotImplementedException(); + int pos = GetTaskPos((uint)ulID); + if (pos < 0) return; + int entrySize = Marshal.SizeOf(); + int start = 4 + pos * entrySize; + m_Buf[start + 3] = 0; } public void AddForFinishCount(ulong ulID, bool bSuccess) { - // TODO: Implement logic to add for finish count - //throw new NotImplementedException(); + // 只用于计数:如果不存在则插入;如果存在则递增 m_FnshedCount + // English: Finish-count bookkeeping: insert if missing; otherwise increment m_FnshedCount. + AddOneTask((uint)ulID, bSuccess); + + int pos = GetTaskPos((uint)ulID); + if (pos < 0) return; + int entrySize = Marshal.SizeOf(); + int start = 4 + pos * entrySize; + byte cur = m_Buf[start + 3]; + if (cur < byte.MaxValue) m_Buf[start + 3] = (byte)(cur + 1); } public void RemoveAll()