document hardware_id in login commands
This commit is contained in:
+41
-31
@@ -347,7 +347,7 @@ struct S_ServerInitWithAfterMessageT_DC_PC_V3_02_17_91_9B {
|
||||
// TODO: Are the DCv1 and DCv2 formats the same as this structure?
|
||||
|
||||
struct C_LegacyLogin_PC_V3_03 {
|
||||
/* 00 */ le_uint64_t unused = 0; // Same as unused field in 9D/9E
|
||||
/* 00 */ be_uint64_t hardware_id;
|
||||
/* 08 */ le_uint32_t sub_version = 0;
|
||||
/* 0C */ uint8_t is_extended = 0;
|
||||
/* 0D */ uint8_t language = 0;
|
||||
@@ -403,7 +403,7 @@ struct S_ServerInitWithAfterMessageT_BB_03_9B {
|
||||
// TODO: Are the DCv1 and DCv2 formats the same as this structure?
|
||||
|
||||
struct C_LegacyLogin_PC_V3_04 {
|
||||
/* 00 */ le_uint64_t unused1 = 0; // Same as unused field in 9D/9E
|
||||
/* 00 */ be_uint64_t hardware_id;
|
||||
/* 08 */ le_uint32_t sub_version = 0;
|
||||
/* 0C */ uint8_t is_extended = 0;
|
||||
/* 0D */ uint8_t language = 0;
|
||||
@@ -1594,7 +1594,7 @@ struct S_ArrowUpdateEntry_88 {
|
||||
// The server should respond with an 8A command.
|
||||
|
||||
struct C_ConnectionInfo_DCNTE_8A {
|
||||
pstring<TextEncoding::ASCII, 0x08> hardware_id;
|
||||
be_uint64_t hardware_id;
|
||||
le_uint32_t sub_version = 0x20;
|
||||
le_uint32_t unknown_a1 = 0;
|
||||
pstring<TextEncoding::ASCII, 0x30> username;
|
||||
@@ -1624,7 +1624,7 @@ struct C_ConnectionInfo_DCNTE_8A {
|
||||
struct C_Login_DCNTE_8B {
|
||||
le_uint32_t player_tag = 0x00010000;
|
||||
le_uint32_t guild_card_number = 0;
|
||||
parray<uint8_t, 0x08> hardware_id;
|
||||
be_uint64_t hardware_id;
|
||||
le_uint32_t sub_version = 0x20;
|
||||
uint8_t is_extended = 0;
|
||||
uint8_t language = 0;
|
||||
@@ -1685,13 +1685,13 @@ struct C_LoginV1_DC_PC_V3_90 {
|
||||
// 92 (C->S): Register (DC)
|
||||
|
||||
struct C_RegisterV1_DC_92 {
|
||||
parray<uint8_t, 0x08> unknown_a1;
|
||||
be_uint64_t hardware_id;
|
||||
le_uint32_t sub_version;
|
||||
uint8_t is_extended = 0; // TODO: This is a guess
|
||||
uint8_t language = 0; // TODO: This is a guess; verify it
|
||||
parray<uint8_t, 2> unknown_a3;
|
||||
pstring<TextEncoding::ASCII, 0x30> hardware_id;
|
||||
pstring<TextEncoding::ASCII, 0x30> unknown_a4;
|
||||
pstring<TextEncoding::ASCII, 0x30> serial_number2;
|
||||
pstring<TextEncoding::ASCII, 0x30> access_key2;
|
||||
pstring<TextEncoding::ASCII, 0x30> email; // According to Sylverant documentation
|
||||
} __packed_ws__(C_RegisterV1_DC_92, 0xA0);
|
||||
|
||||
@@ -1702,20 +1702,20 @@ struct C_RegisterV1_DC_92 {
|
||||
// 93 (C->S): Log in (DCv1)
|
||||
|
||||
struct C_LoginV1_DC_93 {
|
||||
le_uint32_t player_tag = 0x00010000;
|
||||
le_uint32_t guild_card_number = 0;
|
||||
le_uint32_t unknown_a1 = 0;
|
||||
le_uint32_t unknown_a2 = 0;
|
||||
le_uint32_t sub_version = 0;
|
||||
uint8_t is_extended = 0;
|
||||
uint8_t language = 0;
|
||||
parray<uint8_t, 2> unused1;
|
||||
pstring<TextEncoding::ASCII, 0x11> serial_number;
|
||||
pstring<TextEncoding::ASCII, 0x11> access_key;
|
||||
pstring<TextEncoding::ASCII, 0x30> hardware_id;
|
||||
pstring<TextEncoding::ASCII, 0x30> unknown_a3;
|
||||
pstring<TextEncoding::ASCII, 0x10> name;
|
||||
parray<uint8_t, 2> unused2;
|
||||
/* 00 */ le_uint32_t player_tag = 0x00010000;
|
||||
/* 04 */ le_uint32_t guild_card_number = 0;
|
||||
/* 08 */ be_uint64_t hardware_id;
|
||||
/* 10 */ le_uint32_t sub_version = 0;
|
||||
/* 14 */ uint8_t is_extended = 0;
|
||||
/* 15 */ uint8_t language = 0;
|
||||
/* 16 */ parray<uint8_t, 2> unused1;
|
||||
/* 18 */ pstring<TextEncoding::ASCII, 0x11> serial_number;
|
||||
/* 29 */ pstring<TextEncoding::ASCII, 0x11> access_key;
|
||||
/* 3A */ pstring<TextEncoding::ASCII, 0x30> serial_number2;
|
||||
/* 6A */ pstring<TextEncoding::ASCII, 0x30> access_key2;
|
||||
/* 9A */ pstring<TextEncoding::ASCII, 0x10> name;
|
||||
/* AA */ parray<uint8_t, 2> unused2;
|
||||
/* AC */
|
||||
} __packed_ws__(C_LoginV1_DC_93, 0xAC);
|
||||
|
||||
struct C_LoginExtendedV1_DC_93 : C_LoginV1_DC_93 {
|
||||
@@ -1886,14 +1886,15 @@ struct C_Login_DC_PC_V3_9A {
|
||||
// It appears PSO GC sends uninitialized data in the header.flag field here.
|
||||
|
||||
struct C_Register_DC_PC_V3_9C {
|
||||
le_uint64_t unused = 0;
|
||||
le_uint32_t sub_version = 0;
|
||||
uint8_t unused1 = 0;
|
||||
uint8_t language = 0;
|
||||
parray<uint8_t, 2> unused2;
|
||||
pstring<TextEncoding::ASCII, 0x30> serial_number; // On XB, this is the XBL gamertag
|
||||
pstring<TextEncoding::ASCII, 0x30> access_key; // On XB, this is the XBL user ID
|
||||
pstring<TextEncoding::ASCII, 0x30> password; // On XB, this contains "xbox-pso"
|
||||
/* 00 */ be_uint64_t hardware_id;
|
||||
/* 08 */ le_uint32_t sub_version = 0;
|
||||
/* 0C */ uint8_t unused1 = 0;
|
||||
/* 0D */ uint8_t language = 0;
|
||||
/* 0E */ parray<uint8_t, 2> unused2;
|
||||
/* 10 */ pstring<TextEncoding::ASCII, 0x30> serial_number; // On XB, this is the XBL gamertag
|
||||
/* 40 */ pstring<TextEncoding::ASCII, 0x30> access_key; // On XB, this is the XBL user ID
|
||||
/* 70 */ pstring<TextEncoding::ASCII, 0x30> password; // On XB, this contains "xbox-pso"
|
||||
/* A0 */
|
||||
} __packed_ws__(C_Register_DC_PC_V3_9C, 0xA0);
|
||||
|
||||
struct C_Register_BB_9C {
|
||||
@@ -1925,8 +1926,17 @@ struct C_Register_BB_9C {
|
||||
struct C_Login_DC_PC_GC_9D {
|
||||
/* 00 */ le_uint32_t player_tag = 0x00010000; // 0x00010000 if guild card is set (via 04)
|
||||
/* 04 */ le_uint32_t guild_card_number = 0; // 0xFFFFFFFF if not set
|
||||
/* 08 */ le_uint32_t unused1 = 0;
|
||||
/* 0C */ le_uint32_t unused2 = 0;
|
||||
// The hardware ID is different for various PSO versions:
|
||||
// - All DC versions: the hardware ID comes from the FUNC_SYSINFO_ID syscall
|
||||
// (as KallistiOS refers to it), which returns a 64-bit integer. PSO uses
|
||||
// the low 48 bits; the high 16 bits are masked out and are always zero.
|
||||
// - PC V2: the hardware ID is always 0000FFFFFFFFFFFF
|
||||
// - GC NTE: the last byte of the hardware ID is uninitialized memory from
|
||||
// the TProtocol constructor's stack; the other bytes are all zeroes.
|
||||
// - V3: the hardware ID is all zeroes.
|
||||
// On the client, this is actually an array of 8 bytes, but we treat it as a
|
||||
// single integer for simplicity.
|
||||
/* 08 */ be_uint64_t hardware_id;
|
||||
/* 10 */ le_uint32_t sub_version = 0;
|
||||
/* 14 */ uint8_t is_extended = 0; // If 1, structure has extended format
|
||||
/* 15 */ uint8_t language = 0; // 0 = JP, 1 = EN, 2 = DE, 3 = FR, 4 = ES
|
||||
|
||||
+12
-5
@@ -48,7 +48,7 @@ DownloadSession::DownloadSession(
|
||||
Version version,
|
||||
uint8_t language,
|
||||
std::shared_ptr<const PSOBBEncryption::KeyFile> bb_key_file,
|
||||
uint32_t hardware_id,
|
||||
uint32_t serial_number2,
|
||||
uint32_t serial_number,
|
||||
const std::string& access_key,
|
||||
const std::string& username,
|
||||
@@ -63,7 +63,7 @@ DownloadSession::DownloadSession(
|
||||
bool show_command_data)
|
||||
: output_dir(output_dir),
|
||||
bb_key_file(bb_key_file),
|
||||
hardware_id(hardware_id),
|
||||
serial_number2(serial_number2),
|
||||
serial_number(serial_number),
|
||||
access_key(access_key),
|
||||
username(username),
|
||||
@@ -86,6 +86,7 @@ DownloadSession::DownloadSession(
|
||||
phosg::render_sockaddr_storage(remote),
|
||||
show_command_data ? phosg::TerminalFormat::FG_GREEN : phosg::TerminalFormat::END,
|
||||
show_command_data ? phosg::TerminalFormat::FG_YELLOW : phosg::TerminalFormat::END),
|
||||
hardware_id(generate_random_hardware_id(this->channel.version)),
|
||||
guild_card_number(0),
|
||||
prev_cmd_data(0),
|
||||
client_config(0),
|
||||
@@ -103,7 +104,7 @@ DownloadSession::DownloadSession(
|
||||
switch (this->channel.version) {
|
||||
case Version::DC_V1:
|
||||
case Version::DC_V2:
|
||||
if (this->hardware_id == 0 || this->serial_number == 0 || this->access_key.empty()) {
|
||||
if (this->serial_number2 == 0 || this->serial_number == 0 || this->access_key.empty()) {
|
||||
throw runtime_error("missing credentials");
|
||||
}
|
||||
break;
|
||||
@@ -163,12 +164,13 @@ void DownloadSession::send_93_9D_9E(bool extended) {
|
||||
C_LoginExtendedV1_DC_93 ret;
|
||||
ret.player_tag = this->guild_card_number ? 0xFFFF0000 : 0x00010000;
|
||||
ret.guild_card_number = this->guild_card_number;
|
||||
ret.hardware_id = this->hardware_id;
|
||||
ret.sub_version = default_sub_version_for_version(this->channel.version);
|
||||
ret.is_extended = extended ? 1 : 0;
|
||||
ret.language = this->channel.language;
|
||||
ret.serial_number.encode(phosg::string_printf("%08" PRIX32, this->serial_number));
|
||||
ret.access_key.encode(this->access_key);
|
||||
ret.hardware_id.encode(phosg::string_printf("%08" PRIX32, this->hardware_id));
|
||||
ret.serial_number2.encode(phosg::string_printf("%08" PRIX32, this->serial_number2));
|
||||
ret.name.encode(this->character->disp.name.decode());
|
||||
this->channel.send(0x93, 0x01, &ret, extended ? sizeof(ret) : sizeof(C_LoginV1_DC_93));
|
||||
|
||||
@@ -176,6 +178,7 @@ void DownloadSession::send_93_9D_9E(bool extended) {
|
||||
C_LoginExtended_PC_9D ret;
|
||||
ret.player_tag = this->guild_card_number ? 0xFFFF0000 : 0x00010000;
|
||||
ret.guild_card_number = this->guild_card_number;
|
||||
ret.hardware_id = this->hardware_id;
|
||||
ret.sub_version = default_sub_version_for_version(this->channel.version);
|
||||
ret.is_extended = extended ? 1 : 0;
|
||||
ret.language = this->channel.language;
|
||||
@@ -193,6 +196,7 @@ void DownloadSession::send_93_9D_9E(bool extended) {
|
||||
C_LoginExtended_GC_9E ret;
|
||||
ret.player_tag = this->guild_card_number ? 0xFFFF0000 : 0x00010000;
|
||||
ret.guild_card_number = this->guild_card_number;
|
||||
ret.hardware_id = this->hardware_id;
|
||||
ret.sub_version = default_sub_version_for_version(this->channel.version);
|
||||
ret.is_extended = extended ? 1 : 0;
|
||||
ret.language = this->channel.language;
|
||||
@@ -208,6 +212,7 @@ void DownloadSession::send_93_9D_9E(bool extended) {
|
||||
C_LoginExtended_XB_9E ret;
|
||||
ret.player_tag = this->guild_card_number ? 0xFFFF0000 : 0x00010000;
|
||||
ret.guild_card_number = this->guild_card_number;
|
||||
ret.hardware_id = this->hardware_id;
|
||||
ret.sub_version = default_sub_version_for_version(this->channel.version);
|
||||
ret.is_extended = extended ? 1 : 0;
|
||||
ret.language = this->channel.language;
|
||||
@@ -377,13 +382,15 @@ void DownloadSession::on_channel_input(uint16_t command, uint32_t flag, std::str
|
||||
if (flag == 1) {
|
||||
if (is_v1(this->channel.version)) {
|
||||
C_RegisterV1_DC_92 ret;
|
||||
ret.hardware_id = this->hardware_id;
|
||||
ret.sub_version = default_sub_version_for_version(this->channel.version);
|
||||
ret.language = this->channel.language;
|
||||
ret.hardware_id.encode(phosg::string_printf("%08" PRIX32, this->hardware_id));
|
||||
ret.serial_number2.encode(phosg::string_printf("%08" PRIX32, this->serial_number2));
|
||||
this->channel.send(0x92, 0x00, ret);
|
||||
|
||||
} else if (!is_v4(this->channel.version)) {
|
||||
C_Register_DC_PC_V3_9C ret;
|
||||
ret.hardware_id = this->hardware_id;
|
||||
ret.sub_version = default_sub_version_for_version(this->channel.version);
|
||||
ret.language = this->channel.language;
|
||||
if (this->channel.version == Version::XB_V3) {
|
||||
|
||||
@@ -24,7 +24,7 @@ public:
|
||||
Version version,
|
||||
uint8_t language,
|
||||
std::shared_ptr<const PSOBBEncryption::KeyFile> bb_key_file,
|
||||
uint32_t hardware_id,
|
||||
uint32_t serial_number2,
|
||||
uint32_t serial_number,
|
||||
const std::string& access_key,
|
||||
const std::string& username,
|
||||
@@ -47,7 +47,7 @@ protected:
|
||||
// Config (must be set by caller)
|
||||
std::string output_dir;
|
||||
std::shared_ptr<const PSOBBEncryption::KeyFile> bb_key_file;
|
||||
uint32_t hardware_id;
|
||||
uint32_t serial_number2;
|
||||
uint32_t serial_number;
|
||||
std::string access_key;
|
||||
std::string username;
|
||||
@@ -64,6 +64,7 @@ protected:
|
||||
phosg::PrefixedLogger log;
|
||||
std::shared_ptr<struct event_base> base;
|
||||
Channel channel;
|
||||
uint64_t hardware_id;
|
||||
uint32_t guild_card_number;
|
||||
parray<uint8_t, 0x28> prev_cmd_data;
|
||||
parray<uint8_t, 0x20> client_config;
|
||||
|
||||
+1
-1
@@ -734,7 +734,7 @@ phosg::JSON HTTPServer::generate_proxy_client_json_st(shared_ptr<const ProxyServ
|
||||
{"Version", phosg::name_for_enum(ses->version())},
|
||||
{"SubVersion", ses->sub_version},
|
||||
{"Name", ses->character_name},
|
||||
{"DCHardwareID", ses->hardware_id},
|
||||
{"DCSerialNumber2", ses->serial_number2},
|
||||
{"RemoteGuildCardNumber", ses->remote_guild_card_number},
|
||||
{"RemoteClientConfigData", phosg::format_data_string(&ses->remote_client_config_data[0], ses->remote_client_config_data.size())},
|
||||
{"Config", HTTPServer::generate_client_config_json_st(ses->config)},
|
||||
|
||||
+8
-13
@@ -167,8 +167,7 @@ static HandlerResult S_G_9A(shared_ptr<ProxyServer::LinkedSession> ses, uint16_t
|
||||
cmd.player_tag = 0x00010000;
|
||||
cmd.guild_card_number = ses->remote_guild_card_number;
|
||||
}
|
||||
cmd.unused1 = 0;
|
||||
cmd.unused2 = 0;
|
||||
cmd.hardware_id = ses->hardware_id;
|
||||
cmd.sub_version = ses->effective_sub_version();
|
||||
cmd.is_extended = (ses->remote_guild_card_number < 0) ? 1 : 0;
|
||||
cmd.language = ses->language();
|
||||
@@ -277,15 +276,14 @@ static HandlerResult S_V123P_02_17(
|
||||
cmd.player_tag = 0x00010000;
|
||||
cmd.guild_card_number = ses->remote_guild_card_number;
|
||||
}
|
||||
cmd.unknown_a1 = 0;
|
||||
cmd.unknown_a2 = 0;
|
||||
cmd.hardware_id = ses->hardware_id;
|
||||
cmd.sub_version = ses->effective_sub_version();
|
||||
cmd.is_extended = 0;
|
||||
cmd.language = ses->language();
|
||||
cmd.serial_number.encode(phosg::string_printf("%08" PRIX32 "", ses->login->dc_license->serial_number));
|
||||
cmd.access_key.encode(ses->login->dc_license->access_key);
|
||||
cmd.access_key.clear_after_bytes(8);
|
||||
cmd.hardware_id.encode(ses->hardware_id);
|
||||
cmd.serial_number2.encode(ses->serial_number2);
|
||||
cmd.name.encode(ses->character_name);
|
||||
ses->server_channel.send(0x93, 0x00, &cmd, sizeof(cmd));
|
||||
return HandlerResult::Type::SUPPRESS;
|
||||
@@ -334,7 +332,7 @@ static HandlerResult S_V123P_02_17(
|
||||
cmd.access_key.clear_after_bytes(8);
|
||||
}
|
||||
if (is_dc(ses->version())) {
|
||||
cmd.serial_number2.encode(ses->hardware_id);
|
||||
cmd.serial_number2.encode(ses->serial_number2);
|
||||
} else {
|
||||
cmd.serial_number2 = cmd.serial_number;
|
||||
}
|
||||
@@ -353,8 +351,7 @@ static HandlerResult S_V123P_02_17(
|
||||
cmd.player_tag = 0x00010000;
|
||||
cmd.guild_card_number = ses->remote_guild_card_number;
|
||||
}
|
||||
cmd.unused1 = 0;
|
||||
cmd.unused2 = 0;
|
||||
cmd.hardware_id = ses->hardware_id;
|
||||
cmd.sub_version = ses->effective_sub_version();
|
||||
cmd.is_extended = 0;
|
||||
cmd.language = ses->language();
|
||||
@@ -364,7 +361,7 @@ static HandlerResult S_V123P_02_17(
|
||||
cmd.access_key.clear_after_bytes(8);
|
||||
}
|
||||
if (is_dc(ses->version())) {
|
||||
cmd.serial_number2.encode(ses->hardware_id);
|
||||
cmd.serial_number2.encode(ses->serial_number2);
|
||||
} else {
|
||||
cmd.serial_number2 = cmd.serial_number;
|
||||
}
|
||||
@@ -417,8 +414,7 @@ static HandlerResult S_V123P_02_17(
|
||||
C_LoginExtended_GC_9E cmd;
|
||||
cmd.player_tag = 0x00010000;
|
||||
cmd.guild_card_number = guild_card_number;
|
||||
cmd.unused1 = 0;
|
||||
cmd.unused2 = 0;
|
||||
cmd.hardware_id = ses->hardware_id;
|
||||
cmd.sub_version = ses->effective_sub_version();
|
||||
cmd.is_extended = 0;
|
||||
cmd.language = ses->language();
|
||||
@@ -453,8 +449,7 @@ static HandlerResult S_V123P_02_17(
|
||||
cmd.player_tag = 0x00010000;
|
||||
cmd.guild_card_number = ses->remote_guild_card_number;
|
||||
}
|
||||
cmd.unused1 = 0;
|
||||
cmd.unused2 = 0;
|
||||
cmd.hardware_id = ses->hardware_id;
|
||||
cmd.sub_version = ses->effective_sub_version();
|
||||
cmd.is_extended = (ses->remote_guild_card_number < 0) ? 1 : 0;
|
||||
cmd.language = ses->language();
|
||||
|
||||
+16
-4
@@ -306,11 +306,13 @@ void ProxyServer::UnlinkedSession::on_input(Channel& ch, uint16_t command, uint3
|
||||
ses->log.info("Version changed to DC_NTE");
|
||||
ses->config.specific_version = SPECIFIC_VERSION_DC_NTE;
|
||||
const auto& cmd = check_size_t<C_Login_DCNTE_8B>(data, sizeof(C_LoginExtended_DCNTE_8B));
|
||||
ses->set_login(s->account_index->from_dc_nte_credentials(cmd.serial_number.decode(), cmd.access_key.decode(), false));
|
||||
ses->set_login(s->account_index->from_dc_nte_credentials(
|
||||
cmd.serial_number.decode(), cmd.access_key.decode(), false));
|
||||
ses->sub_version = cmd.sub_version;
|
||||
ses->channel.language = cmd.language;
|
||||
ses->character_name = cmd.name.decode(ses->channel.language);
|
||||
// TODO: Parse cmd.hardware_id
|
||||
ses->hardware_id = cmd.hardware_id;
|
||||
|
||||
} else if (command == 0x93) { // 11/2000 proto through DC V1
|
||||
ses->channel.version = Version::DC_V1;
|
||||
ses->log.info("Version changed to DC_V1");
|
||||
@@ -323,7 +325,9 @@ void ProxyServer::UnlinkedSession::on_input(Channel& ch, uint16_t command, uint3
|
||||
ses->sub_version = cmd.sub_version;
|
||||
ses->channel.language = cmd.language;
|
||||
ses->character_name = cmd.name.decode(ses->channel.language);
|
||||
ses->hardware_id = cmd.hardware_id.decode();
|
||||
ses->serial_number2 = cmd.serial_number2.decode();
|
||||
ses->hardware_id = cmd.hardware_id;
|
||||
|
||||
} else if (command == 0x9D) {
|
||||
const auto& cmd = check_size_t<C_Login_DC_PC_GC_9D>(data, sizeof(C_LoginExtended_DC_GC_9D));
|
||||
if (cmd.sub_version >= 0x30) {
|
||||
@@ -345,6 +349,8 @@ void ProxyServer::UnlinkedSession::on_input(Channel& ch, uint16_t command, uint3
|
||||
ses->channel.language = cmd.language;
|
||||
ses->character_name = cmd.name.decode(ses->channel.language);
|
||||
ses->config.set_flags_for_version(ses->version(), cmd.sub_version);
|
||||
ses->hardware_id = cmd.hardware_id;
|
||||
|
||||
} else {
|
||||
throw runtime_error("command is not 93 or 9D");
|
||||
}
|
||||
@@ -362,6 +368,7 @@ void ProxyServer::UnlinkedSession::on_input(Channel& ch, uint16_t command, uint3
|
||||
ses->sub_version = cmd.sub_version;
|
||||
ses->channel.language = cmd.language;
|
||||
ses->character_name = cmd.name.decode(ses->channel.language);
|
||||
ses->hardware_id = cmd.hardware_id;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -376,6 +383,7 @@ void ProxyServer::UnlinkedSession::on_input(Channel& ch, uint16_t command, uint3
|
||||
ses->sub_version = cmd.sub_version;
|
||||
ses->channel.language = cmd.language;
|
||||
ses->character_name = cmd.name.decode(ses->channel.language);
|
||||
ses->hardware_id = cmd.hardware_id;
|
||||
ses->config.parse_from(cmd.client_config);
|
||||
if (cmd.sub_version >= 0x40) {
|
||||
ses->log.info("Version changed to GC_EP3");
|
||||
@@ -402,6 +410,7 @@ void ProxyServer::UnlinkedSession::on_input(Channel& ch, uint16_t command, uint3
|
||||
ses->character_name = cmd.name.decode(ses->channel.language);
|
||||
ses->xb_netloc = cmd.netloc;
|
||||
ses->xb_9E_unknown_a1a = cmd.unknown_a1a;
|
||||
ses->hardware_id = cmd.hardware_id;
|
||||
ses->channel.send(0x9F, 0x00);
|
||||
return;
|
||||
} else if (command == 0x9F) {
|
||||
@@ -478,6 +487,7 @@ void ProxyServer::UnlinkedSession::on_input(Channel& ch, uint16_t command, uint3
|
||||
ses->detector_crypt,
|
||||
ses->sub_version,
|
||||
ses->character_name,
|
||||
ses->serial_number2,
|
||||
ses->hardware_id,
|
||||
ses->xb_netloc,
|
||||
ses->xb_9E_unknown_a1a);
|
||||
@@ -617,11 +627,13 @@ void ProxyServer::LinkedSession::resume(
|
||||
shared_ptr<PSOBBMultiKeyDetectorEncryption> detector_crypt,
|
||||
uint32_t sub_version,
|
||||
const string& character_name,
|
||||
const string& hardware_id,
|
||||
const string& serial_number2,
|
||||
uint64_t hardware_id,
|
||||
const XBNetworkLocation& xb_netloc,
|
||||
const parray<le_uint32_t, 3>& xb_9E_unknown_a1a) {
|
||||
this->sub_version = sub_version;
|
||||
this->character_name = character_name;
|
||||
this->serial_number2 = serial_number2;
|
||||
this->hardware_id = hardware_id;
|
||||
this->xb_netloc = xb_netloc;
|
||||
this->xb_9E_unknown_a1a = xb_9E_unknown_a1a;
|
||||
|
||||
+6
-3
@@ -58,7 +58,8 @@ public:
|
||||
|
||||
uint32_t sub_version;
|
||||
std::string character_name;
|
||||
std::string hardware_id; // Only used for DC sessions
|
||||
std::string serial_number2; // Only used for DC sessions
|
||||
uint64_t hardware_id;
|
||||
std::string login_command_bb;
|
||||
XBNetworkLocation xb_netloc;
|
||||
parray<le_uint32_t, 3> xb_9E_unknown_a1a;
|
||||
@@ -170,7 +171,8 @@ public:
|
||||
std::shared_ptr<PSOBBMultiKeyDetectorEncryption> detector_crypt,
|
||||
uint32_t sub_version,
|
||||
const std::string& character_name,
|
||||
const std::string& hardware_id,
|
||||
const std::string& serial_number2,
|
||||
uint64_t hardware_id,
|
||||
const XBNetworkLocation& xb_netloc,
|
||||
const parray<le_uint32_t, 3>& xb_9E_unknown_a1a);
|
||||
void resume(
|
||||
@@ -260,7 +262,8 @@ private:
|
||||
std::string character_name;
|
||||
Client::Config config;
|
||||
std::string login_command_bb;
|
||||
std::string hardware_id;
|
||||
std::string serial_number2;
|
||||
uint64_t hardware_id;
|
||||
XBNetworkLocation xb_netloc;
|
||||
parray<le_uint32_t, 3> xb_9E_unknown_a1a;
|
||||
|
||||
|
||||
+15
-1
@@ -703,11 +703,25 @@ CommandDefinition c_delete_license(
|
||||
fprintf(stderr, "Account %08" PRIX32 " updated\n", account->account_id);
|
||||
});
|
||||
|
||||
CommandDefinition c_lookup(
|
||||
"lookup", "lookup USER\n\
|
||||
Find the account for a logged-in user.",
|
||||
true,
|
||||
+[](CommandArgs& args) {
|
||||
auto target = args.s->find_client(&args.args);
|
||||
if (target->login) {
|
||||
fprintf(stderr, "Found client %s with account ID %08" PRIX32 "\n",
|
||||
target->channel.name.c_str(), target->login->account->account_id);
|
||||
} else {
|
||||
// This should be impossible
|
||||
throw std::logic_error("find_client found user who is not logged in");
|
||||
}
|
||||
});
|
||||
CommandDefinition c_kick(
|
||||
"kick", "kick USER\n\
|
||||
Disconnect a user from the server. USER may be an account ID, player name,\n\
|
||||
or client ID (beginning with \"C-\"). This does not ban the user; they are\n\
|
||||
free to reconnect after doing this.\n",
|
||||
free to reconnect after doing this.",
|
||||
true,
|
||||
+[](CommandArgs& args) {
|
||||
auto target = args.s->find_client(&args.args);
|
||||
|
||||
@@ -382,3 +382,28 @@ const char* file_path_token_for_version(Version version) {
|
||||
throw runtime_error("invalid game version");
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t generate_random_hardware_id(Version version) {
|
||||
switch (version) {
|
||||
case Version::DC_NTE:
|
||||
case Version::DC_11_2000:
|
||||
case Version::DC_V1:
|
||||
case Version::DC_V2:
|
||||
return phosg::random_object<uint64_t>() & 0x0000FFFFFFFFFFFF;
|
||||
case Version::PC_NTE:
|
||||
case Version::PC_V2:
|
||||
return 0x0000FFFFFFFFFFFF;
|
||||
case Version::GC_NTE:
|
||||
// On GC NTE, the low byte is uninitialized memory from the TProtocol
|
||||
// constructor's stack
|
||||
return phosg::random_object<uint8_t>();
|
||||
case Version::GC_V3:
|
||||
case Version::GC_EP3_NTE:
|
||||
case Version::GC_EP3:
|
||||
case Version::XB_V3:
|
||||
case Version::BB_V4:
|
||||
return 0;
|
||||
default:
|
||||
throw runtime_error("invalid game version");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,3 +235,5 @@ template <>
|
||||
ServerBehavior phosg::enum_for_name<ServerBehavior>(const char* name);
|
||||
|
||||
const char* file_path_token_for_version(Version version);
|
||||
|
||||
uint64_t generate_random_hardware_id(Version version);
|
||||
|
||||
Reference in New Issue
Block a user