1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use BinRead;
use Cursor;
/// SQPK `T` command body: declares the target platform, region, and patch
/// statistics for all subsequent operations in a patch file.
///
/// A real FFXIV patch file begins with a `T` command before any write
/// operations, so the platform declared here is in effect for all subsequent
/// path resolution. The apply layer updates [`crate::apply::ApplyContext::platform`]
/// from [`platform_id`](SqpkTargetInfo::platform_id) and otherwise ignores the
/// remaining fields.
///
/// ## Wire format
///
/// **Important:** Most fields are big-endian (the struct-level `#[br(big)]`
/// default), but [`deleted_data_size`](SqpkTargetInfo::deleted_data_size) and
/// [`seek_count`](SqpkTargetInfo::seek_count) are **little-endian**. This
/// endian anomaly is present in the original C# implementation
/// (`SqpkTargetInfo.cs`) and must be preserved exactly.
///
/// ```text
/// ┌───────────────────────────────────────────────────────────────────┐
/// │ <reserved> : [u8; 3] (always zero) │ bytes 0–2
/// │ platform_id : u16 BE 0=Win32, 1=PS3, 2=PS4 │ bytes 3–4
/// │ region : i16 BE -1=Global │ bytes 5–6
/// │ is_debug : i16 BE 0=release, nonzero=debug │ bytes 7–8
/// │ version : u16 BE client version │ bytes 9–10
/// │ deleted_data_size : u64 LE ← little-endian anomaly │ bytes 11–18
/// │ seek_count : u64 LE ← little-endian anomaly │ bytes 19–26
/// │ <trailing padding> bounded by the body slice │
/// └───────────────────────────────────────────────────────────────────┘
/// ```
///
/// ## Reference
///
/// See `SqpkTargetInfo.cs` in the `XIVLauncher` reference implementation.
///
/// # Errors
///
/// Parsing returns [`crate::ZiPatchError::BinrwError`] if the body is too
/// short to contain all required fields.
pub