add notes and support for final PCv2 version
This commit is contained in:
+14
-10
@@ -2000,8 +2000,9 @@ struct C_LoginExtended_PC_9D : C_Login_DC_PC_GC_9D {
|
||||
SC_MeetUserExtension_PC_BB extension;
|
||||
} __packed_ws__(C_LoginExtended_PC_9D, 0x14C);
|
||||
|
||||
// 9E (C->S): Log in with client config (V3/BB)
|
||||
// Not used on GC Episodes 1&2 Trial Edition.
|
||||
// 9E (C->S): Log in with client config (PC/V3/BB)
|
||||
// Not used on GC Episodes 1&2 Trial Edition, nor on v1 or most v2 versions.
|
||||
// Of all pre-v3 versions, only the latest version of PCv2 appears to use this.
|
||||
// The extended version of this command is used in the same circumstances as
|
||||
// when PSO PC uses the extended version of the 9D command.
|
||||
// PSO XB does not send the client config (security data) in the 9E command,
|
||||
@@ -2009,11 +2010,13 @@ struct C_LoginExtended_PC_9D : C_Login_DC_PC_GC_9D {
|
||||
// retrieve the client config.
|
||||
// header.flag is 1 if the client has UDP disabled.
|
||||
|
||||
struct C_Login_GC_9E : C_Login_DC_PC_GC_9D {
|
||||
struct C_Login_PC_GC_9E : C_Login_DC_PC_GC_9D {
|
||||
parray<uint8_t, 0x20> client_config;
|
||||
} __packed_ws__(C_Login_GC_9E, 0xE8);
|
||||
|
||||
struct C_LoginExtended_GC_9E : C_Login_GC_9E {
|
||||
} __packed_ws__(C_Login_PC_GC_9E, 0xE8);
|
||||
struct C_LoginExtended_PC_9E : C_Login_PC_GC_9E {
|
||||
SC_MeetUserExtension_PC_BB extension;
|
||||
} __packed_ws__(C_LoginExtended_PC_9E, 0x16C);
|
||||
struct C_LoginExtended_GC_9E : C_Login_PC_GC_9E {
|
||||
SC_MeetUserExtension_DC_V3 extension;
|
||||
} __packed_ws__(C_LoginExtended_GC_9E, 0x14C);
|
||||
|
||||
@@ -2051,12 +2054,13 @@ struct C_LoginExtended_BB_9E {
|
||||
/* 0170 */
|
||||
} __packed_ws__(C_LoginExtended_BB_9E, 0x170);
|
||||
|
||||
// 9F (S->C): Request client config / security data (V3/BB)
|
||||
// This command is not valid on PSO GC Episodes 1&2 Trial Edition, nor any
|
||||
// pre-V3 PSO versions. Client will respond with a 9F command.
|
||||
// 9F (S->C): Request client config / security data (PC/V3/BB)
|
||||
// This command is not valid on PSO GC Episodes 1&2 Trial Edition nor on any
|
||||
// other pre-v3 versions, except the latest PC v2 version, which does have it.
|
||||
// Client will respond with a 9F command.
|
||||
// No arguments
|
||||
|
||||
// 9F (C->S): Client config / security data response (V3/BB)
|
||||
// 9F (C->S): Client config / security data response (PC/V3/BB)
|
||||
// The data is opaque to the client, as described at the top of this file.
|
||||
// On BB, this command does not work during the data server phase.
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ void DownloadSession::send_93_9D_9E(bool extended) {
|
||||
ret.access_key2 = ret.access_key;
|
||||
ret.login_character_name.encode(this->character->disp.name.decode());
|
||||
ret.client_config = this->client_config;
|
||||
this->channel->send(0x9E, 0x01, &ret, extended ? sizeof(ret) : sizeof(C_Login_GC_9E));
|
||||
this->channel->send(0x9E, 0x01, &ret, extended ? sizeof(ret) : sizeof(C_Login_PC_GC_9E));
|
||||
|
||||
} else if (this->version == Version::XB_V3) {
|
||||
C_LoginExtended_XB_9E ret;
|
||||
|
||||
@@ -236,7 +236,7 @@ static asio::awaitable<HandlerResult> S_G_9A(shared_ptr<Client> c, Channel::Mess
|
||||
// right after the client config data
|
||||
c->proxy_session->server_channel->send(
|
||||
0x9E, 0x01, &cmd,
|
||||
cmd.is_extended ? sizeof(C_LoginExtended_GC_9E) : sizeof(C_Login_GC_9E));
|
||||
cmd.is_extended ? sizeof(C_LoginExtended_GC_9E) : sizeof(C_Login_PC_GC_9E));
|
||||
|
||||
co_return HandlerResult::SUPPRESS;
|
||||
}
|
||||
|
||||
@@ -2095,6 +2095,15 @@ static const QuestScriptOpcodeDefinition opcode_defs[] = {
|
||||
// is the last opcode implemented before v3.
|
||||
{0xF8BB, "write_flag_buf_to_event_flags2", "unknownF8BB", {REG}, F_V2_V4},
|
||||
|
||||
// TODO(DX): Figure out what these do. They only exist on the latest
|
||||
// version of PCv2; they do not exist in the more common version of PCv2 on
|
||||
// the Internet, nor do they exist in any later PSO version (although F8BC
|
||||
// was replaced with set_episode in GC_V3).
|
||||
{0xF8BC, "unknown_F8BC", nullptr, {REG, REG}, F_PC_V2}, // regA = client ID, regB = result (TODO)
|
||||
{0xF8BD, "unknown_F8BD", nullptr, {REG, {REG_SET_FIXED, 15}}, F_PC_V2}, // TODO: Document args
|
||||
{0xF8BE, "unknown_F8BE", nullptr, {}, F_PC_V2},
|
||||
{0xF8BF, "unknown_F8BF", nullptr, {}, F_PC_V2},
|
||||
|
||||
// Sets the current episode. Must be used in the start label. valueA should
|
||||
// be 0 for Episode 1 (which is the default), 1 for Episode 2, or 2 for
|
||||
// Episode 4 (BB only).
|
||||
|
||||
+16
-10
@@ -1211,17 +1211,21 @@ static asio::awaitable<void> on_9D_9E(shared_ptr<Client> c, Channel::Message& ms
|
||||
}
|
||||
|
||||
} else if (msg.command == 0x9E) {
|
||||
const auto& cmd = check_size_t<C_Login_GC_9E>(msg.data, sizeof(C_LoginExtended_GC_9E));
|
||||
base_cmd = &cmd;
|
||||
if (cmd.is_extended) {
|
||||
const auto& cmd = check_size_t<C_LoginExtended_GC_9E>(msg.data);
|
||||
if (cmd.extension.lobby_refs[0].menu_id == MenuID::LOBBY) {
|
||||
c->preferred_lobby_id = cmd.extension.lobby_refs[0].item_id;
|
||||
auto handle_cmd = [&]<typename BaseCmdT, typename ExtendedCmdT>() {
|
||||
const auto& cmd = check_size_t<BaseCmdT>(msg.data, sizeof(ExtendedCmdT));
|
||||
base_cmd = &cmd;
|
||||
if (cmd.is_extended) {
|
||||
const auto& cmd = check_size_t<ExtendedCmdT>(msg.data);
|
||||
if (cmd.extension.lobby_refs[0].menu_id == MenuID::LOBBY) {
|
||||
c->preferred_lobby_id = cmd.extension.lobby_refs[0].item_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
if (is_v3(c->version())) {
|
||||
handle_cmd.template operator()<C_Login_PC_GC_9E, C_LoginExtended_GC_9E>();
|
||||
c->set_flag(Client::Flag::AT_WELCOME_MESSAGE);
|
||||
} else {
|
||||
handle_cmd.template operator()<C_Login_PC_GC_9E, C_LoginExtended_PC_9E>();
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -1321,8 +1325,10 @@ static asio::awaitable<void> on_9D_9E(shared_ptr<Client> c, Channel::Message& ms
|
||||
}
|
||||
if (resp.checksum == 0x3677024C) {
|
||||
c->specific_version = SPECIFIC_VERSION_PC_V2_DEFAULT;
|
||||
c->log.info_f("Version detected as {:08X} from PE header checksum {:08X}",
|
||||
c->specific_version, resp.checksum);
|
||||
c->log.info_f("Version detected as {:08X} from PE header checksum {:08X}", c->specific_version, resp.checksum);
|
||||
} else if (resp.checksum == 0x058BF2FF) {
|
||||
c->specific_version = SPECIFIC_VERSION_PC_V2_FINAL;
|
||||
c->log.info_f("Version detected as {:08X} from PE header checksum {:08X}", c->specific_version, resp.checksum);
|
||||
} else {
|
||||
c->specific_version = SPECIFIC_VERSION_PC_V2_INDETERMINATE;
|
||||
c->log.info_f("Version cannot be determined from PE header checksum {:08X}", resp.checksum);
|
||||
|
||||
+3
-3
@@ -215,16 +215,16 @@ bool specific_version_is_indeterminate(uint32_t specific_version) {
|
||||
}
|
||||
|
||||
bool specific_version_is_dc(uint32_t specific_version) {
|
||||
// All v1 and v2 specific_versions are DC except 324F4A57 (2OJW), which is PC
|
||||
// All v1 and v2 specific_versions are DC except 2OJW and 2OJZ, which are PC
|
||||
uint8_t major_version = specific_version >> 24;
|
||||
if (major_version < 0x31 || major_version > 0x32) {
|
||||
return false;
|
||||
}
|
||||
return (specific_version != SPECIFIC_VERSION_PC_V2_DEFAULT);
|
||||
return !specific_version_is_pc_v2(specific_version);
|
||||
}
|
||||
|
||||
bool specific_version_is_pc_v2(uint32_t specific_version) {
|
||||
return (specific_version == SPECIFIC_VERSION_PC_V2_DEFAULT);
|
||||
return ((specific_version == SPECIFIC_VERSION_PC_V2_DEFAULT) || (specific_version == SPECIFIC_VERSION_PC_V2_FINAL));
|
||||
}
|
||||
|
||||
bool specific_version_is_gc(uint32_t specific_version) {
|
||||
|
||||
+2
-1
@@ -191,8 +191,9 @@ constexpr uint32_t SPECIFIC_VERSION_DC_V1_US = 0x314F4546; // 1OEF
|
||||
constexpr uint32_t SPECIFIC_VERSION_DC_V1_EU_INDETERMINATE = 0x314F5000; // 1OP_
|
||||
constexpr uint32_t SPECIFIC_VERSION_DC_V1_INDETERMINATE = 0x31000000; // 1___
|
||||
constexpr uint32_t SPECIFIC_VERSION_DC_V2_INDETERMINATE = 0x32000000; // 2___
|
||||
constexpr uint32_t SPECIFIC_VERSION_PC_V2_INDETERMINATE = 0x324F4A00; // 2OJW
|
||||
constexpr uint32_t SPECIFIC_VERSION_PC_V2_INDETERMINATE = 0x324F4A00; // 2OJ_
|
||||
constexpr uint32_t SPECIFIC_VERSION_PC_V2_DEFAULT = 0x324F4A57; // 2OJW
|
||||
constexpr uint32_t SPECIFIC_VERSION_PC_V2_FINAL = 0x324F4A5A; // 2OJZ
|
||||
constexpr uint32_t SPECIFIC_VERSION_GC_NTE = 0x334F4A54; // 3OJT
|
||||
constexpr uint32_t SPECIFIC_VERSION_GC_V3_EU = 0x334F5030; // 3OP0
|
||||
constexpr uint32_t SPECIFIC_VERSION_GC_V3_US_12 = 0x334F4532; // 3OE2
|
||||
|
||||
Reference in New Issue
Block a user