make login faster with MoreSaveSlots
This commit is contained in:
@@ -3109,6 +3109,10 @@ check_struct_size(S_TournamentGameDetails_Ep3NTE_E3, 0x734);
|
||||
check_struct_size(S_TournamentGameDetails_Ep3_E3, 0x73C);
|
||||
|
||||
// E3 (C->S): Player preview request (BB)
|
||||
// header.flag is not used by the vanilla client, but newserv's MoreSaveSlots
|
||||
// patch uses header.flag to tell the server how many save slots the client
|
||||
// expects. The server uses this to send all the character previews at once,
|
||||
// thus reducing the number of network roundtrips during login.
|
||||
|
||||
struct C_PlayerPreviewRequest_BB_E3 {
|
||||
le_int32_t character_index = 0;
|
||||
|
||||
+29
-12
@@ -3616,13 +3616,12 @@ static void on_E0_BB(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
|
||||
send_system_file_bb(c);
|
||||
}
|
||||
|
||||
static void on_E3_BB(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
|
||||
static void on_E3_BB(shared_ptr<Client> c, uint16_t, uint32_t flag, string& data) {
|
||||
const auto& cmd = check_size_t<C_PlayerPreviewRequest_BB_E3>(data);
|
||||
|
||||
c->save_and_unload_character();
|
||||
c->bb_character_index = cmd.character_index;
|
||||
|
||||
if (c->bb_connection_phase != 0x00) {
|
||||
c->save_and_unload_character();
|
||||
c->bb_character_index = cmd.character_index;
|
||||
send_approve_player_choice_bb(c);
|
||||
|
||||
} else {
|
||||
@@ -3631,15 +3630,33 @@ static void on_E3_BB(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto s = c->require_server_state();
|
||||
try {
|
||||
auto preview = c->character()->to_preview();
|
||||
send_player_preview_bb(c, cmd.character_index, &preview);
|
||||
auto send_preview = [&c](size_t index) -> void {
|
||||
c->save_and_unload_character();
|
||||
c->bb_character_index = index;
|
||||
try {
|
||||
auto preview = c->character()->to_preview();
|
||||
send_player_preview_bb(c, c->bb_character_index, &preview);
|
||||
|
||||
} catch (const exception& e) {
|
||||
// Player doesn't exist
|
||||
c->log.warning("Can\'t load character data: %s", e.what());
|
||||
send_player_preview_bb(c, cmd.character_index, nullptr);
|
||||
} catch (const exception& e) {
|
||||
// Player doesn't exist
|
||||
c->log.warning("Can\'t load character data: %s", e.what());
|
||||
send_player_preview_bb(c, c->bb_character_index, nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
if (flag == 0) {
|
||||
if (cmd.character_index < 0 || cmd.character_index >= 0x80) {
|
||||
throw runtime_error("client requested invalid character slot");
|
||||
}
|
||||
send_preview(cmd.character_index);
|
||||
} else if (cmd.character_index == 0) {
|
||||
if (flag >= 0x80) {
|
||||
throw runtime_error("client requested too many character slots");
|
||||
}
|
||||
auto s = c->require_server_state();
|
||||
for (size_t z = 0; z < flag; z++) {
|
||||
send_preview(z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -479,6 +479,28 @@ sig_bad:
|
||||
.binary CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
|
||||
sig_check_end: # 006C1C76
|
||||
|
||||
# Send slot count in E3 command
|
||||
.data 0x0046EB20 # TDataProtocol::send_E3_for_index
|
||||
.deltaof send_slot_count_in_E3_begin, send_slot_count_in_E3_end
|
||||
send_slot_count_in_E3_begin:
|
||||
# ecx = this (TDataProtocol*)
|
||||
# [esp + 4] = slot_index
|
||||
push 0
|
||||
push dword [esp + 8] # slot_index
|
||||
push 0x0C # slot count
|
||||
push 0x00E30010
|
||||
mov eax, esp
|
||||
push 0x10
|
||||
push eax
|
||||
mov eax, [ecx]
|
||||
call [eax + 0x20] # this->send_command(&cmd, 0x10) // ret 8
|
||||
add esp, 8
|
||||
mov eax, 0x006C1A80
|
||||
call eax # set_current_char_slot(slot_index) // ret 0
|
||||
add esp, 8
|
||||
ret 4
|
||||
send_slot_count_in_E3_end:
|
||||
|
||||
# Show slot number in each menu item
|
||||
.data 0x00401D57
|
||||
.deltaof show_slot_number_begin, show_slot_number_end
|
||||
|
||||
Reference in New Issue
Block a user