add notes about protected subcommands

This commit is contained in:
Martin Michelsen
2023-12-25 22:27:41 -08:00
parent d59b59cd51
commit c100d76a5b
+79 -69
View File
@@ -3706,6 +3706,15 @@ struct S_SetShutdownCommand_BB_01EF {
// commands must be used. The 60 and 62 commands exhibit undefined behavior if
// this limit is exceeded.
// Some subcommands are "protected" on V3 and later (not including GC NTE);
// these commands are blocked by the client if they affect the local player. If
// a V3 or later client receives a protected subcommand that would affect its
// own player, it instead ignores the entire subcommand. This means that the
// server or other players cannot send these subcommands to affect other
// players; they can only send these commands to inform other clients about
// changes or actions from their own player.
// The protected subcommands are marked (protected) in the listings below.
// These common structures are used my many subcommands.
struct G_ClientIDHeader {
uint8_t subcommand = 0;
@@ -3840,8 +3849,8 @@ struct G_BoxDestroyed_6x0B {
le_uint32_t object_index = 0;
} __packed__;
// 6x0C: Add condition (poison/slow/etc.)
// 6x0D: Remove condition (poison/slow/etc.)
// 6x0C: Add condition (poison/slow/etc.) (protected on V3/V4)
// 6x0D: Remove condition (poison/slow/etc.) (protected on V3/V4)
struct G_AddOrRemoveCondition_6x0C_6x0D {
G_ClientIDHeader header;
@@ -3849,7 +3858,7 @@ struct G_AddOrRemoveCondition_6x0C_6x0D {
le_uint32_t unknown_a2 = 0;
} __packed__;
// 6x0E: Unknown
// 6x0E: Unknown (protected on V3/V4)
struct G_Unknown_6x0E {
G_ClientIDHeader header;
@@ -3945,13 +3954,13 @@ struct G_DarkFalzActions_6x19 {
// 6x1A: Invalid subcommand
// 6x1B: Unknown (not valid on Episode 3)
// 6x1B: Unknown (not valid on Episode 3) (protected on V3/V4)
struct G_Unknown_6x1B {
G_ClientIDHeader header;
} __packed__;
// 6x1C: Destroy NPC
// 6x1C: Destroy NPC (protected on V3/V4)
struct G_DestroyNPC_6x1C {
G_ClientIDHeader header;
@@ -3971,7 +3980,7 @@ struct G_SetPlayerFloor_6x1F {
le_int32_t floor = 0;
} __packed__;
// 6x20: Set position
// 6x20: Set position (protected on V3/V4)
// Existing clients send this in response to a 6x1F command when a new client
// joins a lobby or game, so the new client knows where to place them.
@@ -3984,22 +3993,22 @@ struct G_SetPosition_6x20 {
le_uint32_t unknown_a1 = 0;
} __packed__;
// 6x21: Inter-level warp
// 6x21: Inter-level warp (protected on V3/V4)
struct G_InterLevelWarp_6x21 {
G_ClientIDHeader header;
le_int32_t floor = 0;
} __packed__;
// 6x22: Set player invisible
// 6x23: Set player visible
// 6x22: Set player invisible (protected on V3/V4)
// 6x23: Set player visible (protected on V3/V4)
// These are generally used while a player is in the process of changing floors.
struct G_SetPlayerVisibility_6x22_6x23 {
G_ClientIDHeader header;
} __packed__;
// 6x24: Teleport player
// 6x24: Teleport player (protected on V3/V4)
struct G_TeleportPlayer_6x24 {
G_ClientIDHeader header;
@@ -4009,7 +4018,7 @@ struct G_TeleportPlayer_6x24 {
le_float z = 0.0f;
} __packed__;
// 6x25: Equip item
// 6x25: Equip item (protected on V3/V4)
struct G_EquipItem_6x25 {
G_ClientIDHeader header;
@@ -4018,7 +4027,7 @@ struct G_EquipItem_6x25 {
le_uint32_t equip_slot = 0;
} __packed__;
// 6x26: Unequip item
// 6x26: Unequip item (protected on V3/V4)
struct G_UnequipItem_6x26 {
G_ClientIDHeader header;
@@ -4026,14 +4035,14 @@ struct G_UnequipItem_6x26 {
le_uint32_t unused = 0;
} __packed__;
// 6x27: Use item
// 6x27: Use item (protected on V3/V4)
struct G_UseItem_6x27 {
G_ClientIDHeader header;
le_uint32_t item_id = 0;
} __packed__;
// 6x28: Feed MAG
// 6x28: Feed MAG (protected on V3/V4)
struct G_FeedMAG_6x28 {
G_ClientIDHeader header;
@@ -4041,7 +4050,7 @@ struct G_FeedMAG_6x28 {
le_uint32_t fed_item_id = 0;
} __packed__;
// 6x29: Delete inventory item (via bank deposit / sale / feeding MAG)
// 6x29: Delete inventory item (via bank deposit / sale / feeding MAG) (protected on V3 but not V4)
// This subcommand is also used for reducing the size of stacks - if amount is
// less than the stack count, the item is not deleted and its ID remains valid.
@@ -4051,7 +4060,7 @@ struct G_DeleteInventoryItem_6x29 {
le_uint32_t amount = 0;
} __packed__;
// 6x2A: Drop item
// 6x2A: Drop item (protected on V3/V4)
struct G_DropItem_6x2A {
G_ClientIDHeader header;
@@ -4063,7 +4072,8 @@ struct G_DropItem_6x2A {
le_float z = 0.0f;
} __packed__;
// 6x2B: Create item in inventory (e.g. via tekker or bank withdraw)
// 6x2B: Create item in inventory (e.g. via tekker or bank withdraw) (protected on V3/V4)
// On BB, the 6xBE command is used instead of 6x2B to create inventory items.
struct G_CreateInventoryItem_DC_6x2B {
G_ClientIDHeader header;
@@ -4076,7 +4086,7 @@ struct G_CreateInventoryItem_PC_V3_BB_6x2B : G_CreateInventoryItem_DC_6x2B {
parray<uint8_t, 2> unused2 = 0;
} __packed__;
// 6x2C: Talk to NPC
// 6x2C: Talk to NPC (protected on V3/V4)
struct G_TalkToNPC_6x2C {
G_ClientIDHeader header;
@@ -4087,13 +4097,13 @@ struct G_TalkToNPC_6x2C {
le_float unknown_a5 = 0.0f;
} __packed__;
// 6x2D: Done talking to NPC
// 6x2D: Done talking to NPC (protected on V3/V4)
struct G_EndTalkToNPC_6x2D {
G_ClientIDHeader header;
} __packed__;
// 6x2E: Set and/or clear player flags
// 6x2E: Set and/or clear player flags (protected on V3/V4)
struct G_SetOrClearPlayerFlags_6x2E {
G_ClientIDHeader header;
@@ -4124,7 +4134,7 @@ struct G_LevelUp_6x30 {
le_uint16_t unknown_a1 = 0; // Must be 0 or 1
} __packed__;
// 6x31: Resurrect player
// 6x31: Resurrect player (protected on V3/V4)
struct G_UseMedicalCenter_6x31 {
G_ClientIDHeader header;
@@ -4136,7 +4146,7 @@ struct G_Unknown_6x32 {
G_UnusedHeader header;
} __packed__;
// 6x33: Resurrect player (with Moon Atomizer)
// 6x33: Resurrect player (with Moon Atomizer) (protected on V3/V4)
struct G_RevivePlayer_6x33 {
G_ClientIDHeader header;
@@ -4152,7 +4162,7 @@ struct G_RevivePlayer_6x33 {
// 6x36: Unknown (supported; game only)
// This subcommand is completely ignored (at least, by PSO GC).
// 6x37: Photon blast
// 6x37: Photon blast (protected on V3/V4)
struct G_PhotonBlast_6x37 {
G_ClientIDHeader header;
@@ -4160,7 +4170,7 @@ struct G_PhotonBlast_6x37 {
le_uint16_t unused = 0;
} __packed__;
// 6x38: Donate to photon blast
// 6x38: Donate to photon blast (protected on V3/V4)
struct G_Unknown_6x38 {
G_ClientIDHeader header;
@@ -4168,19 +4178,19 @@ struct G_Unknown_6x38 {
le_uint16_t unused = 0;
} __packed__;
// 6x39: Photon blast ready
// 6x39: Photon blast ready (protected on V3/V4)
struct G_PhotonBlastReady_6x38 {
G_ClientIDHeader header;
} __packed__;
// 6x3A: Unknown (supported; game only)
// 6x3A: Unknown (supported; game only) (protected on V3/V4)
struct G_Unknown_6x3A {
G_ClientIDHeader header;
} __packed__;
// 6x3B: Unknown (supported; lobby & game)
// 6x3B: Unknown (supported; lobby & game) (protected on V3/V4)
struct G_Unknown_6x3B {
G_ClientIDHeader header;
@@ -4189,7 +4199,7 @@ struct G_Unknown_6x3B {
// 6x3C: Invalid subcommand
// 6x3D: Invalid subcommand
// 6x3E: Stop moving
// 6x3E: Stop moving (protected on V3/V4)
struct G_StopAtPosition_6x3E {
G_ClientIDHeader header;
@@ -4202,7 +4212,7 @@ struct G_StopAtPosition_6x3E {
le_float z = 0.0f;
} __packed__;
// 6x3F: Set position
// 6x3F: Set position (protected on V3/V4)
struct G_SetPosition_6x3F {
G_ClientIDHeader header;
@@ -4215,7 +4225,7 @@ struct G_SetPosition_6x3F {
le_float z = 0.0f;
} __packed__;
// 6x40: Walk
// 6x40: Walk (protected on V3/V4)
struct G_WalkToPosition_6x40 {
G_ClientIDHeader header;
@@ -4227,7 +4237,7 @@ struct G_WalkToPosition_6x40 {
// 6x41: Unknown
// This subcommand is completely ignored (at least, by PSO GC).
// 6x42: Run
// 6x42: Run (protected on V3/V4)
struct G_RunToPosition_6x42 {
G_ClientIDHeader header;
@@ -4235,9 +4245,9 @@ struct G_RunToPosition_6x42 {
le_float z = 0.0f;
} __packed__;
// 6x43: First attack
// 6x44: Second attack
// 6x45: Third attack
// 6x43: First attack (protected on V3/V4)
// 6x44: Second attack (protected on V3/V4)
// 6x45: Third attack (protected on V3/V4)
struct G_Attack_6x43_6x44_6x45 {
G_ClientIDHeader header;
@@ -4245,7 +4255,7 @@ struct G_Attack_6x43_6x44_6x45 {
le_uint16_t unknown_a2 = 0;
} __packed__;
// 6x46: Attack finished (sent after each of 43, 44, and 45)
// 6x46: Attack finished (sent after each of 43, 44, and 45) (protected on V3/V4)
struct G_AttackFinished_6x46 {
G_ClientIDHeader header;
@@ -4258,7 +4268,7 @@ struct G_AttackFinished_6x46 {
parray<TargetEntry, 10> targets;
} __packed__;
// 6x47: Cast technique
// 6x47: Cast technique (protected on V3/V4)
struct G_CastTechnique_6x47 {
G_ClientIDHeader header;
@@ -4279,7 +4289,7 @@ struct G_CastTechnique_6x47 {
parray<TargetEntry, 10> targets;
} __packed__;
// 6x48: Cast technique complete
// 6x48: Cast technique complete (protected on V3/V4)
struct G_CastTechniqueComplete_6x48 {
G_ClientIDHeader header;
@@ -4289,7 +4299,7 @@ struct G_CastTechniqueComplete_6x48 {
le_uint16_t level = 0;
} __packed__;
// 6x49: Subtract photon blast energy
// 6x49: Subtract photon blast energy (protected on V3/V4)
struct G_SubtractPBEnergy_6x49 {
G_ClientIDHeader header;
@@ -4306,14 +4316,14 @@ struct G_SubtractPBEnergy_6x49 {
parray<Entry, 14> entries;
} __packed__;
// 6x4A: Fully shield attack
// 6x4A: Fully shield attack (protected on V3/V4)
struct G_ShieldAttack_6x4A {
G_ClientIDHeader header;
} __packed__;
// 6x4B: Hit by enemy
// 6x4C: Hit by enemy
// 6x4B: Hit by enemy (protected on V3/V4)
// 6x4C: Hit by enemy (protected on V3/V4)
struct G_HitByEnemy_6x4B_6x4C {
G_ClientIDHeader header;
@@ -4323,26 +4333,26 @@ struct G_HitByEnemy_6x4B_6x4C {
le_float z_velocity = 0.0f;
} __packed__;
// 6x4D: Player died
// 6x4D: Player died (protected on V3/V4)
struct G_PlayerDied_6x4D {
G_ClientIDHeader header;
le_uint32_t unknown_a1 = 0;
} __packed__;
// 6x4E: Player died
// 6x4E: Player died (protected on V3/V4)
struct G_PlayerDied_6x4E {
G_ClientIDHeader header;
} __packed__;
// 6x4F: Player resurrected (via Scape Doll)
// 6x4F: Player resurrected (via Scape Doll) (protected on V3/V4)
struct G_PlayerUsedScapeDoll_6x4F {
G_ClientIDHeader header;
} __packed__;
// 6x50: Switch interaction
// 6x50: Switch interaction (protected on V3/V4)
struct G_SwitchInteraction_6x50 {
G_ClientIDHeader header;
@@ -4351,7 +4361,7 @@ struct G_SwitchInteraction_6x50 {
// 6x51: Invalid subcommand
// 6x52: Toggle counter (shop/bank) interaction
// 6x52: Toggle counter (shop/bank) interaction (protected on V3/V4)
struct G_ToggleCounterInteraction_6x52 {
G_ClientIDHeader header;
@@ -4360,7 +4370,7 @@ struct G_ToggleCounterInteraction_6x52 {
le_uint32_t unknown_a3 = 0;
} __packed__;
// 6x53: Unknown (supported; game only)
// 6x53: Unknown (supported; game only) (protected on V3/V4)
struct G_Unknown_6x53 {
G_ClientIDHeader header;
@@ -4369,7 +4379,7 @@ struct G_Unknown_6x53 {
// 6x54: Unknown
// This subcommand is completely ignored (at least, by PSO GC).
// 6x55: Intra-map warp
// 6x55: Intra-map warp (protected on V3/V4)
struct G_IntraMapWarp_6x55 {
G_ClientIDHeader header;
@@ -4382,7 +4392,7 @@ struct G_IntraMapWarp_6x55 {
le_float z2 = 0.0f;
} __packed__;
// 6x56: Unknown (supported; lobby & game)
// 6x56: Unknown (supported; lobby & game) (protected on V3/V4)
struct G_Unknown_6x56 {
G_ClientIDHeader header;
@@ -4392,13 +4402,13 @@ struct G_Unknown_6x56 {
le_float z = 0.0f;
} __packed__;
// 6x57: Unknown (supported; lobby & game)
// 6x57: Unknown (supported; lobby & game) (protected on V3/V4)
struct G_Unknown_6x57 {
G_ClientIDHeader header;
} __packed__;
// 6x58: Lobby animation
// 6x58: Lobby animation (protected on V3/V4)
struct G_LobbyAnimation_6x58 {
G_ClientIDHeader header;
@@ -4929,13 +4939,13 @@ struct G_GogoBall_6x79 {
parray<uint8_t, 3> unused;
} __packed__;
// 6x7A: Unknown
// 6x7A: Unknown (protected on V3/V4)
struct G_Unknown_6x7A {
G_ClientIDHeader header;
} __packed__;
// 6x7B: Unknown
// 6x7B: Unknown (protected on V3/V4)
struct G_Unknown_6x7B {
G_ClientIDHeader header;
@@ -4993,19 +5003,19 @@ struct G_TriggerTrap_6x80 {
le_uint16_t unknown_a2 = 0;
} __packed__;
// 6x81: Unknown
// 6x81: Unknown (protected on V3/V4)
struct G_Unknown_6x81 {
G_ClientIDHeader header;
} __packed__;
// 6x82: Unknown
// 6x82: Unknown (protected on V3/V4)
struct G_Unknown_6x82 {
G_ClientIDHeader header;
} __packed__;
// 6x83: Place trap
// 6x83: Place trap (protected on V3/V4)
struct G_PlaceTrap_6x83 {
G_ClientIDHeader header;
@@ -5041,20 +5051,20 @@ struct G_HitDestructibleObject_6x86 {
le_uint16_t unknown_a4 = 0;
} __packed__;
// 6x87: Shrink player
// 6x87: Shrink player (protected on V3/V4)
struct G_ShrinkPlayer_6x87 {
G_ClientIDHeader header;
le_float unknown_a1 = 0.0f;
} __packed__;
// 6x88: Restore shrunken player
// 6x88: Restore shrunken player (protected on V3/V4)
struct G_RestoreShrunkenPlayer_6x88 {
G_ClientIDHeader header;
} __packed__;
// 6x89: Player killed by monster
// 6x89: Player killed by monster (protected on V3/V4)
struct G_PlayerKilledByMonster_6x89 {
G_ClientIDHeader header;
@@ -5075,7 +5085,7 @@ struct G_Unknown_6x8A {
// 6x8C: Unknown (not valid on Episode 3)
// This subcommand is completely ignored (at least, by PSO GC).
// 6x8D: Set technique level override
// 6x8D: Set technique level override (protected on V3/V4)
// This command is sent immediately before 6x47 if the technique level is above
// 15. Presumably this was done for compatibility between v1 and v2.
@@ -5097,7 +5107,7 @@ struct G_Unknown_6x8F {
le_uint16_t unknown_a1 = 0;
} __packed__;
// 6x90: Unknown (not valid on Episode 3)
// 6x90: Unknown (not valid on Episode 3) (protected on V3/V4)
struct G_Unknown_6x90 {
G_ClientIDHeader header;
@@ -5186,7 +5196,7 @@ struct G_UpdatePlayerStat_6x9A {
uint8_t amount = 0;
} __packed__;
// 6x9B: Unknown
// 6x9B: Unknown (protected on V3/V4)
struct G_Unknown_6x9B {
G_UnusedHeader header;
@@ -5233,7 +5243,7 @@ struct G_GalGryphonBossActions_6xA0 {
parray<le_uint32_t, 4> unknown_a4;
} __packed__;
// 6xA1: Unknown (not valid on pre-V3)
// 6xA1: Unknown (not valid on pre-V3) (protected on V3/V4)
// Part of revive process. Occurs right after revive command; function unclear.
struct G_Unknown_6xA1 {
@@ -5326,7 +5336,7 @@ struct G_BarbaRayBossActions_6xAA {
le_uint32_t unknown_a3 = 0;
} __packed__;
// 6xAB: Create lobby chair (not valid on pre-V3)
// 6xAB: Create lobby chair (not valid on pre-V3) (protected on V3/V4)
struct G_CreateLobbyChair_6xAB {
G_ClientIDHeader header;
@@ -5334,7 +5344,7 @@ struct G_CreateLobbyChair_6xAB {
le_uint16_t unknown_a2 = 0;
} __packed__;
// 6xAC: Unknown (not valid on pre-V3)
// 6xAC: Unknown (not valid on pre-V3) (protected on V3/V4)
// This command's appears to be different on GC NTE than on any other version.
// It also seems that no version (other than perhaps GC NTE) ever sends this
// command.
@@ -5372,14 +5382,14 @@ struct G_SetLobbyChairState_6xAE {
le_uint32_t unknown_a4 = 0;
} __packed__;
// 6xAF: Turn lobby chair (not valid on pre-V3 or GC Trial Edition)
// 6xAF: Turn lobby chair (not valid on pre-V3 or GC Trial Edition) (protected on V3/V4)
struct G_TurnLobbyChair_6xAF {
G_ClientIDHeader header;
le_uint32_t angle = 0; // In range [0x0000, 0xFFFF]
} __packed__;
// 6xB0: Move lobby chair (not valid on pre-V3 or GC Trial Edition)
// 6xB0: Move lobby chair (not valid on pre-V3 or GC Trial Edition) (protected on V3/V4)
struct G_MoveLobbyChair_6xB0 {
G_ClientIDHeader header;
@@ -5668,7 +5678,7 @@ struct G_GiveExperience_BB_6xBF {
le_uint32_t amount = 0;
} __packed__;
// 6xC0: BB sell item at shop
// 6xC0: Sell item at shop (BB) (protected on V3/V4)
struct G_SellItemAtShop_BB_6xC0 {
G_UnusedHeader header;
@@ -5763,7 +5773,7 @@ struct G_TransferItemViaMailMessage_BB_6xCB {
le_uint32_t target_guild_card_number = 0;
} __packed__;
// 6xCC: Exchange item for team points (BB)
// 6xCC: Exchange item for team points (BB) (protected on V3/V4)
struct G_ExchangeItemForTeamPoints_BB_6xCC {
G_ClientIDHeader header;