using System; using System.Runtime.InteropServices; namespace BrewMonster.Scripts.Task { [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct task_sub_tags { // private const int MAX_SUB_TAGS = 32; // union // { // unsigned short sub_task; // unsigned char state; // }; // IMPORTANT: union public ushort sub_task; public byte state; public byte sz; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.MAX_SUB_TAGS)] public byte[] tags; public byte cur_index; // for temporary use, dont take into account public int get_size() { return sz + 3; } public bool valid_size(int _sz) { if (_sz < 3) return false; return get_size() == _sz; } }; [StructLayout(LayoutKind.Sequential, Pack = 1)] public class task_notify_base { public byte reason; public ushort task; }; [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct cmd_task_notify { public uint size; public byte placeholder; // Task data ... } [StructLayout(LayoutKind.Sequential, Pack = 1)] public class svr_monster_killed : task_notify_base { public uint monster_id; public ushort monster_num; public int dps; public int dph; }; [StructLayout(LayoutKind.Sequential, Pack = 1)] public class svr_player_killed : task_notify_base { public ushort index; public ushort player_num; }; [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct StorageTaskList { // unsigned short m_Storages[TASK_STORAGE_COUNT][TASK_STORAGE_LEN]; // NOTE: 2D array flattened [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.TASK_STORAGE_COUNT * TaskTemplConstants.TASK_STORAGE_LEN)] public ushort[] m_Storages; // union { // unsigned short m_StoragesTaskSetCount[TASK_STORAGE_COUNT]; // unsigned short m_StoragesRefreshCount[TASK_STORAGE_COUNT]; // }; // NOTE: union [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.TASK_STORAGE_COUNT)] public ushort[] m_StoragesTaskSetCount; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.TASK_STORAGE_COUNT)] public ushort[] m_StoragesRefreshCount; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.TASK_STORAGE_COUNT)] public uint[] m_StoragesRefreshTime; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskTemplConstants.TASK_STORAGE_COUNT)] public byte[] m_StoragesReceivePerDay; public void RemoveAll() { for (int i = 0; i < TaskTemplConstants.TASK_STORAGE_COUNT; i++) { for (int j = 0; j < TaskTemplConstants.TASK_STORAGE_LEN; j++) { m_Storages[i * TaskTemplConstants.TASK_STORAGE_LEN + j] = 0; } m_StoragesTaskSetCount[i] = 0; m_StoragesRefreshCount[i] = 0; m_StoragesRefreshTime[i] = 0; m_StoragesReceivePerDay[i] = 0; } } public void ReadByte(byte[] data) { int offset = 0; for (int i=0; i < TaskTemplConstants.TASK_STORAGE_COUNT; i++) { for (int j=0; j < TaskTemplConstants.TASK_STORAGE_LEN; j++) { m_Storages[i * TaskTemplConstants.TASK_STORAGE_LEN + j] = BitConverter.ToUInt16(data, (i * TaskTemplConstants.TASK_STORAGE_LEN + j) * 2); } } offset += TaskTemplConstants.TASK_STORAGE_COUNT * TaskTemplConstants.TASK_STORAGE_LEN * 2; // union for (int i=0; i < TaskTemplConstants.TASK_STORAGE_COUNT; i++) { m_StoragesTaskSetCount[i] = BitConverter.ToUInt16(data, offset + i * 2); m_StoragesRefreshCount[i] = BitConverter.ToUInt16(data, offset + i * 2); } offset += TaskTemplConstants.TASK_STORAGE_COUNT * 2; for (int i=0; i < TaskTemplConstants.TASK_STORAGE_COUNT; i++) { m_StoragesRefreshTime[i] = BitConverter.ToUInt32(data, offset + i * 4); } offset += TaskTemplConstants.TASK_STORAGE_COUNT * 4; for (int i=0; i < TaskTemplConstants.TASK_STORAGE_COUNT; i++) { m_StoragesReceivePerDay[i] = data[offset + i]; } } } public class svr_new_task : task_notify_base { public uint cur_time; public uint cap_task; public task_sub_tags sub_tags; public void set_data( uint _cur_time, uint _cap_task, task_sub_tags _sub_tags) { cur_time = _cur_time; cap_task = _cap_task; // memcpy(&sub_tags, &_sub_tags, _sub_tags.get_size()); sub_tags = _sub_tags; } public void get_data( ref uint _cur_time, ref uint _cap_task, ref task_sub_tags _sub_tags) { _cur_time = cur_time; _cap_task = cap_task; // memcpy(&_sub_tags, &sub_tags, sub_tags.get_size()); _sub_tags = sub_tags; } // inline size_t get_size() const { return sizeof(task_notify_base) + 8 + sub_tags.get_size(); } public int get_size() { return Marshal.SizeOf() + 8 + sub_tags.get_size(); } public bool valid_size(int sz) { int base_sz = Marshal.SizeOf() + 8; if (sz <= base_sz) return false; return sub_tags.valid_size(sz - base_sz); } } public class svr_treasure_map : task_notify_base { public int treasure_index; } struct tm { int tm_sec; /* seconds after the minute [0-60] */ int tm_min; /* minutes after the hour [0-59] */ int tm_hour; /* hours since midnight [0-23] */ int tm_mday; /* day of the month [1-31] */ int tm_mon; /* months since January [0-11] */ int tm_year; /* years since 1900 */ int tm_wday; /* days since Sunday [0-6] */ int tm_yday; /* days since January 1 [0-365] */ int tm_isdst; /* Daylight Savings Time flag */ long tm_gmtoff; /* offset from UTC in seconds */ byte tm_zone; /* timezone abbreviation */ }; [StructLayout(LayoutKind.Explicit)] public struct TaskGlobalData { [FieldOffset(0)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = TaskInterfaceConstants.TASK_GLOBAL_DATA_SIZE)] public byte[] buf; [FieldOffset(0)] public ulong m_ulReceiverNum; [FieldOffset(8)] public ulong m_ulRcvUpdateTime; void AddRevNum() { m_ulReceiverNum++; } void CheckRcvUpdateTime(uint ulCurTime, int nFrequency) { // TODO: implement time-based receiver number reset logic // if (nFrequency == TaskCompletionMethod.enumTAFNormal || m_ulRcvUpdateTime == 0) // return; // // tm tmCur = *localtime((time_t*)&ulCurTime); // tm tmRcv = *localtime((time_t*)&m_ulRcvUpdateTime); // // if (nFrequency == enumTAFEachDay) // { // if (tmCur.tm_year != tmRcv.tm_year || tmCur.tm_yday != tmRcv.tm_yday) // m_ulReceiverNum = 0; // } // else if (nFrequency == enumTAFEachWeek) // { // if (!_is_same_week(&tmCur, &tmRcv, ulCurTime, m_ulRcvUpdateTime)) // m_ulReceiverNum = 0; // } // else if (nFrequency == enumTAFEachMonth) // { // if (tmCur.tm_year != tmRcv.tm_year || tmCur.tm_mon != tmRcv.tm_mon) // m_ulReceiverNum = 0; // } // else if (nFrequency == enumTAFEachYear) // { // if (tmCur.tm_year != tmRcv.tm_year) // m_ulReceiverNum = 0; // } } } public class svr_task_complete : task_notify_base { public uint cur_time; public task_sub_tags sub_tags; public void set_data( uint _cur_time, task_sub_tags _sub_tags ) { cur_time = _cur_time; // memcpy(&sub_tags, &_sub_tags, _sub_tags.get_size()); sub_tags = _sub_tags; } public void get_data( ref uint _cur_time, ref task_sub_tags _sub_tags) { _cur_time = cur_time; // memcpy(&_sub_tags, &sub_tags, sub_tags.get_size()); _sub_tags = sub_tags; } public int get_size() { return Marshal.SizeOf() + 4 + sub_tags.get_size(); } public bool valid_size(int sz) { int base_sz = Marshal.SizeOf() + 4; if (sz <= base_sz) return false; return sub_tags.valid_size(sz - base_sz); } } }