diff --git a/README.md b/README.md index dcec5b6f..4e09d4f1 100644 --- a/README.md +++ b/README.md @@ -107,13 +107,16 @@ To use newserv in other ways (e.g. for translating data), see the end of this do newserv automatically finds quests in the system/quests/ directory. To install your own quests, or to use quests you've saved using the proxy's "save files" option, just put them in that directory and name them appropriately. -Standard quest files should be named like `q###-CATEGORY-VERSION.EXT`, battle quests should be named like `b###-VERSION.EXT`, challenge quests should be named like `c###-VERSION.EXT` for Episode 1 or `d###-VERSION.EXT` for Episode 2, and Episode 3 download quests should be named like `e###-gc3.EXT`. The fields in each filename are: +Standard quest files should be named like `q###-CATEGORY-VERSION-LANGUAGE.EXT`, battle quests should be named like `b###-VERSION-LANGUAGE.EXT`, challenge quests should be named like `c###-VERSION-LANGUAGE.EXT` for Episode 1 or `d###-VERSION-LANGUAGE.EXT` for Episode 2, and Episode 3 download quests should be named like `e###-gc3-LANGUAGE.EXT`. The fields in each filename are: - `###`: quest number (this doesn't really matter; it should just be unique across the PSO version) - `CATEGORY`: ret = Retrieval, ext = Extermination, evt = Events, shp = Shops, vr = VR, twr = Tower, gv1/gv2/gv4 = Government (BB only), dl = Download (these don't appear during online play), 1p = Solo (BB only) - `VERSION`: dn = Dreamcast NTE, d1 = Dreamcast v1, dc = Dreamcast v2, pc = PC, gcn = GameCube Trial Edition, gc = GameCube Episodes 1 & 2, gc3 = Episode 3, xb = Xbox, bb = Blue Burst +- `LANGUAGE`: j = Japanese, e = English, g = German, f = French, s = Spanish - `EXT`: file extension (see table below) -For example, the GameCube version of Lost HEAT SWORD is in two files named `q058-ret-gc.bin` and `q058-ret-gc.dat`. newserv knows these files are quests because they're in the system/quests/ directory, it knows they're for PSO GC because the filenames contain `-gc`, and it puts them in the Retrieval category because the filenames contain `-ret`. +On .dat files, the `LANGUAGE` token may be omitted. If it's present, then that .dat file will only be used for that version of the quest; if omitted, then that .dat file will be used for all versions of the quest. + +For example, the GameCube version of Lost HEAT SWORD is in two files named `q058-ret-gc-e.bin` and `q058-ret-gc.dat`. newserv knows these files are quests because they're in the system/quests/ directory, it knows they're for PSO GC because the filenames contain `-gc`, it knows this is the English version of the quest because the .bin filename ends with `-e` (even though the .dat filename does not), and it puts them in the Retrieval category because the filenames contain `-ret`. The type identifiers (`b`, `c`, `d`, `e`, or `q`) and categories are configurable. See QuestCategories in config.example.json for more information on how to make new categories or edit the existing categories. diff --git a/TODO.md b/TODO.md index 79599a44..135386c1 100644 --- a/TODO.md +++ b/TODO.md @@ -14,6 +14,7 @@ - Make reloading happen on separate threads so compression doesn't block active clients - Implement decrypt/encrypt actions for VMS files - Fix Word Select mapping across versions +- Make UI strings localizable (e.g. entries in menus, welcome message, etc.) ## Episode 3 diff --git a/src/ChatCommands.hh b/src/ChatCommands.hh index c79172bb..8b1f9504 100644 --- a/src/ChatCommands.hh +++ b/src/ChatCommands.hh @@ -11,4 +11,4 @@ #include "ServerState.hh" void on_chat_command(std::shared_ptr c, const std::u16string& text); -void on_chat_command(shared_ptr ses, const std::u16string& text); +void on_chat_command(std::shared_ptr ses, const std::u16string& text); diff --git a/src/Client.hh b/src/Client.hh index 1c7faf13..09fc5127 100644 --- a/src/Client.hh +++ b/src/Client.hh @@ -182,7 +182,7 @@ struct Client : public std::enable_shared_from_this { std::unordered_map> sending_files; Client( - shared_ptr server, + std::shared_ptr server, struct bufferevent* bev, GameVersion version, ServerBehavior server_behavior); @@ -190,6 +190,9 @@ struct Client : public std::enable_shared_from_this { void reschedule_ping_and_timeout_events(); + inline uint8_t language() const { + return this->game_data.player()->inventory.language; + } inline GameVersion version() const { return this->channel.version; } diff --git a/src/CommonItemSet.cc b/src/CommonItemSet.cc index 5b0b0f98..a9904376 100644 --- a/src/CommonItemSet.cc +++ b/src/CommonItemSet.cc @@ -2,6 +2,8 @@ #include "StaticGameData.hh" +using namespace std; + CommonItemSet::CommonItemSet(shared_ptr data) : gsl(data, true) {} diff --git a/src/CommonItemSet.hh b/src/CommonItemSet.hh index bdd81d74..adf3c9a0 100644 --- a/src/CommonItemSet.hh +++ b/src/CommonItemSet.hh @@ -18,14 +18,14 @@ struct ProbabilityTable { void push(ItemT item) { if (this->count == MaxCount) { - throw runtime_error("push to full probability table"); + throw std::runtime_error("push to full probability table"); } this->items[this->count++] = item; } ItemT pop() { if (this->count == 0) { - throw runtime_error("pop from empty probability table"); + throw std::runtime_error("pop from empty probability table"); } return this->items[--this->count]; } @@ -41,7 +41,7 @@ struct ProbabilityTable { ItemT sample(PSOLFGEncryption& random_crypt) const { if (this->count == 0) { - throw runtime_error("pop from empty probability table"); + throw std::runtime_error("pop from empty probability table"); } else if (this->count == 1) { return this->items[0]; } else { @@ -303,7 +303,7 @@ public: using WeightTableEntry32 = WeightTableEntry; protected: - std::shared_ptr data; + std::shared_ptr data; StringReader r; struct TableSpec { @@ -320,7 +320,7 @@ protected: const T* entries = &r.pget( spec.offset + index * spec.entries_per_table * sizeof(T), spec.entries_per_table * sizeof(T)); - return make_pair(entries, spec.entries_per_table); + return std::make_pair(entries, spec.entries_per_table); } }; @@ -418,7 +418,7 @@ private: uint8_t section_id) const; int8_t get_luck(uint32_t start_offset, uint8_t delta_index) const; - std::shared_ptr data; + std::shared_ptr data; StringReader r; struct DeltaProbabilityEntry { diff --git a/src/Episode3/DataIndexes.cc b/src/Episode3/DataIndexes.cc index daa942f0..4c707cd4 100644 --- a/src/Episode3/DataIndexes.cc +++ b/src/Episode3/DataIndexes.cc @@ -1536,6 +1536,91 @@ void StateFlags::clear_FF() { this->client_sc_card_types.clear(CardType::INVALID_FF); } +void MapDefinition::assert_semantically_equivalent(const MapDefinition& other) const { + if (this->map_number != other.map_number) { + throw runtime_error("map number not equal"); + } + if (this->width != other.width) { + throw runtime_error("width not equal"); + } + if (this->height != other.height) { + throw runtime_error("width not equal"); + } + if (this->environment_number != other.environment_number) { + throw runtime_error("environment number not equal"); + } + if (this->map_tiles != other.map_tiles) { + throw runtime_error("tiles not equal"); + } + if (this->start_tile_definitions != other.start_tile_definitions) { + throw runtime_error("start tile definitions not equal"); + } + if (this->modification_tiles != other.modification_tiles) { + throw runtime_error("modification tiles not equal"); + } + if (this->unknown_a5 != other.unknown_a5) { + throw runtime_error("unknown_a5 not equal"); + } + if (this->default_rules != other.default_rules) { + throw runtime_error("default rules not equal"); + } + for (size_t z = 0; z < this->npc_decks.size(); z++) { + if (this->npc_decks[z].card_ids != other.npc_decks[z].card_ids) { + throw runtime_error("npc deck card IDs not equal"); + } + const auto& this_ai_params = this->npc_ai_params[z]; + const auto& other_ai_params = other.npc_ai_params[z]; + if (this_ai_params.unknown_a1 != other_ai_params.unknown_a1) { + throw runtime_error("npc AI params unknown_a1 not equal"); + } + if (this_ai_params.is_arkz != other_ai_params.is_arkz) { + throw runtime_error("npc AI params is_arkz not equal"); + } + if (this_ai_params.unknown_a2 != other_ai_params.unknown_a2) { + throw runtime_error("npc AI params unknown_a2 not equal"); + } + if (this_ai_params.params != other_ai_params.params) { + throw runtime_error("npc AI params not equal"); + } + } + if (this->unknown_a7 != other.unknown_a7) { + throw runtime_error("unknown_a7 not equal"); + } + if (this->npc_ai_params_entry_index != other.npc_ai_params_entry_index) { + throw runtime_error("npc AI params entry indexes not equal"); + } + if (this->reward_card_ids != other.reward_card_ids) { + throw runtime_error("reward card IDs not equal"); + } + if (this->win_level_override != other.win_level_override) { + throw runtime_error("win level override not equal"); + } + if (this->loss_level_override != other.loss_level_override) { + throw runtime_error("loss level override not equal"); + } + if (this->field_offset_x != other.field_offset_x) { + throw runtime_error("field x offset not equal"); + } + if (this->field_offset_y != other.field_offset_y) { + throw runtime_error("field y offset not equal"); + } + if (this->map_category != other.map_category) { + throw runtime_error("map category not equal"); + } + if (this->cyber_block_type != other.cyber_block_type) { + throw runtime_error("cyber block type not equal"); + } + if (this->unknown_a11 != other.unknown_a11) { + throw runtime_error("unknown_a11 not equal"); + } + if (this->unavailable_sc_cards != other.unavailable_sc_cards) { + throw runtime_error("unavailable SC cards not equal"); + } + if (this->entry_states != other.entry_states) { + throw runtime_error("entry states not equal"); + } +} + string MapDefinition::CameraSpec::str() const { return string_printf( "CameraSpec[a1=(%g %g %g %g %g %g %g %g %g) camera=(%g %g %g) focus=(%g %g %g) a2=(%g %g %g)]", @@ -2294,31 +2379,157 @@ string CardIndex::normalize_card_name(const string& name) { return ret; } +MapIndex::VersionedMap::VersionedMap(shared_ptr map, uint8_t language) + : map(map), + language(language) {} + +MapIndex::VersionedMap::VersionedMap(std::string&& compressed_data, uint8_t language) + : language(language), + compressed_data(std::move(compressed_data)) { + string decompressed = prs_decompress(this->compressed_data); + if (decompressed.size() != sizeof(MapDefinition)) { + throw runtime_error(string_printf( + "decompressed data size is incorrect (expected %zu bytes, read %zu bytes)", + sizeof(MapDefinition), decompressed.size())); + } + this->map.reset(new MapDefinition(*reinterpret_cast(decompressed.data()))); +} + +shared_ptr MapIndex::VersionedMap::trial() const { + if (!this->trial_map) { + this->trial_map.reset(new MapDefinitionTrial(*this->map)); + } + return this->trial_map; +} + +const std::string& MapIndex::VersionedMap::compressed(bool is_trial) const { + if (is_trial) { + if (this->compressed_trial_data.empty()) { + auto md = this->trial(); + this->compressed_trial_data = prs_compress(md.get(), sizeof(*md)); + } + return this->compressed_trial_data; + } else { + if (this->compressed_data.empty()) { + this->compressed_data = prs_compress(this->map.get(), sizeof(*this->map)); + } + return this->compressed_data; + } +} + +MapIndex::Map::Map(shared_ptr initial_version) + : map_number(initial_version->map->map_number), + initial_version(initial_version) { + this->versions.resize(this->initial_version->language + 1); + this->versions[this->initial_version->language] = initial_version; +} + +void MapIndex::Map::add_version(std::shared_ptr vm) { + if (this->versions.size() <= vm->language) { + this->versions.resize(vm->language + 1); + } + if (this->versions[vm->language]) { + throw runtime_error("map version already exists"); + } + this->initial_version->map->assert_semantically_equivalent(*vm->map); + this->versions[vm->language] = vm; +} + +bool MapIndex::Map::has_version(uint8_t language) const { + return (this->versions.size() > language) && !!this->versions[language]; +} + +shared_ptr MapIndex::Map::version(uint8_t language) const { + // If the requested language exists, return it + if ((language < this->versions.size()) && this->versions[language]) { + return this->versions[language]; + } + // If English exists, return it + if ((1 < this->versions.size()) && this->versions[1]) { + return this->versions[1]; + } + // Return the first version that exists + for (const auto& vm : this->versions) { + if (vm) { + return vm; + } + } + // This should never happen because Map cannot be constructed without an + // initial_version + throw logic_error("no map versions exist"); +} + MapIndex::MapIndex(const string& directory) { - for (const auto& filename : list_directory(directory)) { + for (const auto& filename : list_directory_sorted(directory)) { try { - shared_ptr entry; - + string base_filename; + string compressed_data; + shared_ptr decompressed_data; if (ends_with(filename, ".mnmd") || ends_with(filename, ".bind")) { - entry.reset(new MapEntry(load_object_file(directory + "/" + filename))); + decompressed_data.reset(new MapDefinition(load_object_file(directory + "/" + filename))); + base_filename = filename.substr(0, filename.size() - 5); } else if (ends_with(filename, ".mnm") || ends_with(filename, ".bin")) { - entry.reset(new MapEntry(load_file(directory + "/" + filename))); + compressed_data = load_file(directory + "/" + filename); + base_filename = filename.substr(0, filename.size() - 4); + } else if (ends_with(filename, ".bin.gci") || ends_with(filename, ".mnm.gci")) { + compressed_data = decode_gci_data(load_file(directory + "/" + filename)); + base_filename = filename.substr(0, filename.size() - 8); } else if (ends_with(filename, ".gci")) { - entry.reset(new MapEntry(decode_gci_file(directory + "/" + filename))); + compressed_data = decode_gci_data(load_file(directory + "/" + filename)); + base_filename = filename.substr(0, filename.size() - 4); + } else if (ends_with(filename, ".bin.vms") || ends_with(filename, ".mnm.vms")) { + compressed_data = decode_vms_data(load_file(directory + "/" + filename)); + base_filename = filename.substr(0, filename.size() - 8); + } else if (ends_with(filename, ".vms")) { + compressed_data = decode_vms_data(load_file(directory + "/" + filename)); + base_filename = filename.substr(0, filename.size() - 4); + } else if (ends_with(filename, ".bin.dlq") || ends_with(filename, ".mnm.dlq")) { + compressed_data = decode_dlq_data(load_file(directory + "/" + filename)); + base_filename = filename.substr(0, filename.size() - 8); } else if (ends_with(filename, ".dlq")) { - entry.reset(new MapEntry(decode_dlq_file(directory + "/" + filename))); + compressed_data = decode_dlq_data(load_file(directory + "/" + filename)); + base_filename = filename.substr(0, filename.size() - 4); + } else { + continue; // Silently skip file } - if (entry.get()) { - if (!this->maps.emplace(entry->map.map_number, entry).second) { - throw runtime_error("duplicate map number"); - } - this->maps_by_name.emplace(entry->map.name, entry); - string name = entry->map.name; - static_game_data_log.info("Indexed Episode 3 %s %s (%08" PRIX32 "; %s)", - entry->map.is_quest() ? "online quest" : "free battle map", - filename.c_str(), entry->map.map_number.load(), name.c_str()); + if (base_filename.size() < 2) { + throw runtime_error("filename too short for language code"); } + if (base_filename[base_filename.size() - 2] != '-') { + throw runtime_error("language code not present"); + } + uint8_t language = language_code_for_char(base_filename[base_filename.size() - 1]); + + shared_ptr vm; + if (decompressed_data) { + vm.reset(new VersionedMap(decompressed_data, language)); + } else if (!compressed_data.empty()) { + vm.reset(new VersionedMap(std::move(compressed_data), language)); + } else { + throw runtime_error("unknown map file format"); + } + + string name = format_data_string(vm->map->name); + auto map_it = this->maps.find(vm->map->map_number); + if (map_it == this->maps.end()) { + map_it = this->maps.emplace(vm->map->map_number, new Map(vm)).first; + static_game_data_log.info("(%s) Created Episode 3 map %08" PRIX32 " %c (%s; %s)", + filename.c_str(), + vm->map->map_number.load(), + char_for_language_code(vm->language), + vm->map->is_quest() ? "quest" : "free", + name.c_str()); + } else { + map_it->second->add_version(vm); + static_game_data_log.info("(%s) Added Episode 3 map version %08" PRIX32 " %c (%s; %s)", + filename.c_str(), + vm->map->map_number.load(), + char_for_language_code(vm->language), + vm->map->is_quest() ? "quest" : "free", + name.c_str()); + } + this->maps_by_name.emplace(vm->map->name, map_it->second); } catch (const exception& e) { static_game_data_log.warning("Failed to index Episode 3 map %s: %s", @@ -2327,51 +2538,28 @@ MapIndex::MapIndex(const string& directory) { } } -MapIndex::MapEntry::MapEntry(const MapDefinition& map) : map(map) {} - -MapIndex::MapEntry::MapEntry(const string& compressed) - : compressed_data(compressed) { - string decompressed = prs_decompress(this->compressed_data); - if (decompressed.size() != sizeof(MapDefinition)) { - throw runtime_error(string_printf( - "decompressed data size is incorrect (expected %zu bytes, read %zu bytes)", - sizeof(MapDefinition), decompressed.size())); - } - this->map = *reinterpret_cast(decompressed.data()); -} - -const string& MapIndex::MapEntry::compressed(bool is_trial) const { - if (is_trial) { - if (this->compressed_trial_data.empty()) { - MapDefinitionTrial mdt(this->map); - this->compressed_trial_data = prs_compress(&mdt, sizeof(mdt)); - } - return this->compressed_trial_data; - } else { - if (this->compressed_data.empty()) { - this->compressed_data = prs_compress(&this->map, sizeof(this->map)); - } - return this->compressed_data; - } -} - -const string& MapIndex::get_compressed_list(size_t num_players) const { +const string& MapIndex::get_compressed_list(size_t num_players, uint8_t language) 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 (language >= this->compressed_map_lists.size()) { + this->compressed_map_lists.resize(language + 1); + } + string& compressed_map_list = this->compressed_map_lists[language].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) { + auto vm = map_it.second->version(language); 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; + uint8_t player_type = vm->map->entry_states[z].player_type; if (player_type == 0x00 || player_type == 0x01 || player_type == 0xFF) { map_num_players++; } @@ -2381,29 +2569,28 @@ const string& MapIndex::get_compressed_list(size_t num_players) const { } MapList::Entry e; - const auto& map = map_it.second->map; - e.map_x = map.map_x; - e.map_y = map.map_y; - e.environment_number = map.environment_number; - e.map_number = map.map_number.load(); - e.width = map.width; - e.height = map.height; - e.map_tiles = map.map_tiles; - e.modification_tiles = map.modification_tiles; + e.map_x = vm->map->map_x; + e.map_y = vm->map->map_y; + e.environment_number = vm->map->environment_number; + e.map_number = vm->map->map_number.load(); + e.width = vm->map->width; + e.height = vm->map->height; + e.map_tiles = vm->map->map_tiles; + e.modification_tiles = vm->map->modification_tiles; e.name_offset = strings_w.size(); - strings_w.write(map.name.data(), map.name.len()); + strings_w.write(vm->map->name.data(), vm->map->name.len()); strings_w.put_u8(0); e.location_name_offset = strings_w.size(); - strings_w.write(map.location_name.data(), map.location_name.len()); + strings_w.write(vm->map->location_name.data(), vm->map->location_name.len()); strings_w.put_u8(0); e.quest_name_offset = strings_w.size(); - strings_w.write(map.quest_name.data(), map.quest_name.len()); + strings_w.write(vm->map->quest_name.data(), vm->map->quest_name.len()); strings_w.put_u8(0); e.description_offset = strings_w.size(); - strings_w.write(map.description.data(), map.description.len()); + strings_w.write(vm->map->description.data(), vm->map->description.len()); strings_w.put_u8(0); - e.map_category = map_it.second->map.map_category; + e.map_category = vm->map->map_category; entries_w.put(e); num_maps++; @@ -2434,11 +2621,11 @@ const string& MapIndex::get_compressed_list(size_t num_players) const { return compressed_map_list; } -shared_ptr MapIndex::definition_for_number(uint32_t id) const { +shared_ptr MapIndex::for_number(uint32_t id) const { return this->maps.at(id); } -shared_ptr MapIndex::definition_for_name(const string& name) const { +shared_ptr MapIndex::for_name(const string& name) const { return this->maps_by_name.at(name); } diff --git a/src/Episode3/DataIndexes.hh b/src/Episode3/DataIndexes.hh index e2791c3e..9ab203c9 100644 --- a/src/Episode3/DataIndexes.hh +++ b/src/Episode3/DataIndexes.hh @@ -902,8 +902,8 @@ struct Rules { Rules() = default; explicit Rules(const JSON& json); JSON json() const; - bool operator==(const Rules& other) const; - bool operator!=(const Rules& other) const; + bool operator==(const Rules& other) const = default; + bool operator!=(const Rules& other) const = default; void clear(); void set_defaults(); @@ -1284,6 +1284,9 @@ struct MapDefinition { // .mnmd format; also the format of (decompressed) quests // 01 = DARK ONLY // FF = any deck allowed uint8_t deck_type; + + bool operator==(const EntryState& other) const = default; + bool operator!=(const EntryState& other) const = default; } __attribute__((packed)); /* 5A10 */ parray entry_states; /* 5A18 */ @@ -1292,6 +1295,12 @@ struct MapDefinition { // .mnmd format; also the format of (decompressed) quests return (this->map_category <= 2); } + // This function throws runtime_error if the passed-in map is not semantically + // equivalent to *this. Semantic equivalence means all fields that affect + // gameplay and visuals are equivalent, but dialogue, names, and description + // text may differ. + void assert_semantically_equivalent(const MapDefinition& other) const; + std::string str(const CardIndex* card_index = nullptr) const; } __attribute__((packed)); @@ -1390,30 +1399,51 @@ class MapIndex { public: MapIndex(const std::string& directory); - class MapEntry { + class VersionedMap { public: - MapDefinition map; + std::shared_ptr map; + uint8_t language; - explicit MapEntry(const MapDefinition& map); - explicit MapEntry(const std::string& compressed_data); + VersionedMap(std::shared_ptr map, uint8_t language); + VersionedMap(std::string&& compressed_data, uint8_t language); + std::shared_ptr trial() const; const std::string& compressed(bool is_trial) const; private: + mutable std::shared_ptr trial_map; mutable std::string compressed_data; mutable std::string compressed_trial_data; }; - const std::string& get_compressed_list(size_t num_players) const; - std::shared_ptr definition_for_number(uint32_t id) const; - std::shared_ptr definition_for_name(const std::string& name) const; + class Map { + public: + uint32_t map_number; + std::shared_ptr initial_version; + + explicit Map(std::shared_ptr initial_version); + + void add_version(std::shared_ptr vm); + bool has_version(uint8_t language) const; + std::shared_ptr version(uint8_t language) const; + inline const std::vector>& all_versions() const { + return this->versions; + } + + private: + std::vector> versions; + }; + + const std::string& get_compressed_list(size_t num_players, uint8_t language) const; + std::shared_ptr for_number(uint32_t id) const; + std::shared_ptr for_name(const std::string& name) const; std::set all_numbers() const; private: // The compressed map lists are generated on demand from the maps map below - mutable std::array compressed_map_lists; - std::map> maps; - std::unordered_map> maps_by_name; + mutable std::vector> compressed_map_lists; + std::map> maps; + std::unordered_map> maps_by_name; }; class COMDeckIndex { diff --git a/src/Episode3/Server.cc b/src/Episode3/Server.cc index 3d761e41..e12d3553 100644 --- a/src/Episode3/Server.cc +++ b/src/Episode3/Server.cc @@ -236,24 +236,26 @@ void Server::send_6xB4x46() const { this->options.random_crypt->seed(), this->options.random_crypt->absolute_offset()); if (this->last_chosen_map) { - date_str2 += string_printf(" Map:%08" PRIX32, this->last_chosen_map->map.map_number.load()); + date_str2 += string_printf(" Map:%08" PRIX32, this->last_chosen_map->map_number); } cmd46.date_str2 = date_str2; this->send(cmd46); } string Server::prepare_6xB6x41_map_definition( - shared_ptr map, bool is_trial) { - const auto& compressed = map->compressed(is_trial); + shared_ptr map, uint8_t language, bool is_trial) { + auto vm = map->version(language); + + const auto& compressed = vm->compressed(is_trial); StringWriter w; uint32_t subcommand_size = (compressed.size() + sizeof(G_MapData_GC_Ep3_6xB6x41) + 3) & (~3); - w.put({{{{0xB6, 0, 0}, subcommand_size}, 0x41, {}}, map->map.map_number.load(), compressed.size(), 0}); + w.put({{{{0xB6, 0, 0}, subcommand_size}, 0x41, {}}, vm->map->map_number.load(), compressed.size(), 0}); w.write(compressed); return std::move(w.str()); } -void Server::send_commands_for_joining_spectator(Channel& c, bool is_trial) const { +void Server::send_commands_for_joining_spectator(Channel& c, uint8_t language, bool is_trial) const { bool should_send_state = true; if (this->setup_phase == SetupPhase::REGISTRATION) { // If registration is still in progress, we only need to send the map data @@ -265,7 +267,8 @@ void Server::send_commands_for_joining_spectator(Channel& c, bool is_trial) cons } if (this->last_chosen_map) { - string data = this->prepare_6xB6x41_map_definition(this->last_chosen_map, is_trial); + string data = this->prepare_6xB6x41_map_definition(this->last_chosen_map, language, is_trial); + this->log().info("Sending %c version of map %08" PRIX32, char_for_language_code(language), this->last_chosen_map->map_number); c.send(0x6C, 0x00, data); } @@ -1631,7 +1634,7 @@ const unordered_map Server::subcommand_handlers({ {0x49, &Server::handle_CAx49_card_counts}, }); -void Server::on_server_data_input(const string& data) { +void Server::on_server_data_input(shared_ptr sender_c, const string& data) { auto header = check_size_t(data, 0xFFFF); if (header.size * 4 < data.size()) { throw runtime_error("command is incomplete"); @@ -1650,10 +1653,10 @@ void Server::on_server_data_input(const string& data) { string unmasked_data = data; set_mask_for_ep3_game_command(unmasked_data.data(), unmasked_data.size(), 0); - (this->*handler)(unmasked_data); + (this->*handler)(sender_c, unmasked_data); } -void Server::handle_CAx0B_mulligan_hand(const string& data) { +void Server::handle_CAx0B_mulligan_hand(shared_ptr, const string& data) { const auto& in_cmd = check_size_t(data); this->send_debug_command_received_message( in_cmd.client_id, in_cmd.header.subsubcommand, "REDRAW"); @@ -1684,7 +1687,7 @@ void Server::handle_CAx0B_mulligan_hand(const string& data) { this->send_debug_message_if_error_code_nonzero(in_cmd.client_id, out_cmd.error_code); } -void Server::handle_CAx0C_end_mulligan_phase(const string& data) { +void Server::handle_CAx0C_end_mulligan_phase(shared_ptr, const string& data) { const auto& in_cmd = check_size_t(data); this->send_debug_command_received_message( in_cmd.client_id, in_cmd.header.subsubcommand, "SETUP ADV 2"); @@ -1739,7 +1742,7 @@ void Server::handle_CAx0C_end_mulligan_phase(const string& data) { this->send_debug_message_if_error_code_nonzero(in_cmd.client_id, out_cmd_fin.error_code); } -void Server::handle_CAx0D_end_non_action_phase(const string& data) { +void Server::handle_CAx0D_end_non_action_phase(shared_ptr, const string& data) { const auto& in_cmd = check_size_t(data); this->send_debug_command_received_message( in_cmd.client_id, in_cmd.header.subsubcommand, "END PHASE"); @@ -1760,7 +1763,7 @@ void Server::handle_CAx0D_end_non_action_phase(const string& data) { this->send(out_cmd_fin); } -void Server::handle_CAx0E_discard_card_from_hand(const string& data) { +void Server::handle_CAx0E_discard_card_from_hand(shared_ptr, const string& data) { const auto& in_cmd = check_size_t(data); this->send_debug_command_received_message( in_cmd.client_id, in_cmd.header.subsubcommand, "DISCARD"); @@ -1799,7 +1802,7 @@ void Server::handle_CAx0E_discard_card_from_hand(const string& data) { this->send_debug_message_if_error_code_nonzero(in_cmd.client_id, out_cmd.error_code); } -void Server::handle_CAx0F_set_card_from_hand(const string& data) { +void Server::handle_CAx0F_set_card_from_hand(shared_ptr, const string& data) { const auto& in_cmd = check_size_t(data); this->send_debug_command_received_message( in_cmd.client_id, in_cmd.header.subsubcommand, "SET FC"); @@ -1841,7 +1844,7 @@ void Server::handle_CAx0F_set_card_from_hand(const string& data) { this->send_debug_message_if_error_code_nonzero(in_cmd.client_id, out_cmd.error_code); } -void Server::handle_CAx10_move_fc_to_location(const string& data) { +void Server::handle_CAx10_move_fc_to_location(shared_ptr, const string& data) { const auto& in_cmd = check_size_t(data); this->send_debug_command_received_message( in_cmd.client_id, in_cmd.header.subsubcommand, "MOVE"); @@ -1879,7 +1882,7 @@ void Server::handle_CAx10_move_fc_to_location(const string& data) { this->send_debug_message_if_error_code_nonzero(in_cmd.client_id, out_cmd.error_code); } -void Server::handle_CAx11_enqueue_attack_or_defense(const string& data) { +void Server::handle_CAx11_enqueue_attack_or_defense(shared_ptr, const string& data) { const auto& in_cmd = check_size_t(data); this->send_debug_command_received_message( in_cmd.client_id, in_cmd.header.subsubcommand, "ENQUEUE ACT"); @@ -1915,7 +1918,7 @@ void Server::handle_CAx11_enqueue_attack_or_defense(const string& data) { this->send_debug_message_if_error_code_nonzero(in_cmd.client_id, out_cmd.error_code); } -void Server::handle_CAx12_end_attack_list(const string& data) { +void Server::handle_CAx12_end_attack_list(shared_ptr, const string& data) { const auto& in_cmd = check_size_t(data); this->send_debug_command_received_message( in_cmd.client_id, in_cmd.header.subsubcommand, "END ATK LIST"); @@ -1938,7 +1941,7 @@ void Server::handle_CAx12_end_attack_list(const string& data) { this->send_debug_message_if_error_code_nonzero(in_cmd.client_id, error_code); } -void Server::handle_CAx13_update_map_during_setup(const string& data) { +void Server::handle_CAx13_update_map_during_setup(shared_ptr, const string& data) { const auto& in_cmd = check_size_t(data); this->send_debug_command_received_message( in_cmd.header.subsubcommand, "UPDATE MAP"); @@ -1980,7 +1983,7 @@ void Server::handle_CAx13_update_map_during_setup(const string& data) { } } -void Server::handle_CAx14_update_deck_during_setup(const string& data) { +void Server::handle_CAx14_update_deck_during_setup(shared_ptr, const string& data) { const auto& in_cmd = check_size_t(data); this->send_debug_command_received_message( in_cmd.client_id, in_cmd.header.subsubcommand, "UPDATE DECK"); @@ -2027,7 +2030,7 @@ void Server::handle_CAx14_update_deck_during_setup(const string& data) { } } -void Server::handle_CAx15_unused_hard_reset_server_state(const string& data) { +void Server::handle_CAx15_unused_hard_reset_server_state(shared_ptr, const string& data) { const auto& in_cmd = check_size_t(data); this->send_debug_command_received_message( in_cmd.header.subsubcommand, "HARD RESET"); @@ -2045,7 +2048,7 @@ void Server::handle_CAx15_unused_hard_reset_server_state(const string& data) { throw runtime_error("hard reset command received"); } -void Server::handle_CAx1B_update_player_name(const string& data) { +void Server::handle_CAx1B_update_player_name(shared_ptr, const string& data) { const auto& in_cmd = check_size_t(data); this->send_debug_command_received_message( in_cmd.entry.client_id, in_cmd.header.subsubcommand, "UPDATE NAME"); @@ -2077,7 +2080,7 @@ void Server::handle_CAx1B_update_player_name(const string& data) { this->send(out_cmd); } -void Server::handle_CAx1D_start_battle(const string& data) { +void Server::handle_CAx1D_start_battle(shared_ptr, const string& data) { const auto& in_cmd = check_size_t(data); this->send_debug_command_received_message( in_cmd.header.subsubcommand, "START BATTLE"); @@ -2116,7 +2119,7 @@ void Server::handle_CAx1D_start_battle(const string& data) { } } -void Server::handle_CAx21_end_battle(const string& data) { +void Server::handle_CAx21_end_battle(shared_ptr, const string& data) { const auto& in_cmd = check_size_t(data); this->send_debug_command_received_message( in_cmd.header.subsubcommand, "END BATTLE"); @@ -2131,7 +2134,7 @@ void Server::handle_CAx21_end_battle(const string& data) { } } -void Server::handle_CAx28_end_defense_list(const string& data) { +void Server::handle_CAx28_end_defense_list(shared_ptr, const string& data) { const auto& in_cmd = check_size_t(data); this->send_debug_command_received_message( in_cmd.client_id, in_cmd.header.subsubcommand, "END DEF LIST"); @@ -2184,13 +2187,13 @@ void Server::handle_CAx28_end_defense_list(const string& data) { this->send(out_cmd_fin); } -void Server::handle_CAx2B_legacy_set_card(const string& data) { +void Server::handle_CAx2B_legacy_set_card(shared_ptr, const string& data) { const auto& in_cmd = check_size_t(data); this->send_debug_command_received_message(in_cmd.header.subsubcommand, "EXEC LEGACY"); // Sega's original implementation does nothing here, so we do nothing as well. } -void Server::handle_CAx34_subtract_ally_atk_points(const string& data) { +void Server::handle_CAx34_subtract_ally_atk_points(shared_ptr, const string& data) { const auto& in_cmd = check_size_t(data); uint8_t card_ref_client_id = client_id_for_card_ref(in_cmd.card_ref); @@ -2267,7 +2270,7 @@ void Server::handle_CAx34_subtract_ally_atk_points(const string& data) { } } -void Server::handle_CAx37_client_ready_to_advance_from_starter_roll_phase(const string& data) { +void Server::handle_CAx37_client_ready_to_advance_from_starter_roll_phase(shared_ptr, const string& data) { const auto& in_cmd = check_size_t(data); this->send_debug_command_received_message( in_cmd.client_id, in_cmd.header.subsubcommand, "SETUP ADV 1"); @@ -2297,14 +2300,14 @@ void Server::handle_CAx37_client_ready_to_advance_from_starter_roll_phase(const } } -void Server::handle_CAx3A_time_limit_expired(const string& data) { +void Server::handle_CAx3A_time_limit_expired(shared_ptr, const string& data) { const auto& in_cmd = check_size_t(data); this->send_debug_command_received_message(in_cmd.header.subsubcommand, "TIME EXPIRED"); // We don't need to do anything here because the overall time limit is tracked // server-side instead. } -void Server::handle_CAx40_map_list_request(const string& data) { +void Server::handle_CAx40_map_list_request(shared_ptr sender_c, const string& data) { const auto& in_cmd = check_size_t(data); this->send_debug_command_received_message( in_cmd.header.subsubcommand, "MAP LIST"); @@ -2314,7 +2317,8 @@ void Server::handle_CAx40_map_list_request(const string& data) { throw runtime_error("lobby is deleted"); } - const auto& list_data = this->options.map_index->get_compressed_list(l->count_clients()); + const auto& list_data = this->options.map_index->get_compressed_list( + l->count_clients(), sender_c->language()); StringWriter w; uint32_t subcommand_size = (list_data.size() + sizeof(G_MapList_GC_Ep3_6xB6x40) + 3) & (~3); @@ -2332,30 +2336,61 @@ void Server::handle_CAx40_map_list_request(const string& data) { } } -void Server::handle_CAx41_map_request(const string& data) { - const auto& cmd = check_size_t(data); - this->send_debug_command_received_message( - cmd.header.subsubcommand, "MAP DATA"); - +void Server::send_6xB6x41_to_all_clients() const { auto l = this->lobby.lock(); if (!l) { throw runtime_error("lobby is deleted"); } - this->last_chosen_map = this->options.map_index->definition_for_number(cmd.map_number); - auto out_cmd = this->prepare_6xB6x41_map_definition(this->last_chosen_map, l->flags & Lobby::Flag::IS_EP3_TRIAL); - send_command(l, 0x6C, 0x00, out_cmd); + vector map_commands_by_language; + auto send_to_client = [&](shared_ptr c) -> void { + if (!c) { + return; + } + uint8_t language = c->language(); + if (map_commands_by_language.size() <= language) { + map_commands_by_language.resize(language + 1); + } + if (map_commands_by_language[language].empty()) { + map_commands_by_language[language] = this->prepare_6xB6x41_map_definition( + this->last_chosen_map, language, l->flags & Lobby::Flag::IS_EP3_TRIAL); + } + this->log().info("Sending %c version of map %08" PRIX32, char_for_language_code(language), this->last_chosen_map->map_number); + send_command(c, 0x6C, 0x00, map_commands_by_language[language]); + }; + for (const auto& c : l->clients) { + send_to_client(c); + } for (auto watcher_l : l->watcher_lobbies) { - send_command_if_not_loading(watcher_l, 0x6C, 0x00, out_cmd); + for (const auto& c : watcher_l->clients) { + send_to_client(c); + } } if (l->battle_record && l->battle_record->writable()) { - l->battle_record->add_command( - BattleRecord::Event::Type::BATTLE_COMMAND, std::move(out_cmd)); + // TODO: It's not great that we just pick the first one; ideally we'd put + // all of them in the recording and send the appropriate one to the client + // in the playback lobby + for (string& data : map_commands_by_language) { + if (!data.empty()) { + l->battle_record->add_command( + BattleRecord::Event::Type::BATTLE_COMMAND, std::move(data)); + break; + } + } } } -void Server::handle_CAx48_end_turn(const string& data) { +void Server::handle_CAx41_map_request(shared_ptr, const string& data) { + const auto& cmd = check_size_t(data); + this->send_debug_command_received_message( + cmd.header.subsubcommand, "MAP DATA"); + + this->last_chosen_map = this->options.map_index->for_number(cmd.map_number); + this->send_6xB6x41_to_all_clients(); +} + +void Server::handle_CAx48_end_turn(shared_ptr, const string& data) { const auto& in_cmd = check_size_t(data); this->send_debug_command_received_message( in_cmd.client_id, in_cmd.header.subsubcommand, "END TURN"); @@ -2373,7 +2408,7 @@ void Server::handle_CAx48_end_turn(const string& data) { this->send(out_cmd); } -void Server::handle_CAx49_card_counts(const string& data) { +void Server::handle_CAx49_card_counts(shared_ptr, const string& data) { const auto& in_cmd = check_size_t(data); this->send_debug_command_received_message( in_cmd.header.sender_client_id, in_cmd.header.subsubcommand, "CARD COUNTS"); diff --git a/src/Episode3/Server.hh b/src/Episode3/Server.hh index 865669c1..5b935f41 100644 --- a/src/Episode3/Server.hh +++ b/src/Episode3/Server.hh @@ -111,7 +111,7 @@ public: this->send(&cmd, cmd.header.size * 4); } void send(const void* data, size_t size) const; - void send_commands_for_joining_spectator(Channel& ch, bool is_trial) const; + void send_commands_for_joining_spectator(Channel& ch, uint8_t language, bool is_trial) const; void force_battle_result(uint8_t surrendered_client_id, bool set_winner); void force_destroy_field_character(uint8_t client_id, size_t set_index); @@ -181,30 +181,30 @@ public: void update_battle_state_flags_and_send_6xB4x03_if_needed( bool always_send = false); bool update_registration_phase(); - void on_server_data_input(const std::string& data); - void handle_CAx0B_mulligan_hand(const std::string& data); - void handle_CAx0C_end_mulligan_phase(const std::string& data); - void handle_CAx0D_end_non_action_phase(const std::string& data); - void handle_CAx0E_discard_card_from_hand(const std::string& data); - void handle_CAx0F_set_card_from_hand(const std::string& data); - void handle_CAx10_move_fc_to_location(const std::string& data); - void handle_CAx11_enqueue_attack_or_defense(const std::string& data); - void handle_CAx12_end_attack_list(const std::string& data); - void handle_CAx13_update_map_during_setup(const std::string& data); - void handle_CAx14_update_deck_during_setup(const std::string& data); - void handle_CAx15_unused_hard_reset_server_state(const std::string& data); - void handle_CAx1B_update_player_name(const std::string& data); - void handle_CAx1D_start_battle(const std::string& data); - void handle_CAx21_end_battle(const std::string& data); - void handle_CAx28_end_defense_list(const std::string& data); - void handle_CAx2B_legacy_set_card(const std::string&); - void handle_CAx34_subtract_ally_atk_points(const std::string& data); - void handle_CAx37_client_ready_to_advance_from_starter_roll_phase(const std::string& data); - void handle_CAx3A_time_limit_expired(const std::string& data); - void handle_CAx40_map_list_request(const std::string& data); - void handle_CAx41_map_request(const std::string& data); - void handle_CAx48_end_turn(const std::string& data); - void handle_CAx49_card_counts(const std::string& data); + void on_server_data_input(std::shared_ptr sender_c, const std::string& data); + void handle_CAx0B_mulligan_hand(std::shared_ptr sender_c, const std::string& data); + void handle_CAx0C_end_mulligan_phase(std::shared_ptr sender_c, const std::string& data); + void handle_CAx0D_end_non_action_phase(std::shared_ptr sender_c, const std::string& data); + void handle_CAx0E_discard_card_from_hand(std::shared_ptr sender_c, const std::string& data); + void handle_CAx0F_set_card_from_hand(std::shared_ptr sender_c, const std::string& data); + void handle_CAx10_move_fc_to_location(std::shared_ptr sender_c, const std::string& data); + void handle_CAx11_enqueue_attack_or_defense(std::shared_ptr sender_c, const std::string& data); + void handle_CAx12_end_attack_list(std::shared_ptr sender_c, const std::string& data); + void handle_CAx13_update_map_during_setup(std::shared_ptr sender_c, const std::string& data); + void handle_CAx14_update_deck_during_setup(std::shared_ptr sender_c, const std::string& data); + void handle_CAx15_unused_hard_reset_server_state(std::shared_ptr sender_c, const std::string& data); + void handle_CAx1B_update_player_name(std::shared_ptr sender_c, const std::string& data); + void handle_CAx1D_start_battle(std::shared_ptr sender_c, const std::string& data); + void handle_CAx21_end_battle(std::shared_ptr sender_c, const std::string& data); + void handle_CAx28_end_defense_list(std::shared_ptr sender_c, const std::string& data); + void handle_CAx2B_legacy_set_card(std::shared_ptr sender_c, const std::string&); + void handle_CAx34_subtract_ally_atk_points(std::shared_ptr sender_c, const std::string& data); + void handle_CAx37_client_ready_to_advance_from_starter_roll_phase(std::shared_ptr sender_c, const std::string& data); + void handle_CAx3A_time_limit_expired(std::shared_ptr sender_c, const std::string& data); + void handle_CAx40_map_list_request(std::shared_ptr sender_c, const std::string& data); + void handle_CAx41_map_request(std::shared_ptr sender_c, const std::string& data); + void handle_CAx48_end_turn(std::shared_ptr sender_c, const std::string& data); + void handle_CAx49_card_counts(std::shared_ptr sender_c, const std::string& data); void compute_losing_team_id_and_add_winner_flags(uint32_t flags); uint32_t get_team_exp(uint8_t team_id) const; uint32_t send_6xB4x06_if_card_ref_invalid( @@ -226,21 +226,22 @@ public: G_UpdateDecks_GC_Ep3_6xB4x07 prepare_6xB4x07_decks_update() const; G_SetPlayerNames_GC_Ep3_6xB4x1C prepare_6xB4x1C_names_update() const; static std::string prepare_6xB6x41_map_definition( - std::shared_ptr map, bool is_trial); + std::shared_ptr map, uint8_t language, bool is_trial); + void send_6xB6x41_to_all_clients() const; G_SetTrapTileLocations_GC_Ep3_6xB4x50 prepare_6xB4x50_trap_tile_locations() const; std::vector> const_cast_set_cards_v( const std::vector>& cards); private: - typedef void (Server::*handler_t)(const std::string&); + typedef void (Server::*handler_t)(std::shared_ptr, const std::string&); static const std::unordered_map subcommand_handlers; public: // These fields are not part of the original implementation std::weak_ptr lobby; Options options; - std::shared_ptr last_chosen_map; + std::shared_ptr last_chosen_map; bool tournament_match_result_sent; uint8_t override_environment_number; mutable std::deque logger_stack; diff --git a/src/Episode3/Tournament.cc b/src/Episode3/Tournament.cc index d9eda795..5c49b2e5 100644 --- a/src/Episode3/Tournament.cc +++ b/src/Episode3/Tournament.cc @@ -314,7 +314,7 @@ Tournament::Tournament( shared_ptr map_index, shared_ptr com_deck_index, const string& name, - shared_ptr map, + shared_ptr map, const Rules& rules, size_t num_teams, uint8_t flags) @@ -355,7 +355,7 @@ void Tournament::init() { bool is_registration_complete; if (!this->source_json.is_null()) { this->name = this->source_json.get_string("name"); - this->map = this->map_index->definition_for_number(this->source_json.get_int("map_number")); + this->map = this->map_index->for_number(this->source_json.get_int("map_number")); this->rules = Rules(this->source_json.at("rules")); this->flags = this->source_json.get_int("flags", 0x02); if (this->source_json.get_bool("is_2v2", false)) { @@ -531,7 +531,7 @@ JSON Tournament::json() const { } return JSON::dict({ {"name", this->name}, - {"map_number", this->map->map.map_number.load()}, + {"map_number", this->map->map_number}, {"rules", this->rules.json()}, {"flags", this->flags}, {"is_registration_complete", (this->current_state != State::REGISTRATION)}, @@ -741,8 +741,13 @@ void Tournament::print_bracket(FILE* stream) const { } }; fprintf(stream, "Tournament \"%s\"\n", this->name.c_str()); - string map_name = this->map->map.name; - fprintf(stream, " Map: %08" PRIX32 " (%s)\n", this->map->map.map_number.load(), map_name.c_str()); + auto en_vm = this->map->version(1); + if (en_vm) { + string map_name = en_vm->map->name; + fprintf(stream, " Map: %08" PRIX32 " (%s)\n", this->map->map_number, map_name.c_str()); + } else { + fprintf(stream, " Map: %08" PRIX32 "\n", this->map->map_number); + } string rules_str = this->rules.str(); fprintf(stream, " Rules: %s\n", rules_str.c_str()); fprintf(stream, " Structure: %s, %zu entries\n", (this->flags & Flag::IS_2V2) ? "2v2" : "1v1", this->num_teams); @@ -850,7 +855,7 @@ void TournamentIndex::save() const { shared_ptr TournamentIndex::create_tournament( const string& name, - shared_ptr map, + shared_ptr map, const Rules& rules, size_t num_teams, uint8_t flags) { diff --git a/src/Episode3/Tournament.hh b/src/Episode3/Tournament.hh index e168b812..f463ed23 100644 --- a/src/Episode3/Tournament.hh +++ b/src/Episode3/Tournament.hh @@ -108,7 +108,7 @@ public: std::shared_ptr map_index, std::shared_ptr com_deck_index, const std::string& name, - std::shared_ptr map, + std::shared_ptr map, const Rules& rules, size_t num_teams, uint8_t flags); @@ -124,7 +124,7 @@ public: inline const std::string& get_name() const { return this->name; } - inline std::shared_ptr get_map() const { + inline std::shared_ptr get_map() const { return this->map; } inline const Rules& get_rules() const { @@ -171,7 +171,7 @@ private: std::shared_ptr com_deck_index; JSON source_json; std::string name; - std::shared_ptr map; + std::shared_ptr map; Rules rules; size_t num_teams; uint8_t flags; @@ -225,7 +225,7 @@ public: std::shared_ptr create_tournament( const std::string& name, - std::shared_ptr map, + std::shared_ptr map, const Rules& rules, size_t num_teams, uint8_t flags); diff --git a/src/FileContentsCache.hh b/src/FileContentsCache.hh index 74d76256..eb2b5bac 100644 --- a/src/FileContentsCache.hh +++ b/src/FileContentsCache.hh @@ -7,13 +7,11 @@ #include -using namespace std; - class FileContentsCache { public: struct File { std::string name; - shared_ptr data; + std::shared_ptr data; uint64_t load_time; File() = delete; @@ -37,10 +35,8 @@ public: return this->name_to_file.erase(key); } - std::shared_ptr replace( - const std::string& name, std::string&& data, uint64_t t = 0); - std::shared_ptr replace( - const std::string& name, const void* data, size_t size, uint64_t t = 0); + std::shared_ptr replace(const std::string& name, std::string&& data, uint64_t t = 0); + std::shared_ptr replace(const std::string& name, const void* data, size_t size, uint64_t t = 0); struct GetResult { std::shared_ptr file; @@ -52,10 +48,8 @@ public: std::shared_ptr get_or_throw(const std::string& name); std::shared_ptr get_or_throw(const char* name); - GetResult get( - const std::string& name, std::function generate); - GetResult get( - const char* name, std::function generate); + GetResult get(const std::string& name, std::function generate); + GetResult get(const char* name, std::function generate); template struct GetObjResult { @@ -68,7 +62,7 @@ public: GetObjResult get_obj_or_load(NameT name) { auto res = this->get_or_load(name); if (res.file->data->size() != sizeof(T)) { - throw runtime_error("cached string size is incorrect"); + throw std::runtime_error("cached string size is incorrect"); } return {*reinterpret_cast(res.file->data->data()), res.file, res.generate_called}; } @@ -76,7 +70,7 @@ public: GetObjResult get_obj_or_throw(NameT name) { auto res = this->get_or_throw(name); if (res.file->data->size() != sizeof(T)) { - throw runtime_error("cached string size is incorrect"); + throw std::runtime_error("cached string size is incorrect"); } return {*reinterpret_cast(res.file->data->data()), res.file, res.generate_called}; } @@ -86,12 +80,12 @@ public: try { auto& f = this->name_to_file.at(name); if (f->data->size() != sizeof(T)) { - throw runtime_error("cached string size is incorrect"); + throw std::runtime_error("cached string size is incorrect"); } if (this->ttl_usecs && (t - f->load_time < this->ttl_usecs)) { return {*reinterpret_cast(f->data->data()), f, false}; } - } catch (const out_of_range& e) { + } catch (const std::out_of_range& e) { } T value = generate(name); auto ret = this->replace_obj(name, value); diff --git a/src/GVMEncoder.hh b/src/GVMEncoder.hh index 4159f2cf..207a9e8e 100644 --- a/src/GVMEncoder.hh +++ b/src/GVMEncoder.hh @@ -6,8 +6,6 @@ #include "Text.hh" -using namespace std; - enum class GVRDataFormat : uint8_t { INTENSITY_4 = 0x00, INTENSITY_8 = 0x01, @@ -21,4 +19,4 @@ enum class GVRDataFormat : uint8_t { DXT1 = 0x0E, }; -string encode_gvm(const Image& img, GVRDataFormat data_format); +std::string encode_gvm(const Image& img, GVRDataFormat data_format); diff --git a/src/Lobby.cc b/src/Lobby.cc index c14ef073..574be2af 100644 --- a/src/Lobby.cc +++ b/src/Lobby.cc @@ -43,6 +43,27 @@ shared_ptr Lobby::require_server_state() const { return s; } +void Lobby::create_ep3_server() { + auto s = this->require_server_state(); + if (!this->ep3_server) { + this->log.info("Creating Episode 3 server state"); + } else { + this->log.info("Recreating Episode 3 server state"); + } + auto tourn = this->tournament_match ? this->tournament_match->tournament.lock() : nullptr; + bool is_trial = (this->flags & Lobby::Flag::IS_EP3_TRIAL); + Episode3::Server::Options options = { + .card_index = is_trial ? s->ep3_card_index_trial : s->ep3_card_index, + .map_index = s->ep3_map_index, + .behavior_flags = s->ep3_behavior_flags, + .random_crypt = this->random_crypt, + .tournament = tourn, + .trap_card_ids = s->ep3_trap_card_ids, + }; + this->ep3_server = make_shared(this->shared_from_this(), std::move(options)); + this->ep3_server->init(); +} + void Lobby::reassign_leader_on_client_departure(size_t leaving_client_index) { for (size_t x = 0; x < this->max_clients; x++) { if (x == leaving_client_index) { diff --git a/src/Lobby.hh b/src/Lobby.hh index c3d12605..43cce903 100644 --- a/src/Lobby.hh +++ b/src/Lobby.hh @@ -100,7 +100,7 @@ struct Lobby : public std::enable_shared_from_this { // absent. std::shared_ptr ep3_server; // Only used in primary games std::weak_ptr watched_lobby; // Only used in watcher games - std::unordered_set> watcher_lobbies; // Only used in primary games + std::unordered_set> watcher_lobbies; // Only used in primary games std::shared_ptr battle_record; // Not used in watcher games std::shared_ptr battle_player; // Only used in replay games std::shared_ptr tournament_match; @@ -124,6 +124,7 @@ struct Lobby : public std::enable_shared_from_this { Lobby& operator=(Lobby&&) = delete; std::shared_ptr require_server_state() const; + void create_ep3_server(); inline bool is_game() const { return this->flags & Flag::GAME; diff --git a/src/Main.cc b/src/Main.cc index e4d84d3e..33230921 100644 --- a/src/Main.cc +++ b/src/Main.cc @@ -1329,17 +1329,17 @@ int main(int argc, char** argv) { string output_filename_base = input_filename; if (quest_file_type == QuestFileFormat::BIN_DAT_GCI) { int64_t dec_seed = seed.empty() ? -1 : stoul(seed, nullptr, 16); - auto decoded = decode_gci_file(input_filename, num_threads, dec_seed, skip_checksum); + auto decoded = decode_gci_data(read_input_data(), num_threads, dec_seed, skip_checksum); save_file(output_filename_base + ".dec", decoded); } else if (quest_file_type == QuestFileFormat::BIN_DAT_VMS) { int64_t dec_seed = seed.empty() ? -1 : stoul(seed, nullptr, 16); - auto decoded = decode_vms_file(input_filename, num_threads, dec_seed, skip_checksum); + auto decoded = decode_vms_data(read_input_data(), num_threads, dec_seed, skip_checksum); save_file(output_filename_base + ".dec", decoded); } else if (quest_file_type == QuestFileFormat::BIN_DAT_DLQ) { - auto decoded = decode_dlq_file(input_filename); + auto decoded = decode_dlq_data(read_input_data()); save_file(output_filename_base + ".dec", decoded); } else if (quest_file_type == QuestFileFormat::QST) { - auto data = decode_qst_file(input_filename); + auto data = decode_qst_data(read_input_data()); save_file(output_filename_base + ".bin", data.first); save_file(output_filename_base + ".dat", data.second); } else { @@ -1353,7 +1353,13 @@ int main(int argc, char** argv) { throw invalid_argument("an input filename is required"); } - shared_ptr vq(new VersionedQuest(input_filename, cli_quest_version, nullptr)); + string bin_filename = input_filename; + string dat_filename = ends_with(bin_filename, ".bin") + ? (bin_filename.substr(0, bin_filename.size() - 3) + "dat") + : (bin_filename + ".dat"); + shared_ptr bin_data(new string(load_file(bin_filename))); + shared_ptr dat_data(new string(load_file(dat_filename))); + shared_ptr vq(new VersionedQuest(0, 0, cli_quest_version, 0, bin_data, dat_data)); if (download) { vq = vq->create_download_quest(); } @@ -1872,9 +1878,15 @@ int main(int argc, char** argv) { auto map_ids = map_index.all_numbers(); log_info("%zu maps", map_ids.size()); for (uint32_t map_id : map_ids) { - auto map = map_index.definition_for_number(map_id); - string s = map->map.str(&card_index); - fprintf(stdout, "%s\n", s.c_str()); + auto map = map_index.for_number(map_id); + const auto& vms = map->all_versions(); + for (size_t language = 0; language < vms.size(); language++) { + if (!vms[language]) { + continue; + } + string s = vms[language]->map->str(&card_index); + fprintf(stdout, "(%c) %s\n", char_for_language_code(language), s.c_str()); + } } break; } diff --git a/src/Map.cc b/src/Map.cc index 4fa63142..76dc9cf8 100644 --- a/src/Map.cc +++ b/src/Map.cc @@ -480,6 +480,13 @@ void Map::add_enemies_from_map_data( } } +struct DATSectionHeader { + le_uint32_t type; // 1 = objects, 2 = enemies. There are other types too + le_uint32_t section_size; // Includes this header + le_uint32_t area; + le_uint32_t data_size; +} __attribute__((packed)); + void Map::add_enemies_from_quest_data( Episode episode, uint8_t difficulty, @@ -488,7 +495,7 @@ void Map::add_enemies_from_quest_data( size_t size) { StringReader r(data, size); while (!r.eof()) { - const auto& header = r.get(); + const auto& header = r.get(); if (header.type == 0 && header.section_size == 0) { break; } diff --git a/src/PlayerSubordinates.cc b/src/PlayerSubordinates.cc index 404e9adb..28aeaec6 100644 --- a/src/PlayerSubordinates.cc +++ b/src/PlayerSubordinates.cc @@ -15,6 +15,8 @@ #include "Text.hh" #include "Version.hh" +using namespace std; + FileContentsCache player_files_cache(300 * 1000 * 1000); void PlayerDispDataDCPCV3::enforce_lobby_join_limits(GameVersion target_version) { diff --git a/src/ProxyCommands.hh b/src/ProxyCommands.hh index 37b6f858..090f07e4 100644 --- a/src/ProxyCommands.hh +++ b/src/ProxyCommands.hh @@ -8,7 +8,7 @@ #include "ServerState.hh" void on_proxy_command( - shared_ptr ses, + std::shared_ptr ses, bool from_server, uint16_t command, uint32_t flag, diff --git a/src/Quest.cc b/src/Quest.cc index 97cb2888..bd5a64a0 100644 --- a/src/Quest.cc +++ b/src/Quest.cc @@ -217,99 +217,23 @@ struct PSODownloadQuestHeader { } __attribute__((packed)); VersionedQuest::VersionedQuest( - const string& bin_filename, + uint32_t quest_number, + uint32_t category_id, QuestScriptVersion version, - shared_ptr category_index) - : quest_number(0xFFFFFFFF), - category_id(0xFFFFFFFF), + uint8_t language, + std::shared_ptr bin_contents, + std::shared_ptr dat_contents) + : quest_number(quest_number), + category_id(category_id), episode(Episode::NONE), joinable(false), version(version), - file_format(QuestFileFormat::BIN_DAT), - has_mnm_extension(false), - is_dlq_encoded(false) { + language(language), + is_dlq_encoded(false), + bin_contents(bin_contents), + dat_contents(dat_contents) { - if (ends_with(bin_filename, ".bin.gci") || ends_with(bin_filename, ".mnm.gci")) { - this->file_format = QuestFileFormat::BIN_DAT_GCI; - this->has_mnm_extension = ends_with(bin_filename, ".mnm.gci"); - this->file_basename = bin_filename.substr(0, bin_filename.size() - 8); - } else if (ends_with(bin_filename, ".bin.vms")) { - this->file_format = QuestFileFormat::BIN_DAT_VMS; - this->file_basename = bin_filename.substr(0, bin_filename.size() - 8); - } else if (ends_with(bin_filename, ".bin.dlq") || ends_with(bin_filename, ".mnm.dlq")) { - this->file_format = QuestFileFormat::BIN_DAT_DLQ; - this->has_mnm_extension = ends_with(bin_filename, ".mnm.dlq"); - this->file_basename = bin_filename.substr(0, bin_filename.size() - 8); - } else if (ends_with(bin_filename, ".qst")) { - this->file_format = QuestFileFormat::QST; - this->file_basename = bin_filename.substr(0, bin_filename.size() - 4); - } else if (ends_with(bin_filename, ".bin") || ends_with(bin_filename, ".mnm")) { - this->file_format = QuestFileFormat::BIN_DAT; - this->has_mnm_extension = ends_with(bin_filename, ".mnm"); - this->file_basename = bin_filename.substr(0, bin_filename.size() - 4); - } else if (ends_with(bin_filename, ".bind") || ends_with(bin_filename, ".mnmd")) { - this->file_format = QuestFileFormat::BIN_DAT_UNCOMPRESSED; - this->has_mnm_extension = ends_with(bin_filename, ".mnmd"); - this->file_basename = bin_filename.substr(0, bin_filename.size() - 5); - } else { - throw runtime_error("quest does not have a valid .bin or .mnm file"); - } - - string basename; - { - size_t slash_pos = this->file_basename.rfind('/'); - if (slash_pos != string::npos) { - basename = this->file_basename.substr(slash_pos + 1); - } else { - basename = this->file_basename; - } - } - - if (basename.empty()) { - throw invalid_argument("empty filename"); - } - - if ((version == QuestScriptVersion::UNKNOWN) || category_index) { - vector tokens = split(basename, '-'); - - string category_token; - if (tokens.size() == 3) { - category_token = std::move(tokens[1]); - tokens.erase(tokens.begin() + 1); - } else if (tokens.size() != 2) { - throw invalid_argument("incorrect filename format"); - } - - if (category_index) { - auto& category = category_index->find(basename[0], category_token); - this->category_id = category.category_id; - } else { - this->category_id = 0; - } - - // Parse the number out of the first token - this->quest_number = strtoull(tokens[0].c_str() + 1, nullptr, 10); - - // Get the version from the second (or previously third) token - static const unordered_map name_to_version({ - {"dn", QuestScriptVersion::DC_NTE}, - {"d1", QuestScriptVersion::DC_V1}, - {"dc", QuestScriptVersion::DC_V2}, - {"pc", QuestScriptVersion::PC_V2}, - {"gcn", QuestScriptVersion::GC_NTE}, - {"gc", QuestScriptVersion::GC_V3}, - {"gc3", QuestScriptVersion::GC_EP3}, - {"xb", QuestScriptVersion::XB_V3}, - {"bb", QuestScriptVersion::BB_V4}, - }); - this->version = name_to_version.at(tokens[1]); - } - - // The rest of the information needs to be fetched from the .bin file's - // contents - - auto bin_compressed = this->bin_contents(); - auto bin_decompressed = prs_decompress(*bin_compressed); + auto bin_decompressed = prs_decompress(*this->bin_contents); switch (this->version) { case QuestScriptVersion::DC_NTE: @@ -418,10 +342,6 @@ VersionedQuest::VersionedQuest( default: throw logic_error("invalid quest game version"); } - - if (this->has_mnm_extension && this->episode != Episode::EP3) { - throw runtime_error("non-Episode 3 quest has .mnm extension"); - } } string VersionedQuest::bin_filename() const { @@ -440,80 +360,10 @@ string VersionedQuest::dat_filename() const { } } -shared_ptr VersionedQuest::bin_contents() const { - if (!this->bin_contents_ptr) { - switch (this->file_format) { - case QuestFileFormat::BIN_DAT: - this->bin_contents_ptr.reset(new string(load_file( - this->file_basename + (this->has_mnm_extension ? ".mnm" : ".bin")))); - break; - case QuestFileFormat::BIN_DAT_UNCOMPRESSED: - this->bin_contents_ptr.reset(new string(prs_compress(load_file( - this->file_basename + (this->has_mnm_extension ? ".mnmd" : ".bind"))))); - break; - case QuestFileFormat::BIN_DAT_GCI: - this->bin_contents_ptr.reset(new string(decode_gci_file( - this->file_basename + (this->has_mnm_extension ? ".mnm.gci" : ".bin.gci")))); - break; - case QuestFileFormat::BIN_DAT_VMS: - this->bin_contents_ptr.reset(new string(decode_vms_file( - this->file_basename + (this->has_mnm_extension ? ".mnm.vms" : ".bin.vms")))); - break; - case QuestFileFormat::BIN_DAT_DLQ: - this->bin_contents_ptr.reset(new string(decode_dlq_file( - this->file_basename + (this->has_mnm_extension ? ".mnm.dlq" : ".bin.dlq")))); - break; - case QuestFileFormat::QST: { - auto result = decode_qst_file(this->file_basename + ".qst"); - this->bin_contents_ptr.reset(new string(std::move(result.first))); - this->dat_contents_ptr.reset(new string(std::move(result.second))); - break; - } - default: - throw logic_error("invalid quest file format"); - } - } - return this->bin_contents_ptr; -} - -shared_ptr VersionedQuest::dat_contents() const { - if (this->episode == Episode::EP3) { - throw logic_error("Episode 3 quests do not have .dat files"); - } - if (!this->dat_contents_ptr) { - switch (this->file_format) { - case QuestFileFormat::BIN_DAT: - this->dat_contents_ptr.reset(new string(load_file(this->file_basename + ".dat"))); - break; - case QuestFileFormat::BIN_DAT_UNCOMPRESSED: - this->dat_contents_ptr.reset(new string(prs_compress(load_file(this->file_basename + ".datd")))); - break; - case QuestFileFormat::BIN_DAT_GCI: - this->dat_contents_ptr.reset(new string(decode_gci_file(this->file_basename + ".dat.gci"))); - break; - case QuestFileFormat::BIN_DAT_VMS: - this->dat_contents_ptr.reset(new string(decode_vms_file(this->file_basename + ".dat.vms"))); - break; - case QuestFileFormat::BIN_DAT_DLQ: - this->dat_contents_ptr.reset(new string(decode_dlq_file(this->file_basename + ".dat.dlq"))); - break; - case QuestFileFormat::QST: { - auto result = decode_qst_file(this->file_basename + ".qst"); - this->bin_contents_ptr.reset(new string(std::move(result.first))); - this->dat_contents_ptr.reset(new string(std::move(result.second))); - break; - } - default: - throw logic_error("invalid quest file format"); - } - } - return this->dat_contents_ptr; -} - string VersionedQuest::encode_qst() const { return encode_qst_file( - *this->bin_contents(), - *this->dat_contents(), + *this->bin_contents, + *this->dat_contents, this->name, this->quest_number, this->version, @@ -525,9 +375,12 @@ Quest::Quest(shared_ptr initial_version) category_id(initial_version->category_id), episode(initial_version->episode), joinable(initial_version->joinable), - name(initial_version->name), - versions_present(1 << static_cast(initial_version->version)) { - versions.emplace(initial_version->version, initial_version); + name(initial_version->name) { + this->versions.emplace(this->versions_key(initial_version->version, initial_version->language), initial_version); +} + +uint16_t Quest::versions_key(QuestScriptVersion v, uint8_t language) { + return (static_cast(v) << 8) | language; } void Quest::add_version(shared_ptr vq) { @@ -544,24 +397,30 @@ void Quest::add_version(shared_ptr vq) { throw runtime_error("quest version has a different joinability state"); } - uint16_t presence_mask = 1 << static_cast(vq->version); - if (this->versions_present & presence_mask) { - throw runtime_error("quest version is already present"); - } - this->versions_present |= presence_mask; - this->versions.emplace(vq->version, vq); + this->versions.emplace(this->versions_key(vq->version, vq->language), vq); } -bool Quest::has_version(QuestScriptVersion v) const { - return !!(this->versions_present & (1 << static_cast(v))); +bool Quest::has_version(QuestScriptVersion v, uint8_t language) const { + return this->versions.count(this->versions_key(v, language)); } -shared_ptr Quest::version(QuestScriptVersion v) const { +shared_ptr Quest::version(QuestScriptVersion v, uint8_t language) const { + // Return the requested version, if it exists try { - return this->versions.at(v); + return this->versions.at(this->versions_key(v, language)); } catch (const out_of_range&) { + } + // Return the English version, if it exists + try { + return this->versions.at(this->versions_key(v, 1)); + } catch (const out_of_range&) { + } + // Return the first language, if it exists + auto it = this->versions.lower_bound(this->versions_key(v, 0)); + if ((it == this->versions.end()) || ((it->first & 0xFF00) != this->versions_key(v, 0))) { return nullptr; } + return it->second; } QuestIndex::QuestIndex( @@ -570,54 +429,220 @@ QuestIndex::QuestIndex( : directory(directory), category_index(category_index) { - for (const auto& filename : list_directory_sorted(this->directory)) { - string full_path = this->directory + "/" + filename; + unordered_map> dat_cache; - if (ends_with(filename, ".gba")) { - shared_ptr contents(new string(load_file(full_path))); - this->gba_file_contents.emplace(make_pair(filename, contents)); + for (const auto& bin_filename : list_directory_sorted(directory)) { + string bin_path = this->directory + "/" + bin_filename; + + if (ends_with(bin_filename, ".gba")) { + shared_ptr contents(new string(load_file(bin_path))); + this->gba_file_contents.emplace(make_pair(bin_filename, contents)); continue; } - if (ends_with(filename, ".bin") || - ends_with(filename, ".bind") || - ends_with(filename, ".bin.gci") || - ends_with(filename, ".bin.vms") || - ends_with(filename, ".bin.dlq") || - ends_with(filename, ".mnm") || - ends_with(filename, ".mnmd") || - ends_with(filename, ".mnm.gci") || - ends_with(filename, ".mnm.dlq") || - ends_with(filename, ".qst")) { - try { - shared_ptr vq(new VersionedQuest(full_path, QuestScriptVersion::UNKNOWN, this->category_index)); - - string ascii_name = encode_sjis(vq->name); - auto category_name = encode_sjis(this->category_index->at(vq->category_id).name); - - auto q_it = this->quests_by_number.find(vq->quest_number); - if (q_it != this->quests_by_number.end()) { - q_it->second->add_version(vq); - static_game_data_log.info("(%s) Added %s version of quest %" PRIu32 " \"%s\"", - filename.c_str(), - name_for_enum(vq->version), - vq->quest_number, - ascii_name.c_str()); - } else { - this->quests_by_number.emplace(vq->quest_number, new Quest(vq)); - static_game_data_log.info("(%s) Created %s quest %" PRIu32 " \"%s\" (%s, %s (%" PRIu32 "), %s)", - filename.c_str(), - name_for_enum(vq->version), - vq->quest_number, - ascii_name.c_str(), - name_for_episode(vq->episode), - category_name.c_str(), - vq->category_id, - vq->joinable ? "joinable" : "not joinable"); - } - } catch (const exception& e) { - static_game_data_log.warning("Failed to index quest file %s (%s)", filename.c_str(), e.what()); + try { + QuestFileFormat format; + string basename; + if (ends_with(bin_filename, ".bin.gci") || ends_with(bin_filename, ".mnm.gci")) { + format = QuestFileFormat::BIN_DAT_GCI; + basename = bin_filename.substr(0, bin_filename.size() - 8); + } else if (ends_with(bin_filename, ".bin.vms")) { + format = QuestFileFormat::BIN_DAT_VMS; + basename = bin_filename.substr(0, bin_filename.size() - 8); + } else if (ends_with(bin_filename, ".bin.dlq") || ends_with(bin_filename, ".mnm.dlq")) { + format = QuestFileFormat::BIN_DAT_DLQ; + basename = bin_filename.substr(0, bin_filename.size() - 8); + } else if (ends_with(bin_filename, ".qst")) { + format = QuestFileFormat::QST; + basename = bin_filename.substr(0, bin_filename.size() - 4); + } else if (ends_with(bin_filename, ".bin") || ends_with(bin_filename, ".mnm")) { + format = QuestFileFormat::BIN_DAT; + basename = bin_filename.substr(0, bin_filename.size() - 4); + } else if (ends_with(bin_filename, ".bind") || ends_with(bin_filename, ".mnmd")) { + format = QuestFileFormat::BIN_DAT_UNCOMPRESSED; + basename = bin_filename.substr(0, bin_filename.size() - 5); + } else { + continue; // Silently skip file } + if (basename.empty()) { + throw invalid_argument("empty filename"); + } + + // Quest .bin filenames are like K###-CAT-VERS-LANG.EXT, where: + // K = class (quest, battle, challenge, etc.) + // # = quest number (does not have to match the internal quest number) + // CAT = menu category in which quest should appear (optional) + // VERS = PSO version that the quest is for + // LANG = client language (j, e, g, f, s) + // EXT = file type (bin, bind, bin.dlq, qst, etc.) + // Quest .dat filenames are like K###-CAT-VERS.EXT (same as for .bin except + // the LANG token is omitted) + vector filename_tokens = split(basename, '-'); + + string category_token; + if (filename_tokens.size() == 4) { + category_token = std::move(filename_tokens[1]); + filename_tokens.erase(filename_tokens.begin() + 1); + } else if (filename_tokens.size() != 3) { + throw invalid_argument("incorrect filename format"); + } + + uint32_t category_id = this->category_index + ? this->category_index->find(basename[0], category_token).category_id + : 0; + + // Parse the number out of the first token + uint32_t quest_number = strtoull(filename_tokens[0].c_str() + 1, nullptr, 10); + + // Get the version from the second (or previously third) token + static const unordered_map name_to_version({ + {"dn", QuestScriptVersion::DC_NTE}, + {"d1", QuestScriptVersion::DC_V1}, + {"dc", QuestScriptVersion::DC_V2}, + {"pc", QuestScriptVersion::PC_V2}, + {"gcn", QuestScriptVersion::GC_NTE}, + {"gc", QuestScriptVersion::GC_V3}, + {"gc3", QuestScriptVersion::GC_EP3}, + {"xb", QuestScriptVersion::XB_V3}, + {"bb", QuestScriptVersion::BB_V4}, + }); + auto version = name_to_version.at(filename_tokens[1]); + + // Get the language from the last token + if (filename_tokens[2].size() != 1) { + throw runtime_error("language token is not a single character"); + } + uint8_t language = language_code_for_char(filename_tokens[2][0]); + + shared_ptr bin_contents; + shared_ptr dat_contents; + string bin_data = load_file(bin_path); + switch (format) { + case QuestFileFormat::BIN_DAT: + bin_contents.reset(new string(std::move(bin_data))); + break; + case QuestFileFormat::BIN_DAT_UNCOMPRESSED: + bin_contents.reset(new string(prs_compress(bin_data))); + break; + case QuestFileFormat::BIN_DAT_GCI: + bin_contents.reset(new string(decode_gci_data(bin_data))); + break; + case QuestFileFormat::BIN_DAT_VMS: + bin_contents.reset(new string(decode_vms_data(bin_data))); + break; + case QuestFileFormat::BIN_DAT_DLQ: + bin_contents.reset(new string(decode_dlq_data(bin_data))); + break; + case QuestFileFormat::QST: { + auto result = decode_qst_data(bin_data); + bin_contents.reset(new string(std::move(result.first))); + dat_contents.reset(new string(std::move(result.second))); + dat_cache.emplace(basename, dat_contents); + break; + } + default: + throw logic_error("invalid quest file format"); + } + + string dat_filename; + if (!dat_contents && (version != QuestScriptVersion::GC_EP3)) { + if (basename.size() < 2) { + throw logic_error("basename too short for language trim"); + } + // Look for dat file with the same basename as the bin file; if not + // found, look for a dat file without the language suffix + string dat_basename; + for (size_t z = 0; z < 2; z++) { + dat_basename = z ? basename.substr(0, basename.size() - 2) : basename; + try { + dat_contents = dat_cache.at(dat_basename); + break; + } catch (const out_of_range&) { + } + + dat_filename = dat_basename + ".dat"; + string dat_path = this->directory + "/" + dat_filename; + if (isfile(dat_path)) { + dat_contents.reset(new string(load_file(dat_path))); + break; + } + + dat_filename = dat_basename + ".datd"; + dat_path = this->directory + "/" + dat_filename; + if (isfile(dat_path)) { + string decompressed = load_file(dat_path); + dat_contents.reset(new string(prs_compress_optimal(decompressed.data(), decompressed.size()))); + break; + } + + dat_filename = dat_basename + ".dat.gci"; + dat_path = this->directory + "/" + dat_filename; + if (isfile(dat_path)) { + dat_contents.reset(new string(decode_gci_data(load_file(dat_path)))); + break; + } + + dat_filename = dat_basename + ".dat.vms"; + dat_path = this->directory + "/" + dat_filename; + if (isfile(dat_path)) { + dat_contents.reset(new string(decode_vms_data(load_file(dat_path)))); + break; + } + + dat_filename = dat_basename + ".dat.dlq"; + dat_path = this->directory + "/" + dat_filename; + if (isfile(dat_path)) { + dat_contents.reset(new string(decode_dlq_data(load_file(dat_path)))); + break; + } + + dat_filename = dat_basename + ".qst"; + dat_path = this->directory + "/" + dat_filename; + if (isfile(dat_basename + ".qst")) { + dat_contents.reset(new string(decode_dlq_data(load_file(dat_basename + ".dat.dlq")))); + break; + } + } + if (dat_contents) { + dat_cache.emplace(dat_basename, dat_contents); + } else { + throw runtime_error("no dat file found"); + } + } + + shared_ptr vq(new VersionedQuest( + quest_number, category_id, version, language, bin_contents, dat_contents)); + + string ascii_name = format_data_string(encode_sjis(vq->name)); + auto category_name = encode_sjis(this->category_index->at(vq->category_id).name); + + string dat_str = dat_filename.empty() ? "" : (" with layout file " + dat_filename); + auto q_it = this->quests_by_number.find(vq->quest_number); + if (q_it != this->quests_by_number.end()) { + q_it->second->add_version(vq); + static_game_data_log.info("(%s) Added %s %c version of quest %" PRIu32 " %s%s", + bin_filename.c_str(), + name_for_enum(vq->version), + char_for_language_code(vq->language), + vq->quest_number, + ascii_name.c_str(), + dat_str.c_str()); + } else { + this->quests_by_number.emplace(vq->quest_number, new Quest(vq)); + static_game_data_log.info("(%s) Created %s %c quest %" PRIu32 " %s (%s, %s (%" PRIu32 "), %s)%s", + bin_filename.c_str(), + name_for_enum(vq->version), + char_for_language_code(vq->language), + vq->quest_number, + ascii_name.c_str(), + name_for_episode(vq->episode), + category_name.c_str(), + vq->category_id, + vq->joinable ? "joinable" : "not joinable", + dat_str.c_str()); + } + } catch (const exception& e) { + static_game_data_log.warning("(%s) Failed to index quest file: (%s)", bin_filename.c_str(), e.what()); } } } @@ -638,17 +663,17 @@ shared_ptr QuestIndex::get_gba(const string& name) const { } } -vector> QuestIndex::filter(uint32_t category_id, QuestScriptVersion version) const { +vector> QuestIndex::filter(uint32_t category_id, QuestScriptVersion version, uint8_t language) const { vector> ret; for (auto it : this->quests_by_number) { - if (it.second->category_id == category_id && it.second->has_version(version)) { + if (it.second->category_id == category_id && it.second->has_version(version, language)) { ret.emplace_back(it.second); } } return ret; } -string encode_download_quest_file(const string& compressed_data, size_t decompressed_size, uint32_t encryption_seed) { +string encode_download_quest_data(const string& compressed_data, size_t decompressed_size, uint32_t encryption_seed) { // Download quest files are like normal (PRS-compressed) quest files, but they // are encrypted with PSO V2 encryption (even on V3 / PSO GC), and a small // header (PSODownloadQuestHeader) is prepended to the encrypted data. @@ -691,7 +716,7 @@ shared_ptr VersionedQuest::create_download_quest() const { throw logic_error("Episode 3 quests cannot be converted to download quests"); } - string decompressed_bin = prs_decompress(*this->bin_contents()); + string decompressed_bin = prs_decompress(*this->bin_contents); void* data_ptr = decompressed_bin.data(); switch (this->version) { @@ -730,19 +755,17 @@ shared_ptr VersionedQuest::create_download_quest() const { // Return a new VersionedQuest object with appropriately-processed .bin and // .dat file contents shared_ptr dlq(new VersionedQuest(*this)); - dlq->bin_contents_ptr.reset(new string(encode_download_quest_file(compressed_bin, decompressed_bin.size()))); - dlq->dat_contents_ptr.reset(new string(encode_download_quest_file(*this->dat_contents()))); + dlq->bin_contents.reset(new string(encode_download_quest_data(compressed_bin, decompressed_bin.size()))); + dlq->dat_contents.reset(new string(encode_download_quest_data(*this->dat_contents))); dlq->is_dlq_encoded = true; return dlq; } -string decode_gci_file( - const string& filename, +string decode_gci_data( + const string& data, ssize_t find_seed_num_threads, int64_t known_seed, bool skip_checksum) { - string data = load_file(filename); - StringReader r(data); const auto& header = r.get(); header.check(); @@ -817,22 +840,22 @@ string decode_gci_file( } r.skip(9); - data = r.readx(header.data_size - 40); + string decrypted = r.readx(header.data_size - 40); // For some reason, Sega decided not to encrypt Episode 3 quest files in the // same way as Episodes 1&2 quest files (see above). Instead, they just // wrote a fairly trivial XOR loop over the first 0x100 bytes, leaving the // remaining bytes completely unencrypted (but still compressed). size_t unscramble_size = min(0x100, data.size()); - decrypt_trivial_gci_data(data.data(), unscramble_size, 0); + decrypt_trivial_gci_data(decrypted.data(), unscramble_size, 0); - size_t decompressed_size = prs_decompress_size(data); + size_t decompressed_size = prs_decompress_size(decrypted); if (decompressed_size != sizeof(Episode3::MapDefinition)) { throw runtime_error(string_printf( "decompressed quest is 0x%zX bytes; expected 0x%zX bytes", decompressed_size, sizeof(Episode3::MapDefinition))); } - return data; + return decrypted; } } else { @@ -840,13 +863,11 @@ string decode_gci_file( } } -string decode_vms_file( - const string& filename, +string decode_vms_data( + const string& data, ssize_t find_seed_num_threads, int64_t known_seed, bool skip_checksum) { - string data = load_file(filename); - StringReader r(data); const auto& header = r.get(); if (!header.checksum_correct()) { @@ -899,15 +920,9 @@ string decode_dlq_data(const string& data) { return decrypted; } -string decode_dlq_file(const string& filename) { - auto f = fopen_unique(filename, "rb"); - return decode_dlq_data(read_all(f.get())); -} - template -static pair decode_qst_t(FILE* f) { - string qst_data = read_all(f); - StringReader r(qst_data); +static pair decode_qst_data_t(const string& data) { + StringReader r(data); string bin_contents; string dat_contents; @@ -945,7 +960,7 @@ static pair decode_qst_t(FILE* f) { if (header.size != sizeof(HeaderT) + sizeof(OpenFileT)) { throw runtime_error("qst open file command has incorrect size"); } - const auto& cmd = r.get(f); + const auto& cmd = r.get(); string internal_filename = cmd.filename; if (ends_with(internal_filename, ".bin")) { @@ -1011,32 +1026,30 @@ static pair decode_qst_t(FILE* f) { } if (subformat == QuestFileFormat::BIN_DAT_DLQ) { - bin_contents = decode_dlq_file(bin_contents); - dat_contents = decode_dlq_file(dat_contents); + bin_contents = decode_dlq_data(bin_contents); + dat_contents = decode_dlq_data(dat_contents); } return make_pair(bin_contents, dat_contents); } -pair decode_qst_file(const string& filename) { - auto f = fopen_unique(filename, "rb"); - +pair decode_qst_data(const string& data) { // QST files start with an open file command, but the format differs depending // on the PSO version that the qst file is for. We can detect the format from // the first 4 bytes in the file: // - BB: 58 00 44 00 or 58 00 A6 00 // - PC: 3C 00 44 ?? or 3C 00 A6 ?? // - DC/V3: 44 ?? 3C 00 or A6 ?? 3C 00 - uint32_t signature = freadx(f.get()); - fseek(f.get(), 0, SEEK_SET); + StringReader r(data); + uint32_t signature = r.get_u32b(); if (signature == 0x58004400 || signature == 0x5800A600) { - return decode_qst_t(f.get()); + return decode_qst_data_t(data); } else if ((signature & 0xFFFFFF00) == 0x3C004400 || (signature & 0xFFFFFF00) == 0x3C00A600) { - return decode_qst_t(f.get()); + return decode_qst_data_t(data); } else if ((signature & 0xFF00FFFF) == 0x44003C00 || (signature & 0xFF00FFFF) == 0xA6003C00) { - return decode_qst_t(f.get()); + return decode_qst_data_t(data); } else if ((signature & 0xFF00FFFF) == 0x44005400 || (signature & 0xFF00FFFF) == 0xA6005400) { - return decode_qst_t(f.get()); + return decode_qst_data_t(data); } else { throw runtime_error("invalid qst file format"); } diff --git a/src/Quest.hh b/src/Quest.hh index 4a182baf..b9ca60a9 100644 --- a/src/Quest.hh +++ b/src/Quest.hh @@ -52,47 +52,33 @@ struct QuestCategoryIndex { const Category& at(uint32_t category_id) const; }; -class VersionedQuest { -public: - struct DATSectionHeader { - le_uint32_t type; // 1 = objects, 2 = enemies. There are other types too - le_uint32_t section_size; // Includes this header - le_uint32_t area; - le_uint32_t data_size; - } __attribute__((packed)); - +struct VersionedQuest { uint32_t quest_number; uint32_t category_id; Episode episode; bool joinable; - QuestScriptVersion version; - std::string file_basename; // we append -. when reading - QuestFileFormat file_format; - bool has_mnm_extension; - bool is_dlq_encoded; std::u16string name; + QuestScriptVersion version; + uint8_t language; + bool is_dlq_encoded; std::u16string short_description; std::u16string long_description; + std::shared_ptr bin_contents; + std::shared_ptr dat_contents; - VersionedQuest(const std::string& file_basename, QuestScriptVersion version, std::shared_ptr category_index); - VersionedQuest(const VersionedQuest&) = default; - VersionedQuest(VersionedQuest&&) = default; - VersionedQuest& operator=(const VersionedQuest&) = default; - VersionedQuest& operator=(VersionedQuest&&) = default; + VersionedQuest( + uint32_t quest_number, + uint32_t category_id, + QuestScriptVersion version, + uint8_t language, + std::shared_ptr bin_contents, + std::shared_ptr dat_contents); std::string bin_filename() const; std::string dat_filename() const; - std::shared_ptr bin_contents() const; - std::shared_ptr dat_contents() const; - std::shared_ptr create_download_quest() const; std::string encode_qst() const; - -private: - // these are populated when requested - mutable std::shared_ptr bin_contents_ptr; - mutable std::shared_ptr dat_contents_ptr; }; class Quest { @@ -104,18 +90,18 @@ public: Quest& operator=(const Quest&) = default; Quest& operator=(Quest&&) = default; - void add_version(shared_ptr vq); - bool has_version(QuestScriptVersion v) const; - shared_ptr version(QuestScriptVersion v) const; + void add_version(std::shared_ptr vq); + bool has_version(QuestScriptVersion v, uint8_t language) const; + std::shared_ptr version(QuestScriptVersion v, uint8_t language) const; + + static uint16_t versions_key(QuestScriptVersion v, uint8_t language); uint32_t quest_number; uint32_t category_id; Episode episode; bool joinable; std::u16string name; - - uint16_t versions_present; - std::unordered_map> versions; + std::map> versions; }; struct QuestIndex { @@ -130,29 +116,27 @@ struct QuestIndex { std::shared_ptr get(uint32_t quest_number) const; std::shared_ptr get_gba(const std::string& name) const; - std::vector> filter(uint32_t category_id, QuestScriptVersion version) const; + std::vector> filter(uint32_t category_id, QuestScriptVersion version, uint8_t language) const; }; -std::string encode_download_quest_file( +std::string encode_download_quest_data( const std::string& compressed_data, size_t decompressed_size = 0, uint32_t encryption_seed = 0); -std::string decode_gci_file( - const std::string& filename, +std::string decode_gci_data( + const std::string& data, ssize_t find_seed_num_threads = -1, int64_t known_seed = -1, bool skip_checksum = false); -std::string decode_vms_file( - const std::string& filename, +std::string decode_vms_data( + const std::string& data, ssize_t find_seed_num_threads = -1, int64_t known_seed = -1, bool skip_checksum = false); - -std::string decode_dlq_file(const std::string& filename); std::string decode_dlq_data(const std::string& data); +std::pair decode_qst_data(const std::string& data); -std::pair decode_qst_file(const std::string& filename); std::string encode_qst_file( const std::string& bin_data, const std::string& dat_data, diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index f5d61b17..78131e1d 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -1296,23 +1296,7 @@ static void on_CA_Ep3(shared_ptr c, uint16_t, uint32_t, const string& da if (!l->ep3_server || l->ep3_server->battle_finished) { auto s = c->require_server_state(); - if (!l->ep3_server) { - l->log.info("Creating Episode 3 server state"); - } else { - l->log.info("Recreating Episode 3 server state"); - } - auto tourn = l->tournament_match ? l->tournament_match->tournament.lock() : nullptr; - bool is_trial = (l->flags & Lobby::Flag::IS_EP3_TRIAL); - Episode3::Server::Options options = { - .card_index = is_trial ? s->ep3_card_index_trial : s->ep3_card_index, - .map_index = s->ep3_map_index, - .behavior_flags = s->ep3_behavior_flags, - .random_crypt = l->random_crypt, - .tournament = tourn, - .trap_card_ids = s->ep3_trap_card_ids, - }; - l->ep3_server = make_shared(l, std::move(options)); - l->ep3_server->init(); + l->create_ep3_server(); if (s->ep3_behavior_flags & Episode3::BehaviorFlag::ENABLE_STATUS_MESSAGES) { for (size_t z = 0; z < l->max_clients; z++) { @@ -1353,7 +1337,7 @@ static void on_CA_Ep3(shared_ptr c, uint16_t, uint32_t, const string& da } } bool battle_finished_before = l->ep3_server->battle_finished; - l->ep3_server->on_server_data_input(data); + l->ep3_server->on_server_data_input(c, data); if (!battle_finished_before && l->ep3_server->battle_finished && l->battle_record) { l->battle_record->set_battle_end_timestamp(); } @@ -1485,7 +1469,7 @@ static void on_09(shared_ptr c, uint16_t, uint32_t, const string& data) if (!q) { send_quest_info(c, u"$C4Quest does not\nexist.", is_download_quest); } else { - auto vq = q->version(c->quest_version()); + auto vq = q->version(c->quest_version(), c->language()); if (!vq) { send_quest_info(c, u"$C4Quest does not\nexist for this game\nversion.", is_download_quest); } else { @@ -1732,7 +1716,7 @@ static void on_10(shared_ptr c, uint16_t, uint32_t, const string& data) } } if (num_ep3_categories == 1) { - auto quests = s->quest_index->filter(ep3_category_id, c->quest_version()); + auto quests = s->quest_index->filter(ep3_category_id, c->quest_version(), c->language()); send_quest_menu(c, MenuID::QUEST, quests, true); break; } @@ -1983,7 +1967,7 @@ static void on_10(shared_ptr c, uint16_t, uint32_t, const string& data) break; } shared_ptr l = c->lobby.lock(); - auto quests = s->quest_index->filter(item_id, c->quest_version()); + auto quests = s->quest_index->filter(item_id, c->quest_version(), c->language()); // Hack: Assume the menu to be sent is the download quest menu if the // client is not in any lobby @@ -2033,7 +2017,7 @@ static void on_10(shared_ptr c, uint16_t, uint32_t, const string& data) continue; } - auto vq = q->version(lc->quest_version()); + auto vq = q->version(lc->quest_version(), c->language()); if (!vq) { send_lobby_message_box(lc, u"$C6Quest does not exist\nfor this game version."); lc->should_disconnect = true; @@ -2041,10 +2025,8 @@ static void on_10(shared_ptr c, uint16_t, uint32_t, const string& data) } string bin_filename = vq->bin_filename(); string dat_filename = vq->dat_filename(); - shared_ptr bin_contents = vq->bin_contents(); - shared_ptr dat_contents = vq->dat_contents(); - send_open_quest_file(lc, bin_filename, bin_filename, bin_contents, QuestFileType::ONLINE); - send_open_quest_file(lc, dat_filename, dat_filename, dat_contents, QuestFileType::ONLINE); + send_open_quest_file(lc, bin_filename, bin_filename, vq->bin_contents, QuestFileType::ONLINE); + send_open_quest_file(lc, dat_filename, dat_filename, vq->dat_contents, QuestFileType::ONLINE); // There is no such thing as command AC on PSO V1 and V2 - quests just // start immediately when they're done downloading. (This is also the @@ -2064,7 +2046,7 @@ static void on_10(shared_ptr c, uint16_t, uint32_t, const string& data) } else { string quest_name = encode_sjis(q->name); - auto vq = q->version(c->quest_version()); + auto vq = q->version(c->quest_version(), c->language()); if (!vq) { send_lobby_message_box(c, u"$C6Quest does not exist\nfor this game version."); break; @@ -2075,11 +2057,11 @@ static void on_10(shared_ptr c, uint16_t, uint32_t, const string& data) // TODO: This is not true for Episode 3 Trial Edition. We also would // have to convert the map to a MapDefinitionTrial, though. if (vq->version == QuestScriptVersion::GC_EP3) { - send_open_quest_file(c, quest_name, vq->bin_filename(), vq->bin_contents(), QuestFileType::EPISODE_3); + send_open_quest_file(c, quest_name, vq->bin_filename(), vq->bin_contents, QuestFileType::EPISODE_3); } else { vq = vq->create_download_quest(); - send_open_quest_file(c, quest_name, vq->bin_filename(), vq->bin_contents(), QuestFileType::DOWNLOAD); - send_open_quest_file(c, quest_name, vq->dat_filename(), vq->dat_contents(), QuestFileType::DOWNLOAD); + send_open_quest_file(c, quest_name, vq->bin_filename(), vq->bin_contents, QuestFileType::DOWNLOAD); + send_open_quest_file(c, quest_name, vq->dat_filename(), vq->dat_contents, QuestFileType::DOWNLOAD); } } break; @@ -2423,7 +2405,7 @@ static void on_AC_V3_BB(shared_ptr c, uint16_t, uint32_t, const string& (l->base_version == GameVersion::BB) && l->map && l->quest) { - auto dat_contents = prs_decompress(*l->quest->version(QuestScriptVersion::BB_V4)->dat_contents()); + auto dat_contents = prs_decompress(*l->quest->version(QuestScriptVersion::BB_V4, c->language())->dat_contents); l->map->clear(); l->map->add_enemies_from_quest_data(l->episode, l->difficulty, l->event, dat_contents.data(), dat_contents.size()); c->log.info("Replaced enemies list with quest layout (%zu entries)", @@ -3616,19 +3598,15 @@ static void on_6F(shared_ptr c, uint16_t, uint32_t, const string& data) if (!l->quest) { throw runtime_error("JOINABLE_QUEST_IN_PROGRESS is set, but lobby has no quest"); } - auto vq = l->quest->version(c->quest_version()); + auto vq = l->quest->version(c->quest_version(), c->language()); if (!vq) { throw runtime_error("JOINABLE_QUEST_IN_PROGRESS is set, but lobby has no quest for client version"); } string bin_basename = vq->bin_filename(); - shared_ptr bin_contents = vq->bin_contents(); string dat_basename = vq->dat_filename(); - shared_ptr dat_contents = vq->dat_contents(); - send_open_quest_file(c, bin_basename + ".bin", - bin_basename, bin_contents, QuestFileType::ONLINE); - send_open_quest_file(c, dat_basename + ".dat", - dat_basename, dat_contents, QuestFileType::ONLINE); + send_open_quest_file(c, bin_basename + ".bin", bin_basename, vq->bin_contents, QuestFileType::ONLINE); + send_open_quest_file(c, dat_basename + ".dat", dat_basename, vq->dat_contents, QuestFileType::ONLINE); c->flags |= Client::Flag::LOADING_RUNNING_QUEST; } else if (l->map) { send_rare_enemy_index_list(c, l->map->rare_enemy_indexes); @@ -3642,7 +3620,7 @@ static void on_6F(shared_ptr c, uint16_t, uint32_t, const string& data) } else if (watched_lobby && watched_lobby->ep3_server) { if (!watched_lobby->ep3_server->battle_finished) { watched_lobby->ep3_server->send_commands_for_joining_spectator( - c->channel, c->flags & Client::Flag::IS_EP3_TRIAL_EDITION); + c->channel, c->language(), c->flags & Client::Flag::IS_EP3_TRIAL_EDITION); } send_ep3_update_game_metadata(watched_lobby); } diff --git a/src/ReceiveSubcommands.cc b/src/ReceiveSubcommands.cc index 8dc784eb..e4b94505 100644 --- a/src/ReceiveSubcommands.cc +++ b/src/ReceiveSubcommands.cc @@ -1158,19 +1158,20 @@ static void on_sort_inventory_bb(shared_ptr c, uint8_t, uint8_t, const v PlayerInventory sorted; + const auto& inv = c->game_data.player()->inventory; for (size_t x = 0; x < 30; x++) { if (cmd.item_ids[x] == 0xFFFFFFFF) { sorted.items[x].data.id = 0xFFFFFFFF; } else { - size_t index = c->game_data.player()->inventory.find_item(cmd.item_ids[x]); - sorted.items[x] = c->game_data.player()->inventory.items[index]; + size_t index = inv.find_item(cmd.item_ids[x]); + sorted.items[x] = inv.items[index]; } } - sorted.num_items = c->game_data.player()->inventory.num_items; - sorted.hp_materials_used = c->game_data.player()->inventory.hp_materials_used; - sorted.tp_materials_used = c->game_data.player()->inventory.tp_materials_used; - sorted.language = c->game_data.player()->inventory.language; + sorted.num_items = inv.num_items; + sorted.hp_materials_used = inv.hp_materials_used; + sorted.tp_materials_used = inv.tp_materials_used; + sorted.language = inv.language; c->game_data.player()->inventory = sorted; } } diff --git a/src/SaveFileFormats.hh b/src/SaveFileFormats.hh index 803cdf70..b56fb5ba 100644 --- a/src/SaveFileFormats.hh +++ b/src/SaveFileFormats.hh @@ -405,7 +405,7 @@ std::string decrypt_fixed_size_data_section_s( using U32T = std::conditional_t; if (size < 2 * sizeof(U32T)) { - throw runtime_error("data size is too small"); + throw std::runtime_error("data size is too small"); } std::string decrypted = decrypt_data_section(data_section, size, round1_seed); @@ -476,12 +476,12 @@ std::string encrypt_fixed_size_data_section_s(const void* data, size_t size, uin using U32T = std::conditional_t; if (size < 2 * sizeof(U32T)) { - throw runtime_error("data size is too small"); + throw std::runtime_error("data size is too small"); } uint32_t round2_seed = random_object(); - string encrypted(reinterpret_cast(data), size); + std::string encrypted(reinterpret_cast(data), size); *reinterpret_cast(encrypted.data()) = 0; *reinterpret_cast(encrypted.data() + encrypted.size() - sizeof(U32T)) = round2_seed; *reinterpret_cast(encrypted.data()) = crc32(encrypted.data(), encrypted.size()); diff --git a/src/SendCommands.cc b/src/SendCommands.cc index 50557f50..f4651e2e 100644 --- a/src/SendCommands.cc +++ b/src/SendCommands.cc @@ -1276,7 +1276,7 @@ void send_quest_menu_t( auto v = c->quest_version(); vector entries; for (const auto& quest : quests) { - auto vq = quest->version(v); + auto vq = quest->version(v, c->language()); if (!vq) { continue; } @@ -2389,7 +2389,7 @@ void send_ep3_tournament_details( shared_ptr tourn) { S_TournamentGameDetails_GC_Ep3_E3 cmd; cmd.name = tourn->get_name(); - cmd.map_name = tourn->get_map()->map.name; + cmd.map_name = tourn->get_map()->version(c->language())->map->name; cmd.rules = tourn->get_rules(); const auto& teams = tourn->all_teams(); for (size_t z = 0; z < min(teams.size(), 0x20); z++) { @@ -2430,7 +2430,7 @@ void send_ep3_game_details(shared_ptr c, shared_ptr l) { S_TournamentGameDetails_GC_Ep3_E3 cmd; cmd.name = encode_sjis(l->name); - cmd.map_name = tourn->get_map()->map.name; + cmd.map_name = tourn->get_map()->version(c->language())->map->name; cmd.rules = tourn->get_rules(); const auto& teams = tourn->all_teams(); @@ -2546,7 +2546,7 @@ void send_ep3_set_tournament_player_decks(shared_ptr c) { G_SetTournamentPlayerDecks_GC_Ep3_6xB4x3D cmd; cmd.rules = tourn->get_rules(); - cmd.map_number = tourn->get_map()->map.map_number.load(); + cmd.map_number = tourn->get_map()->map_number; cmd.player_slot = 0xFF; for (size_t z = 0; z < 4; z++) { @@ -2862,9 +2862,10 @@ bool send_ep3_start_tournament_deck_select_if_all_clients_ready(shared_ptrmax_clients) { - string data = Episode3::Server::prepare_6xB6x41_map_definition( - tourn->get_map(), l->flags & Lobby::Flag::IS_EP3_TRIAL); - send_command(l, 0x6C, 0x00, data); + if (!l->ep3_server) { + l->create_ep3_server(); + } + l->ep3_server->send_6xB6x41_to_all_clients(); for (auto c : l->clients) { if (c) { send_ep3_set_tournament_player_decks(c); diff --git a/src/SendCommands.hh b/src/SendCommands.hh index 9fffb03e..296d455a 100644 --- a/src/SendCommands.hh +++ b/src/SendCommands.hh @@ -55,7 +55,7 @@ inline void send_command_excluding_client(std::shared_ptr l, void send_command_if_not_loading(std::shared_ptr l, uint16_t command, uint32_t flag, const void* data, size_t size); inline void send_command_if_not_loading(std::shared_ptr l, - uint16_t command, uint32_t flag, const string& data) { + uint16_t command, uint32_t flag, const std::string& data) { send_command_if_not_loading(l, command, flag, data.data(), data.size()); } template @@ -208,7 +208,7 @@ void send_chat_message( std::shared_ptr c, uint32_t from_guild_card_number, const std::u16string& from_name, - const u16string& text, + const std::u16string& text, char private_flags); void send_simple_mail( std::shared_ptr c, @@ -240,9 +240,9 @@ void send_card_search_result( void send_guild_card( Channel& ch, uint32_t guild_card_number, - const u16string& name, - const u16string& team_name, - const u16string& description, + const std::u16string& name, + const std::u16string& team_name, + const std::u16string& description, uint8_t section_id, uint8_t char_class); void send_guild_card(std::shared_ptr c, std::shared_ptr source); @@ -359,8 +359,8 @@ void send_open_quest_file( std::shared_ptr contents, QuestFileType type); void send_quest_file_chunk( - shared_ptr c, - const string& filename, + std::shared_ptr c, + const std::string& filename, size_t chunk_index, const void* data, size_t size, diff --git a/src/ServerShell.cc b/src/ServerShell.cc index 3916a5bf..dfc93785 100644 --- a/src/ServerShell.cc +++ b/src/ServerShell.cc @@ -471,7 +471,7 @@ Proxy session commands:\n\ } else if (command_name == "create-tournament") { string name = get_quoted_string(command_args); string map_name = get_quoted_string(command_args); - auto map = this->state->ep3_map_index->definition_for_name(map_name); + auto map = this->state->ep3_map_index->for_name(map_name); uint32_t num_teams = stoul(get_quoted_string(command_args), nullptr, 0); Episode3::Rules rules; rules.set_defaults(); diff --git a/src/ServerState.cc b/src/ServerState.cc index e58ff533..e7015ce8 100644 --- a/src/ServerState.cc +++ b/src/ServerState.cc @@ -584,27 +584,33 @@ void ServerState::parse_config(const JSON& json, bool is_reload) { this->ep3_card_auction_max_size = 0; } - for (const auto& it : json.get("CardAuctionPool", JSON::dict()).as_dict()) { - this->ep3_card_auction_pool.emplace_back( - CardAuctionPoolEntry{ - .probability = static_cast(it.second->at(0).as_int()), - .card_id = 0, - .min_price = static_cast(it.second->at(1).as_int()), - .card_name = it.first}); + try { + for (const auto& it : json.get_dict("CardAuctionPool")) { + this->ep3_card_auction_pool.emplace_back( + CardAuctionPoolEntry{ + .probability = static_cast(it.second->at(0).as_int()), + .card_id = 0, + .min_price = static_cast(it.second->at(1).as_int()), + .card_name = it.first}); + } + } catch (const out_of_range&) { } - const auto& ep3_trap_cards_json = json.get("Episode3TrapCards", JSON::list()).as_list(); - if (!ep3_trap_cards_json.empty()) { - if (ep3_trap_cards_json.size() != 5) { - throw runtime_error("Episode3TrapCards must be a list of 5 lists"); - } - this->ep3_trap_card_names.clear(); - for (const auto& trap_type_it : ep3_trap_cards_json) { - auto& names = this->ep3_trap_card_names.emplace_back(); - for (const auto& card_it : trap_type_it->as_list()) { - names.emplace_back(card_it->as_string()); + try { + const auto& ep3_trap_cards_json = json.get_list("Episode3TrapCards"); + if (!ep3_trap_cards_json.empty()) { + if (ep3_trap_cards_json.size() != 5) { + throw runtime_error("Episode3TrapCards must be a list of 5 lists"); + } + this->ep3_trap_card_names.clear(); + for (const auto& trap_type_it : ep3_trap_cards_json) { + auto& names = this->ep3_trap_card_names.emplace_back(); + for (const auto& card_it : trap_type_it->as_list()) { + names.emplace_back(card_it->as_string()); + } } } + } catch (const out_of_range&) { } if (!this->is_replay) { diff --git a/src/StaticGameData.cc b/src/StaticGameData.cc index 59c26ff9..f3d37403 100644 --- a/src/StaticGameData.cc +++ b/src/StaticGameData.cc @@ -462,8 +462,8 @@ char abbreviation_for_difficulty(uint8_t difficulty) { } } -char char_for_language_code(uint8_t language) { - switch (language) { +char char_for_language_code(uint8_t language_code) { + switch (language_code) { case 0: return 'J'; case 1: @@ -479,6 +479,28 @@ char char_for_language_code(uint8_t language) { } } +uint8_t language_code_for_char(char language_char) { + switch (language_char) { + case 'J': + case 'j': + return 0; + case 'E': + case 'e': + return 1; + case 'G': + case 'g': + return 2; + case 'F': + case 'f': + return 3; + case 'S': + case 's': + return 4; + default: + throw runtime_error("unknown language"); + } +} + size_t max_stack_size_for_item(uint8_t data0, uint8_t data1) { if (data0 == 4) { return 999999; diff --git a/src/StaticGameData.hh b/src/StaticGameData.hh index 7f6ac24d..92c579d5 100644 --- a/src/StaticGameData.hh +++ b/src/StaticGameData.hh @@ -2,7 +2,9 @@ #include +#include #include +#include #include "FileContentsCache.hh" #include "Player.hh" @@ -32,8 +34,8 @@ const char* abbreviation_for_mode(GameMode mode); size_t max_stack_size_for_item(uint8_t data0, uint8_t data1); -extern const vector tech_id_to_name; -extern const unordered_map name_to_tech_id; +extern const std::vector tech_id_to_name; +extern const std::unordered_map name_to_tech_id; const std::string& name_for_technique(uint8_t tech); std::u16string u16name_for_technique(uint8_t tech); @@ -74,7 +76,8 @@ const char* name_for_difficulty(uint8_t difficulty); const char* token_name_for_difficulty(uint8_t difficulty); char abbreviation_for_difficulty(uint8_t difficulty); -char char_for_language_code(uint8_t language); +char char_for_language_code(uint8_t language_code); +uint8_t language_code_for_char(char language_char); extern const std::vector name_for_mag_color; extern const std::unordered_map mag_color_for_name; diff --git a/system/ep3/maps/e765-dlt-gc3-e.mnm b/system/ep3/maps/e765-dlt-gc3-e.mnm new file mode 120000 index 00000000..2d81f9a3 --- /dev/null +++ b/system/ep3/maps/e765-dlt-gc3-e.mnm @@ -0,0 +1 @@ +../../quests/e765-dlt-gc3-e.mnm \ No newline at end of file diff --git a/system/ep3/maps/e765-dlt-gc3.mnm b/system/ep3/maps/e765-dlt-gc3.mnm deleted file mode 120000 index 5e782af3..00000000 --- a/system/ep3/maps/e765-dlt-gc3.mnm +++ /dev/null @@ -1 +0,0 @@ -../../quests/e765-dlt-gc3.mnm \ No newline at end of file diff --git a/system/ep3/maps/e901-dl-gc3-e.mnm b/system/ep3/maps/e901-dl-gc3-e.mnm new file mode 120000 index 00000000..1adb9eed --- /dev/null +++ b/system/ep3/maps/e901-dl-gc3-e.mnm @@ -0,0 +1 @@ +../../quests/e901-dl-gc3-e.mnm \ No newline at end of file diff --git a/system/ep3/maps/e901-dl-gc3.mnm b/system/ep3/maps/e901-dl-gc3.mnm deleted file mode 120000 index d4b126a3..00000000 --- a/system/ep3/maps/e901-dl-gc3.mnm +++ /dev/null @@ -1 +0,0 @@ -../../quests/e901-dl-gc3.mnm \ No newline at end of file diff --git a/system/ep3/maps/e903-dl-gc3-e.mnm b/system/ep3/maps/e903-dl-gc3-e.mnm new file mode 120000 index 00000000..f602cf2a --- /dev/null +++ b/system/ep3/maps/e903-dl-gc3-e.mnm @@ -0,0 +1 @@ +../../quests/e903-dl-gc3-e.mnm \ No newline at end of file diff --git a/system/ep3/maps/e903-dl-gc3.mnm b/system/ep3/maps/e903-dl-gc3.mnm deleted file mode 120000 index 3805059a..00000000 --- a/system/ep3/maps/e903-dl-gc3.mnm +++ /dev/null @@ -1 +0,0 @@ -../../quests/e903-dl-gc3.mnm \ No newline at end of file diff --git a/system/ep3/maps/e904-dl-gc3-e.mnm b/system/ep3/maps/e904-dl-gc3-e.mnm new file mode 120000 index 00000000..2474c67e --- /dev/null +++ b/system/ep3/maps/e904-dl-gc3-e.mnm @@ -0,0 +1 @@ +../../quests/e904-dl-gc3-e.mnm \ No newline at end of file diff --git a/system/ep3/maps/e904-dl-gc3.mnm b/system/ep3/maps/e904-dl-gc3.mnm deleted file mode 120000 index 5d64d31e..00000000 --- a/system/ep3/maps/e904-dl-gc3.mnm +++ /dev/null @@ -1 +0,0 @@ -../../quests/e904-dl-gc3.mnm \ No newline at end of file diff --git a/system/ep3/maps/e905-dl-gc3-e.mnm b/system/ep3/maps/e905-dl-gc3-e.mnm new file mode 120000 index 00000000..c49439f1 --- /dev/null +++ b/system/ep3/maps/e905-dl-gc3-e.mnm @@ -0,0 +1 @@ +../../quests/e905-dl-gc3-e.mnm \ No newline at end of file diff --git a/system/ep3/maps/e905-dl-gc3.mnm b/system/ep3/maps/e905-dl-gc3.mnm deleted file mode 120000 index 35cff1c6..00000000 --- a/system/ep3/maps/e905-dl-gc3.mnm +++ /dev/null @@ -1 +0,0 @@ -../../quests/e905-dl-gc3.mnm \ No newline at end of file diff --git a/system/ep3/maps/e906-dl-gc3-e.mnm b/system/ep3/maps/e906-dl-gc3-e.mnm new file mode 120000 index 00000000..a991c6f1 --- /dev/null +++ b/system/ep3/maps/e906-dl-gc3-e.mnm @@ -0,0 +1 @@ +../../quests/e906-dl-gc3-e.mnm \ No newline at end of file diff --git a/system/ep3/maps/e906-dl-gc3.mnm b/system/ep3/maps/e906-dl-gc3.mnm deleted file mode 120000 index 9abc1083..00000000 --- a/system/ep3/maps/e906-dl-gc3.mnm +++ /dev/null @@ -1 +0,0 @@ -../../quests/e906-dl-gc3.mnm \ No newline at end of file diff --git a/system/ep3/maps/e907-dl-gc3-e.mnm b/system/ep3/maps/e907-dl-gc3-e.mnm new file mode 120000 index 00000000..fbea39c9 --- /dev/null +++ b/system/ep3/maps/e907-dl-gc3-e.mnm @@ -0,0 +1 @@ +../../quests/e907-dl-gc3-e.mnm \ No newline at end of file diff --git a/system/ep3/maps/e907-dl-gc3.mnm b/system/ep3/maps/e907-dl-gc3.mnm deleted file mode 120000 index 560a13e2..00000000 --- a/system/ep3/maps/e907-dl-gc3.mnm +++ /dev/null @@ -1 +0,0 @@ -../../quests/e907-dl-gc3.mnm \ No newline at end of file diff --git a/system/ep3/maps/e908-dl-gc3-e.mnm b/system/ep3/maps/e908-dl-gc3-e.mnm new file mode 120000 index 00000000..ed56596c --- /dev/null +++ b/system/ep3/maps/e908-dl-gc3-e.mnm @@ -0,0 +1 @@ +../../quests/e908-dl-gc3-e.mnm \ No newline at end of file diff --git a/system/ep3/maps/e908-dl-gc3.mnm b/system/ep3/maps/e908-dl-gc3.mnm deleted file mode 120000 index b62ce610..00000000 --- a/system/ep3/maps/e908-dl-gc3.mnm +++ /dev/null @@ -1 +0,0 @@ -../../quests/e908-dl-gc3.mnm \ No newline at end of file diff --git a/system/ep3/maps/m000011p_e.bind b/system/ep3/maps/m000011p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000011p_e.bind rename to system/ep3/maps/m000011p-e.bind diff --git a/system/ep3/maps/m000011p-j.bind b/system/ep3/maps/m000011p-j.bind new file mode 100755 index 00000000..bbc7da09 Binary files /dev/null and b/system/ep3/maps/m000011p-j.bind differ diff --git a/system/ep3/maps/m000021p_e.bind b/system/ep3/maps/m000021p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000021p_e.bind rename to system/ep3/maps/m000021p-e.bind diff --git a/system/ep3/maps/m000021p-j.bind b/system/ep3/maps/m000021p-j.bind new file mode 100755 index 00000000..8398643a Binary files /dev/null and b/system/ep3/maps/m000021p-j.bind differ diff --git a/system/ep3/maps/m000031p_e.bind b/system/ep3/maps/m000031p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000031p_e.bind rename to system/ep3/maps/m000031p-e.bind diff --git a/system/ep3/maps/m000031p-j.bind b/system/ep3/maps/m000031p-j.bind new file mode 100755 index 00000000..2582869b Binary files /dev/null and b/system/ep3/maps/m000031p-j.bind differ diff --git a/system/ep3/maps/m000032p_e.bind b/system/ep3/maps/m000032p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000032p_e.bind rename to system/ep3/maps/m000032p-e.bind diff --git a/system/ep3/maps/m000032p-j.bind b/system/ep3/maps/m000032p-j.bind new file mode 100755 index 00000000..3165401b Binary files /dev/null and b/system/ep3/maps/m000032p-j.bind differ diff --git a/system/ep3/maps/m000041p_e.bind b/system/ep3/maps/m000041p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000041p_e.bind rename to system/ep3/maps/m000041p-e.bind diff --git a/system/ep3/maps/m000041p-j.bind b/system/ep3/maps/m000041p-j.bind new file mode 100755 index 00000000..a2abac16 Binary files /dev/null and b/system/ep3/maps/m000041p-j.bind differ diff --git a/system/ep3/maps/m000042p_e.bind b/system/ep3/maps/m000042p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000042p_e.bind rename to system/ep3/maps/m000042p-e.bind diff --git a/system/ep3/maps/m000042p-j.bind b/system/ep3/maps/m000042p-j.bind new file mode 100755 index 00000000..60beeb05 Binary files /dev/null and b/system/ep3/maps/m000042p-j.bind differ diff --git a/system/ep3/maps/m000043p_e.bind b/system/ep3/maps/m000043p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000043p_e.bind rename to system/ep3/maps/m000043p-e.bind diff --git a/system/ep3/maps/m000043p-j.bind b/system/ep3/maps/m000043p-j.bind new file mode 100755 index 00000000..7d189037 Binary files /dev/null and b/system/ep3/maps/m000043p-j.bind differ diff --git a/system/ep3/maps/m000051p_e.bind b/system/ep3/maps/m000051p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000051p_e.bind rename to system/ep3/maps/m000051p-e.bind diff --git a/system/ep3/maps/m000051p-j.bind b/system/ep3/maps/m000051p-j.bind new file mode 100755 index 00000000..51a0d8ad Binary files /dev/null and b/system/ep3/maps/m000051p-j.bind differ diff --git a/system/ep3/maps/m000052p_e.bind b/system/ep3/maps/m000052p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000052p_e.bind rename to system/ep3/maps/m000052p-e.bind diff --git a/system/ep3/maps/m000052p-j.bind b/system/ep3/maps/m000052p-j.bind new file mode 100755 index 00000000..fca6097f Binary files /dev/null and b/system/ep3/maps/m000052p-j.bind differ diff --git a/system/ep3/maps/m000053p_e.bind b/system/ep3/maps/m000053p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000053p_e.bind rename to system/ep3/maps/m000053p-e.bind diff --git a/system/ep3/maps/m000053p-j.bind b/system/ep3/maps/m000053p-j.bind new file mode 100755 index 00000000..eab2bd1c Binary files /dev/null and b/system/ep3/maps/m000053p-j.bind differ diff --git a/system/ep3/maps/m000061p_e.bind b/system/ep3/maps/m000061p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000061p_e.bind rename to system/ep3/maps/m000061p-e.bind diff --git a/system/ep3/maps/m000061p-j.bind b/system/ep3/maps/m000061p-j.bind new file mode 100755 index 00000000..57de33d2 Binary files /dev/null and b/system/ep3/maps/m000061p-j.bind differ diff --git a/system/ep3/maps/m000062p_e.bind b/system/ep3/maps/m000062p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000062p_e.bind rename to system/ep3/maps/m000062p-e.bind diff --git a/system/ep3/maps/m000062p-j.bind b/system/ep3/maps/m000062p-j.bind new file mode 100755 index 00000000..508333eb Binary files /dev/null and b/system/ep3/maps/m000062p-j.bind differ diff --git a/system/ep3/maps/m000063p_e.bind b/system/ep3/maps/m000063p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000063p_e.bind rename to system/ep3/maps/m000063p-e.bind diff --git a/system/ep3/maps/m000063p-j.bind b/system/ep3/maps/m000063p-j.bind new file mode 100755 index 00000000..7b5c8984 Binary files /dev/null and b/system/ep3/maps/m000063p-j.bind differ diff --git a/system/ep3/maps/m000071p_e.bind b/system/ep3/maps/m000071p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000071p_e.bind rename to system/ep3/maps/m000071p-e.bind diff --git a/system/ep3/maps/m000071p-j.bind b/system/ep3/maps/m000071p-j.bind new file mode 100755 index 00000000..6c707715 Binary files /dev/null and b/system/ep3/maps/m000071p-j.bind differ diff --git a/system/ep3/maps/m000072p_e.bind b/system/ep3/maps/m000072p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000072p_e.bind rename to system/ep3/maps/m000072p-e.bind diff --git a/system/ep3/maps/m000072p-j.bind b/system/ep3/maps/m000072p-j.bind new file mode 100755 index 00000000..42b43be8 Binary files /dev/null and b/system/ep3/maps/m000072p-j.bind differ diff --git a/system/ep3/maps/m000073p_e.bind b/system/ep3/maps/m000073p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000073p_e.bind rename to system/ep3/maps/m000073p-e.bind diff --git a/system/ep3/maps/m000073p-j.bind b/system/ep3/maps/m000073p-j.bind new file mode 100755 index 00000000..5faa13f6 Binary files /dev/null and b/system/ep3/maps/m000073p-j.bind differ diff --git a/system/ep3/maps/m000081p_e.bind b/system/ep3/maps/m000081p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000081p_e.bind rename to system/ep3/maps/m000081p-e.bind diff --git a/system/ep3/maps/m000081p-j.bind b/system/ep3/maps/m000081p-j.bind new file mode 100755 index 00000000..f80229b1 Binary files /dev/null and b/system/ep3/maps/m000081p-j.bind differ diff --git a/system/ep3/maps/m000082p_e.bind b/system/ep3/maps/m000082p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000082p_e.bind rename to system/ep3/maps/m000082p-e.bind diff --git a/system/ep3/maps/m000082p-j.bind b/system/ep3/maps/m000082p-j.bind new file mode 100755 index 00000000..33715e7c Binary files /dev/null and b/system/ep3/maps/m000082p-j.bind differ diff --git a/system/ep3/maps/m000083p_e.bind b/system/ep3/maps/m000083p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000083p_e.bind rename to system/ep3/maps/m000083p-e.bind diff --git a/system/ep3/maps/m000083p-j.bind b/system/ep3/maps/m000083p-j.bind new file mode 100755 index 00000000..21779c84 Binary files /dev/null and b/system/ep3/maps/m000083p-j.bind differ diff --git a/system/ep3/maps/m000091p_e.bind b/system/ep3/maps/m000091p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000091p_e.bind rename to system/ep3/maps/m000091p-e.bind diff --git a/system/ep3/maps/m000091p-j.bind b/system/ep3/maps/m000091p-j.bind new file mode 100755 index 00000000..2aa108d5 Binary files /dev/null and b/system/ep3/maps/m000091p-j.bind differ diff --git a/system/ep3/maps/m000092p_e.bind b/system/ep3/maps/m000092p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000092p_e.bind rename to system/ep3/maps/m000092p-e.bind diff --git a/system/ep3/maps/m000092p-j.bind b/system/ep3/maps/m000092p-j.bind new file mode 100755 index 00000000..c4937dfd Binary files /dev/null and b/system/ep3/maps/m000092p-j.bind differ diff --git a/system/ep3/maps/m000093p_e.bind b/system/ep3/maps/m000093p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000093p_e.bind rename to system/ep3/maps/m000093p-e.bind diff --git a/system/ep3/maps/m000093p-j.bind b/system/ep3/maps/m000093p-j.bind new file mode 100755 index 00000000..e3818cd7 Binary files /dev/null and b/system/ep3/maps/m000093p-j.bind differ diff --git a/system/ep3/maps/m000101p_e.bind b/system/ep3/maps/m000101p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000101p_e.bind rename to system/ep3/maps/m000101p-e.bind diff --git a/system/ep3/maps/m000101p-j.bind b/system/ep3/maps/m000101p-j.bind new file mode 100755 index 00000000..1222f06b Binary files /dev/null and b/system/ep3/maps/m000101p-j.bind differ diff --git a/system/ep3/maps/m000102p_e.bind b/system/ep3/maps/m000102p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000102p_e.bind rename to system/ep3/maps/m000102p-e.bind diff --git a/system/ep3/maps/m000102p-j.bind b/system/ep3/maps/m000102p-j.bind new file mode 100755 index 00000000..732a76da Binary files /dev/null and b/system/ep3/maps/m000102p-j.bind differ diff --git a/system/ep3/maps/m000103p_e.bind b/system/ep3/maps/m000103p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000103p_e.bind rename to system/ep3/maps/m000103p-e.bind diff --git a/system/ep3/maps/m000103p-j.bind b/system/ep3/maps/m000103p-j.bind new file mode 100755 index 00000000..4341b7bb Binary files /dev/null and b/system/ep3/maps/m000103p-j.bind differ diff --git a/system/ep3/maps/m000111p_e.bind b/system/ep3/maps/m000111p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000111p_e.bind rename to system/ep3/maps/m000111p-e.bind diff --git a/system/ep3/maps/m000111p-j.bind b/system/ep3/maps/m000111p-j.bind new file mode 100755 index 00000000..ce2c9e43 Binary files /dev/null and b/system/ep3/maps/m000111p-j.bind differ diff --git a/system/ep3/maps/m000112p_e.bind b/system/ep3/maps/m000112p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000112p_e.bind rename to system/ep3/maps/m000112p-e.bind diff --git a/system/ep3/maps/m000112p-j.bind b/system/ep3/maps/m000112p-j.bind new file mode 100755 index 00000000..85ca4c8c Binary files /dev/null and b/system/ep3/maps/m000112p-j.bind differ diff --git a/system/ep3/maps/m000113p_e.bind b/system/ep3/maps/m000113p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000113p_e.bind rename to system/ep3/maps/m000113p-e.bind diff --git a/system/ep3/maps/m000113p-j.bind b/system/ep3/maps/m000113p-j.bind new file mode 100755 index 00000000..6ad4a11c Binary files /dev/null and b/system/ep3/maps/m000113p-j.bind differ diff --git a/system/ep3/maps/m000121p_e.bind b/system/ep3/maps/m000121p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000121p_e.bind rename to system/ep3/maps/m000121p-e.bind diff --git a/system/ep3/maps/m000121p-j.bind b/system/ep3/maps/m000121p-j.bind new file mode 100755 index 00000000..5326121b Binary files /dev/null and b/system/ep3/maps/m000121p-j.bind differ diff --git a/system/ep3/maps/m000122p_e.bind b/system/ep3/maps/m000122p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000122p_e.bind rename to system/ep3/maps/m000122p-e.bind diff --git a/system/ep3/maps/m000122p-j.bind b/system/ep3/maps/m000122p-j.bind new file mode 100755 index 00000000..36e49e89 Binary files /dev/null and b/system/ep3/maps/m000122p-j.bind differ diff --git a/system/ep3/maps/m000123p_e.bind b/system/ep3/maps/m000123p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000123p_e.bind rename to system/ep3/maps/m000123p-e.bind diff --git a/system/ep3/maps/m000123p-j.bind b/system/ep3/maps/m000123p-j.bind new file mode 100755 index 00000000..dd60c0c3 Binary files /dev/null and b/system/ep3/maps/m000123p-j.bind differ diff --git a/system/ep3/maps/m000131p_e.bind b/system/ep3/maps/m000131p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000131p_e.bind rename to system/ep3/maps/m000131p-e.bind diff --git a/system/ep3/maps/m000131p-j.bind b/system/ep3/maps/m000131p-j.bind new file mode 100755 index 00000000..b7d5234a Binary files /dev/null and b/system/ep3/maps/m000131p-j.bind differ diff --git a/system/ep3/maps/m000141p_e.bind b/system/ep3/maps/m000141p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000141p_e.bind rename to system/ep3/maps/m000141p-e.bind diff --git a/system/ep3/maps/m000141p-j.bind b/system/ep3/maps/m000141p-j.bind new file mode 100755 index 00000000..1be045f0 Binary files /dev/null and b/system/ep3/maps/m000141p-j.bind differ diff --git a/system/ep3/maps/m000142p_e.bind b/system/ep3/maps/m000142p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000142p_e.bind rename to system/ep3/maps/m000142p-e.bind diff --git a/system/ep3/maps/m000142p-j.bind b/system/ep3/maps/m000142p-j.bind new file mode 100755 index 00000000..0567e9ac Binary files /dev/null and b/system/ep3/maps/m000142p-j.bind differ diff --git a/system/ep3/maps/m000143p_e.bind b/system/ep3/maps/m000143p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000143p_e.bind rename to system/ep3/maps/m000143p-e.bind diff --git a/system/ep3/maps/m000143p-j.bind b/system/ep3/maps/m000143p-j.bind new file mode 100755 index 00000000..31d1f8e1 Binary files /dev/null and b/system/ep3/maps/m000143p-j.bind differ diff --git a/system/ep3/maps/m000151p_e.bind b/system/ep3/maps/m000151p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000151p_e.bind rename to system/ep3/maps/m000151p-e.bind diff --git a/system/ep3/maps/m000151p-j.bind b/system/ep3/maps/m000151p-j.bind new file mode 100755 index 00000000..b4a74ea0 Binary files /dev/null and b/system/ep3/maps/m000151p-j.bind differ diff --git a/system/ep3/maps/m000152p_e.bind b/system/ep3/maps/m000152p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000152p_e.bind rename to system/ep3/maps/m000152p-e.bind diff --git a/system/ep3/maps/m000152p-j.bind b/system/ep3/maps/m000152p-j.bind new file mode 100755 index 00000000..670f29d0 Binary files /dev/null and b/system/ep3/maps/m000152p-j.bind differ diff --git a/system/ep3/maps/m000153p_e.bind b/system/ep3/maps/m000153p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000153p_e.bind rename to system/ep3/maps/m000153p-e.bind diff --git a/system/ep3/maps/m000153p-j.bind b/system/ep3/maps/m000153p-j.bind new file mode 100755 index 00000000..3aeebaea Binary files /dev/null and b/system/ep3/maps/m000153p-j.bind differ diff --git a/system/ep3/maps/m000161p_e.bind b/system/ep3/maps/m000161p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000161p_e.bind rename to system/ep3/maps/m000161p-e.bind diff --git a/system/ep3/maps/m000161p-j.bind b/system/ep3/maps/m000161p-j.bind new file mode 100755 index 00000000..2d0b24df Binary files /dev/null and b/system/ep3/maps/m000161p-j.bind differ diff --git a/system/ep3/maps/m000162p_e.bind b/system/ep3/maps/m000162p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000162p_e.bind rename to system/ep3/maps/m000162p-e.bind diff --git a/system/ep3/maps/m000162p-j.bind b/system/ep3/maps/m000162p-j.bind new file mode 100755 index 00000000..f8f23d01 Binary files /dev/null and b/system/ep3/maps/m000162p-j.bind differ diff --git a/system/ep3/maps/m000163p_e.bind b/system/ep3/maps/m000163p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000163p_e.bind rename to system/ep3/maps/m000163p-e.bind diff --git a/system/ep3/maps/m000163p-j.bind b/system/ep3/maps/m000163p-j.bind new file mode 100755 index 00000000..fa535034 Binary files /dev/null and b/system/ep3/maps/m000163p-j.bind differ diff --git a/system/ep3/maps/m000171p_e.bind b/system/ep3/maps/m000171p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000171p_e.bind rename to system/ep3/maps/m000171p-e.bind diff --git a/system/ep3/maps/m000171p-j.bind b/system/ep3/maps/m000171p-j.bind new file mode 100755 index 00000000..ec4261b0 Binary files /dev/null and b/system/ep3/maps/m000171p-j.bind differ diff --git a/system/ep3/maps/m000172p_e.bind b/system/ep3/maps/m000172p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000172p_e.bind rename to system/ep3/maps/m000172p-e.bind diff --git a/system/ep3/maps/m000172p-j.bind b/system/ep3/maps/m000172p-j.bind new file mode 100755 index 00000000..ae81da82 Binary files /dev/null and b/system/ep3/maps/m000172p-j.bind differ diff --git a/system/ep3/maps/m000173p_e.bind b/system/ep3/maps/m000173p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000173p_e.bind rename to system/ep3/maps/m000173p-e.bind diff --git a/system/ep3/maps/m000173p-j.bind b/system/ep3/maps/m000173p-j.bind new file mode 100755 index 00000000..37798053 Binary files /dev/null and b/system/ep3/maps/m000173p-j.bind differ diff --git a/system/ep3/maps/m000181p_e.bind b/system/ep3/maps/m000181p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000181p_e.bind rename to system/ep3/maps/m000181p-e.bind diff --git a/system/ep3/maps/m000181p-j.bind b/system/ep3/maps/m000181p-j.bind new file mode 100755 index 00000000..77d55e1f Binary files /dev/null and b/system/ep3/maps/m000181p-j.bind differ diff --git a/system/ep3/maps/m000182p_e.bind b/system/ep3/maps/m000182p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000182p_e.bind rename to system/ep3/maps/m000182p-e.bind diff --git a/system/ep3/maps/m000182p-j.bind b/system/ep3/maps/m000182p-j.bind new file mode 100755 index 00000000..8724136c Binary files /dev/null and b/system/ep3/maps/m000182p-j.bind differ diff --git a/system/ep3/maps/m000183p_e.bind b/system/ep3/maps/m000183p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000183p_e.bind rename to system/ep3/maps/m000183p-e.bind diff --git a/system/ep3/maps/m000183p-j.bind b/system/ep3/maps/m000183p-j.bind new file mode 100755 index 00000000..d9da8003 Binary files /dev/null and b/system/ep3/maps/m000183p-j.bind differ diff --git a/system/ep3/maps/m000191p_e.bind b/system/ep3/maps/m000191p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000191p_e.bind rename to system/ep3/maps/m000191p-e.bind diff --git a/system/ep3/maps/m000191p-j.bind b/system/ep3/maps/m000191p-j.bind new file mode 100755 index 00000000..9c6c5483 Binary files /dev/null and b/system/ep3/maps/m000191p-j.bind differ diff --git a/system/ep3/maps/m000192p_e.bind b/system/ep3/maps/m000192p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000192p_e.bind rename to system/ep3/maps/m000192p-e.bind diff --git a/system/ep3/maps/m000192p-j.bind b/system/ep3/maps/m000192p-j.bind new file mode 100755 index 00000000..97c177be Binary files /dev/null and b/system/ep3/maps/m000192p-j.bind differ diff --git a/system/ep3/maps/m000193p_e.bind b/system/ep3/maps/m000193p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000193p_e.bind rename to system/ep3/maps/m000193p-e.bind diff --git a/system/ep3/maps/m000193p-j.bind b/system/ep3/maps/m000193p-j.bind new file mode 100755 index 00000000..579f1514 Binary files /dev/null and b/system/ep3/maps/m000193p-j.bind differ diff --git a/system/ep3/maps/m000201p_e.bind b/system/ep3/maps/m000201p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000201p_e.bind rename to system/ep3/maps/m000201p-e.bind diff --git a/system/ep3/maps/m000201p-j.bind b/system/ep3/maps/m000201p-j.bind new file mode 100755 index 00000000..86f71a60 Binary files /dev/null and b/system/ep3/maps/m000201p-j.bind differ diff --git a/system/ep3/maps/m000202p_e.bind b/system/ep3/maps/m000202p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000202p_e.bind rename to system/ep3/maps/m000202p-e.bind diff --git a/system/ep3/maps/m000202p-j.bind b/system/ep3/maps/m000202p-j.bind new file mode 100755 index 00000000..03a5f696 Binary files /dev/null and b/system/ep3/maps/m000202p-j.bind differ diff --git a/system/ep3/maps/m000203p_e.bind b/system/ep3/maps/m000203p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000203p_e.bind rename to system/ep3/maps/m000203p-e.bind diff --git a/system/ep3/maps/m000203p-j.bind b/system/ep3/maps/m000203p-j.bind new file mode 100755 index 00000000..43037792 Binary files /dev/null and b/system/ep3/maps/m000203p-j.bind differ diff --git a/system/ep3/maps/m000204p_e.bind b/system/ep3/maps/m000204p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000204p_e.bind rename to system/ep3/maps/m000204p-e.bind diff --git a/system/ep3/maps/m000204p-j.bind b/system/ep3/maps/m000204p-j.bind new file mode 100755 index 00000000..4f816b98 Binary files /dev/null and b/system/ep3/maps/m000204p-j.bind differ diff --git a/system/ep3/maps/m000211p_e.bind b/system/ep3/maps/m000211p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000211p_e.bind rename to system/ep3/maps/m000211p-e.bind diff --git a/system/ep3/maps/m000211p-j.bind b/system/ep3/maps/m000211p-j.bind new file mode 100755 index 00000000..4e928be0 Binary files /dev/null and b/system/ep3/maps/m000211p-j.bind differ diff --git a/system/ep3/maps/m000221p_e.bind b/system/ep3/maps/m000221p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000221p_e.bind rename to system/ep3/maps/m000221p-e.bind diff --git a/system/ep3/maps/m000221p-j.bind b/system/ep3/maps/m000221p-j.bind new file mode 100755 index 00000000..7e29af32 Binary files /dev/null and b/system/ep3/maps/m000221p-j.bind differ diff --git a/system/ep3/maps/m000222p_e.bind b/system/ep3/maps/m000222p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000222p_e.bind rename to system/ep3/maps/m000222p-e.bind diff --git a/system/ep3/maps/m000222p-j.bind b/system/ep3/maps/m000222p-j.bind new file mode 100755 index 00000000..9804f80a Binary files /dev/null and b/system/ep3/maps/m000222p-j.bind differ diff --git a/system/ep3/maps/m000223p_e.bind b/system/ep3/maps/m000223p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000223p_e.bind rename to system/ep3/maps/m000223p-e.bind diff --git a/system/ep3/maps/m000223p-j.bind b/system/ep3/maps/m000223p-j.bind new file mode 100755 index 00000000..33dbfeee Binary files /dev/null and b/system/ep3/maps/m000223p-j.bind differ diff --git a/system/ep3/maps/m000261p_e.bind b/system/ep3/maps/m000261p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000261p_e.bind rename to system/ep3/maps/m000261p-e.bind diff --git a/system/ep3/maps/m000261p-j.bind b/system/ep3/maps/m000261p-j.bind new file mode 100755 index 00000000..64e245aa Binary files /dev/null and b/system/ep3/maps/m000261p-j.bind differ diff --git a/system/ep3/maps/m000271p_e.bind b/system/ep3/maps/m000271p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000271p_e.bind rename to system/ep3/maps/m000271p-e.bind diff --git a/system/ep3/maps/m000271p-j.bind b/system/ep3/maps/m000271p-j.bind new file mode 100755 index 00000000..dbac81e0 Binary files /dev/null and b/system/ep3/maps/m000271p-j.bind differ diff --git a/system/ep3/maps/m000281p_e.bind b/system/ep3/maps/m000281p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000281p_e.bind rename to system/ep3/maps/m000281p-e.bind diff --git a/system/ep3/maps/m000281p-j.bind b/system/ep3/maps/m000281p-j.bind new file mode 100755 index 00000000..0d89ae51 Binary files /dev/null and b/system/ep3/maps/m000281p-j.bind differ diff --git a/system/ep3/maps/m000282p_e.bind b/system/ep3/maps/m000282p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000282p_e.bind rename to system/ep3/maps/m000282p-e.bind diff --git a/system/ep3/maps/m000282p-j.bind b/system/ep3/maps/m000282p-j.bind new file mode 100755 index 00000000..ddc0b7ca Binary files /dev/null and b/system/ep3/maps/m000282p-j.bind differ diff --git a/system/ep3/maps/m000291p_e.bind b/system/ep3/maps/m000291p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000291p_e.bind rename to system/ep3/maps/m000291p-e.bind diff --git a/system/ep3/maps/m000291p-j.bind b/system/ep3/maps/m000291p-j.bind new file mode 100755 index 00000000..639e8f03 Binary files /dev/null and b/system/ep3/maps/m000291p-j.bind differ diff --git a/system/ep3/maps/m000292p_e.bind b/system/ep3/maps/m000292p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000292p_e.bind rename to system/ep3/maps/m000292p-e.bind diff --git a/system/ep3/maps/m000292p-j.bind b/system/ep3/maps/m000292p-j.bind new file mode 100755 index 00000000..6c8e2048 Binary files /dev/null and b/system/ep3/maps/m000292p-j.bind differ diff --git a/system/ep3/maps/m000293p_e.bind b/system/ep3/maps/m000293p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000293p_e.bind rename to system/ep3/maps/m000293p-e.bind diff --git a/system/ep3/maps/m000293p-j.bind b/system/ep3/maps/m000293p-j.bind new file mode 100755 index 00000000..de2ff0fb Binary files /dev/null and b/system/ep3/maps/m000293p-j.bind differ diff --git a/system/ep3/maps/m000301p_e.bind b/system/ep3/maps/m000301p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000301p_e.bind rename to system/ep3/maps/m000301p-e.bind diff --git a/system/ep3/maps/m000301p-j.bind b/system/ep3/maps/m000301p-j.bind new file mode 100755 index 00000000..ac16f5d1 Binary files /dev/null and b/system/ep3/maps/m000301p-j.bind differ diff --git a/system/ep3/maps/m000302p_e.bind b/system/ep3/maps/m000302p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000302p_e.bind rename to system/ep3/maps/m000302p-e.bind diff --git a/system/ep3/maps/m000302p-j.bind b/system/ep3/maps/m000302p-j.bind new file mode 100755 index 00000000..bc8e20c9 Binary files /dev/null and b/system/ep3/maps/m000302p-j.bind differ diff --git a/system/ep3/maps/m000303p_e.bind b/system/ep3/maps/m000303p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000303p_e.bind rename to system/ep3/maps/m000303p-e.bind diff --git a/system/ep3/maps/m000303p-j.bind b/system/ep3/maps/m000303p-j.bind new file mode 100755 index 00000000..c02bf592 Binary files /dev/null and b/system/ep3/maps/m000303p-j.bind differ diff --git a/system/ep3/maps/m000311p_e.bind b/system/ep3/maps/m000311p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000311p_e.bind rename to system/ep3/maps/m000311p-e.bind diff --git a/system/ep3/maps/m000311p-j.bind b/system/ep3/maps/m000311p-j.bind new file mode 100755 index 00000000..ca680873 Binary files /dev/null and b/system/ep3/maps/m000311p-j.bind differ diff --git a/system/ep3/maps/m000312p_e.bind b/system/ep3/maps/m000312p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000312p_e.bind rename to system/ep3/maps/m000312p-e.bind diff --git a/system/ep3/maps/m000312p-j.bind b/system/ep3/maps/m000312p-j.bind new file mode 100755 index 00000000..da34caf0 Binary files /dev/null and b/system/ep3/maps/m000312p-j.bind differ diff --git a/system/ep3/maps/m000313p_e.bind b/system/ep3/maps/m000313p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000313p_e.bind rename to system/ep3/maps/m000313p-e.bind diff --git a/system/ep3/maps/m000313p-j.bind b/system/ep3/maps/m000313p-j.bind new file mode 100755 index 00000000..39dfb44c Binary files /dev/null and b/system/ep3/maps/m000313p-j.bind differ diff --git a/system/ep3/maps/m000321p_e.bind b/system/ep3/maps/m000321p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000321p_e.bind rename to system/ep3/maps/m000321p-e.bind diff --git a/system/ep3/maps/m000321p-j.bind b/system/ep3/maps/m000321p-j.bind new file mode 100755 index 00000000..9e369bda Binary files /dev/null and b/system/ep3/maps/m000321p-j.bind differ diff --git a/system/ep3/maps/m000322p_e.bind b/system/ep3/maps/m000322p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000322p_e.bind rename to system/ep3/maps/m000322p-e.bind diff --git a/system/ep3/maps/m000322p-j.bind b/system/ep3/maps/m000322p-j.bind new file mode 100755 index 00000000..5f71a769 Binary files /dev/null and b/system/ep3/maps/m000322p-j.bind differ diff --git a/system/ep3/maps/m000323p_e.bind b/system/ep3/maps/m000323p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000323p_e.bind rename to system/ep3/maps/m000323p-e.bind diff --git a/system/ep3/maps/m000323p-j.bind b/system/ep3/maps/m000323p-j.bind new file mode 100755 index 00000000..51074996 Binary files /dev/null and b/system/ep3/maps/m000323p-j.bind differ diff --git a/system/ep3/maps/m000331p_e.bind b/system/ep3/maps/m000331p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000331p_e.bind rename to system/ep3/maps/m000331p-e.bind diff --git a/system/ep3/maps/m000331p-j.bind b/system/ep3/maps/m000331p-j.bind new file mode 100755 index 00000000..19dbd800 Binary files /dev/null and b/system/ep3/maps/m000331p-j.bind differ diff --git a/system/ep3/maps/m000332p_e.bind b/system/ep3/maps/m000332p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000332p_e.bind rename to system/ep3/maps/m000332p-e.bind diff --git a/system/ep3/maps/m000332p-j.bind b/system/ep3/maps/m000332p-j.bind new file mode 100755 index 00000000..c830e057 Binary files /dev/null and b/system/ep3/maps/m000332p-j.bind differ diff --git a/system/ep3/maps/m000333p_e.bind b/system/ep3/maps/m000333p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000333p_e.bind rename to system/ep3/maps/m000333p-e.bind diff --git a/system/ep3/maps/m000333p-j.bind b/system/ep3/maps/m000333p-j.bind new file mode 100755 index 00000000..8996b9c6 Binary files /dev/null and b/system/ep3/maps/m000333p-j.bind differ diff --git a/system/ep3/maps/m000341p_e.bind b/system/ep3/maps/m000341p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000341p_e.bind rename to system/ep3/maps/m000341p-e.bind diff --git a/system/ep3/maps/m000341p-j.bind b/system/ep3/maps/m000341p-j.bind new file mode 100755 index 00000000..bc6c8faa Binary files /dev/null and b/system/ep3/maps/m000341p-j.bind differ diff --git a/system/ep3/maps/m000342p_e.bind b/system/ep3/maps/m000342p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000342p_e.bind rename to system/ep3/maps/m000342p-e.bind diff --git a/system/ep3/maps/m000342p-j.bind b/system/ep3/maps/m000342p-j.bind new file mode 100755 index 00000000..857d8c34 Binary files /dev/null and b/system/ep3/maps/m000342p-j.bind differ diff --git a/system/ep3/maps/m000343p_e.bind b/system/ep3/maps/m000343p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000343p_e.bind rename to system/ep3/maps/m000343p-e.bind diff --git a/system/ep3/maps/m000343p-j.bind b/system/ep3/maps/m000343p-j.bind new file mode 100755 index 00000000..29e8534c Binary files /dev/null and b/system/ep3/maps/m000343p-j.bind differ diff --git a/system/ep3/maps/m000351p_e.bind b/system/ep3/maps/m000351p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000351p_e.bind rename to system/ep3/maps/m000351p-e.bind diff --git a/system/ep3/maps/m000351p-j.bind b/system/ep3/maps/m000351p-j.bind new file mode 100755 index 00000000..2f0d2dd6 Binary files /dev/null and b/system/ep3/maps/m000351p-j.bind differ diff --git a/system/ep3/maps/m000352p_e.bind b/system/ep3/maps/m000352p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000352p_e.bind rename to system/ep3/maps/m000352p-e.bind diff --git a/system/ep3/maps/m000352p-j.bind b/system/ep3/maps/m000352p-j.bind new file mode 100755 index 00000000..1705484c Binary files /dev/null and b/system/ep3/maps/m000352p-j.bind differ diff --git a/system/ep3/maps/m000353p_e.bind b/system/ep3/maps/m000353p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000353p_e.bind rename to system/ep3/maps/m000353p-e.bind diff --git a/system/ep3/maps/m000353p-j.bind b/system/ep3/maps/m000353p-j.bind new file mode 100755 index 00000000..bd3545ec Binary files /dev/null and b/system/ep3/maps/m000353p-j.bind differ diff --git a/system/ep3/maps/m000361p_e.bind b/system/ep3/maps/m000361p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000361p_e.bind rename to system/ep3/maps/m000361p-e.bind diff --git a/system/ep3/maps/m000361p-j.bind b/system/ep3/maps/m000361p-j.bind new file mode 100755 index 00000000..547f9b84 Binary files /dev/null and b/system/ep3/maps/m000361p-j.bind differ diff --git a/system/ep3/maps/m000362p_e.bind b/system/ep3/maps/m000362p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000362p_e.bind rename to system/ep3/maps/m000362p-e.bind diff --git a/system/ep3/maps/m000362p-j.bind b/system/ep3/maps/m000362p-j.bind new file mode 100755 index 00000000..0a017ca7 Binary files /dev/null and b/system/ep3/maps/m000362p-j.bind differ diff --git a/system/ep3/maps/m000363p_e.bind b/system/ep3/maps/m000363p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000363p_e.bind rename to system/ep3/maps/m000363p-e.bind diff --git a/system/ep3/maps/m000363p-j.bind b/system/ep3/maps/m000363p-j.bind new file mode 100755 index 00000000..4a0c27cc Binary files /dev/null and b/system/ep3/maps/m000363p-j.bind differ diff --git a/system/ep3/maps/m000371p_e.bind b/system/ep3/maps/m000371p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000371p_e.bind rename to system/ep3/maps/m000371p-e.bind diff --git a/system/ep3/maps/m000371p-j.bind b/system/ep3/maps/m000371p-j.bind new file mode 100755 index 00000000..28b0cd20 Binary files /dev/null and b/system/ep3/maps/m000371p-j.bind differ diff --git a/system/ep3/maps/m000372p_e.bind b/system/ep3/maps/m000372p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000372p_e.bind rename to system/ep3/maps/m000372p-e.bind diff --git a/system/ep3/maps/m000372p-j.bind b/system/ep3/maps/m000372p-j.bind new file mode 100755 index 00000000..ed9bf2e2 Binary files /dev/null and b/system/ep3/maps/m000372p-j.bind differ diff --git a/system/ep3/maps/m000373p_e.bind b/system/ep3/maps/m000373p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000373p_e.bind rename to system/ep3/maps/m000373p-e.bind diff --git a/system/ep3/maps/m000373p-j.bind b/system/ep3/maps/m000373p-j.bind new file mode 100755 index 00000000..433641f9 Binary files /dev/null and b/system/ep3/maps/m000373p-j.bind differ diff --git a/system/ep3/maps/m000381p_e.bind b/system/ep3/maps/m000381p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000381p_e.bind rename to system/ep3/maps/m000381p-e.bind diff --git a/system/ep3/maps/m000381p-j.bind b/system/ep3/maps/m000381p-j.bind new file mode 100755 index 00000000..dc417bc5 Binary files /dev/null and b/system/ep3/maps/m000381p-j.bind differ diff --git a/system/ep3/maps/m000391p_e.bind b/system/ep3/maps/m000391p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000391p_e.bind rename to system/ep3/maps/m000391p-e.bind diff --git a/system/ep3/maps/m000391p-j.bind b/system/ep3/maps/m000391p-j.bind new file mode 100755 index 00000000..e5f5fc9c Binary files /dev/null and b/system/ep3/maps/m000391p-j.bind differ diff --git a/system/ep3/maps/m000392p_e.bind b/system/ep3/maps/m000392p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000392p_e.bind rename to system/ep3/maps/m000392p-e.bind diff --git a/system/ep3/maps/m000392p-j.bind b/system/ep3/maps/m000392p-j.bind new file mode 100755 index 00000000..623012ce Binary files /dev/null and b/system/ep3/maps/m000392p-j.bind differ diff --git a/system/ep3/maps/m000393p_e.bind b/system/ep3/maps/m000393p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000393p_e.bind rename to system/ep3/maps/m000393p-e.bind diff --git a/system/ep3/maps/m000393p-j.bind b/system/ep3/maps/m000393p-j.bind new file mode 100755 index 00000000..cae3aded Binary files /dev/null and b/system/ep3/maps/m000393p-j.bind differ diff --git a/system/ep3/maps/m000401p_e.bind b/system/ep3/maps/m000401p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000401p_e.bind rename to system/ep3/maps/m000401p-e.bind diff --git a/system/ep3/maps/m000401p-j.bind b/system/ep3/maps/m000401p-j.bind new file mode 100755 index 00000000..1f4827b7 Binary files /dev/null and b/system/ep3/maps/m000401p-j.bind differ diff --git a/system/ep3/maps/m000402p_e.bind b/system/ep3/maps/m000402p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000402p_e.bind rename to system/ep3/maps/m000402p-e.bind diff --git a/system/ep3/maps/m000402p-j.bind b/system/ep3/maps/m000402p-j.bind new file mode 100755 index 00000000..0fd2876a Binary files /dev/null and b/system/ep3/maps/m000402p-j.bind differ diff --git a/system/ep3/maps/m000403p_e.bind b/system/ep3/maps/m000403p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000403p_e.bind rename to system/ep3/maps/m000403p-e.bind diff --git a/system/ep3/maps/m000403p-j.bind b/system/ep3/maps/m000403p-j.bind new file mode 100755 index 00000000..8531f64b Binary files /dev/null and b/system/ep3/maps/m000403p-j.bind differ diff --git a/system/ep3/maps/m000411p_e.bind b/system/ep3/maps/m000411p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000411p_e.bind rename to system/ep3/maps/m000411p-e.bind diff --git a/system/ep3/maps/m000411p-j.bind b/system/ep3/maps/m000411p-j.bind new file mode 100755 index 00000000..d38e4c9e Binary files /dev/null and b/system/ep3/maps/m000411p-j.bind differ diff --git a/system/ep3/maps/m000412p_e.bind b/system/ep3/maps/m000412p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000412p_e.bind rename to system/ep3/maps/m000412p-e.bind diff --git a/system/ep3/maps/m000412p-j.bind b/system/ep3/maps/m000412p-j.bind new file mode 100755 index 00000000..f86d09b4 Binary files /dev/null and b/system/ep3/maps/m000412p-j.bind differ diff --git a/system/ep3/maps/m000413p_e.bind b/system/ep3/maps/m000413p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000413p_e.bind rename to system/ep3/maps/m000413p-e.bind diff --git a/system/ep3/maps/m000413p-j.bind b/system/ep3/maps/m000413p-j.bind new file mode 100755 index 00000000..a8dc449e Binary files /dev/null and b/system/ep3/maps/m000413p-j.bind differ diff --git a/system/ep3/maps/m000421p_e.bind b/system/ep3/maps/m000421p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000421p_e.bind rename to system/ep3/maps/m000421p-e.bind diff --git a/system/ep3/maps/m000421p-j.bind b/system/ep3/maps/m000421p-j.bind new file mode 100755 index 00000000..70af9e6d Binary files /dev/null and b/system/ep3/maps/m000421p-j.bind differ diff --git a/system/ep3/maps/m000422p_e.bind b/system/ep3/maps/m000422p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000422p_e.bind rename to system/ep3/maps/m000422p-e.bind diff --git a/system/ep3/maps/m000422p-j.bind b/system/ep3/maps/m000422p-j.bind new file mode 100755 index 00000000..4546067e Binary files /dev/null and b/system/ep3/maps/m000422p-j.bind differ diff --git a/system/ep3/maps/m000423p_e.bind b/system/ep3/maps/m000423p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000423p_e.bind rename to system/ep3/maps/m000423p-e.bind diff --git a/system/ep3/maps/m000423p-j.bind b/system/ep3/maps/m000423p-j.bind new file mode 100755 index 00000000..4a8687b9 Binary files /dev/null and b/system/ep3/maps/m000423p-j.bind differ diff --git a/system/ep3/maps/m000431p_e.bind b/system/ep3/maps/m000431p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000431p_e.bind rename to system/ep3/maps/m000431p-e.bind diff --git a/system/ep3/maps/m000431p-j.bind b/system/ep3/maps/m000431p-j.bind new file mode 100755 index 00000000..3b629af6 Binary files /dev/null and b/system/ep3/maps/m000431p-j.bind differ diff --git a/system/ep3/maps/m000432p_e.bind b/system/ep3/maps/m000432p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000432p_e.bind rename to system/ep3/maps/m000432p-e.bind diff --git a/system/ep3/maps/m000432p-j.bind b/system/ep3/maps/m000432p-j.bind new file mode 100755 index 00000000..4a35fb5b Binary files /dev/null and b/system/ep3/maps/m000432p-j.bind differ diff --git a/system/ep3/maps/m000433p_e.bind b/system/ep3/maps/m000433p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000433p_e.bind rename to system/ep3/maps/m000433p-e.bind diff --git a/system/ep3/maps/m000433p-j.bind b/system/ep3/maps/m000433p-j.bind new file mode 100755 index 00000000..870ba25a Binary files /dev/null and b/system/ep3/maps/m000433p-j.bind differ diff --git a/system/ep3/maps/m000441p_e.bind b/system/ep3/maps/m000441p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000441p_e.bind rename to system/ep3/maps/m000441p-e.bind diff --git a/system/ep3/maps/m000441p-j.bind b/system/ep3/maps/m000441p-j.bind new file mode 100755 index 00000000..5ea64f68 Binary files /dev/null and b/system/ep3/maps/m000441p-j.bind differ diff --git a/system/ep3/maps/m000442p_e.bind b/system/ep3/maps/m000442p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000442p_e.bind rename to system/ep3/maps/m000442p-e.bind diff --git a/system/ep3/maps/m000442p-j.bind b/system/ep3/maps/m000442p-j.bind new file mode 100755 index 00000000..71992b99 Binary files /dev/null and b/system/ep3/maps/m000442p-j.bind differ diff --git a/system/ep3/maps/m000443p_e.bind b/system/ep3/maps/m000443p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000443p_e.bind rename to system/ep3/maps/m000443p-e.bind diff --git a/system/ep3/maps/m000443p-j.bind b/system/ep3/maps/m000443p-j.bind new file mode 100755 index 00000000..1039e975 Binary files /dev/null and b/system/ep3/maps/m000443p-j.bind differ diff --git a/system/ep3/maps/m000451p_e.bind b/system/ep3/maps/m000451p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000451p_e.bind rename to system/ep3/maps/m000451p-e.bind diff --git a/system/ep3/maps/m000451p-j.bind b/system/ep3/maps/m000451p-j.bind new file mode 100755 index 00000000..ef26ff46 Binary files /dev/null and b/system/ep3/maps/m000451p-j.bind differ diff --git a/system/ep3/maps/m000452p_e.bind b/system/ep3/maps/m000452p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000452p_e.bind rename to system/ep3/maps/m000452p-e.bind diff --git a/system/ep3/maps/m000452p-j.bind b/system/ep3/maps/m000452p-j.bind new file mode 100755 index 00000000..32839f7f Binary files /dev/null and b/system/ep3/maps/m000452p-j.bind differ diff --git a/system/ep3/maps/m000453p_e.bind b/system/ep3/maps/m000453p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000453p_e.bind rename to system/ep3/maps/m000453p-e.bind diff --git a/system/ep3/maps/m000453p-j.bind b/system/ep3/maps/m000453p-j.bind new file mode 100755 index 00000000..f0c5f2f3 Binary files /dev/null and b/system/ep3/maps/m000453p-j.bind differ diff --git a/system/ep3/maps/m000461p_e.bind b/system/ep3/maps/m000461p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000461p_e.bind rename to system/ep3/maps/m000461p-e.bind diff --git a/system/ep3/maps/m000461p-j.bind b/system/ep3/maps/m000461p-j.bind new file mode 100755 index 00000000..24d79c57 Binary files /dev/null and b/system/ep3/maps/m000461p-j.bind differ diff --git a/system/ep3/maps/m000471p_e.bind b/system/ep3/maps/m000471p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000471p_e.bind rename to system/ep3/maps/m000471p-e.bind diff --git a/system/ep3/maps/m000471p-j.bind b/system/ep3/maps/m000471p-j.bind new file mode 100755 index 00000000..1b1dd050 Binary files /dev/null and b/system/ep3/maps/m000471p-j.bind differ diff --git a/system/ep3/maps/m000472p_e.bind b/system/ep3/maps/m000472p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000472p_e.bind rename to system/ep3/maps/m000472p-e.bind diff --git a/system/ep3/maps/m000472p-j.bind b/system/ep3/maps/m000472p-j.bind new file mode 100755 index 00000000..5136882a Binary files /dev/null and b/system/ep3/maps/m000472p-j.bind differ diff --git a/system/ep3/maps/m000473p_e.bind b/system/ep3/maps/m000473p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000473p_e.bind rename to system/ep3/maps/m000473p-e.bind diff --git a/system/ep3/maps/m000473p-j.bind b/system/ep3/maps/m000473p-j.bind new file mode 100755 index 00000000..5764ed24 Binary files /dev/null and b/system/ep3/maps/m000473p-j.bind differ diff --git a/system/ep3/maps/m000501p_e.bind b/system/ep3/maps/m000501p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000501p_e.bind rename to system/ep3/maps/m000501p-e.bind diff --git a/system/ep3/maps/m000501p-j.bind b/system/ep3/maps/m000501p-j.bind new file mode 100755 index 00000000..7855bdb3 Binary files /dev/null and b/system/ep3/maps/m000501p-j.bind differ diff --git a/system/ep3/maps/m000502p_e.bind b/system/ep3/maps/m000502p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000502p_e.bind rename to system/ep3/maps/m000502p-e.bind diff --git a/system/ep3/maps/m000502p-j.bind b/system/ep3/maps/m000502p-j.bind new file mode 100755 index 00000000..63163db8 Binary files /dev/null and b/system/ep3/maps/m000502p-j.bind differ diff --git a/system/ep3/maps/m000503p_e.bind b/system/ep3/maps/m000503p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000503p_e.bind rename to system/ep3/maps/m000503p-e.bind diff --git a/system/ep3/maps/m000503p-j.bind b/system/ep3/maps/m000503p-j.bind new file mode 100755 index 00000000..97f51657 Binary files /dev/null and b/system/ep3/maps/m000503p-j.bind differ diff --git a/system/ep3/maps/m000504p_e.bind b/system/ep3/maps/m000504p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000504p_e.bind rename to system/ep3/maps/m000504p-e.bind diff --git a/system/ep3/maps/m000504p-j.bind b/system/ep3/maps/m000504p-j.bind new file mode 100755 index 00000000..77153ca2 Binary files /dev/null and b/system/ep3/maps/m000504p-j.bind differ diff --git a/system/ep3/maps/m000505p_e.bind b/system/ep3/maps/m000505p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000505p_e.bind rename to system/ep3/maps/m000505p-e.bind diff --git a/system/ep3/maps/m000505p-j.bind b/system/ep3/maps/m000505p-j.bind new file mode 100755 index 00000000..8817dafd Binary files /dev/null and b/system/ep3/maps/m000505p-j.bind differ diff --git a/system/ep3/maps/m000506p_e.bind b/system/ep3/maps/m000506p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000506p_e.bind rename to system/ep3/maps/m000506p-e.bind diff --git a/system/ep3/maps/m000506p-j.bind b/system/ep3/maps/m000506p-j.bind new file mode 100755 index 00000000..cd6facab Binary files /dev/null and b/system/ep3/maps/m000506p-j.bind differ diff --git a/system/ep3/maps/m000507p_e.bind b/system/ep3/maps/m000507p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000507p_e.bind rename to system/ep3/maps/m000507p-e.bind diff --git a/system/ep3/maps/m000507p-j.bind b/system/ep3/maps/m000507p-j.bind new file mode 100755 index 00000000..92d51ee8 Binary files /dev/null and b/system/ep3/maps/m000507p-j.bind differ diff --git a/system/ep3/maps/m000508p_e.bind b/system/ep3/maps/m000508p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000508p_e.bind rename to system/ep3/maps/m000508p-e.bind diff --git a/system/ep3/maps/m000508p-j.bind b/system/ep3/maps/m000508p-j.bind new file mode 100755 index 00000000..61a94307 Binary files /dev/null and b/system/ep3/maps/m000508p-j.bind differ diff --git a/system/ep3/maps/m000509p_e.bind b/system/ep3/maps/m000509p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000509p_e.bind rename to system/ep3/maps/m000509p-e.bind diff --git a/system/ep3/maps/m000509p-j.bind b/system/ep3/maps/m000509p-j.bind new file mode 100755 index 00000000..6ffe8540 Binary files /dev/null and b/system/ep3/maps/m000509p-j.bind differ diff --git a/system/ep3/maps/m000510p_e.bind b/system/ep3/maps/m000510p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000510p_e.bind rename to system/ep3/maps/m000510p-e.bind diff --git a/system/ep3/maps/m000510p-j.bind b/system/ep3/maps/m000510p-j.bind new file mode 100755 index 00000000..325ee9e7 Binary files /dev/null and b/system/ep3/maps/m000510p-j.bind differ diff --git a/system/ep3/maps/m000511p_e.bind b/system/ep3/maps/m000511p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000511p_e.bind rename to system/ep3/maps/m000511p-e.bind diff --git a/system/ep3/maps/m000511p-j.bind b/system/ep3/maps/m000511p-j.bind new file mode 100755 index 00000000..664e5a81 Binary files /dev/null and b/system/ep3/maps/m000511p-j.bind differ diff --git a/system/ep3/maps/m000512p-e.bind b/system/ep3/maps/m000512p-e.bind new file mode 100644 index 00000000..19769871 Binary files /dev/null and b/system/ep3/maps/m000512p-e.bind differ diff --git a/system/ep3/maps/m000512p-j.bind b/system/ep3/maps/m000512p-j.bind new file mode 100755 index 00000000..19769871 Binary files /dev/null and b/system/ep3/maps/m000512p-j.bind differ diff --git a/system/ep3/maps/m000513p_e.bind b/system/ep3/maps/m000513p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000513p_e.bind rename to system/ep3/maps/m000513p-e.bind diff --git a/system/ep3/maps/m000513p-j.bind b/system/ep3/maps/m000513p-j.bind new file mode 100755 index 00000000..d4c0b800 Binary files /dev/null and b/system/ep3/maps/m000513p-j.bind differ diff --git a/system/ep3/maps/m000514p_e.bind b/system/ep3/maps/m000514p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000514p_e.bind rename to system/ep3/maps/m000514p-e.bind diff --git a/system/ep3/maps/m000514p-j.bind b/system/ep3/maps/m000514p-j.bind new file mode 100755 index 00000000..aa2edb74 Binary files /dev/null and b/system/ep3/maps/m000514p-j.bind differ diff --git a/system/ep3/maps/m000515p_e.bind b/system/ep3/maps/m000515p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000515p_e.bind rename to system/ep3/maps/m000515p-e.bind diff --git a/system/ep3/maps/m000515p-j.bind b/system/ep3/maps/m000515p-j.bind new file mode 100755 index 00000000..a1124294 Binary files /dev/null and b/system/ep3/maps/m000515p-j.bind differ diff --git a/system/ep3/maps/m000516p_e.bind b/system/ep3/maps/m000516p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000516p_e.bind rename to system/ep3/maps/m000516p-e.bind diff --git a/system/ep3/maps/m000512p_e.bind b/system/ep3/maps/m000516p-j.bind similarity index 74% rename from system/ep3/maps/m000512p_e.bind rename to system/ep3/maps/m000516p-j.bind index e7f5a790..098cb196 100755 Binary files a/system/ep3/maps/m000512p_e.bind and b/system/ep3/maps/m000516p-j.bind differ diff --git a/system/ep3/maps/m000517p_e.bind b/system/ep3/maps/m000517p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000517p_e.bind rename to system/ep3/maps/m000517p-e.bind diff --git a/system/ep3/maps/m000517p-j.bind b/system/ep3/maps/m000517p-j.bind new file mode 100755 index 00000000..da7c3e7c Binary files /dev/null and b/system/ep3/maps/m000517p-j.bind differ diff --git a/system/ep3/maps/m000518p_e.bind b/system/ep3/maps/m000518p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000518p_e.bind rename to system/ep3/maps/m000518p-e.bind diff --git a/system/ep3/maps/m000518p-j.bind b/system/ep3/maps/m000518p-j.bind new file mode 100755 index 00000000..13204a31 Binary files /dev/null and b/system/ep3/maps/m000518p-j.bind differ diff --git a/system/ep3/maps/m000519p_e.bind b/system/ep3/maps/m000519p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000519p_e.bind rename to system/ep3/maps/m000519p-e.bind diff --git a/system/ep3/maps/m000519p-j.bind b/system/ep3/maps/m000519p-j.bind new file mode 100755 index 00000000..eeff4927 Binary files /dev/null and b/system/ep3/maps/m000519p-j.bind differ diff --git a/system/ep3/maps/m000521p_e.bind b/system/ep3/maps/m000521p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000521p_e.bind rename to system/ep3/maps/m000521p-e.bind diff --git a/system/ep3/maps/m000521p-j.bind b/system/ep3/maps/m000521p-j.bind new file mode 100755 index 00000000..eb4b46e6 Binary files /dev/null and b/system/ep3/maps/m000521p-j.bind differ diff --git a/system/ep3/maps/m000522p_e.bind b/system/ep3/maps/m000522p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000522p_e.bind rename to system/ep3/maps/m000522p-e.bind diff --git a/system/ep3/maps/m000522p-j.bind b/system/ep3/maps/m000522p-j.bind new file mode 100755 index 00000000..dc14fe97 Binary files /dev/null and b/system/ep3/maps/m000522p-j.bind differ diff --git a/system/ep3/maps/m000523p_e.bind b/system/ep3/maps/m000523p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000523p_e.bind rename to system/ep3/maps/m000523p-e.bind diff --git a/system/ep3/maps/m000523p-j.bind b/system/ep3/maps/m000523p-j.bind new file mode 100755 index 00000000..f211b46d Binary files /dev/null and b/system/ep3/maps/m000523p-j.bind differ diff --git a/system/ep3/maps/m000524p_e.bind b/system/ep3/maps/m000524p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000524p_e.bind rename to system/ep3/maps/m000524p-e.bind diff --git a/system/ep3/maps/m000524p-j.bind b/system/ep3/maps/m000524p-j.bind new file mode 100755 index 00000000..fff1e1a3 Binary files /dev/null and b/system/ep3/maps/m000524p-j.bind differ diff --git a/system/ep3/maps/m000525p_e.bind b/system/ep3/maps/m000525p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000525p_e.bind rename to system/ep3/maps/m000525p-e.bind diff --git a/system/ep3/maps/m000525p-j.bind b/system/ep3/maps/m000525p-j.bind new file mode 100755 index 00000000..0ffa5bdd Binary files /dev/null and b/system/ep3/maps/m000525p-j.bind differ diff --git a/system/ep3/maps/m000526p_e.bind b/system/ep3/maps/m000526p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000526p_e.bind rename to system/ep3/maps/m000526p-e.bind diff --git a/system/ep3/maps/m000526p-j.bind b/system/ep3/maps/m000526p-j.bind new file mode 100755 index 00000000..3c7e5545 Binary files /dev/null and b/system/ep3/maps/m000526p-j.bind differ diff --git a/system/ep3/maps/m000527p_e.bind b/system/ep3/maps/m000527p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000527p_e.bind rename to system/ep3/maps/m000527p-e.bind diff --git a/system/ep3/maps/m000527p-j.bind b/system/ep3/maps/m000527p-j.bind new file mode 100755 index 00000000..82788e08 Binary files /dev/null and b/system/ep3/maps/m000527p-j.bind differ diff --git a/system/ep3/maps/m000528p_e.bind b/system/ep3/maps/m000528p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000528p_e.bind rename to system/ep3/maps/m000528p-e.bind diff --git a/system/ep3/maps/m000528p-j.bind b/system/ep3/maps/m000528p-j.bind new file mode 100755 index 00000000..e0fcd11b Binary files /dev/null and b/system/ep3/maps/m000528p-j.bind differ diff --git a/system/ep3/maps/m000529p_e.bind b/system/ep3/maps/m000529p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000529p_e.bind rename to system/ep3/maps/m000529p-e.bind diff --git a/system/ep3/maps/m000529p-j.bind b/system/ep3/maps/m000529p-j.bind new file mode 100755 index 00000000..180873a8 Binary files /dev/null and b/system/ep3/maps/m000529p-j.bind differ diff --git a/system/ep3/maps/m000530p_e.bind b/system/ep3/maps/m000530p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000530p_e.bind rename to system/ep3/maps/m000530p-e.bind diff --git a/system/ep3/maps/m000530p-j.bind b/system/ep3/maps/m000530p-j.bind new file mode 100755 index 00000000..9dabcd3d Binary files /dev/null and b/system/ep3/maps/m000530p-j.bind differ diff --git a/system/ep3/maps/m000531p_e.bind b/system/ep3/maps/m000531p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000531p_e.bind rename to system/ep3/maps/m000531p-e.bind diff --git a/system/ep3/maps/m000531p-j.bind b/system/ep3/maps/m000531p-j.bind new file mode 100755 index 00000000..8689e8d3 Binary files /dev/null and b/system/ep3/maps/m000531p-j.bind differ diff --git a/system/ep3/maps/m000532p_e.bind b/system/ep3/maps/m000532p-e.bind old mode 100755 new mode 100644 similarity index 99% rename from system/ep3/maps/m000532p_e.bind rename to system/ep3/maps/m000532p-e.bind index 1b616999..a6669456 Binary files a/system/ep3/maps/m000532p_e.bind and b/system/ep3/maps/m000532p-e.bind differ diff --git a/system/ep3/maps/m000532p-j.bind b/system/ep3/maps/m000532p-j.bind new file mode 100755 index 00000000..a6669456 Binary files /dev/null and b/system/ep3/maps/m000532p-j.bind differ diff --git a/system/ep3/maps/m000533p_e.bind b/system/ep3/maps/m000533p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000533p_e.bind rename to system/ep3/maps/m000533p-e.bind diff --git a/system/ep3/maps/m000533p-j.bind b/system/ep3/maps/m000533p-j.bind new file mode 100755 index 00000000..e7e299c0 Binary files /dev/null and b/system/ep3/maps/m000533p-j.bind differ diff --git a/system/ep3/maps/m000534p_e.bind b/system/ep3/maps/m000534p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000534p_e.bind rename to system/ep3/maps/m000534p-e.bind diff --git a/system/ep3/maps/m000534p-j.bind b/system/ep3/maps/m000534p-j.bind new file mode 100755 index 00000000..6ac1fc18 Binary files /dev/null and b/system/ep3/maps/m000534p-j.bind differ diff --git a/system/ep3/maps/m000535p_e.bind b/system/ep3/maps/m000535p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000535p_e.bind rename to system/ep3/maps/m000535p-e.bind diff --git a/system/ep3/maps/m000535p-j.bind b/system/ep3/maps/m000535p-j.bind new file mode 100755 index 00000000..464c6647 Binary files /dev/null and b/system/ep3/maps/m000535p-j.bind differ diff --git a/system/ep3/maps/m000536p_e.bind b/system/ep3/maps/m000536p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000536p_e.bind rename to system/ep3/maps/m000536p-e.bind diff --git a/system/ep3/maps/m000536p-j.bind b/system/ep3/maps/m000536p-j.bind new file mode 100755 index 00000000..48c78d5f Binary files /dev/null and b/system/ep3/maps/m000536p-j.bind differ diff --git a/system/ep3/maps/m000537p_e.bind b/system/ep3/maps/m000537p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000537p_e.bind rename to system/ep3/maps/m000537p-e.bind diff --git a/system/ep3/maps/m000537p-j.bind b/system/ep3/maps/m000537p-j.bind new file mode 100755 index 00000000..df0c4e51 Binary files /dev/null and b/system/ep3/maps/m000537p-j.bind differ diff --git a/system/ep3/maps/m000538p_e.bind b/system/ep3/maps/m000538p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000538p_e.bind rename to system/ep3/maps/m000538p-e.bind diff --git a/system/ep3/maps/m000538p-j.bind b/system/ep3/maps/m000538p-j.bind new file mode 100755 index 00000000..3ec9783a Binary files /dev/null and b/system/ep3/maps/m000538p-j.bind differ diff --git a/system/ep3/maps/m000539p_e.bind b/system/ep3/maps/m000539p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000539p_e.bind rename to system/ep3/maps/m000539p-e.bind diff --git a/system/ep3/maps/m000539p-j.bind b/system/ep3/maps/m000539p-j.bind new file mode 100755 index 00000000..5e4a7002 Binary files /dev/null and b/system/ep3/maps/m000539p-j.bind differ diff --git a/system/ep3/maps/m000550p_e.bind b/system/ep3/maps/m000550p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000550p_e.bind rename to system/ep3/maps/m000550p-e.bind diff --git a/system/ep3/maps/m000550p-j.bind b/system/ep3/maps/m000550p-j.bind new file mode 100755 index 00000000..c8e4d24e Binary files /dev/null and b/system/ep3/maps/m000550p-j.bind differ diff --git a/system/ep3/maps/m000551p_e.bind b/system/ep3/maps/m000551p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000551p_e.bind rename to system/ep3/maps/m000551p-e.bind diff --git a/system/ep3/maps/m000551p-j.bind b/system/ep3/maps/m000551p-j.bind new file mode 100755 index 00000000..172e3a4a Binary files /dev/null and b/system/ep3/maps/m000551p-j.bind differ diff --git a/system/ep3/maps/m000552p_e.bind b/system/ep3/maps/m000552p-e.bind old mode 100755 new mode 100644 similarity index 100% rename from system/ep3/maps/m000552p_e.bind rename to system/ep3/maps/m000552p-e.bind diff --git a/system/ep3/maps/m000552p-j.bind b/system/ep3/maps/m000552p-j.bind new file mode 100755 index 00000000..d066e2e2 Binary files /dev/null and b/system/ep3/maps/m000552p-j.bind differ diff --git a/system/ep3/maps/m000601p-j.bind b/system/ep3/maps/m000601p-j.bind new file mode 100755 index 00000000..de531c26 Binary files /dev/null and b/system/ep3/maps/m000601p-j.bind differ diff --git a/system/ep3/maps/m000602p-j.bind b/system/ep3/maps/m000602p-j.bind new file mode 100755 index 00000000..4dd57dfa Binary files /dev/null and b/system/ep3/maps/m000602p-j.bind differ diff --git a/system/ep3/maps/m000603p-j.bind b/system/ep3/maps/m000603p-j.bind new file mode 100755 index 00000000..27d9e2e9 Binary files /dev/null and b/system/ep3/maps/m000603p-j.bind differ diff --git a/system/ep3/maps/m000604p-j.bind b/system/ep3/maps/m000604p-j.bind new file mode 100755 index 00000000..2dff3473 Binary files /dev/null and b/system/ep3/maps/m000604p-j.bind differ diff --git a/system/ep3/maps/m000605p-j.bind b/system/ep3/maps/m000605p-j.bind new file mode 100755 index 00000000..ee8c7a55 Binary files /dev/null and b/system/ep3/maps/m000605p-j.bind differ diff --git a/system/ep3/maps/m000606p-j.bind b/system/ep3/maps/m000606p-j.bind new file mode 100755 index 00000000..3a19ebf1 Binary files /dev/null and b/system/ep3/maps/m000606p-j.bind differ diff --git a/system/ep3/maps/m000607p-j.bind b/system/ep3/maps/m000607p-j.bind new file mode 100755 index 00000000..209a747a Binary files /dev/null and b/system/ep3/maps/m000607p-j.bind differ diff --git a/system/ep3/maps/m000608p-j.bind b/system/ep3/maps/m000608p-j.bind new file mode 100755 index 00000000..c0ba0ef4 Binary files /dev/null and b/system/ep3/maps/m000608p-j.bind differ diff --git a/system/ep3/maps/m000609p-j.bind b/system/ep3/maps/m000609p-j.bind new file mode 100755 index 00000000..898f8d1c Binary files /dev/null and b/system/ep3/maps/m000609p-j.bind differ diff --git a/system/ep3/maps/m000610p-j.bind b/system/ep3/maps/m000610p-j.bind new file mode 100755 index 00000000..568e532c Binary files /dev/null and b/system/ep3/maps/m000610p-j.bind differ diff --git a/system/ep3/maps/m000613p-j.bind b/system/ep3/maps/m000613p-j.bind new file mode 100755 index 00000000..0b9f5258 Binary files /dev/null and b/system/ep3/maps/m000613p-j.bind differ diff --git a/system/ep3/maps/m000614p-j.bind b/system/ep3/maps/m000614p-j.bind new file mode 100755 index 00000000..49742e9e Binary files /dev/null and b/system/ep3/maps/m000614p-j.bind differ diff --git a/system/ep3/maps/m000615p-j.bind b/system/ep3/maps/m000615p-j.bind new file mode 100755 index 00000000..8de36fc7 Binary files /dev/null and b/system/ep3/maps/m000615p-j.bind differ diff --git a/system/ep3/maps/m000616p-j.bind b/system/ep3/maps/m000616p-j.bind new file mode 100755 index 00000000..b8f090c8 Binary files /dev/null and b/system/ep3/maps/m000616p-j.bind differ diff --git a/system/ep3/maps/m000618p-j.bind b/system/ep3/maps/m000618p-j.bind new file mode 100755 index 00000000..389c702d Binary files /dev/null and b/system/ep3/maps/m000618p-j.bind differ diff --git a/system/ep3/maps/m000619p-j.bind b/system/ep3/maps/m000619p-j.bind new file mode 100755 index 00000000..e3b09321 Binary files /dev/null and b/system/ep3/maps/m000619p-j.bind differ diff --git a/system/ep3/maps/m000999p-j.bind b/system/ep3/maps/m000999p-j.bind new file mode 100755 index 00000000..364cf85e Binary files /dev/null and b/system/ep3/maps/m000999p-j.bind differ diff --git a/system/ep3/maps/map00000230.mnmd b/system/ep3/maps/map00000230-e.mnmd similarity index 100% rename from system/ep3/maps/map00000230.mnmd rename to system/ep3/maps/map00000230-e.mnmd diff --git a/system/ep3/maps/map00000244.mnmd b/system/ep3/maps/map00000244-e.mnmd similarity index 100% rename from system/ep3/maps/map00000244.mnmd rename to system/ep3/maps/map00000244-e.mnmd diff --git a/system/ep3/maps/map00000258.mnmd b/system/ep3/maps/map00000258-e.mnmd similarity index 100% rename from system/ep3/maps/map00000258.mnmd rename to system/ep3/maps/map00000258-e.mnmd diff --git a/system/ep3/maps/map0000026C.mnmd b/system/ep3/maps/map0000026C-e.mnmd similarity index 100% rename from system/ep3/maps/map0000026C.mnmd rename to system/ep3/maps/map0000026C-e.mnmd diff --git a/system/ep3/maps/map00000280.mnmd b/system/ep3/maps/map00000280-e.mnmd similarity index 100% rename from system/ep3/maps/map00000280.mnmd rename to system/ep3/maps/map00000280-e.mnmd diff --git a/system/ep3/maps/map00000294.mnmd b/system/ep3/maps/map00000294-e.mnmd similarity index 100% rename from system/ep3/maps/map00000294.mnmd rename to system/ep3/maps/map00000294-e.mnmd diff --git a/system/ep3/maps/map000002A8.mnmd b/system/ep3/maps/map000002A8-e.mnmd similarity index 100% rename from system/ep3/maps/map000002A8.mnmd rename to system/ep3/maps/map000002A8-e.mnmd diff --git a/system/ep3/maps/map000002BC.mnmd b/system/ep3/maps/map000002BC-e.mnmd similarity index 100% rename from system/ep3/maps/map000002BC.mnmd rename to system/ep3/maps/map000002BC-e.mnmd diff --git a/system/ep3/maps/map000002BD.mnmd b/system/ep3/maps/map000002BD-e.mnmd similarity index 100% rename from system/ep3/maps/map000002BD.mnmd rename to system/ep3/maps/map000002BD-e.mnmd diff --git a/system/ep3/maps/map000002E4.mnmd b/system/ep3/maps/map000002E4-e.mnmd similarity index 100% rename from system/ep3/maps/map000002E4.mnmd rename to system/ep3/maps/map000002E4-e.mnmd diff --git a/system/ep3/maps/map000002F8.mnmd b/system/ep3/maps/map000002F8-e.mnmd similarity index 100% rename from system/ep3/maps/map000002F8.mnmd rename to system/ep3/maps/map000002F8-e.mnmd diff --git a/system/ep3/maps/map000002F9.mnmd b/system/ep3/maps/map000002F9-e.mnmd similarity index 100% rename from system/ep3/maps/map000002F9.mnmd rename to system/ep3/maps/map000002F9-e.mnmd diff --git a/system/ep3/maps/map00000320.mnmd b/system/ep3/maps/map00000320-e.mnmd similarity index 100% rename from system/ep3/maps/map00000320.mnmd rename to system/ep3/maps/map00000320-e.mnmd diff --git a/system/ep3/maps/map00000334.mnmd b/system/ep3/maps/map00000334-e.mnmd similarity index 100% rename from system/ep3/maps/map00000334.mnmd rename to system/ep3/maps/map00000334-e.mnmd diff --git a/system/quests/b88001-bb.bin b/system/quests/b88001-bb-e.bin similarity index 100% rename from system/quests/b88001-bb.bin rename to system/quests/b88001-bb-e.bin diff --git a/system/quests/b88001-dc.bin b/system/quests/b88001-dc-e.bin similarity index 100% rename from system/quests/b88001-dc.bin rename to system/quests/b88001-dc-e.bin diff --git a/system/quests/b88001-gc.bin b/system/quests/b88001-gc-e.bin similarity index 100% rename from system/quests/b88001-gc.bin rename to system/quests/b88001-gc-e.bin diff --git a/system/quests/b88001-pc.bin b/system/quests/b88001-pc-e.bin similarity index 100% rename from system/quests/b88001-pc.bin rename to system/quests/b88001-pc-e.bin diff --git a/system/quests/b88002-bb.bin b/system/quests/b88002-bb-e.bin similarity index 100% rename from system/quests/b88002-bb.bin rename to system/quests/b88002-bb-e.bin diff --git a/system/quests/b88002-dc.bin b/system/quests/b88002-dc-e.bin similarity index 100% rename from system/quests/b88002-dc.bin rename to system/quests/b88002-dc-e.bin diff --git a/system/quests/b88002-gc.bin b/system/quests/b88002-gc-e.bin similarity index 100% rename from system/quests/b88002-gc.bin rename to system/quests/b88002-gc-e.bin diff --git a/system/quests/b88002-pc.bin b/system/quests/b88002-pc-e.bin similarity index 100% rename from system/quests/b88002-pc.bin rename to system/quests/b88002-pc-e.bin diff --git a/system/quests/b88003-bb.bin b/system/quests/b88003-bb-e.bin similarity index 100% rename from system/quests/b88003-bb.bin rename to system/quests/b88003-bb-e.bin diff --git a/system/quests/b88003-dc.bin b/system/quests/b88003-dc-e.bin similarity index 100% rename from system/quests/b88003-dc.bin rename to system/quests/b88003-dc-e.bin diff --git a/system/quests/b88003-gc.bin b/system/quests/b88003-gc-e.bin similarity index 100% rename from system/quests/b88003-gc.bin rename to system/quests/b88003-gc-e.bin diff --git a/system/quests/b88003-pc.bin b/system/quests/b88003-pc-e.bin similarity index 100% rename from system/quests/b88003-pc.bin rename to system/quests/b88003-pc-e.bin diff --git a/system/quests/b88004-bb.bin b/system/quests/b88004-bb-e.bin similarity index 100% rename from system/quests/b88004-bb.bin rename to system/quests/b88004-bb-e.bin diff --git a/system/quests/b88004-dc.bin b/system/quests/b88004-dc-e.bin similarity index 100% rename from system/quests/b88004-dc.bin rename to system/quests/b88004-dc-e.bin diff --git a/system/quests/b88004-gc.bin b/system/quests/b88004-gc-e.bin similarity index 100% rename from system/quests/b88004-gc.bin rename to system/quests/b88004-gc-e.bin diff --git a/system/quests/b88004-pc.bin b/system/quests/b88004-pc-e.bin similarity index 100% rename from system/quests/b88004-pc.bin rename to system/quests/b88004-pc-e.bin diff --git a/system/quests/b88005-bb.bin b/system/quests/b88005-bb-e.bin similarity index 100% rename from system/quests/b88005-bb.bin rename to system/quests/b88005-bb-e.bin diff --git a/system/quests/b88005-dc.bin b/system/quests/b88005-dc-e.bin similarity index 100% rename from system/quests/b88005-dc.bin rename to system/quests/b88005-dc-e.bin diff --git a/system/quests/b88005-gc.bin b/system/quests/b88005-gc-e.bin similarity index 100% rename from system/quests/b88005-gc.bin rename to system/quests/b88005-gc-e.bin diff --git a/system/quests/b88005-pc.bin b/system/quests/b88005-pc-e.bin similarity index 100% rename from system/quests/b88005-pc.bin rename to system/quests/b88005-pc-e.bin diff --git a/system/quests/b88006-bb.bin b/system/quests/b88006-bb-e.bin similarity index 100% rename from system/quests/b88006-bb.bin rename to system/quests/b88006-bb-e.bin diff --git a/system/quests/b88006-dc.bin b/system/quests/b88006-dc-e.bin similarity index 100% rename from system/quests/b88006-dc.bin rename to system/quests/b88006-dc-e.bin diff --git a/system/quests/b88006-gc.bin b/system/quests/b88006-gc-e.bin similarity index 100% rename from system/quests/b88006-gc.bin rename to system/quests/b88006-gc-e.bin diff --git a/system/quests/b88006-pc.bin b/system/quests/b88006-pc-e.bin similarity index 100% rename from system/quests/b88006-pc.bin rename to system/quests/b88006-pc-e.bin diff --git a/system/quests/b88007-bb.bin b/system/quests/b88007-bb-e.bin similarity index 100% rename from system/quests/b88007-bb.bin rename to system/quests/b88007-bb-e.bin diff --git a/system/quests/b88007-dc.bin b/system/quests/b88007-dc-e.bin similarity index 100% rename from system/quests/b88007-dc.bin rename to system/quests/b88007-dc-e.bin diff --git a/system/quests/b88007-gc.bin b/system/quests/b88007-gc-e.bin similarity index 100% rename from system/quests/b88007-gc.bin rename to system/quests/b88007-gc-e.bin diff --git a/system/quests/b88007-pc.bin b/system/quests/b88007-pc-e.bin similarity index 100% rename from system/quests/b88007-pc.bin rename to system/quests/b88007-pc-e.bin diff --git a/system/quests/b88008-bb.bin b/system/quests/b88008-bb-e.bin similarity index 100% rename from system/quests/b88008-bb.bin rename to system/quests/b88008-bb-e.bin diff --git a/system/quests/b88008-dc.bin b/system/quests/b88008-dc-e.bin similarity index 100% rename from system/quests/b88008-dc.bin rename to system/quests/b88008-dc-e.bin diff --git a/system/quests/b88008-gc.bin b/system/quests/b88008-gc-e.bin similarity index 100% rename from system/quests/b88008-gc.bin rename to system/quests/b88008-gc-e.bin diff --git a/system/quests/b88008-pc.bin b/system/quests/b88008-pc-e.bin similarity index 100% rename from system/quests/b88008-pc.bin rename to system/quests/b88008-pc-e.bin diff --git a/system/quests/c88101-bb.bin b/system/quests/c88101-bb-e.bin similarity index 100% rename from system/quests/c88101-bb.bin rename to system/quests/c88101-bb-e.bin diff --git a/system/quests/c88101-dc.bin b/system/quests/c88101-dc-e.bin similarity index 100% rename from system/quests/c88101-dc.bin rename to system/quests/c88101-dc-e.bin diff --git a/system/quests/c88101-gc.bin b/system/quests/c88101-gc-e.bin similarity index 100% rename from system/quests/c88101-gc.bin rename to system/quests/c88101-gc-e.bin diff --git a/system/quests/c88101-pc.bin b/system/quests/c88101-pc-e.bin similarity index 100% rename from system/quests/c88101-pc.bin rename to system/quests/c88101-pc-e.bin diff --git a/system/quests/c88102-bb.bin b/system/quests/c88102-bb-e.bin similarity index 100% rename from system/quests/c88102-bb.bin rename to system/quests/c88102-bb-e.bin diff --git a/system/quests/c88102-dc.bin b/system/quests/c88102-dc-e.bin similarity index 100% rename from system/quests/c88102-dc.bin rename to system/quests/c88102-dc-e.bin diff --git a/system/quests/c88102-gc.bin b/system/quests/c88102-gc-e.bin similarity index 100% rename from system/quests/c88102-gc.bin rename to system/quests/c88102-gc-e.bin diff --git a/system/quests/c88102-pc.bin b/system/quests/c88102-pc-e.bin similarity index 100% rename from system/quests/c88102-pc.bin rename to system/quests/c88102-pc-e.bin diff --git a/system/quests/c88103-bb.bin b/system/quests/c88103-bb-e.bin similarity index 100% rename from system/quests/c88103-bb.bin rename to system/quests/c88103-bb-e.bin diff --git a/system/quests/c88103-dc.bin b/system/quests/c88103-dc-e.bin similarity index 100% rename from system/quests/c88103-dc.bin rename to system/quests/c88103-dc-e.bin diff --git a/system/quests/c88103-gc.bin b/system/quests/c88103-gc-e.bin similarity index 100% rename from system/quests/c88103-gc.bin rename to system/quests/c88103-gc-e.bin diff --git a/system/quests/c88103-pc.bin b/system/quests/c88103-pc-e.bin similarity index 100% rename from system/quests/c88103-pc.bin rename to system/quests/c88103-pc-e.bin diff --git a/system/quests/c88104-bb.bin b/system/quests/c88104-bb-e.bin similarity index 100% rename from system/quests/c88104-bb.bin rename to system/quests/c88104-bb-e.bin diff --git a/system/quests/c88104-dc.bin b/system/quests/c88104-dc-e.bin similarity index 100% rename from system/quests/c88104-dc.bin rename to system/quests/c88104-dc-e.bin diff --git a/system/quests/c88104-gc.bin b/system/quests/c88104-gc-e.bin similarity index 100% rename from system/quests/c88104-gc.bin rename to system/quests/c88104-gc-e.bin diff --git a/system/quests/c88104-pc.bin b/system/quests/c88104-pc-e.bin similarity index 100% rename from system/quests/c88104-pc.bin rename to system/quests/c88104-pc-e.bin diff --git a/system/quests/c88105-bb.bin b/system/quests/c88105-bb-e.bin similarity index 100% rename from system/quests/c88105-bb.bin rename to system/quests/c88105-bb-e.bin diff --git a/system/quests/c88105-dc.bin b/system/quests/c88105-dc-e.bin similarity index 100% rename from system/quests/c88105-dc.bin rename to system/quests/c88105-dc-e.bin diff --git a/system/quests/c88105-gc.bin b/system/quests/c88105-gc-e.bin similarity index 100% rename from system/quests/c88105-gc.bin rename to system/quests/c88105-gc-e.bin diff --git a/system/quests/c88105-pc.bin b/system/quests/c88105-pc-e.bin similarity index 100% rename from system/quests/c88105-pc.bin rename to system/quests/c88105-pc-e.bin diff --git a/system/quests/c88106-bb.bin b/system/quests/c88106-bb-e.bin similarity index 100% rename from system/quests/c88106-bb.bin rename to system/quests/c88106-bb-e.bin diff --git a/system/quests/c88106-dc.bin b/system/quests/c88106-dc-e.bin similarity index 100% rename from system/quests/c88106-dc.bin rename to system/quests/c88106-dc-e.bin diff --git a/system/quests/c88106-gc.bin b/system/quests/c88106-gc-e.bin similarity index 100% rename from system/quests/c88106-gc.bin rename to system/quests/c88106-gc-e.bin diff --git a/system/quests/c88106-pc.bin b/system/quests/c88106-pc-e.bin similarity index 100% rename from system/quests/c88106-pc.bin rename to system/quests/c88106-pc-e.bin diff --git a/system/quests/c88107-bb.bin b/system/quests/c88107-bb-e.bin similarity index 100% rename from system/quests/c88107-bb.bin rename to system/quests/c88107-bb-e.bin diff --git a/system/quests/c88107-dc.bin b/system/quests/c88107-dc-e.bin similarity index 100% rename from system/quests/c88107-dc.bin rename to system/quests/c88107-dc-e.bin diff --git a/system/quests/c88107-gc.bin b/system/quests/c88107-gc-e.bin similarity index 100% rename from system/quests/c88107-gc.bin rename to system/quests/c88107-gc-e.bin diff --git a/system/quests/c88107-pc.bin b/system/quests/c88107-pc-e.bin similarity index 100% rename from system/quests/c88107-pc.bin rename to system/quests/c88107-pc-e.bin diff --git a/system/quests/c88108-bb.bin b/system/quests/c88108-bb-e.bin similarity index 100% rename from system/quests/c88108-bb.bin rename to system/quests/c88108-bb-e.bin diff --git a/system/quests/c88108-dc.bin b/system/quests/c88108-dc-e.bin similarity index 100% rename from system/quests/c88108-dc.bin rename to system/quests/c88108-dc-e.bin diff --git a/system/quests/c88108-gc.bin b/system/quests/c88108-gc-e.bin similarity index 100% rename from system/quests/c88108-gc.bin rename to system/quests/c88108-gc-e.bin diff --git a/system/quests/c88108-pc.bin b/system/quests/c88108-pc-e.bin similarity index 100% rename from system/quests/c88108-pc.bin rename to system/quests/c88108-pc-e.bin diff --git a/system/quests/c88109-bb.bin b/system/quests/c88109-bb-e.bin similarity index 100% rename from system/quests/c88109-bb.bin rename to system/quests/c88109-bb-e.bin diff --git a/system/quests/c88109-dc.bin b/system/quests/c88109-dc-e.bin similarity index 100% rename from system/quests/c88109-dc.bin rename to system/quests/c88109-dc-e.bin diff --git a/system/quests/c88109-gc.bin b/system/quests/c88109-gc-e.bin similarity index 100% rename from system/quests/c88109-gc.bin rename to system/quests/c88109-gc-e.bin diff --git a/system/quests/c88109-pc.bin b/system/quests/c88109-pc-e.bin similarity index 100% rename from system/quests/c88109-pc.bin rename to system/quests/c88109-pc-e.bin diff --git a/system/quests/d88201-bb.bin b/system/quests/d88201-bb-e.bin similarity index 100% rename from system/quests/d88201-bb.bin rename to system/quests/d88201-bb-e.bin diff --git a/system/quests/d88201-gc.bin b/system/quests/d88201-gc-e.bin similarity index 100% rename from system/quests/d88201-gc.bin rename to system/quests/d88201-gc-e.bin diff --git a/system/quests/d88202-bb.bin b/system/quests/d88202-bb-e.bin similarity index 100% rename from system/quests/d88202-bb.bin rename to system/quests/d88202-bb-e.bin diff --git a/system/quests/d88202-gc.bin b/system/quests/d88202-gc-e.bin similarity index 100% rename from system/quests/d88202-gc.bin rename to system/quests/d88202-gc-e.bin diff --git a/system/quests/d88203-bb.bin b/system/quests/d88203-bb-e.bin similarity index 100% rename from system/quests/d88203-bb.bin rename to system/quests/d88203-bb-e.bin diff --git a/system/quests/d88203-gc.bin b/system/quests/d88203-gc-e.bin similarity index 100% rename from system/quests/d88203-gc.bin rename to system/quests/d88203-gc-e.bin diff --git a/system/quests/d88204-bb.bin b/system/quests/d88204-bb-e.bin similarity index 100% rename from system/quests/d88204-bb.bin rename to system/quests/d88204-bb-e.bin diff --git a/system/quests/d88204-gc.bin b/system/quests/d88204-gc-e.bin similarity index 100% rename from system/quests/d88204-gc.bin rename to system/quests/d88204-gc-e.bin diff --git a/system/quests/d88205-bb.bin b/system/quests/d88205-bb-e.bin similarity index 100% rename from system/quests/d88205-bb.bin rename to system/quests/d88205-bb-e.bin diff --git a/system/quests/d88205-gc.bin b/system/quests/d88205-gc-e.bin similarity index 100% rename from system/quests/d88205-gc.bin rename to system/quests/d88205-gc-e.bin diff --git a/system/quests/e765-dlt-gc3.mnm b/system/quests/e765-dlt-gc3-e.mnm similarity index 100% rename from system/quests/e765-dlt-gc3.mnm rename to system/quests/e765-dlt-gc3-e.mnm diff --git a/system/quests/e901-dl-gc3.mnm b/system/quests/e901-dl-gc3-e.mnm similarity index 100% rename from system/quests/e901-dl-gc3.mnm rename to system/quests/e901-dl-gc3-e.mnm diff --git a/system/quests/e903-dl-gc3.mnm b/system/quests/e903-dl-gc3-e.mnm similarity index 100% rename from system/quests/e903-dl-gc3.mnm rename to system/quests/e903-dl-gc3-e.mnm diff --git a/system/quests/e904-dl-gc3.mnm b/system/quests/e904-dl-gc3-e.mnm similarity index 100% rename from system/quests/e904-dl-gc3.mnm rename to system/quests/e904-dl-gc3-e.mnm diff --git a/system/quests/e905-dl-gc3.mnm b/system/quests/e905-dl-gc3-e.mnm similarity index 100% rename from system/quests/e905-dl-gc3.mnm rename to system/quests/e905-dl-gc3-e.mnm diff --git a/system/quests/e906-dl-gc3.mnm b/system/quests/e906-dl-gc3-e.mnm similarity index 100% rename from system/quests/e906-dl-gc3.mnm rename to system/quests/e906-dl-gc3-e.mnm diff --git a/system/quests/e907-dl-gc3.mnm b/system/quests/e907-dl-gc3-e.mnm similarity index 100% rename from system/quests/e907-dl-gc3.mnm rename to system/quests/e907-dl-gc3-e.mnm diff --git a/system/quests/e908-dl-gc3.mnm b/system/quests/e908-dl-gc3-e.mnm similarity index 100% rename from system/quests/e908-dl-gc3.mnm rename to system/quests/e908-dl-gc3-e.mnm diff --git a/system/quests/q000-dl-gc.bin b/system/quests/q000-dl-gc-e.bin similarity index 100% rename from system/quests/q000-dl-gc.bin rename to system/quests/q000-dl-gc-e.bin diff --git a/system/quests/q001-1p-bb.bin b/system/quests/q001-1p-bb-e.bin similarity index 100% rename from system/quests/q001-1p-bb.bin rename to system/quests/q001-1p-bb-e.bin diff --git a/system/quests/q002-1p-bb.bin b/system/quests/q002-1p-bb-e.bin similarity index 100% rename from system/quests/q002-1p-bb.bin rename to system/quests/q002-1p-bb-e.bin diff --git a/system/quests/q003-1p-bb.bin b/system/quests/q003-1p-bb-e.bin similarity index 100% rename from system/quests/q003-1p-bb.bin rename to system/quests/q003-1p-bb-e.bin diff --git a/system/quests/q004-1p-bb.bin b/system/quests/q004-1p-bb-e.bin similarity index 100% rename from system/quests/q004-1p-bb.bin rename to system/quests/q004-1p-bb-e.bin diff --git a/system/quests/q005-1p-bb.bin b/system/quests/q005-1p-bb-e.bin similarity index 100% rename from system/quests/q005-1p-bb.bin rename to system/quests/q005-1p-bb-e.bin diff --git a/system/quests/q006-1p-bb.bin b/system/quests/q006-1p-bb-e.bin similarity index 100% rename from system/quests/q006-1p-bb.bin rename to system/quests/q006-1p-bb-e.bin diff --git a/system/quests/q007-1p-bb.bin b/system/quests/q007-1p-bb-e.bin similarity index 100% rename from system/quests/q007-1p-bb.bin rename to system/quests/q007-1p-bb-e.bin diff --git a/system/quests/q008-1p-bb.bin b/system/quests/q008-1p-bb-e.bin similarity index 100% rename from system/quests/q008-1p-bb.bin rename to system/quests/q008-1p-bb-e.bin diff --git a/system/quests/q009-1p-bb.bin b/system/quests/q009-1p-bb-e.bin similarity index 100% rename from system/quests/q009-1p-bb.bin rename to system/quests/q009-1p-bb-e.bin diff --git a/system/quests/q010-1p-bb.bin b/system/quests/q010-1p-bb-e.bin similarity index 100% rename from system/quests/q010-1p-bb.bin rename to system/quests/q010-1p-bb-e.bin diff --git a/system/quests/q011-1p-bb.bin b/system/quests/q011-1p-bb-e.bin similarity index 100% rename from system/quests/q011-1p-bb.bin rename to system/quests/q011-1p-bb-e.bin diff --git a/system/quests/q012-1p-bb.bin b/system/quests/q012-1p-bb-e.bin similarity index 100% rename from system/quests/q012-1p-bb.bin rename to system/quests/q012-1p-bb-e.bin diff --git a/system/quests/q013-1p-bb.bin b/system/quests/q013-1p-bb-e.bin similarity index 100% rename from system/quests/q013-1p-bb.bin rename to system/quests/q013-1p-bb-e.bin diff --git a/system/quests/q014-1p-bb.bin b/system/quests/q014-1p-bb-e.bin similarity index 100% rename from system/quests/q014-1p-bb.bin rename to system/quests/q014-1p-bb-e.bin diff --git a/system/quests/q015-1p-bb.bin b/system/quests/q015-1p-bb-e.bin similarity index 100% rename from system/quests/q015-1p-bb.bin rename to system/quests/q015-1p-bb-e.bin diff --git a/system/quests/q016-1p-bb.bin b/system/quests/q016-1p-bb-e.bin similarity index 100% rename from system/quests/q016-1p-bb.bin rename to system/quests/q016-1p-bb-e.bin diff --git a/system/quests/q017-1p-bb.bin b/system/quests/q017-1p-bb-e.bin similarity index 100% rename from system/quests/q017-1p-bb.bin rename to system/quests/q017-1p-bb-e.bin diff --git a/system/quests/q018-1p-bb.bin b/system/quests/q018-1p-bb-e.bin similarity index 100% rename from system/quests/q018-1p-bb.bin rename to system/quests/q018-1p-bb-e.bin diff --git a/system/quests/q019-1p-bb.bin b/system/quests/q019-1p-bb-e.bin similarity index 100% rename from system/quests/q019-1p-bb.bin rename to system/quests/q019-1p-bb-e.bin diff --git a/system/quests/q020-1p-bb.bin b/system/quests/q020-1p-bb-e.bin similarity index 100% rename from system/quests/q020-1p-bb.bin rename to system/quests/q020-1p-bb-e.bin diff --git a/system/quests/q021-1p-bb.bin b/system/quests/q021-1p-bb-e.bin similarity index 100% rename from system/quests/q021-1p-bb.bin rename to system/quests/q021-1p-bb-e.bin diff --git a/system/quests/q022-1p-bb.bin b/system/quests/q022-1p-bb-e.bin similarity index 100% rename from system/quests/q022-1p-bb.bin rename to system/quests/q022-1p-bb-e.bin diff --git a/system/quests/q023-1p-bb.bin b/system/quests/q023-1p-bb-e.bin similarity index 100% rename from system/quests/q023-1p-bb.bin rename to system/quests/q023-1p-bb-e.bin diff --git a/system/quests/q024-1p-bb.bin b/system/quests/q024-1p-bb-e.bin similarity index 100% rename from system/quests/q024-1p-bb.bin rename to system/quests/q024-1p-bb-e.bin diff --git a/system/quests/q025-1p-bb.bin b/system/quests/q025-1p-bb-e.bin similarity index 100% rename from system/quests/q025-1p-bb.bin rename to system/quests/q025-1p-bb-e.bin diff --git a/system/quests/q026-1p-bb.bin b/system/quests/q026-1p-bb-e.bin similarity index 100% rename from system/quests/q026-1p-bb.bin rename to system/quests/q026-1p-bb-e.bin diff --git a/system/quests/q027-dl-gc.bin b/system/quests/q027-dl-gc-e.bin similarity index 100% rename from system/quests/q027-dl-gc.bin rename to system/quests/q027-dl-gc-e.bin diff --git a/system/quests/q031-1p-bb.bin b/system/quests/q031-1p-bb-e.bin similarity index 100% rename from system/quests/q031-1p-bb.bin rename to system/quests/q031-1p-bb-e.bin diff --git a/system/quests/q033-1p-bb.bin b/system/quests/q033-1p-bb-e.bin similarity index 100% rename from system/quests/q033-1p-bb.bin rename to system/quests/q033-1p-bb-e.bin diff --git a/system/quests/q058-ret-bb.bin b/system/quests/q058-ret-bb-e.bin similarity index 100% rename from system/quests/q058-ret-bb.bin rename to system/quests/q058-ret-bb-e.bin diff --git a/system/quests/q058-ret-d1.bin b/system/quests/q058-ret-d1-e.bin similarity index 100% rename from system/quests/q058-ret-d1.bin rename to system/quests/q058-ret-d1-e.bin diff --git a/system/quests/q058-ret-dc.bin b/system/quests/q058-ret-dc-e.bin similarity index 100% rename from system/quests/q058-ret-dc.bin rename to system/quests/q058-ret-dc-e.bin diff --git a/system/quests/q058-ret-gc.bin b/system/quests/q058-ret-gc-e.bin similarity index 100% rename from system/quests/q058-ret-gc.bin rename to system/quests/q058-ret-gc-e.bin diff --git a/system/quests/q058-ret-pc.bin b/system/quests/q058-ret-pc-e.bin similarity index 100% rename from system/quests/q058-ret-pc.bin rename to system/quests/q058-ret-pc-e.bin diff --git a/system/quests/q059-ret-bb.bin b/system/quests/q059-ret-bb-e.bin similarity index 100% rename from system/quests/q059-ret-bb.bin rename to system/quests/q059-ret-bb-e.bin diff --git a/system/quests/q059-ret-d1.bin b/system/quests/q059-ret-d1-e.bin similarity index 100% rename from system/quests/q059-ret-d1.bin rename to system/quests/q059-ret-d1-e.bin diff --git a/system/quests/q059-ret-dc.bin b/system/quests/q059-ret-dc-e.bin similarity index 100% rename from system/quests/q059-ret-dc.bin rename to system/quests/q059-ret-dc-e.bin diff --git a/system/quests/q059-ret-gc.bin b/system/quests/q059-ret-gc-e.bin similarity index 100% rename from system/quests/q059-ret-gc.bin rename to system/quests/q059-ret-gc-e.bin diff --git a/system/quests/q059-ret-pc.bin b/system/quests/q059-ret-pc-e.bin similarity index 100% rename from system/quests/q059-ret-pc.bin rename to system/quests/q059-ret-pc-e.bin diff --git a/system/quests/q060-ret-bb.bin b/system/quests/q060-ret-bb-e.bin similarity index 100% rename from system/quests/q060-ret-bb.bin rename to system/quests/q060-ret-bb-e.bin diff --git a/system/quests/q060-ret-d1.bin b/system/quests/q060-ret-d1-e.bin similarity index 100% rename from system/quests/q060-ret-d1.bin rename to system/quests/q060-ret-d1-e.bin diff --git a/system/quests/q060-ret-dc.bin b/system/quests/q060-ret-dc-e.bin similarity index 100% rename from system/quests/q060-ret-dc.bin rename to system/quests/q060-ret-dc-e.bin diff --git a/system/quests/q060-ret-gc.bin b/system/quests/q060-ret-gc-e.bin similarity index 100% rename from system/quests/q060-ret-gc.bin rename to system/quests/q060-ret-gc-e.bin diff --git a/system/quests/q060-ret-pc.bin b/system/quests/q060-ret-pc-e.bin similarity index 100% rename from system/quests/q060-ret-pc.bin rename to system/quests/q060-ret-pc-e.bin diff --git a/system/quests/q068-ret-dc.bin b/system/quests/q068-ret-dc-e.bin similarity index 100% rename from system/quests/q068-ret-dc.bin rename to system/quests/q068-ret-dc-e.bin diff --git a/system/quests/q068-ret-pc.bin b/system/quests/q068-ret-pc-e.bin similarity index 100% rename from system/quests/q068-ret-pc.bin rename to system/quests/q068-ret-pc-e.bin diff --git a/system/quests/q073-evt-gc.bin b/system/quests/q073-evt-gc-e.bin similarity index 100% rename from system/quests/q073-evt-gc.bin rename to system/quests/q073-evt-gc-e.bin diff --git a/system/quests/q073-evt-pc.bin b/system/quests/q073-evt-pc-e.bin similarity index 100% rename from system/quests/q073-evt-pc.bin rename to system/quests/q073-evt-pc-e.bin diff --git a/system/quests/q080-vr-dc.bin b/system/quests/q080-vr-dc-e.bin similarity index 100% rename from system/quests/q080-vr-dc.bin rename to system/quests/q080-vr-dc-e.bin diff --git a/system/quests/q095-evt-gc.bin b/system/quests/q095-evt-gc-e.bin similarity index 100% rename from system/quests/q095-evt-gc.bin rename to system/quests/q095-evt-gc-e.bin diff --git a/system/quests/q095-evt-pc.bin b/system/quests/q095-evt-pc-e.bin similarity index 100% rename from system/quests/q095-evt-pc.bin rename to system/quests/q095-evt-pc-e.bin diff --git a/system/quests/q096-evt-gc.bin b/system/quests/q096-evt-gc-e.bin similarity index 100% rename from system/quests/q096-evt-gc.bin rename to system/quests/q096-evt-gc-e.bin diff --git a/system/quests/q096-evt-pc.bin b/system/quests/q096-evt-pc-e.bin similarity index 100% rename from system/quests/q096-evt-pc.bin rename to system/quests/q096-evt-pc-e.bin diff --git a/system/quests/q101-ext-bb.bin b/system/quests/q101-ext-bb-e.bin similarity index 100% rename from system/quests/q101-ext-bb.bin rename to system/quests/q101-ext-bb-e.bin diff --git a/system/quests/q101-ext-d1.bin b/system/quests/q101-ext-d1-e.bin similarity index 100% rename from system/quests/q101-ext-d1.bin rename to system/quests/q101-ext-d1-e.bin diff --git a/system/quests/q101-ext-dc.bin b/system/quests/q101-ext-dc-e.bin similarity index 100% rename from system/quests/q101-ext-dc.bin rename to system/quests/q101-ext-dc-e.bin diff --git a/system/quests/q101-ext-gc.bin b/system/quests/q101-ext-gc-e.bin similarity index 100% rename from system/quests/q101-ext-gc.bin rename to system/quests/q101-ext-gc-e.bin diff --git a/system/quests/q101-ext-pc.bin b/system/quests/q101-ext-pc-e.bin similarity index 100% rename from system/quests/q101-ext-pc.bin rename to system/quests/q101-ext-pc-e.bin diff --git a/system/quests/q102-ext-bb.bin b/system/quests/q102-ext-bb-e.bin similarity index 100% rename from system/quests/q102-ext-bb.bin rename to system/quests/q102-ext-bb-e.bin diff --git a/system/quests/q102-ext-d1.bin b/system/quests/q102-ext-d1-e.bin similarity index 100% rename from system/quests/q102-ext-d1.bin rename to system/quests/q102-ext-d1-e.bin diff --git a/system/quests/q102-ext-dc.bin b/system/quests/q102-ext-dc-e.bin similarity index 100% rename from system/quests/q102-ext-dc.bin rename to system/quests/q102-ext-dc-e.bin diff --git a/system/quests/q102-ext-gc.bin b/system/quests/q102-ext-gc-e.bin similarity index 100% rename from system/quests/q102-ext-gc.bin rename to system/quests/q102-ext-gc-e.bin diff --git a/system/quests/q102-ext-pc.bin b/system/quests/q102-ext-pc-e.bin similarity index 100% rename from system/quests/q102-ext-pc.bin rename to system/quests/q102-ext-pc-e.bin diff --git a/system/quests/q103-ext-bb.bin b/system/quests/q103-ext-bb-e.bin similarity index 100% rename from system/quests/q103-ext-bb.bin rename to system/quests/q103-ext-bb-e.bin diff --git a/system/quests/q103-ext-d1.bin b/system/quests/q103-ext-d1-e.bin similarity index 100% rename from system/quests/q103-ext-d1.bin rename to system/quests/q103-ext-d1-e.bin diff --git a/system/quests/q103-ext-gc.bin b/system/quests/q103-ext-gc-e.bin similarity index 100% rename from system/quests/q103-ext-gc.bin rename to system/quests/q103-ext-gc-e.bin diff --git a/system/quests/q103-ext-pc.bin b/system/quests/q103-ext-pc-e.bin similarity index 100% rename from system/quests/q103-ext-pc.bin rename to system/quests/q103-ext-pc-e.bin diff --git a/system/quests/q104-ext-bb.bin b/system/quests/q104-ext-bb-e.bin similarity index 100% rename from system/quests/q104-ext-bb.bin rename to system/quests/q104-ext-bb-e.bin diff --git a/system/quests/q104-ext-d1.bin b/system/quests/q104-ext-d1-e.bin similarity index 100% rename from system/quests/q104-ext-d1.bin rename to system/quests/q104-ext-d1-e.bin diff --git a/system/quests/q104-ext-dc.bin b/system/quests/q104-ext-dc-e.bin similarity index 100% rename from system/quests/q104-ext-dc.bin rename to system/quests/q104-ext-dc-e.bin diff --git a/system/quests/q104-ext-gc.bin b/system/quests/q104-ext-gc-e.bin similarity index 100% rename from system/quests/q104-ext-gc.bin rename to system/quests/q104-ext-gc-e.bin diff --git a/system/quests/q104-ext-pc.bin b/system/quests/q104-ext-pc-e.bin similarity index 100% rename from system/quests/q104-ext-pc.bin rename to system/quests/q104-ext-pc-e.bin diff --git a/system/quests/q108-ext-bb.bin b/system/quests/q108-ext-bb-e.bin similarity index 100% rename from system/quests/q108-ext-bb.bin rename to system/quests/q108-ext-bb-e.bin diff --git a/system/quests/q108-ext-d1.bin b/system/quests/q108-ext-d1-e.bin similarity index 100% rename from system/quests/q108-ext-d1.bin rename to system/quests/q108-ext-d1-e.bin diff --git a/system/quests/q108-ext-dc.bin b/system/quests/q108-ext-dc-e.bin similarity index 100% rename from system/quests/q108-ext-dc.bin rename to system/quests/q108-ext-dc-e.bin diff --git a/system/quests/q108-ext-gc.bin b/system/quests/q108-ext-gc-e.bin similarity index 100% rename from system/quests/q108-ext-gc.bin rename to system/quests/q108-ext-gc-e.bin diff --git a/system/quests/q108-ext-pc.bin b/system/quests/q108-ext-pc-e.bin similarity index 100% rename from system/quests/q108-ext-pc.bin rename to system/quests/q108-ext-pc-e.bin diff --git a/system/quests/q109-ext-bb.bin b/system/quests/q109-ext-bb-e.bin similarity index 100% rename from system/quests/q109-ext-bb.bin rename to system/quests/q109-ext-bb-e.bin diff --git a/system/quests/q109-ext-d1.bin b/system/quests/q109-ext-d1-e.bin similarity index 100% rename from system/quests/q109-ext-d1.bin rename to system/quests/q109-ext-d1-e.bin diff --git a/system/quests/q109-ext-dc.bin b/system/quests/q109-ext-dc-e.bin similarity index 100% rename from system/quests/q109-ext-dc.bin rename to system/quests/q109-ext-dc-e.bin diff --git a/system/quests/q109-ext-gc.bin b/system/quests/q109-ext-gc-e.bin similarity index 100% rename from system/quests/q109-ext-gc.bin rename to system/quests/q109-ext-gc-e.bin diff --git a/system/quests/q109-ext-pc.bin b/system/quests/q109-ext-pc-e.bin similarity index 100% rename from system/quests/q109-ext-pc.bin rename to system/quests/q109-ext-pc-e.bin diff --git a/system/quests/q110-ext-bb.bin b/system/quests/q110-ext-bb-e.bin similarity index 100% rename from system/quests/q110-ext-bb.bin rename to system/quests/q110-ext-bb-e.bin diff --git a/system/quests/q110-ext-d1.bin b/system/quests/q110-ext-d1-e.bin similarity index 100% rename from system/quests/q110-ext-d1.bin rename to system/quests/q110-ext-d1-e.bin diff --git a/system/quests/q110-ext-dc.bin b/system/quests/q110-ext-dc-e.bin similarity index 100% rename from system/quests/q110-ext-dc.bin rename to system/quests/q110-ext-dc-e.bin diff --git a/system/quests/q110-ext-gc.bin b/system/quests/q110-ext-gc-e.bin similarity index 100% rename from system/quests/q110-ext-gc.bin rename to system/quests/q110-ext-gc-e.bin diff --git a/system/quests/q110-ext-pc.bin b/system/quests/q110-ext-pc-e.bin similarity index 100% rename from system/quests/q110-ext-pc.bin rename to system/quests/q110-ext-pc-e.bin diff --git a/system/quests/q111-ext-bb.bin b/system/quests/q111-ext-bb-e.bin similarity index 100% rename from system/quests/q111-ext-bb.bin rename to system/quests/q111-ext-bb-e.bin diff --git a/system/quests/q111-ext-d1.bin b/system/quests/q111-ext-d1-e.bin similarity index 100% rename from system/quests/q111-ext-d1.bin rename to system/quests/q111-ext-d1-e.bin diff --git a/system/quests/q111-ext-dc.bin b/system/quests/q111-ext-dc-e.bin similarity index 100% rename from system/quests/q111-ext-dc.bin rename to system/quests/q111-ext-dc-e.bin diff --git a/system/quests/q111-ext-gc.bin b/system/quests/q111-ext-gc-e.bin similarity index 100% rename from system/quests/q111-ext-gc.bin rename to system/quests/q111-ext-gc-e.bin diff --git a/system/quests/q111-ext-pc.bin b/system/quests/q111-ext-pc-e.bin similarity index 100% rename from system/quests/q111-ext-pc.bin rename to system/quests/q111-ext-pc-e.bin diff --git a/system/quests/q117-ext-bb.bin b/system/quests/q117-ext-bb-e.bin similarity index 100% rename from system/quests/q117-ext-bb.bin rename to system/quests/q117-ext-bb-e.bin diff --git a/system/quests/q117-ext-dc.bin b/system/quests/q117-ext-dc-e.bin similarity index 100% rename from system/quests/q117-ext-dc.bin rename to system/quests/q117-ext-dc-e.bin diff --git a/system/quests/q117-ext-gc.bin b/system/quests/q117-ext-gc-e.bin similarity index 100% rename from system/quests/q117-ext-gc.bin rename to system/quests/q117-ext-gc-e.bin diff --git a/system/quests/q117-ext-pc.bin b/system/quests/q117-ext-pc-e.bin similarity index 100% rename from system/quests/q117-ext-pc.bin rename to system/quests/q117-ext-pc-e.bin diff --git a/system/quests/q118-vr-bb.bin b/system/quests/q118-vr-bb-e.bin similarity index 100% rename from system/quests/q118-vr-bb.bin rename to system/quests/q118-vr-bb-e.bin diff --git a/system/quests/q118-vr-dc.bin b/system/quests/q118-vr-dc-e.bin similarity index 100% rename from system/quests/q118-vr-dc.bin rename to system/quests/q118-vr-dc-e.bin diff --git a/system/quests/q118-vr-gc.bin b/system/quests/q118-vr-gc-e.bin similarity index 100% rename from system/quests/q118-vr-gc.bin rename to system/quests/q118-vr-gc-e.bin diff --git a/system/quests/q118-vr-pc.bin b/system/quests/q118-vr-pc-e.bin similarity index 100% rename from system/quests/q118-vr-pc.bin rename to system/quests/q118-vr-pc-e.bin diff --git a/system/quests/q124-evt-bb.bin b/system/quests/q124-evt-bb-e.bin similarity index 100% rename from system/quests/q124-evt-bb.bin rename to system/quests/q124-evt-bb-e.bin diff --git a/system/quests/q137-evt-bb.bin b/system/quests/q137-evt-bb-e.bin similarity index 100% rename from system/quests/q137-evt-bb.bin rename to system/quests/q137-evt-bb-e.bin diff --git a/system/quests/q137-evt-dc.bin b/system/quests/q137-evt-dc-e.bin similarity index 100% rename from system/quests/q137-evt-dc.bin rename to system/quests/q137-evt-dc-e.bin diff --git a/system/quests/q137-evt-gc.bin b/system/quests/q137-evt-gc-e.bin similarity index 100% rename from system/quests/q137-evt-gc.bin rename to system/quests/q137-evt-gc-e.bin diff --git a/system/quests/q137-evt-pc.bin b/system/quests/q137-evt-pc-e.bin similarity index 100% rename from system/quests/q137-evt-pc.bin rename to system/quests/q137-evt-pc-e.bin diff --git a/system/quests/q138-evt-bb.bin b/system/quests/q138-evt-bb-e.bin similarity index 100% rename from system/quests/q138-evt-bb.bin rename to system/quests/q138-evt-bb-e.bin diff --git a/system/quests/q138-evt-dc.bin b/system/quests/q138-evt-dc-e.bin similarity index 100% rename from system/quests/q138-evt-dc.bin rename to system/quests/q138-evt-dc-e.bin diff --git a/system/quests/q138-evt-gc.bin b/system/quests/q138-evt-gc-e.bin similarity index 100% rename from system/quests/q138-evt-gc.bin rename to system/quests/q138-evt-gc-e.bin diff --git a/system/quests/q138-evt-pc.bin b/system/quests/q138-evt-pc-e.bin similarity index 100% rename from system/quests/q138-evt-pc.bin rename to system/quests/q138-evt-pc-e.bin diff --git a/system/quests/q140-evt-pc.bin b/system/quests/q140-evt-pc-e.bin similarity index 100% rename from system/quests/q140-evt-pc.bin rename to system/quests/q140-evt-pc-e.bin diff --git a/system/quests/q141-vr-bb.bin b/system/quests/q141-vr-bb-e.bin similarity index 100% rename from system/quests/q141-vr-bb.bin rename to system/quests/q141-vr-bb-e.bin diff --git a/system/quests/q141-vr-gc.bin b/system/quests/q141-vr-gc-e.bin similarity index 100% rename from system/quests/q141-vr-gc.bin rename to system/quests/q141-vr-gc-e.bin diff --git a/system/quests/q142-vr-bb.bin b/system/quests/q142-vr-bb-e.bin similarity index 100% rename from system/quests/q142-vr-bb.bin rename to system/quests/q142-vr-bb-e.bin diff --git a/system/quests/q201-evt-bb.bin b/system/quests/q201-evt-bb-e.bin similarity index 100% rename from system/quests/q201-evt-bb.bin rename to system/quests/q201-evt-bb-e.bin diff --git a/system/quests/q201-evt-gc.bin b/system/quests/q201-evt-gc-e.bin similarity index 100% rename from system/quests/q201-evt-gc.bin rename to system/quests/q201-evt-gc-e.bin diff --git a/system/quests/q202-shp-gc.bin b/system/quests/q202-shp-gc-e.bin similarity index 100% rename from system/quests/q202-shp-gc.bin rename to system/quests/q202-shp-gc-e.bin diff --git a/system/quests/q203-vr-bb.bin b/system/quests/q203-vr-bb-e.bin similarity index 100% rename from system/quests/q203-vr-bb.bin rename to system/quests/q203-vr-bb-e.bin diff --git a/system/quests/q203-vr-gc.bin b/system/quests/q203-vr-gc-e.bin similarity index 100% rename from system/quests/q203-vr-gc.bin rename to system/quests/q203-vr-gc-e.bin diff --git a/system/quests/q204-shp-bb.bin b/system/quests/q204-shp-bb-e.bin similarity index 100% rename from system/quests/q204-shp-bb.bin rename to system/quests/q204-shp-bb-e.bin diff --git a/system/quests/q204-shp-gc.bin b/system/quests/q204-shp-gc-e.bin similarity index 100% rename from system/quests/q204-shp-gc.bin rename to system/quests/q204-shp-gc-e.bin diff --git a/system/quests/q213-evt-gc.bin b/system/quests/q213-evt-gc-e.bin similarity index 100% rename from system/quests/q213-evt-gc.bin rename to system/quests/q213-evt-gc-e.bin diff --git a/system/quests/q220-evt-gc.bin b/system/quests/q220-evt-gc-e.bin similarity index 100% rename from system/quests/q220-evt-gc.bin rename to system/quests/q220-evt-gc-e.bin diff --git a/system/quests/q222-vr-bb.bin b/system/quests/q222-vr-bb-e.bin similarity index 100% rename from system/quests/q222-vr-bb.bin rename to system/quests/q222-vr-bb-e.bin diff --git a/system/quests/q222-vr-gc.bin b/system/quests/q222-vr-gc-e.bin similarity index 100% rename from system/quests/q222-vr-gc.bin rename to system/quests/q222-vr-gc-e.bin diff --git a/system/quests/q223-twr-bb.bin b/system/quests/q223-twr-bb-e.bin similarity index 100% rename from system/quests/q223-twr-bb.bin rename to system/quests/q223-twr-bb-e.bin diff --git a/system/quests/q223-twr-gc.bin b/system/quests/q223-twr-gc-e.bin similarity index 100% rename from system/quests/q223-twr-gc.bin rename to system/quests/q223-twr-gc-e.bin diff --git a/system/quests/q224-twr-bb.bin b/system/quests/q224-twr-bb-e.bin similarity index 100% rename from system/quests/q224-twr-bb.bin rename to system/quests/q224-twr-bb-e.bin diff --git a/system/quests/q224-twr-gc.bin b/system/quests/q224-twr-gc-e.bin similarity index 100% rename from system/quests/q224-twr-gc.bin rename to system/quests/q224-twr-gc-e.bin diff --git a/system/quests/q230-vr-gc.bin b/system/quests/q230-vr-gc-e.bin similarity index 100% rename from system/quests/q230-vr-gc.bin rename to system/quests/q230-vr-gc-e.bin diff --git a/system/quests/q231-vr-gc.bin b/system/quests/q231-vr-gc-e.bin similarity index 100% rename from system/quests/q231-vr-gc.bin rename to system/quests/q231-vr-gc-e.bin diff --git a/system/quests/q232-evt-gc.bin b/system/quests/q232-evt-gc-e.bin similarity index 100% rename from system/quests/q232-evt-gc.bin rename to system/quests/q232-evt-gc-e.bin diff --git a/system/quests/q233-ext-bb.bin b/system/quests/q233-ext-bb-e.bin similarity index 100% rename from system/quests/q233-ext-bb.bin rename to system/quests/q233-ext-bb-e.bin diff --git a/system/quests/q233-ext-gc.bin b/system/quests/q233-ext-gc-e.bin similarity index 100% rename from system/quests/q233-ext-gc.bin rename to system/quests/q233-ext-gc-e.bin diff --git a/system/quests/q234-ext-bb.bin b/system/quests/q234-ext-bb-e.bin similarity index 100% rename from system/quests/q234-ext-bb.bin rename to system/quests/q234-ext-bb-e.bin diff --git a/system/quests/q234-ext-gc.bin b/system/quests/q234-ext-gc-e.bin similarity index 100% rename from system/quests/q234-ext-gc.bin rename to system/quests/q234-ext-gc-e.bin diff --git a/system/quests/q235-ext-bb.bin b/system/quests/q235-ext-bb-e.bin similarity index 100% rename from system/quests/q235-ext-bb.bin rename to system/quests/q235-ext-bb-e.bin diff --git a/system/quests/q235-ext-gc.bin b/system/quests/q235-ext-gc-e.bin similarity index 100% rename from system/quests/q235-ext-gc.bin rename to system/quests/q235-ext-gc-e.bin diff --git a/system/quests/q236-ext-bb.bin b/system/quests/q236-ext-bb-e.bin similarity index 100% rename from system/quests/q236-ext-bb.bin rename to system/quests/q236-ext-bb-e.bin diff --git a/system/quests/q236-ext-gc.bin b/system/quests/q236-ext-gc-e.bin similarity index 100% rename from system/quests/q236-ext-gc.bin rename to system/quests/q236-ext-gc-e.bin diff --git a/system/quests/q237-vr-gc.bin b/system/quests/q237-vr-gc-e.bin similarity index 100% rename from system/quests/q237-vr-gc.bin rename to system/quests/q237-vr-gc-e.bin diff --git a/system/quests/q238-vr-gc.bin b/system/quests/q238-vr-gc-e.bin similarity index 100% rename from system/quests/q238-vr-gc.bin rename to system/quests/q238-vr-gc-e.bin diff --git a/system/quests/q239-evt-gc.bin b/system/quests/q239-evt-gc-e.bin similarity index 100% rename from system/quests/q239-evt-gc.bin rename to system/quests/q239-evt-gc-e.bin diff --git a/system/quests/q335-evt-gc.bin b/system/quests/q335-evt-gc-e.bin similarity index 100% rename from system/quests/q335-evt-gc.bin rename to system/quests/q335-evt-gc-e.bin diff --git a/system/quests/q401-gv1-bb.bin b/system/quests/q401-gv1-bb-e.bin similarity index 100% rename from system/quests/q401-gv1-bb.bin rename to system/quests/q401-gv1-bb-e.bin diff --git a/system/quests/q402-gv1-bb.bin b/system/quests/q402-gv1-bb-e.bin similarity index 100% rename from system/quests/q402-gv1-bb.bin rename to system/quests/q402-gv1-bb-e.bin diff --git a/system/quests/q403-gv1-bb.bin b/system/quests/q403-gv1-bb-e.bin similarity index 100% rename from system/quests/q403-gv1-bb.bin rename to system/quests/q403-gv1-bb-e.bin diff --git a/system/quests/q404-gv1-bb.bin b/system/quests/q404-gv1-bb-e.bin similarity index 100% rename from system/quests/q404-gv1-bb.bin rename to system/quests/q404-gv1-bb-e.bin diff --git a/system/quests/q405-gv1-bb.bin b/system/quests/q405-gv1-bb-e.bin similarity index 100% rename from system/quests/q405-gv1-bb.bin rename to system/quests/q405-gv1-bb-e.bin diff --git a/system/quests/q406-gv1-bb.bin b/system/quests/q406-gv1-bb-e.bin similarity index 100% rename from system/quests/q406-gv1-bb.bin rename to system/quests/q406-gv1-bb-e.bin diff --git a/system/quests/q407-gv1-bb.bin b/system/quests/q407-gv1-bb-e.bin similarity index 100% rename from system/quests/q407-gv1-bb.bin rename to system/quests/q407-gv1-bb-e.bin diff --git a/system/quests/q408-gv1-bb.bin b/system/quests/q408-gv1-bb-e.bin similarity index 100% rename from system/quests/q408-gv1-bb.bin rename to system/quests/q408-gv1-bb-e.bin diff --git a/system/quests/q409-gv1-bb.bin b/system/quests/q409-gv1-bb-e.bin similarity index 100% rename from system/quests/q409-gv1-bb.bin rename to system/quests/q409-gv1-bb-e.bin diff --git a/system/quests/q410-gv1-bb.bin b/system/quests/q410-gv1-bb-e.bin similarity index 100% rename from system/quests/q410-gv1-bb.bin rename to system/quests/q410-gv1-bb-e.bin diff --git a/system/quests/q411-gv1-bb.bin b/system/quests/q411-gv1-bb-e.bin similarity index 100% rename from system/quests/q411-gv1-bb.bin rename to system/quests/q411-gv1-bb-e.bin diff --git a/system/quests/q412-gv1-bb.bin b/system/quests/q412-gv1-bb-e.bin similarity index 100% rename from system/quests/q412-gv1-bb.bin rename to system/quests/q412-gv1-bb-e.bin diff --git a/system/quests/q413-gv1-bb.bin b/system/quests/q413-gv1-bb-e.bin similarity index 100% rename from system/quests/q413-gv1-bb.bin rename to system/quests/q413-gv1-bb-e.bin diff --git a/system/quests/q414-gv1-bb.bin b/system/quests/q414-gv1-bb-e.bin similarity index 100% rename from system/quests/q414-gv1-bb.bin rename to system/quests/q414-gv1-bb-e.bin diff --git a/system/quests/q415-gv1-bb.bin b/system/quests/q415-gv1-bb-e.bin similarity index 100% rename from system/quests/q415-gv1-bb.bin rename to system/quests/q415-gv1-bb-e.bin diff --git a/system/quests/q451-gv2-bb.bin b/system/quests/q451-gv2-bb-e.bin similarity index 100% rename from system/quests/q451-gv2-bb.bin rename to system/quests/q451-gv2-bb-e.bin diff --git a/system/quests/q452-gv2-bb.bin b/system/quests/q452-gv2-bb-e.bin similarity index 100% rename from system/quests/q452-gv2-bb.bin rename to system/quests/q452-gv2-bb-e.bin diff --git a/system/quests/q453-gv2-bb.bin b/system/quests/q453-gv2-bb-e.bin similarity index 100% rename from system/quests/q453-gv2-bb.bin rename to system/quests/q453-gv2-bb-e.bin diff --git a/system/quests/q454-gv2-bb.bin b/system/quests/q454-gv2-bb-e.bin similarity index 100% rename from system/quests/q454-gv2-bb.bin rename to system/quests/q454-gv2-bb-e.bin diff --git a/system/quests/q455-gv2-bb.bin b/system/quests/q455-gv2-bb-e.bin similarity index 100% rename from system/quests/q455-gv2-bb.bin rename to system/quests/q455-gv2-bb-e.bin diff --git a/system/quests/q456-gv2-bb.bin b/system/quests/q456-gv2-bb-e.bin similarity index 100% rename from system/quests/q456-gv2-bb.bin rename to system/quests/q456-gv2-bb-e.bin diff --git a/system/quests/q457-gv2-bb.bin b/system/quests/q457-gv2-bb-e.bin similarity index 100% rename from system/quests/q457-gv2-bb.bin rename to system/quests/q457-gv2-bb-e.bin diff --git a/system/quests/q458-gv2-bb.bin b/system/quests/q458-gv2-bb-e.bin similarity index 100% rename from system/quests/q458-gv2-bb.bin rename to system/quests/q458-gv2-bb-e.bin diff --git a/system/quests/q459-gv2-bb.bin b/system/quests/q459-gv2-bb-e.bin similarity index 100% rename from system/quests/q459-gv2-bb.bin rename to system/quests/q459-gv2-bb-e.bin diff --git a/system/quests/q460-gv2-bb.bin b/system/quests/q460-gv2-bb-e.bin similarity index 100% rename from system/quests/q460-gv2-bb.bin rename to system/quests/q460-gv2-bb-e.bin diff --git a/system/quests/q461-gv2-bb.bin b/system/quests/q461-gv2-bb-e.bin similarity index 100% rename from system/quests/q461-gv2-bb.bin rename to system/quests/q461-gv2-bb-e.bin diff --git a/system/quests/q462-gv2-bb.bin b/system/quests/q462-gv2-bb-e.bin similarity index 100% rename from system/quests/q462-gv2-bb.bin rename to system/quests/q462-gv2-bb-e.bin diff --git a/system/quests/q463-gv2-bb.bin b/system/quests/q463-gv2-bb-e.bin similarity index 100% rename from system/quests/q463-gv2-bb.bin rename to system/quests/q463-gv2-bb-e.bin diff --git a/system/quests/q464-gv2-bb.bin b/system/quests/q464-gv2-bb-e.bin similarity index 100% rename from system/quests/q464-gv2-bb.bin rename to system/quests/q464-gv2-bb-e.bin diff --git a/system/quests/q465-gv2-bb.bin b/system/quests/q465-gv2-bb-e.bin similarity index 100% rename from system/quests/q465-gv2-bb.bin rename to system/quests/q465-gv2-bb-e.bin diff --git a/system/quests/q466-gv2-bb.bin b/system/quests/q466-gv2-bb-e.bin similarity index 100% rename from system/quests/q466-gv2-bb.bin rename to system/quests/q466-gv2-bb-e.bin diff --git a/system/quests/q467-gv2-bb.bin b/system/quests/q467-gv2-bb-e.bin similarity index 100% rename from system/quests/q467-gv2-bb.bin rename to system/quests/q467-gv2-bb-e.bin diff --git a/system/quests/q468-gv2-bb.bin b/system/quests/q468-gv2-bb-e.bin similarity index 100% rename from system/quests/q468-gv2-bb.bin rename to system/quests/q468-gv2-bb-e.bin diff --git a/system/quests/q496-evt-gc.bin b/system/quests/q496-evt-gc-e.bin similarity index 100% rename from system/quests/q496-evt-gc.bin rename to system/quests/q496-evt-gc-e.bin diff --git a/system/quests/q701-gv4-bb.bin b/system/quests/q701-gv4-bb-e.bin similarity index 100% rename from system/quests/q701-gv4-bb.bin rename to system/quests/q701-gv4-bb-e.bin diff --git a/system/quests/q702-gv4-bb.bin b/system/quests/q702-gv4-bb-e.bin similarity index 100% rename from system/quests/q702-gv4-bb.bin rename to system/quests/q702-gv4-bb-e.bin diff --git a/system/quests/q703-gv4-bb.bin b/system/quests/q703-gv4-bb-e.bin similarity index 100% rename from system/quests/q703-gv4-bb.bin rename to system/quests/q703-gv4-bb-e.bin diff --git a/system/quests/q704-gv4-bb.bin b/system/quests/q704-gv4-bb-e.bin similarity index 100% rename from system/quests/q704-gv4-bb.bin rename to system/quests/q704-gv4-bb-e.bin diff --git a/system/quests/q705-gv4-bb.bin b/system/quests/q705-gv4-bb-e.bin similarity index 100% rename from system/quests/q705-gv4-bb.bin rename to system/quests/q705-gv4-bb-e.bin diff --git a/system/quests/q706-gv4-bb.bin b/system/quests/q706-gv4-bb-e.bin similarity index 100% rename from system/quests/q706-gv4-bb.bin rename to system/quests/q706-gv4-bb-e.bin diff --git a/system/quests/q707-gv4-bb.bin b/system/quests/q707-gv4-bb-e.bin similarity index 100% rename from system/quests/q707-gv4-bb.bin rename to system/quests/q707-gv4-bb-e.bin diff --git a/system/quests/q708-gv4-bb.bin b/system/quests/q708-gv4-bb-e.bin similarity index 100% rename from system/quests/q708-gv4-bb.bin rename to system/quests/q708-gv4-bb-e.bin diff --git a/system/quests/q709-gv4-bb.bin b/system/quests/q709-gv4-bb-e.bin similarity index 100% rename from system/quests/q709-gv4-bb.bin rename to system/quests/q709-gv4-bb-e.bin diff --git a/system/quests/q811-ext-bb.bin b/system/quests/q811-ext-bb-e.bin similarity index 100% rename from system/quests/q811-ext-bb.bin rename to system/quests/q811-ext-bb-e.bin diff --git a/system/quests/q812-ext-bb.bin b/system/quests/q812-ext-bb-e.bin similarity index 100% rename from system/quests/q812-ext-bb.bin rename to system/quests/q812-ext-bb-e.bin diff --git a/system/quests/q813-ext-bb.bin b/system/quests/q813-ext-bb-e.bin similarity index 100% rename from system/quests/q813-ext-bb.bin rename to system/quests/q813-ext-bb-e.bin diff --git a/system/quests/q814-ext-bb.bin b/system/quests/q814-ext-bb-e.bin similarity index 100% rename from system/quests/q814-ext-bb.bin rename to system/quests/q814-ext-bb-e.bin diff --git a/system/quests/q815-ext-bb.bin b/system/quests/q815-ext-bb-e.bin similarity index 100% rename from system/quests/q815-ext-bb.bin rename to system/quests/q815-ext-bb-e.bin diff --git a/system/quests/q999-shp-gc.bin b/system/quests/q999-shp-gc-e.bin similarity index 100% rename from system/quests/q999-shp-gc.bin rename to system/quests/q999-shp-gc-e.bin diff --git a/tests/GC-Episode3BattleWithSpectator.test.txt b/tests/GC-Episode3BattleWithSpectator.test.txt index 88c9491d..4bdb62e3 100644 --- a/tests/GC-Episode3BattleWithSpectator.test.txt +++ b/tests/GC-Episode3BattleWithSpectator.test.txt @@ -10357,8 +10357,8 @@ I 17097 2023-09-19 21:54:08 - [Commands] Sending to C-4 (Tali) (version=GC comma 0000 | B1 00 1C 00 32 30 32 33 3A 30 39 3A 32 30 3A 20 | 2023:09:20: 0010 | 30 34 3A 35 34 3A 30 38 2E 30 30 30 | 04:54:08.000 I 17097 2023-09-19 21:54:08 - [Commands] Sending to C-4 (Tali) (version=GC command=6C flag=00) -0000 | 6C 00 1C 04 B6 00 00 00 18 04 00 00 41 00 00 00 | l A -0010 | F9 01 00 00 03 04 00 00 07 00 00 01 FD F8 FC F9 | +0000 | 6C 00 10 04 B6 00 00 00 0C 04 00 00 41 00 00 00 | l A +0010 | F9 01 00 00 F8 03 00 00 07 00 00 01 FD F8 FC F9 | 0020 | 06 08 04 07 E8 F7 F8 FF 0D 01 06 8B 07 08 80 FF | 0030 | 0C FF 5E 80 FF 3C 04 03 02 D8 FC 10 1F F8 FF 89 | ^ < 0040 | C3 C3 C4 C2 0E FD 46 47 46 FD 55 48 98 FE 20 A0 | FGF UH @@ -10394,35 +10394,34 @@ I 17097 2023-09-19 21:54:08 - [Commands] Sending to C-4 (Tali) (version=GC comma 0220 | C2 5D 14 7B 87 FF 3A 8F 8F 5C 43 34 B8 65 C8 44 | ] { : \C4 e D 0230 | FD B8 B7 81 ED C2 3C 60 FE 0A 20 20 D5 12 D8 B8 | <` 0240 | 42 C0 FD 0A C1 B6 C0 FD 16 42 C0 FD 0A C1 C0 FD | B B -0250 | 12 FA F8 FF FB 40 E6 87 4D 6F 6C 61 FF 65 20 56 | @ Mola e V -0260 | 65 6E 74 69 20 55 41 25 FB 60 FF 0A 87 FA FD 60 | enti UA% ` ` -0270 | FF 13 F8 FF 27 54 68 69 73 20 1F 61 72 65 61 20 | 'This area -0280 | 87 F8 6F 6E B9 0A 1F 6F 66 20 74 68 1E F8 62 65 | on of th be -0290 | 73 74 9E F3 73 70 6F 74 1E E8 20 52 61 67 E0 9A | st spot Rag -02A0 | F0 66 6F 72 C7 20 67 61 E0 72 87 69 6E 67 F1 70 | for ga r ing p -02B0 | 01 68 E1 C2 E3 2E E2 65 63 08 82 F0 10 EB 76 63 | h . ec vc -02C0 | C9 69 DE 69 3C CC 0A 68 61 00 C4 A5 3C ED 61 6C | i i< ha < al -02D0 | 65 64 00 F2 CA 00 E9 9A 3C FD 61 63 74 75 0C EE | ed < actu -02E0 | 6C 79 EE 00 E4 D3 10 DE 75 00 9C D4 FC 80 9D FD | ly u -02F0 | 20 66 6C 6F 77 C3 2D 6C B6 65 2E 01 0A 63 C4 78 | flow -l e. c x -0300 | 55 FF 62 0A 01 63 7E 00 B7 C3 43 B4 77 B9 68 22 | U b c~ C w h" -0310 | AF EA 78 F4 6E 64 6D 69 18 E6 2D 73 12 A0 70 98 | x ndmi -s p -0320 | C0 AA DC 69 66 21 69 5D 20 18 A2 BD FB 61 08 DD | if!i] a -0330 | 2B 07 F6 74 72 F4 4C 2B 72 BA 00 A8 F0 31 50 E0 | + tr L+r 1P -0340 | 65 EE D5 32 2E 20 EC 85 02 09 AB 00 BC F8 EB 57 | e 2. W -0350 | 40 FD B0 95 E3 AA F8 38 FF 60 F4 6B 60 F7 FF 60 | @ 8 ` k` ` -0360 | EE FF AA A0 1D FF E0 E1 FF 60 D5 FF A0 05 FF AA | ` -0370 | 60 F3 CF 00 FE BF E0 F7 FF C0 EF FF AA A0 E7 FF | ` -0380 | 80 DF FF 60 D7 FF 40 CF FF AA 20 C7 FF 00 BF FF | ` @ -0390 | E0 B6 FF C0 AE FF AA A0 A6 FF 80 9E FF 28 58 FF | (X -03A0 | 28 50 FF AA 28 48 FF 00 7E FF 00 7E FF E0 75 FF | (P (H ~ ~ u -03B0 | AA C0 6D FF A0 65 FF 80 5D FF 60 55 FF AA 40 4D | m e ] `U @M -03C0 | FF 20 45 FF 00 3D FF E0 34 FF AA C0 2C FF A0 24 | E = 4 , $ -03D0 | FF E0 09 FF 68 03 FF AA 88 6F FF 00 7E FF 20 04 | h o ~ -03E0 | FF 20 04 FF AA 20 04 FF 20 04 FF 20 04 FF 20 04 | -03F0 | FF AA 20 04 FF 20 04 FF 20 04 FF 20 04 FF AA 20 | -0400 | 04 FF A0 24 FF 00 7E FF 08 00 FF 7A 08 00 FF E0 | $ ~ z -0410 | 7C E4 0C FF F4 05 00 FE 3B 00 00 00 | | ; +0250 | 12 FA F8 FF FB 40 E6 87 83 94 83 46 FF 83 93 83 | @ F +0260 | 65 83 42 81 40 FD 41 25 FB 4D 6F 6C 61 65 BF 20 | e B @ A% Molae +0270 | 56 65 6E 74 69 87 FA FF 81 75 83 82 81 5B 83 89 | Venti u [ +0280 | FB 81 45 70 FE 09 82 CC 83 74 0F 83 48 83 67 F2 | Ep t H g +0290 | FF 90 AE 97 AC 8F 8A 81 76 3D 0A 28 FE 13 00 82 | v= ( +02A0 | B1 FC D6 8E FC 88 CD 82 CD F0 C0 83 4F 83 49 C3 | O I +02B0 | 83 8B F0 92 86 EF 82 C5 82 E0 06 FE 82 AA FF 8F | +02C0 | 57 82 DC 82 E8 82 E2 FF 82 B7 82 AD 81 41 8D C5 | W A +02D0 | E3 8B DF DC B2 8D 11 B8 DA 1C CA D5 FE 96 AC 21 | ! +02E0 | 8E BE 43 FC F6 8F E3 82 C9 8F E6 FF 82 C1 82 C4 | C +02F0 | 82 A2 82 E9 18 A0 C6 DE BE 95 AA 82 A9 76 FF 81 | v +0300 | 0B 42 0A 2F FD 89 F8 81 95 97 8E D4 03 8C 5E F8 | B / ^ +0310 | FD 57 8B 40 82 F0 92 CA 03 82 B5 D5 0C 8B 90 CF | W @ +0320 | F8 30 91 83 70 C2 AB 69 6A 83 1F 41 82 51 82 D6 | 0 p ij A Q +0330 | 9E B3 93 5D 91 97 F4 E0 AC FD 20 EC D0 02 09 00 | ] +0340 | 55 BC F8 EB 57 40 FD B0 95 E3 55 F8 38 FF 60 F4 | U W@ U 8 ` +0350 | 6B 60 F7 FF 60 EE FF 55 A0 1D FF E0 E1 FF 60 D5 | k` ` U ` +0360 | FF A0 05 FF 55 60 F3 CF 00 FE BF E0 F7 FF C0 EF | U` +0370 | FF 55 A0 E7 FF 80 DF FF 60 D7 FF 40 CF FF 55 20 | U ` @ U +0380 | C7 FF 00 BF FF E0 B6 FF C0 AE FF 55 A0 A6 FF 80 | U +0390 | 9E FF 28 58 FF 28 50 FF 55 28 48 FF 00 7E FF 00 | (X (P U(H ~ +03A0 | 7E FF E0 75 FF 55 C0 6D FF A0 65 FF 80 5D FF 60 | ~ u U m e ] ` +03B0 | 55 FF 55 40 4D FF 20 45 FF 00 3D FF E0 34 FF 55 | U U@M E = 4 U +03C0 | C0 2C FF A0 24 FF E0 09 FF 68 03 FF 55 88 6F FF | , $ h U o +03D0 | 00 7E FF 20 04 FF 20 04 FF 55 20 04 FF 20 04 FF | ~ U +03E0 | 20 04 FF 20 04 FF 55 20 04 FF 20 04 FF 20 04 FF | U +03F0 | 20 04 FF 55 20 04 FF A0 24 FF 00 7E FF 08 00 FF | U $ ~ +0400 | BD 08 00 FF E0 7C E4 0C FF F4 00 FE 3B 02 00 00 | | ; I 17097 2023-09-19 21:54:08 - [Commands] Received from C-4 (Tali) (version=GC command=99 flag=00) 0000 | 99 00 04 00 | I 17097 2023-09-19 21:54:57 - [Commands] Sending to C-2 (Tali) (version=GC command=C9 flag=00) diff --git a/tests/decrypt-gci-save.test.sh b/tests/decrypt-gci-save.test.sh index b64a8470..3015a404 100755 --- a/tests/decrypt-gci-save.test.sh +++ b/tests/decrypt-gci-save.test.sh @@ -24,4 +24,4 @@ $EXECUTABLE decrypt-gci-save $DIR/8P-GPSJ-PSO3_GUILDCARD.gci --sys=$DIR/8P-GPSJ- diff $DIR/8P-GPSJ-PSO3_GUILDCARD-expected.gcid $DIR/8P-GPSJ-PSO3_GUILDCARD.gcid echo "... clean up" -rm -f $DIR/8P-GPOJ-PSO_CHARACTER.gcid $DIR/8P-GPOJ-PSO_GUILDCARD.gcid $DIR/8P-GPSJ-PSO_CHARACTER.gcid $DIR/8P-GPSJ-PSO_GUILDCARD.gcid +rm -f $DIR/8P-GPOJ-PSO_CHARACTER.gcid $DIR/8P-GPOJ-PSO_GUILDCARD.gcid $DIR/8P-GPSJ-PSO3_CHARACTER.gcid $DIR/8P-GPSJ-PSO3_GUILDCARD.gcid