skip guild card file download if checksums match

This commit is contained in:
Martin Michelsen
2022-07-30 13:08:22 -07:00
parent f4517ab92e
commit 286997188e
5 changed files with 30 additions and 10 deletions
+15 -2
View File
@@ -2284,9 +2284,13 @@ struct C_GuildCardChecksum_01E8 {
};
// 02E8 (S->C): Accept/decline guild card file checksum
// If needs_update is nonzero, the client will request the guild card file by
// sending an 03E8 command. If needs_update is zero, the client will skip
// downloading the guild card file and send a 04EB command (requesting the
// stream file) instead.
struct S_GuildCardChecksumResponse_BB_02E8 {
le_uint32_t verify;
le_uint32_t needs_update;
le_uint32_t unused;
};
@@ -2436,7 +2440,7 @@ struct S_Unknown_GC_Ep3_EB {
PlayerEntry players[12];
};
// EB (S->C): Send stream file index and chunks (BB)
// 01EB (S->C): Send stream file index (BB)
// Command is a list of these; header.flag is the entry count.
struct S_StreamFileIndexEntry_BB_01EB {
@@ -2446,11 +2450,20 @@ struct S_StreamFileIndexEntry_BB_01EB {
ptext<char, 0x40> filename;
};
// 02EB (S->C): Send stream file chunk (BB)
struct S_StreamFileChunk_BB_02EB {
le_uint32_t chunk_index;
uint8_t data[0x6800];
};
// 03EB (C->S): Request a specific stream file chunk
// header.flag is the chunk index. Server should respond with a 02EB command.
// 04EB (C->S): Request stream file header
// No arguments
// Server should respond with a 01EB command.
// EC: Create game (Episode 3)
// Same format as C1; some fields are unused (e.g. episode, difficulty).
+5
View File
@@ -6,6 +6,7 @@
#include <stdexcept>
#include <phosg/Filesystem.hh>
#include <phosg/Hash.hh>
#include "FileContentsCache.hh"
#include "Loggers.hh"
@@ -298,6 +299,10 @@ void GuildCardEntryBB::clear() {
this->unknown_a1.clear();
}
uint32_t GuildCardFileBB::checksum() const {
return crc32(this, sizeof(*this));
}
void PlayerBank::load(const string& filename) {
+2
View File
@@ -252,6 +252,8 @@ struct GuildCardFileBB {
GuildCardBB blocked[0x1C];
parray<uint8_t, 0x180> unknown_a2;
GuildCardEntryBB entries[0x69];
uint32_t checksum() const;
} __attribute__((packed));
struct KeyAndTeamConfigBB {
+7 -6
View File
@@ -1587,12 +1587,13 @@ void process_client_checksum_bb(shared_ptr<ServerState>, shared_ptr<Client> c,
constexpr size_t max_blocked = sizeof(GuildCardFileBB::blocked) / sizeof(GuildCardBB);
switch (command) {
case 0x01E8: { // Check guild card file checksum
check_size_v(data.size(), sizeof(C_GuildCardChecksum_01E8));
// TODO: Presumably this response tells the client whether the file needs
// to be downloaded at all. In the future, we could actually use the
// checksum to skip downloading if the file isn't modified, to save time.
S_GuildCardChecksumResponse_BB_02E8 cmd = {1, 0};
send_command_t(c, 0x02E8, 0x00000000, cmd);
const auto& cmd = check_size_t<C_GuildCardChecksum_01E8>(data);
uint32_t checksum = c->game_data.account()->guild_cards.checksum();
c->log.info("(Guild card file) Server checksum = %08" PRIX32 ", client checksum = %08" PRIX32,
checksum, cmd.checksum.load());
S_GuildCardChecksumResponse_BB_02E8 response = {
(cmd.checksum != checksum), 0};
send_command_t(c, 0x02E8, 0x00000000, response);
break;
}
case 0x03E8: // Download guild card file
+1 -2
View File
@@ -322,8 +322,7 @@ void send_player_preview_bb(shared_ptr<Client> c, uint8_t player_index,
}
void send_guild_card_header_bb(shared_ptr<Client> c) {
uint32_t checksum = crc32(
&c->game_data.account()->guild_cards, sizeof(GuildCardFileBB));
uint32_t checksum = c->game_data.account()->guild_cards.checksum();
S_GuildCardHeader_BB_01DC cmd = {1, sizeof(GuildCardFileBB), checksum};
send_command_t(c, 0x01DC, 0x00000000, cmd);
}