more info on 0E command

This commit is contained in:
Martin Michelsen
2023-02-21 18:17:49 -08:00
parent 34812d5037
commit 9ff23b2aee
2 changed files with 36 additions and 14 deletions
+35 -12
View File
@@ -581,20 +581,37 @@ struct C_MenuItemInfoRequest_09 {
// 0D: Invalid command
// 0E (S->C): Unknown; possibly legacy join game (PC/V3)
// There is a failure mode in the command handlers on PC and V3 that causes the
// thread receiving the command to loop infinitely doing nothing, effectively
// softlocking the game.
// 0E (S->C): Incomplete/legacy join game (PC/V3)
// header.flag = number of valid entries in lobby_data
// It's fairly clear that this command was intended for joining games since its
// structure is similar to that of 64. Furthermore, 0E sets a flag on the client
// which is also set by commands 64, 67, and E8 (on Episode 3), which are all
// lobby and game join commands.
// There is a failure mode in the 0E command handlers on PC and V3 that causes
// the thread receiving the command to loop infinitely doing nothing,
// effectively softlocking the game. This happens if the local player's Guild
// Card number doesn't match any of the lobby_data entries. (Notably, only the
// first (header.flag) entries are checked.)
// If the local players' Guild Card number does match one of the entries, the
// command does not softlock, but instead does nothing (at least, on PC and V3)
// because the 0E second-phase handler is missing on the client.
// TODO: Check if this command exists on DC v1/v2.
struct S_Unknown_PC_0E {
parray<uint8_t, 0x08> unknown_a1;
parray<parray<uint8_t, 0x18>, 4> unknown_a2;
parray<uint8_t, 0x18> unknown_a3;
struct S_LegacyJoinGame_PC_0E {
struct UnknownA1 {
le_uint32_t player_tag;
le_uint32_t guild_card_number;
parray<uint8_t, 0x10> unknown_a1;
} __packed__;
parray<UnknownA1, 4> unknown_a1;
parray<uint8_t, 0x20> unknown_a3;
} __packed__;
struct S_Unknown_GC_0E {
PlayerLobbyDataDCGC lobby_data[4]; // This type is a guess
struct S_LegacyJoinGame_GC_0E {
PlayerLobbyDataDCGC lobby_data[4];
struct UnknownA0 {
parray<uint8_t, 2> unknown_a1;
le_uint16_t unknown_a2 = 0;
@@ -606,8 +623,14 @@ struct S_Unknown_GC_0E {
parray<uint8_t, 4> unknown_a3;
} __packed__;
struct S_Unknown_XB_0E {
parray<uint8_t, 0xE8> unknown_a1;
struct S_LegacyJoinGame_XB_0E {
struct UnknownA1 {
le_uint32_t player_tag;
le_uint32_t guild_card_number;
parray<uint8_t, 0x18> unknown_a1;
} __packed__;
parray<UnknownA1, 4> unknown_a1;
parray<uint8_t, 0x68> unknown_a2;
} __packed__;
// 0F: Invalid command
+1 -2
View File
@@ -281,8 +281,7 @@ copy_handle_B2_word_again:
bctrl # flush_code(copied_B2_handler, copied_B2_handler_bytes)
# Replace the command handler table entry for command 0E (which appears to be
# a legacy command - it's unused by any modern private server and was
# presumably unused by Sega too) with our copied B2 implementation
# a legacy command and has very broken behavior) with our B2 implementation
lis r5, 0x8044
ori r5, r5, 0xF684
li r0, 0x00B2