fix convert task data
This commit is contained in:
@@ -9,7 +9,7 @@ When reading binary data from C++ files using `FileStream`, follow these convers
|
||||
## Important Type Mappings
|
||||
|
||||
- `unsigned long` in C++ → `uint` in C#
|
||||
- `bool` in C++ → 1 byte (same as C# in struct layout)
|
||||
- `bool` in C++ → 1 byte (read as `byte` in C#, then convert with `> 0`)
|
||||
- `wchar_t` on Windows → 2 bytes
|
||||
- `task_char` → `ushort`
|
||||
- Pointer size in C++ binary → typically 4 bytes (32-bit)
|
||||
@@ -32,13 +32,24 @@ float m_fLibraryTasksProbability;
|
||||
```csharp
|
||||
// Read value and assign to the field
|
||||
fixedData.m_ID = AAssit.ReadFromBinaryOf<uint>(fp, ref readBytes);
|
||||
fixedData.m_bHasSign = AAssit.ReadFromBinaryOf<bool>(fp, ref readBytes);
|
||||
|
||||
// Special case for bool: read as byte and compare with > 0
|
||||
fixedData.m_bHasSign = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0;
|
||||
fixedData.m_bChooseOne = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0;
|
||||
|
||||
// Other primitive types
|
||||
fixedData.m_lAvailFrequency = AAssit.ReadFromBinaryOf<int>(fp, ref readBytes);
|
||||
fixedData.m_fLibraryTasksProbability = AAssit.ReadFromBinaryOf<float>(fp, ref readBytes);
|
||||
```
|
||||
|
||||
**Rule**: Use `AAssit.ReadFromBinaryOf<T>(fp, ref readBytes)` where T is the C# equivalent type.
|
||||
|
||||
**Important for bool**: C++ bool is stored as 1 byte in binary files. Always read as `byte` and convert to C# bool using `> 0`:
|
||||
```csharp
|
||||
// Correct pattern for bool
|
||||
fixedData.m_boolField = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Case 2: Fixed-Size Arrays (Inline Memory)
|
||||
@@ -195,8 +206,8 @@ task_tm* m_tmStart; // Only has data if m_ulTimetable > 0
|
||||
|
||||
**C# Conversion**:
|
||||
```csharp
|
||||
// First read the flag/count
|
||||
fixedData.m_bHasSign = AAssit.ReadFromBinaryOf<bool>(fp, ref readBytes);
|
||||
// First read the flag/count (read bool as byte and convert with > 0)
|
||||
fixedData.m_bHasSign = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0;
|
||||
|
||||
// Skip the pointer (Case 3)
|
||||
fp.Seek(4, SeekOrigin.Current);
|
||||
@@ -250,6 +261,20 @@ public static T[] ReadArrayFromBinary<T>(FileStream fp, int count, ref long read
|
||||
|
||||
## Common Mistakes to Avoid
|
||||
|
||||
❌ **Wrong**: Reading bool directly as bool type
|
||||
```csharp
|
||||
// C++: bool m_bHasSign
|
||||
fixedData.m_bHasSign = AAssit.ReadFromBinaryOf<bool>(fp, ref readBytes); // Wrong!
|
||||
```
|
||||
|
||||
✅ **Correct**:
|
||||
```csharp
|
||||
// Read as byte and compare with > 0
|
||||
fixedData.m_bHasSign = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0; // Correct!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
❌ **Wrong**: Skipping pointer size instead of basic type size for Case 5
|
||||
```csharp
|
||||
// C++: ushort* m_pszSignature
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace PerfectWorld.Scripts.Task
|
||||
pOffs = AAssit.ReadArrayFromBinary<uint>(fs, (int)tph.item_count, ref readBytes);
|
||||
|
||||
|
||||
for (int i = 0; i < 1; i++) //TODO: tph.item_count
|
||||
for (int i = 0; i < 3; i++) //TODO: tph.item_count
|
||||
{
|
||||
fs.Seek(pOffs[i], SeekOrigin.Begin);
|
||||
|
||||
|
||||
@@ -2457,95 +2457,146 @@ namespace PerfectWorld.Scripts.Task
|
||||
}
|
||||
private bool LoadFixedDataFromBinFile(FileStream fp)
|
||||
{
|
||||
for (int i = 1; i <= 8; i++)
|
||||
{
|
||||
for (int j = 1; j <= 8; j++)
|
||||
{
|
||||
Debug.LogError($"==== {i},{j} ===");
|
||||
ConvertFixedData(fp, i, j);
|
||||
Debug.LogError($"==========");
|
||||
}
|
||||
}
|
||||
// for (int j = 1; j <= 20; j++)
|
||||
// {
|
||||
// Debug.LogError($"==== {j} ===");
|
||||
// ConvertFixedData(fp, j);
|
||||
// Debug.LogError($"==========");
|
||||
// }
|
||||
ConvertFixedData(fp, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ConvertFixedData(FileStream fp, int x1, int x2)
|
||||
private void ConvertFixedData(FileStream fp, int x2)
|
||||
{
|
||||
long readBytes = 0;
|
||||
BMLogger.Log($"LoadFixedDataFromBinFile: {fp.Length}");
|
||||
ATaskTemplFixedData fixedData;
|
||||
|
||||
// Task ID
|
||||
fixedData.m_ID = AAssit.ReadFromBinaryOf<uint>(fp, ref readBytes); // unsigned long m_ID;
|
||||
BMLogger.Log($"LoadFixedDataFromBinFile: {fixedData.m_ID}");
|
||||
var originalPos = fp.Position;
|
||||
// Task ID
|
||||
fixedData.m_ID = AAssit.ReadFromBinaryOf<uint>(fp, ref readBytes); // unsigned long m_ID;
|
||||
BMLogger.LogError($"m_ID: {fixedData.m_ID}");
|
||||
|
||||
// Task Name (task_char m_szName[MAX_TASK_NAME_LEN];)
|
||||
fixedData.m_szName = AAssit.ReadArrayFromBinary<ushort>(fp, x1*TaskTemplConstants.MAX_TASK_NAME_LEN, ref readBytes);
|
||||
// Debug.LogError($"m_szName: {fixedData.m_szName}");
|
||||
// Task Name (task_char m_szName[MAX_TASK_NAME_LEN];)
|
||||
fixedData.m_szName = AAssit.ReadArrayFromBinary<ushort>(fp, TaskTemplConstants.MAX_TASK_NAME_LEN, ref readBytes); //64
|
||||
|
||||
// Has Signature (bool m_bHasSign;)
|
||||
fixedData.m_bHasSign = AAssit.ReadFromBinaryOf<bool>(fp, ref readBytes);
|
||||
Debug.LogError($"m_bHasSign: {fixedData.m_bHasSign}");
|
||||
// Has Signature (bool m_bHasSign;)
|
||||
fixedData.m_bHasSign = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0;
|
||||
BMLogger.LogError($"m_bHasSign: {fixedData.m_bHasSign}"); //68
|
||||
|
||||
// Signature pointer (task_char* m_pszSignature;)
|
||||
// Only the pointer address is stored in the binary (skip 4 bytes)
|
||||
fp.Seek(x2, SeekOrigin.Current);
|
||||
// Signature pointer (task_char* m_pszSignature;)
|
||||
// Only the pointer address is stored in the binary (skip 4 bytes)
|
||||
fp.Seek(4, SeekOrigin.Current);
|
||||
|
||||
// Task Type (unsigned long m_ulType;)
|
||||
fixedData.m_ulType = AAssit.ReadFromBinaryOf<uint>(fp, ref readBytes);
|
||||
// Debug.LogError($"Type: {fixedData.m_ulType}");
|
||||
// Task Type (unsigned long m_ulType;)
|
||||
fixedData.m_ulType = AAssit.ReadFromBinaryOf<uint>(fp, ref readBytes);//value 103
|
||||
BMLogger.LogError($"Type: {fixedData.m_ulType}");
|
||||
|
||||
// Time Limit (unsigned long m_ulTimeLimit;)
|
||||
fixedData.m_ulTimeLimit = AAssit.ReadFromBinaryOf<uint>(fp, ref readBytes);
|
||||
|
||||
if (fixedData.m_ulType == 103)
|
||||
{
|
||||
//fixedData.m_bHasSign ==0 &&
|
||||
Debug.LogError("Catch it!");
|
||||
}
|
||||
// Offline Fail (bool m_bOfflineFail;)
|
||||
fixedData.m_bOfflineFail = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0;
|
||||
|
||||
// Time Limit (unsigned long m_ulTimeLimit;)
|
||||
fixedData.m_ulTimeLimit = AAssit.ReadFromBinaryOf<uint>(fp, ref readBytes);
|
||||
// Absolute Fail (bool m_bAbsFail;)
|
||||
fixedData.m_bAbsFail = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0;
|
||||
|
||||
// Offline Fail (bool m_bOfflineFail;)
|
||||
fixedData.m_bOfflineFail = AAssit.ReadFromBinaryOf<bool>(fp, ref readBytes);
|
||||
// Absolute Fail Time (task_tm m_tmAbsFailTime;)
|
||||
fixedData.m_tmAbsFailTime = AAssit.ReadFromBinaryOf<task_tm>(fp, ref readBytes);
|
||||
|
||||
|
||||
|
||||
// Absolute Fail (bool m_bAbsFail;)
|
||||
fixedData.m_bAbsFail = AAssit.ReadFromBinaryOf<bool>(fp, ref readBytes);
|
||||
// (unsigned long m_ulAbsFailTime;) // commented out in C++ source
|
||||
|
||||
// Absolute Fail Time (task_tm m_tmAbsFailTime;)
|
||||
fixedData.m_tmAbsFailTime = AAssit.ReadFromBinaryOf<task_tm>(fp, ref readBytes);
|
||||
// Item Not Take Off (bool m_bItemNotTakeOff;)
|
||||
fixedData.m_bItemNotTakeOff = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0;
|
||||
|
||||
// (unsigned long m_ulAbsFailTime;) // commented out in C++ source
|
||||
// Absolute Time (bool m_bAbsTime;)
|
||||
fixedData.m_bAbsTime = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0;
|
||||
|
||||
|
||||
|
||||
// Item Not Take Off (bool m_bItemNotTakeOff;)
|
||||
fixedData.m_bItemNotTakeOff = AAssit.ReadFromBinaryOf<bool>(fp, ref readBytes);
|
||||
// Timetable count (unsigned long m_ulTimetable;)
|
||||
fixedData.m_ulTimetable = AAssit.ReadFromBinaryOf<uint>(fp, ref readBytes);
|
||||
|
||||
// Absolute Time (bool m_bAbsTime;)
|
||||
fixedData.m_bAbsTime = AAssit.ReadFromBinaryOf<bool>(fp, ref readBytes);
|
||||
// Timetable type (char m_tmType[MAX_TIMETABLE_SIZE];)
|
||||
fixedData.m_tmType = AAssit.ReadArrayFromBinary<byte>(fp, TaskTemplConstants.MAX_TIMETABLE_SIZE, ref readBytes);
|
||||
|
||||
// Timetable count (unsigned long m_ulTimetable;)
|
||||
fixedData.m_ulTimetable = AAssit.ReadFromBinaryOf<uint>(fp, ref readBytes);
|
||||
// Start time pointer (task_tm* m_tmStart; [MAX_TIMETABLE_SIZE])
|
||||
// Only the pointer address is stored in the binary (skip 4 bytes)
|
||||
fp.Seek(4, SeekOrigin.Current);
|
||||
|
||||
// Timetable type (char m_tmType[MAX_TIMETABLE_SIZE];)
|
||||
fixedData.m_tmType = AAssit.ReadArrayFromBinary<byte>(fp, TaskTemplConstants.MAX_TIMETABLE_SIZE, ref readBytes);
|
||||
// End time pointer (task_tm* m_tmEnd; [MAX_TIMETABLE_SIZE])
|
||||
// Only the pointer address is stored in the binary (skip 4 bytes)
|
||||
fp.Seek(4, SeekOrigin.Current);
|
||||
|
||||
// Start time pointer (task_tm* m_tmStart; [MAX_TIMETABLE_SIZE])
|
||||
// Only the pointer address is stored in the binary (skip 4 bytes)
|
||||
fp.Seek(4, SeekOrigin.Current);
|
||||
// Available frequency (long m_lAvailFrequency;)
|
||||
fixedData.m_lAvailFrequency = AAssit.ReadFromBinaryOf<int>(fp, ref readBytes);
|
||||
|
||||
// End time pointer (task_tm* m_tmEnd; [MAX_TIMETABLE_SIZE])
|
||||
// Only the pointer address is stored in the binary (skip 4 bytes)
|
||||
fp.Seek(4, SeekOrigin.Current);
|
||||
// Period limit (long m_lPeriodLimit;)
|
||||
fixedData.m_lPeriodLimit = AAssit.ReadFromBinaryOf<int>(fp, ref readBytes);
|
||||
|
||||
// Available frequency (long m_lAvailFrequency;)
|
||||
fixedData.m_lAvailFrequency = AAssit.ReadFromBinaryOf<int>(fp, ref readBytes);
|
||||
// Choose one subtask (bool m_bChooseOne;)
|
||||
fixedData.m_bChooseOne = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0;
|
||||
|
||||
// Period limit (long m_lPeriodLimit;)
|
||||
fixedData.m_lPeriodLimit = AAssit.ReadFromBinaryOf<int>(fp, ref readBytes);
|
||||
// Random one subtask (bool m_bRandOne;)
|
||||
fixedData.m_bRandOne = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0;
|
||||
|
||||
// bool m_bExeChildInOrder;
|
||||
// Whether subtasks are executed in order
|
||||
fixedData.m_bExeChildInOrder = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0; // 是否子任务有顺序 // Whether subtasks are executed in order
|
||||
|
||||
// Choose one subtask (bool m_bChooseOne;)
|
||||
fixedData.m_bChooseOne = AAssit.ReadFromBinaryOf<bool>(fp, ref readBytes);
|
||||
// bool m_bParentAlsoFail;
|
||||
// Whether the parent task fails if this one does
|
||||
fixedData.m_bParentAlsoFail = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0; // 失败后是否认为父任务也失败 // Whether the parent task fails if this one does
|
||||
|
||||
// Whether parent task succeeds after subtask succeeds
|
||||
// bool m_bParentAlsoSucc;
|
||||
fixedData.m_bParentAlsoSucc = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0; // 子任务成功后父任务成功 // Whether parent task succeeds after subtask succeeds
|
||||
|
||||
// Random one subtask (bool m_bRandOne;)
|
||||
fixedData.m_bRandOne = AAssit.ReadFromBinaryOf<bool>(fp, ref readBytes);
|
||||
// Whether this task can be abandoned
|
||||
// bool m_bCanGiveUp;
|
||||
fixedData.m_bCanGiveUp = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0; // 能否放弃此任务 // Whether this task can be abandoned
|
||||
|
||||
// Whether the task can be repeated/completed again
|
||||
// bool m_bCanRedo;
|
||||
fixedData.m_bCanRedo = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0; // 是否可重复完成 // Whether the task can be repeated/completed again
|
||||
|
||||
// Whether task can be repeated after failure
|
||||
// bool m_bCanRedoAfterFailure;
|
||||
fixedData.m_bCanRedoAfterFailure = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0; // 失败后是否可重新完成 // Whether task can be repeated after failure
|
||||
|
||||
// Give up clears the task
|
||||
// bool m_bClearAsGiveUp;
|
||||
fixedData.m_bClearAsGiveUp = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0; // 放弃清空任务 // Give up clears the task
|
||||
|
||||
// Whether recording is needed
|
||||
// bool m_bNeedRecord;
|
||||
fixedData.m_bNeedRecord = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0; // 是否需要记录 // Whether recording is needed
|
||||
|
||||
// Player's death causes failure
|
||||
// bool m_bFailAsPlayerDie;
|
||||
fixedData.m_bFailAsPlayerDie = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0; // 玩家被击杀是否认为失败 // Player's death causes failure
|
||||
|
||||
// Maximum number of receivers
|
||||
// unsigned long m_ulMaxReceiver;
|
||||
fixedData.m_ulMaxReceiver = AAssit.ReadFromBinaryOf<uint>(fp, ref readBytes); // 接受者上限 // Maximum number of receivers
|
||||
|
||||
// Is in delivery zone
|
||||
// bool m_bDelvInZone;
|
||||
fixedData.m_bDelvInZone = AAssit.ReadFromBinaryOf<byte>(fp, ref readBytes) > 0; // 发放区域 // Is in delivery zone
|
||||
|
||||
// Delivery world id
|
||||
// unsigned long m_ulDelvWorld;
|
||||
fixedData.m_ulDelvWorld = AAssit.ReadFromBinaryOf<uint>(fp, ref readBytes); // 发放世界 // Delivery world id
|
||||
|
||||
// Number of delivery regions
|
||||
// unsigned long m_ulDelvRegionCnt;
|
||||
fixedData.m_ulDelvRegionCnt = AAssit.ReadFromBinaryOf<uint>(fp, ref readBytes); // 发放区域计数 // Number of delivery regions
|
||||
|
||||
fp.Seek(originalPos, SeekOrigin.Begin);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user