clean up memory handling for client configs

This commit is contained in:
Martin Michelsen
2022-04-01 10:39:04 -07:00
parent 07a6e40b18
commit 583925045e
6 changed files with 28 additions and 17 deletions
+7 -1
View File
@@ -65,7 +65,13 @@ ClientConfig Client::export_config() const {
cc.proxy_destination_address = this->proxy_destination_address; cc.proxy_destination_address = this->proxy_destination_address;
cc.proxy_destination_port = this->proxy_destination_port; cc.proxy_destination_port = this->proxy_destination_port;
cc.unused.clear(0xFF); cc.unused.clear(0xFF);
cc.unused_bb_only.clear(0xFF); return cc;
}
ClientConfigBB Client::export_config_bb() const {
ClientConfigBB cc;
cc.cfg = this->export_config();
cc.unused.clear(0xFF);
return cc; return cc;
} }
+6 -1
View File
@@ -34,7 +34,11 @@ struct ClientConfig {
uint32_t proxy_destination_address; uint32_t proxy_destination_address;
uint16_t proxy_destination_port; uint16_t proxy_destination_port;
parray<uint8_t, 0x0E> unused; parray<uint8_t, 0x0E> unused;
parray<uint8_t, 0x08> unused_bb_only; } __attribute__((packed));
struct ClientConfigBB {
ClientConfig cfg;
parray<uint8_t, 0x08> unused;
} __attribute__((packed)); } __attribute__((packed));
struct Client { struct Client {
@@ -91,5 +95,6 @@ struct Client {
ServerBehavior server_behavior); ServerBehavior server_behavior);
ClientConfig export_config() const; ClientConfig export_config() const;
ClientConfigBB export_config_bb() const;
void import_config(const ClientConfig& cc); void import_config(const ClientConfig& cc);
}; };
+9 -7
View File
@@ -579,7 +579,7 @@ struct C_Login_BB_93 {
ptext<char, 0x20> unused2; ptext<char, 0x20> unused2;
ptext<char, 0x10> password; ptext<char, 0x10> password;
ptext<char, 0x30> unused3; ptext<char, 0x30> unused3;
ClientConfig cfg; ClientConfigBB client_config;
}; };
// 94: Invalid command // 94: Invalid command
@@ -649,11 +649,13 @@ struct C_Login_PC_GC_9D_9E {
ptext<char, 0x30> serial_number2; ptext<char, 0x30> serial_number2;
ptext<char, 0x30> access_key2; ptext<char, 0x30> access_key2;
ptext<char, 0x10> name; ptext<char, 0x10> name;
// Note: there are 8 bytes at the end of cfg that are technically not union ClientConfigFields {
// included in the client config on GC, but the field after it is ClientConfig cfg;
// sufficiently large and unused anyway parray<uint8_t, 0x20> data;
ClientConfig cfg;
parray<uint8_t, 0x5C> unused4; ClientConfigFields() : cfg() { }
} client_config;
parray<uint8_t, 0x64> unused4;
}; };
// 9F: Invalid command // 9F: Invalid command
@@ -1081,7 +1083,7 @@ struct S_ClientInit_BB_E6 {
le_uint32_t player_tag; le_uint32_t player_tag;
le_uint32_t guild_card_number; le_uint32_t guild_card_number;
le_uint32_t team_id; le_uint32_t team_id;
ClientConfig cfg; ClientConfigBB cfg;
le_uint32_t caps; // should be 0x00000102 le_uint32_t caps; // should be 0x00000102
}; };
+3 -5
View File
@@ -204,8 +204,7 @@ void ProxyServer::UnlinkedSession::on_client_input() {
serial_number, cmd->access_key.c_str(), nullptr); serial_number, cmd->access_key.c_str(), nullptr);
sub_version = cmd->sub_version; sub_version = cmd->sub_version;
character_name = cmd->name; character_name = cmd->name;
memcpy(&client_config, &cmd->cfg, offsetof(ClientConfig, unused_bb_only)); client_config = cmd->client_config.cfg;
client_config.unused_bb_only.clear(0xFF);
} catch (const exception& e) { } catch (const exception& e) {
log(ERROR, "[ProxyServer] Unlinked client has no valid license"); log(ERROR, "[ProxyServer] Unlinked client has no valid license");
should_close_unlinked_session = true; should_close_unlinked_session = true;
@@ -626,7 +625,6 @@ void ProxyServer::LinkedSession::on_server_input() {
// did (when it was in an unlinked session). // did (when it was in an unlinked session).
if (command == 0x17) { if (command == 0x17) {
C_VerifyLicense_GC_DB cmd; C_VerifyLicense_GC_DB cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.serial_number = string_printf("%08" PRIX32 "", cmd.serial_number = string_printf("%08" PRIX32 "",
this->license->serial_number); this->license->serial_number);
cmd.access_key = this->license->access_key; cmd.access_key = this->license->access_key;
@@ -664,7 +662,7 @@ void ProxyServer::LinkedSession::on_server_input() {
cmd.serial_number2 = cmd.serial_number; cmd.serial_number2 = cmd.serial_number;
cmd.access_key2 = cmd.access_key; cmd.access_key2 = cmd.access_key;
cmd.name = this->character_name; cmd.name = this->character_name;
memcpy(&cmd.cfg, this->remote_client_config_data.data(), 0x20); cmd.client_config.data = this->remote_client_config_data;
// If there's a guild card number, a shorter 9E is sent that ends // If there's a guild card number, a shorter 9E is sent that ends
// right after the client config data // right after the client config data
@@ -675,7 +673,7 @@ void ProxyServer::LinkedSession::on_server_input() {
0x9E, 0x9E,
0x01, 0x01,
&cmd, &cmd,
this->guild_card_number ? (offsetof(C_Login_PC_GC_9D_9E, cfg) + 0x20) : sizeof(cmd), this->guild_card_number ? offsetof(C_Login_PC_GC_9D_9E, unused4) : sizeof(cmd),
name.c_str()); name.c_str());
break; break;
} }
+2 -2
View File
@@ -335,7 +335,7 @@ void process_login_d_e_pc_gc(shared_ptr<ServerState> s, shared_ptr<Client> c,
} }
try { try {
c->import_config(cmd.cfg); c->import_config(cmd.client_config.cfg);
} catch (const invalid_argument&) { } catch (const invalid_argument&) {
// If we can't import the config, assume that the client was not connected // If we can't import the config, assume that the client was not connected
// to newserv before, so we should show the welcome message. // to newserv before, so we should show the welcome message.
@@ -370,7 +370,7 @@ void process_login_bb(shared_ptr<ServerState> s, shared_ptr<Client> c,
} }
try { try {
c->import_config(cmd.cfg); c->import_config(cmd.client_config.cfg);
c->bb_game_state++; c->bb_game_state++;
} catch (const invalid_argument&) { } catch (const invalid_argument&) {
c->bb_game_state = 0; c->bb_game_state = 0;
+1 -1
View File
@@ -278,7 +278,7 @@ void send_client_init_bb(shared_ptr<Client> c, uint32_t error) {
cmd.player_tag = 0x00010000; cmd.player_tag = 0x00010000;
cmd.guild_card_number = c->license->serial_number; cmd.guild_card_number = c->license->serial_number;
cmd.team_id = static_cast<uint32_t>(random_object<uint32_t>()); cmd.team_id = static_cast<uint32_t>(random_object<uint32_t>());
cmd.cfg = c->export_config(); cmd.cfg = c->export_config_bb();
cmd.caps = 0x00000102; cmd.caps = 0x00000102;
send_command(c, 0x00E6, 0x00000000, cmd); send_command(c, 0x00E6, 0x00000000, cmd);
} }