hide Ep3 maps that don't have enough player slots for the game
This commit is contained in:
@@ -2026,12 +2026,31 @@ const string& MapIndex::MapEntry::compressed(bool is_trial) const {
|
||||
}
|
||||
}
|
||||
|
||||
const string& MapIndex::get_compressed_list() const {
|
||||
if (this->compressed_map_list.empty()) {
|
||||
const string& MapIndex::get_compressed_list(size_t num_players) const {
|
||||
if (num_players == 0) {
|
||||
throw runtime_error("cannot generate map list for no players");
|
||||
}
|
||||
if (num_players > 4) {
|
||||
throw logic_error("player count is too high in map list generation");
|
||||
}
|
||||
string& compressed_map_list = this->compressed_map_lists.at(num_players - 1);
|
||||
if (compressed_map_list.empty()) {
|
||||
StringWriter entries_w;
|
||||
StringWriter strings_w;
|
||||
|
||||
size_t num_maps = 0;
|
||||
for (const auto& map_it : this->maps) {
|
||||
size_t map_num_players = 0;
|
||||
for (size_t z = 0; z < 4; z++) {
|
||||
uint8_t player_type = map_it.second->map.entry_states[z].player_type;
|
||||
if (player_type == 0x00 || player_type == 0x01 || player_type == 0xFF) {
|
||||
map_num_players++;
|
||||
}
|
||||
}
|
||||
if (map_num_players < num_players) {
|
||||
continue;
|
||||
}
|
||||
|
||||
MapList::Entry e;
|
||||
const auto& map = map_it.second->map;
|
||||
e.map_x = map.map_x;
|
||||
@@ -2059,10 +2078,11 @@ const string& MapIndex::get_compressed_list() const {
|
||||
e.unknown_a1 = map_it.second->is_quest ? 0x00 : 0xFF;
|
||||
|
||||
entries_w.put(e);
|
||||
num_maps++;
|
||||
}
|
||||
|
||||
MapList header;
|
||||
header.num_maps = this->maps.size();
|
||||
header.num_maps = num_maps;
|
||||
header.unknown_a1 = 0;
|
||||
header.strings_offset = entries_w.size();
|
||||
header.total_size = sizeof(MapList) + entries_w.size() + strings_w.size();
|
||||
@@ -2075,15 +2095,15 @@ const string& MapIndex::get_compressed_list() const {
|
||||
StringWriter compressed_w;
|
||||
compressed_w.put_u32b(prs.input_size());
|
||||
compressed_w.write(prs.close());
|
||||
this->compressed_map_list = std::move(compressed_w.str());
|
||||
if (this->compressed_map_list.size() > 0x7BEC) {
|
||||
throw runtime_error("Episode 3 compressed map list is too large");
|
||||
compressed_map_list = std::move(compressed_w.str());
|
||||
if (compressed_map_list.size() > 0x7BEC) {
|
||||
throw runtime_error(string_printf("compressed map list for %zu players is too large (0x%zX bytes)", num_players, compressed_map_list.size()));
|
||||
}
|
||||
size_t decompressed_size = sizeof(header) + entries_w.size() + strings_w.size();
|
||||
static_game_data_log.info("Generated Episode 3 compressed map list (0x%zX -> 0x%zX bytes)",
|
||||
decompressed_size, this->compressed_map_list.size());
|
||||
static_game_data_log.info("Generated Episode 3 compressed map list for %zu player(s) (%zu maps; 0x%zX -> 0x%zX bytes)",
|
||||
num_players, num_maps, decompressed_size, compressed_map_list.size());
|
||||
}
|
||||
return this->compressed_map_list;
|
||||
return compressed_map_list;
|
||||
}
|
||||
|
||||
shared_ptr<const MapIndex::MapEntry> MapIndex::definition_for_number(uint32_t id) const {
|
||||
|
||||
@@ -1145,17 +1145,14 @@ public:
|
||||
mutable std::string compressed_trial_data;
|
||||
};
|
||||
|
||||
const std::string& get_compressed_list() const;
|
||||
const std::string& get_compressed_list(size_t num_players) const;
|
||||
std::shared_ptr<const MapEntry> definition_for_number(uint32_t id) const;
|
||||
std::shared_ptr<const MapEntry> definition_for_name(const std::string& name) const;
|
||||
std::set<uint32_t> all_numbers() const;
|
||||
|
||||
private:
|
||||
// The compressed map list is generated on demand from the maps map below.
|
||||
// It's marked mutable because the logical consistency of the MapIndex object
|
||||
// is not violated from the caller's perspective even if we don't generate the
|
||||
// compressed map list at load time.
|
||||
mutable std::string compressed_map_list;
|
||||
// The compressed map lists are generated on demand from the maps map below
|
||||
mutable std::array<std::string, 4> compressed_map_lists;
|
||||
std::map<uint32_t, std::shared_ptr<MapEntry>> maps;
|
||||
std::unordered_map<std::string, std::shared_ptr<MapEntry>> maps_by_name;
|
||||
};
|
||||
|
||||
@@ -2168,7 +2168,7 @@ void Server::handle_6xB3x40_map_list_request(const string& data) {
|
||||
throw runtime_error("lobby is deleted");
|
||||
}
|
||||
|
||||
const auto& list_data = this->base()->map_index->get_compressed_list();
|
||||
const auto& list_data = this->base()->map_index->get_compressed_list(l->count_clients());
|
||||
|
||||
StringWriter w;
|
||||
uint32_t subcommand_size = (list_data.size() + sizeof(G_MapList_GC_Ep3_6xB6x40) + 3) & (~3);
|
||||
|
||||
Reference in New Issue
Block a user