diff --git a/CMakeLists.txt b/CMakeLists.txt index 63b06d84..c9ce0295 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -134,7 +134,7 @@ foreach(LogTestCase IN ITEMS ${LogTestCases}) add_test( NAME ${LogTestCase} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - COMMAND ${CMAKE_BINARY_DIR}/newserv replay-log ${LogTestCase} --config=${CMAKE_SOURCE_DIR}/tests/config.json --require-basic-credentials) + COMMAND ${CMAKE_BINARY_DIR}/newserv replay-log ${LogTestCase} --config=${CMAKE_SOURCE_DIR}/tests/config.json) endforeach() file(GLOB ScriptTestCases ${CMAKE_SOURCE_DIR}/tests/*.test.sh) diff --git a/README.md b/README.md index 202858e3..8208286e 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ newserv supports several versions of PSO. Specifically: | GC Ep1&2 Plus | Yes | Yes | Yes | Yes | | GC Ep3 Trial | Yes | Yes | Partial (4) | Yes | | GC Ep3 | Yes | Yes | Yes | Yes | -| XBOX Ep1&2 | Untested (1) | Untested (1) | Untested (1) | Untested (1) | +| Xbox Ep1&2 | Yes | Yes | Yes | Partial (5) | | BB (vanilla) | Yes | Yes | Yes (2) | Yes | | BB (Tethealla) | Yes | Yes | Yes (2) | Yes | @@ -76,6 +76,7 @@ newserv supports several versions of PSO. Specifically: 2. *BB games are mostly playable, but there are still some unimplemented features (for example, some quests that use rare commands may not work). Please submit a GitHub issue if you find something that doesn't work.* 3. *Support for PSO Dreamcast Trial Edition and the December 2000 prototype is somewhat incomplete and probably never will be complete. These versions are rather unstable and seem to crash often, but it's not obvious whether it's because they're prototypes or because newserv sends data they can't handle.* 4. *Creating a game works and battle setup behaves mostly normally, but starting a battle doesn't work.* +5. *PSO Xbox sessions can be proxied to Sylverant. On Schtserv, Xbox proxy sessions can connect, but Schtserv does not recognize them as Xbox sessions when they join the lobby, so the session fails at that point.* ## Setup @@ -118,6 +119,8 @@ On .dat files, the `LANGUAGE` token may be omitted. If it's present, then that . 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 GameCube and Xbox quest formats are very similar, but newserv treats them as different. If you want to use the same quest file for GameCube and Xbox clients, you can make one a symbolic link to the other. + 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. There are multiple PSO quest formats out there; newserv supports all of them. It can also decode any known format to standard .bin/.dat format. Specifically: diff --git a/TODO.md b/TODO.md index c69b751c..ecfe1a1f 100644 --- a/TODO.md +++ b/TODO.md @@ -31,16 +31,10 @@ ## PSO XBOX -- Test the following things: - - Login - - Lobby interactions with GC players - - Symbol chats: any byteswapping required? - - Word Select mapping to other consoles (is it the same as GC? probably?) - - Guild card send/receive, simple mail (+ auto reply), info board - - Crossplay in games - - Check mag correctness in various situations, including on the ground at join time - - Voice chat (both in games and lobbies) - - Quest loading (symlink all XB quests to GC quests by default, make sure they load properly) +- Fix receiving Guild Cards from non-Xbox players +- Make the Guild Card description field in SavedPlayerDataBB longer to accommodate XB descriptions (0x200 bytes) +- Implement and test voice chat +- Fix whatever causes Schtserv to not recognize proxy connections as Xbox ## PSOBB diff --git a/src/ChatCommands.cc b/src/ChatCommands.cc index 8a3a1bed..9f7745f2 100644 --- a/src/ChatCommands.cc +++ b/src/ChatCommands.cc @@ -383,9 +383,7 @@ static void server_command_exit(shared_ptr c, const std::string&) { send_message_box(c, ""); } - const auto& port_name = version_to_login_port_name.at(static_cast(c->version())); - auto s = c->require_server_state(); - send_reconnect(c, s->connect_address_for_client(c), s->name_to_port_config.at(port_name)->port); + send_client_to_login_server(c); } } @@ -431,7 +429,7 @@ static void proxy_command_get_player_card(shared_ptr bool any_card_sent = false; for (const auto& p : ses->lobby_players) { if (!p.name.empty() && args == p.name) { - send_guild_card(ses->client_channel, p.guild_card_number, p.name, "", "", p.language, p.section_id, p.char_class); + send_guild_card(ses->client_channel, p.guild_card_number, p.guild_card_number, p.name, "", "", p.language, p.section_id, p.char_class); any_card_sent = true; } } @@ -441,7 +439,7 @@ static void proxy_command_get_player_card(shared_ptr size_t index = stoull(args, nullptr, 0); const auto& p = ses->lobby_players.at(index); if (!p.name.empty()) { - send_guild_card(ses->client_channel, p.guild_card_number, p.name, "", "", p.language, p.section_id, p.char_class); + send_guild_card(ses->client_channel, p.guild_card_number, p.guild_card_number, p.name, "", "", p.language, p.section_id, p.char_class); } } catch (const exception& e) { send_text_message_printf(ses->client_channel, "Error: %s", e.what()); diff --git a/src/Client.cc b/src/Client.cc index cb037576..472ee442 100644 --- a/src/Client.cc +++ b/src/Client.cc @@ -35,6 +35,8 @@ void Client::Config::set_flags_for_version(GameVersion version, int64_t sub_vers case GameVersion::GC: break; case GameVersion::XB: + // TODO: Do all versions of XB need this flag? US does, at least. + this->set_flag(Flag::NO_D6_AFTER_LOBBY); this->set_flag(Flag::SEND_FUNCTION_CALL_NO_CACHE_PATCH); break; case GameVersion::PC: @@ -81,7 +83,7 @@ void Client::Config::set_flags_for_version(GameVersion version, int64_t sub_vers this->set_flag(Flag::SEND_FUNCTION_CALL_NO_CACHE_PATCH); break; case 0x30: // GC Ep1&2 GameJam demo, GC Ep1&2 JP v1.02, at least one version of PSO XB - case 0x31: // GC Ep1&2 US v1.00, GC US v1.01, GC EU v1.00, GC JP v1.00 + case 0x31: // GC Ep1&2 US v1.00, GC US v1.01, GC EU v1.00, GC JP v1.00, XB US case 0x34: // GC Ep1&2 JP v1.03 // In the case of GC Trial Edition, the IS_GC_TRIAL_EDITION flag is // already set when we get here (because the client has used V2 encryption @@ -145,6 +147,7 @@ Client::Client( should_send_to_lobby_server(false), should_send_to_proxy_server(false), bb_connection_phase(0xFF), + sub_version(-1), x(0.0f), z(0.0f), area(0), @@ -307,3 +310,9 @@ void Client::idle_timeout() { this->log.info("Server is deleted; cannot disconnect client"); } } + +void Client::suspend_timeouts() { + event_del(this->send_ping_event.get()); + event_del(this->idle_timeout_event.get()); + this->log.info("Timeouts suspended"); +} diff --git a/src/Client.hh b/src/Client.hh index 1f6181f4..df3a3ef6 100644 --- a/src/Client.hh +++ b/src/Client.hh @@ -163,6 +163,8 @@ struct Client : public std::enable_shared_from_this { bool should_send_to_lobby_server; bool should_send_to_proxy_server; std::unordered_map> disconnect_hooks; + std::shared_ptr xb_netloc; + parray xb_9E_unknown_a1a; uint8_t bb_connection_phase; // Patch server @@ -170,6 +172,7 @@ struct Client : public std::enable_shared_from_this { // Lobby/positioning Config config; + int32_t sub_version; float x; float z; uint32_t area; @@ -229,4 +232,6 @@ struct Client : public std::enable_shared_from_this { void send_ping(); static void dispatch_idle_timeout(evutil_socket_t, short, void* ctx); void idle_timeout(); + + void suspend_timeouts(); }; diff --git a/src/CommandFormats.hh b/src/CommandFormats.hh index 8080556f..7bcc6c22 100644 --- a/src/CommandFormats.hh +++ b/src/CommandFormats.hh @@ -38,9 +38,9 @@ // DC = Both DCv1 and DCv2 // PC = PSO PC (v2) // GC = PSO GC Episodes 1&2 and/or Episode 3 -// XB = PSO XBOX Episodes 1&2 +// XB = PSO Xbox Episodes 1&2 // BB = PSO Blue Burst -// V3 = PSO GC and PSO XBOX (these versions are similar and share many formats) +// V3 = PSO GC and PSO Xbox (these versions are similar and share many formats) // For variable-length commands, generally a zero-length array is included on // the end of the struct if the command is received by newserv, and is omitted @@ -988,7 +988,9 @@ struct S_OpenFile_PC_GC_44_A6 { // those extra bytes are unused, and the client does not fail if they're // omitted. struct S_OpenFile_XB_44_A6 : S_OpenFile_PC_GC_44_A6 { - parray unused2; + pstring xb_filename; + le_uint32_t content_meta; + parray unused2; } __packed__; struct S_OpenFile_BB_44_A6 { @@ -1858,21 +1860,22 @@ struct C_Register_BB_9C { // by its menu ID and item ID. struct C_Login_DC_PC_GC_9D { - le_uint32_t player_tag = 0x00010000; // 0x00010000 if guild card is set (via 04) - le_uint32_t guild_card_number = 0; // 0xFFFFFFFF if not set - le_uint32_t unused1 = 0; - le_uint32_t unused2 = 0; - le_uint32_t sub_version = 0; - uint8_t is_extended = 0; // If 1, structure has extended format - uint8_t language = 0; // 0 = JP, 1 = EN, 2 = DE, 3 = FR, 4 = ES - parray unused3; // Always zeroes - pstring v1_serial_number; - pstring v1_access_key; - pstring serial_number; // On XB, this is the XBL gamertag - pstring access_key; // On XB, this is the XBL user ID - pstring serial_number2; // On XB, this is the XBL gamertag - pstring access_key2; // On XB, this is the XBL user ID - pstring name; + /* 04 */ le_uint32_t player_tag = 0x00010000; // 0x00010000 if guild card is set (via 04) + /* 08 */ le_uint32_t guild_card_number = 0; // 0xFFFFFFFF if not set + /* 0C */ le_uint32_t unused1 = 0; + /* 10 */ le_uint32_t unused2 = 0; + /* 14 */ le_uint32_t sub_version = 0; + /* 18 */ uint8_t is_extended = 0; // If 1, structure has extended format + /* 19 */ uint8_t language = 0; // 0 = JP, 1 = EN, 2 = DE, 3 = FR, 4 = ES + /* 1A */ parray unused3; // Always zeroes + /* 1C */ pstring v1_serial_number; + /* 2C */ pstring v1_access_key; + /* 3C */ pstring serial_number; // On XB, this is the XBL gamertag + /* 4C */ pstring access_key; // On XB, this is the XBL user ID + /* 5C */ pstring serial_number2; // On XB, this is the XBL gamertag + /* 8C */ pstring access_key2; // On XB, this is the XBL user ID + /* BC */ pstring name; + /* CC */ } __packed__; struct C_LoginExtended_DC_GC_9D : C_Login_DC_PC_GC_9D { SC_MeetUserExtension extension; @@ -1896,7 +1899,10 @@ struct C_LoginExtended_GC_9E : C_Login_GC_9E { struct C_Login_XB_9E : C_Login_GC_9E { XBNetworkLocation netloc; - parray unknown_a1; + parray unknown_a1a; + le_uint32_t xb_user_id_high = 0; + le_uint32_t xb_user_id_low = 0; + le_uint32_t unknown_a1b = 0; } __packed__; struct C_LoginExtended_XB_9E : C_Login_XB_9E { SC_MeetUserExtension extension; @@ -2480,6 +2486,10 @@ struct C_SetBlockedSenders_BB_C6 : C_SetBlockedSenders_C6<28> { // commands), except for map data requests. This differs from Sega's original // implementation, which sent CA responses via 60 commands instead. +// C9 (C->S): Change connection status (Xbox) +// header.flag specifies if the player's online status should be hidden; 1 means +// shown, 2 means hidden. + // CA (C->S): Server data request (Episode 3) // Internal name: SndCardServerData // The CA command format is the same as that of the 6xB3 commands, and the @@ -3699,9 +3709,14 @@ struct G_SendGuildCard_PC_6x06 { GuildCardPC guild_card; } __packed__; -struct G_SendGuildCard_V3_6x06 { +struct G_SendGuildCard_GC_6x06 { G_UnusedHeader header; - GuildCardV3 guild_card; + GuildCardGC guild_card; +} __packed__; + +struct G_SendGuildCard_XB_6x06 { + G_UnusedHeader header; + GuildCardXB guild_card; } __packed__; struct G_SendGuildCard_BB_6x06 { @@ -4554,7 +4569,7 @@ struct G_SetQuestFlags_6x6F { // Episode 3 does not send this command at all since the relevant data is sent // to the joining player in the 64 command instead. -struct G_SyncPlayerDispAndInventory_DC_PC_V3_6x70 { +struct G_SyncPlayerDispAndInventory_DC_PC_GC_6x70 { // Offsets in this struct are relative to the overall command header /* 0004 */ G_ExtendedHeader header; /* 000C */ le_uint16_t client_id = 0; @@ -4589,6 +4604,14 @@ struct G_SyncPlayerDispAndInventory_DC_PC_V3_6x70 { /* 0498 */ } __packed__; +struct G_SyncPlayerDispAndInventory_XB_6x70 : G_SyncPlayerDispAndInventory_DC_PC_GC_6x70 { + // Offsets in this struct are relative to the overall command header + /* 0498 */ le_uint32_t xb_user_id_high = 0; + /* 049C */ le_uint32_t xb_user_id_low = 0; + /* 04A0 */ le_uint32_t unknown_a16 = 0; + /* 04A4 */ +} __packed__; + // 6x71: Unknown (used while loading into game) struct G_Unknown_6x71 { @@ -5130,7 +5153,7 @@ struct G_Unknown_6xB2 { le_uint32_t unknown_a3 = 0; // PSO GC puts 0x00051720 (333600) here } __packed__; -// 6xB3: Unknown (XBOX; voice chat) +// 6xB3: Unknown (Xbox; voice chat) // 6xB3: CARD battle server data request (Episode 3) @@ -5176,7 +5199,7 @@ struct G_CardServerDataCommandHeader { /* 10 */ } __packed__; -// 6xB4: Unknown (XBOX; voice chat) +// 6xB4: Unknown (Xbox; voice chat) // 6xB4: CARD battle server response (Episode 3) - see 6xB3 above // 6xB5: CARD battle client command (Episode 3) - see 6xB3 above diff --git a/src/License.cc b/src/License.cc index 24827815..7a6e8c51 100644 --- a/src/License.cc +++ b/src/License.cc @@ -6,7 +6,6 @@ #include #include "License.hh" -#include "Loggers.hh" using namespace std; @@ -19,6 +18,9 @@ License::License(const JSON& json) this->serial_number = json.get_int("SerialNumber"); this->access_key = json.get_string("AccessKey", ""); this->gc_password = json.get_string("GCPassword", ""); + this->xb_gamertag = json.get_string("XBGamerTag", ""); + this->xb_user_id = json.get_int("XBUserID", 0); + this->xb_account_id = json.get_int("XBAccountID", 0); this->bb_username = json.get_string("BBUsername", ""); this->bb_password = json.get_string("BBPassword", ""); this->flags = json.get_int("Flags", 0); @@ -32,6 +34,9 @@ JSON License::json() const { {"SerialNumber", this->serial_number}, {"AccessKey", this->access_key}, {"GCPassword", this->gc_password}, + {"XBGamerTag", this->xb_gamertag}, + {"XBUserID", this->xb_user_id}, + {"XBAccountID", this->xb_account_id}, {"BBUsername", this->bb_username}, {"BBPassword", this->bb_password}, {"Flags", this->flags}, @@ -62,6 +67,15 @@ string License::str() const { if (!this->gc_password.empty()) { tokens.emplace_back("gc_password=" + this->gc_password); } + if (!this->xb_gamertag.empty()) { + tokens.emplace_back("xb_gamertag=" + this->xb_gamertag); + } + if (this->xb_user_id != 0) { + tokens.emplace_back(string_printf("xb_user_id=%016" PRIX64, this->xb_user_id)); + } + if (this->xb_account_id != 0) { + tokens.emplace_back(string_printf("xb_account_id=%016" PRIX64, this->xb_account_id)); + } if (!this->bb_username.empty()) { tokens.emplace_back("bb_username=" + this->bb_username); } @@ -156,6 +170,9 @@ void LicenseIndex::add(shared_ptr l) { if (!l->bb_username.empty()) { this->bb_username_to_license[l->bb_username] = l; } + if (!l->xb_gamertag.empty()) { + this->xb_gamertag_to_license[l->xb_gamertag] = l; + } } void LicenseIndex::remove(uint32_t serial_number) { @@ -164,6 +181,9 @@ void LicenseIndex::remove(uint32_t serial_number) { if (!l->bb_username.empty()) { this->bb_username_to_license.erase(l->bb_username); } + if (!l->xb_gamertag.empty()) { + this->xb_gamertag_to_license.erase(l->xb_gamertag); + } } shared_ptr LicenseIndex::verify_v1_v2(uint32_t serial_number, const string& access_key) const { @@ -223,6 +243,27 @@ shared_ptr LicenseIndex::verify_gc(uint32_t serial_number, const string } } +shared_ptr LicenseIndex::verify_xb(const string& gamertag, uint64_t user_id, uint64_t account_id) const { + if (user_id == 0 || account_id == 0) { + throw incorrect_access_key(); + } + try { + auto& license = this->xb_gamertag_to_license.at(gamertag); + if (license->xb_user_id && (license->xb_user_id != user_id)) { + throw incorrect_access_key(); + } + if (license->xb_account_id && (license->xb_account_id != account_id)) { + throw incorrect_access_key(); + } + if (license->ban_end_time && (license->ban_end_time >= now())) { + throw invalid_argument("user is banned"); + } + return license; + } catch (const out_of_range&) { + throw missing_license(); + } +} + shared_ptr LicenseIndex::verify_bb(const string& username, const string& password) const { if (username.empty() || password.empty()) { throw no_username(); diff --git a/src/License.hh b/src/License.hh index f5b8935b..6d3e8c90 100644 --- a/src/License.hh +++ b/src/License.hh @@ -33,6 +33,9 @@ struct License { uint32_t serial_number = 0; std::string access_key; std::string gc_password; + std::string xb_gamertag; + uint64_t xb_user_id = 0; + uint64_t xb_account_id = 0; std::string bb_username; std::string bb_password; @@ -84,9 +87,11 @@ public: std::shared_ptr verify_v1_v2(uint32_t serial_number, const std::string& access_key) const; std::shared_ptr verify_gc(uint32_t serial_number, const std::string& access_key) const; std::shared_ptr verify_gc(uint32_t serial_number, const std::string& access_key, const std::string& password) const; + std::shared_ptr verify_xb(const std::string& gamertag, uint64_t user_id, uint64_t account_id) const; std::shared_ptr verify_bb(const std::string& username, const std::string& password) const; protected: std::unordered_map> bb_username_to_license; + std::unordered_map> xb_gamertag_to_license; std::unordered_map> serial_number_to_license; }; diff --git a/src/PlayerSubordinates.cc b/src/PlayerSubordinates.cc index 52c95a4f..6475caaa 100644 --- a/src/PlayerSubordinates.cc +++ b/src/PlayerSubordinates.cc @@ -257,9 +257,10 @@ void XBNetworkLocation::clear() { this->external_ipv4_address = 0; this->port = 0; this->mac_address.clear(0); - this->unknown_a1.clear(0); + this->unknown_a1 = 0; + this->unknown_a2 = 0; this->account_id = 0; - this->unknown_a2.clear(0); + this->unknown_a3.clear(0); } void PlayerLobbyDataXB::clear() { diff --git a/src/PlayerSubordinates.hh b/src/PlayerSubordinates.hh index e2ed2b66..6769d359 100644 --- a/src/PlayerSubordinates.hh +++ b/src/PlayerSubordinates.hh @@ -210,9 +210,7 @@ struct GuildCardPC { /* F0 */ } __attribute__((packed)); -// TODO: Is this the same for XB as it is for GC? (This struct is based on the -// GC format) -struct GuildCardV3 { +struct GuildCardGC { /* 00 */ le_uint32_t player_tag = 0; /* 04 */ le_uint32_t guild_card_number = 0; /* 08 */ pstring name; @@ -224,6 +222,20 @@ struct GuildCardV3 { /* 90 */ } __attribute__((packed)); +struct GuildCardXB { + /* 0000 */ le_uint32_t player_tag = 0; + /* 0004 */ le_uint32_t guild_card_number = 0; + /* 0008 */ le_uint32_t xb_user_id_high = 0; + /* 000C */ le_uint32_t xb_user_id_low = 0; + /* 0010 */ pstring name; + /* 0028 */ pstring description; + /* 0228 */ uint8_t present = 0; + /* 0229 */ uint8_t language = 0; + /* 022A */ uint8_t section_id = 0; + /* 022B */ uint8_t char_class = 0; + /* 022C */ +} __attribute__((packed)); + struct GuildCardBB { /* 0000 */ le_uint32_t guild_card_number = 0; /* 0004 */ pstring name; @@ -266,11 +278,12 @@ struct PlayerLobbyDataDCGC { struct XBNetworkLocation { le_uint32_t internal_ipv4_address = 0x0A0A0A0A; le_uint32_t external_ipv4_address = 0x23232323; - le_uint16_t port = 9100; + le_uint16_t port = 9500; parray mac_address = 0x77; - parray unknown_a1; + le_uint32_t unknown_a1; + le_uint32_t unknown_a2; le_uint64_t account_id = 0xFFFFFFFFFFFFFFFF; - parray unknown_a2; + parray unknown_a3; void clear(); } __attribute__((packed)); diff --git a/src/ProxyCommands.cc b/src/ProxyCommands.cc index c60fbd27..dec1c642 100644 --- a/src/ProxyCommands.cc +++ b/src/ProxyCommands.cc @@ -227,12 +227,11 @@ static HandlerResult S_V123P_02_17( if (!ses->license) { ses->log.info("No license in linked session"); - // We have to forward the command before setting up encryption, so the - // client will be able to understand it. + // We have to forward the command BEFORE setting up encryption, so the + // client will be able to understand what we sent. forward_command(ses, false, command, flag, data); - if ((ses->version() == GameVersion::GC) || - (ses->version() == GameVersion::XB)) { + if ((ses->version() == GameVersion::GC) || (ses->version() == GameVersion::XB)) { ses->server_channel.crypt_in.reset(new PSOV3Encryption(cmd.server_key)); ses->server_channel.crypt_out.reset(new PSOV3Encryption(cmd.client_key)); ses->client_channel.crypt_in.reset(new PSOV3Encryption(cmd.client_key)); @@ -270,130 +269,164 @@ static HandlerResult S_V123P_02_17( // because it believes it already did (when it was in an unlinked session, or // in the patch server case, during the current session due to a hidden // redirect). - if (ses->version() == GameVersion::PATCH) { - ses->server_channel.send(0x02); - return HandlerResult::Type::SUPPRESS; + switch (ses->version()) { + case GameVersion::PATCH: + ses->server_channel.send(0x02); + return HandlerResult::Type::SUPPRESS; - } else if ((ses->version() == GameVersion::DC) || (ses->version() == GameVersion::PC)) { - if (ses->config.check_flag(Client::Flag::IS_DC_V1)) { - if (command == 0x17) { - C_LoginV1_DC_PC_V3_90 cmd; - cmd.serial_number.encode(string_printf("%08" PRIX32 "", ses->license->serial_number)); - cmd.access_key.encode(ses->license->access_key); - cmd.access_key.clear_after(8); - ses->server_channel.send(0x90, 0x00, &cmd, sizeof(cmd)); - return HandlerResult::Type::SUPPRESS; - } else { - C_LoginV1_DC_93 cmd; - if (ses->remote_guild_card_number < 0) { - cmd.player_tag = 0xFFFF0000; - cmd.guild_card_number = 0xFFFFFFFF; + case GameVersion::DC: + case GameVersion::PC: + if (ses->config.check_flag(Client::Flag::IS_DC_V1)) { + if (command == 0x17) { + C_LoginV1_DC_PC_V3_90 cmd; + cmd.serial_number.encode(string_printf("%08" PRIX32 "", ses->license->serial_number)); + cmd.access_key.encode(ses->license->access_key); + cmd.access_key.clear_after(8); + ses->server_channel.send(0x90, 0x00, &cmd, sizeof(cmd)); + return HandlerResult::Type::SUPPRESS; } else { - cmd.player_tag = 0x00010000; - cmd.guild_card_number = ses->remote_guild_card_number; + C_LoginV1_DC_93 cmd; + if (ses->remote_guild_card_number < 0) { + cmd.player_tag = 0xFFFF0000; + cmd.guild_card_number = 0xFFFFFFFF; + } else { + cmd.player_tag = 0x00010000; + cmd.guild_card_number = ses->remote_guild_card_number; + } + cmd.unknown_a1 = 0; + cmd.unknown_a2 = 0; + cmd.sub_version = ses->sub_version; + cmd.is_extended = 0; + cmd.language = ses->language(); + cmd.serial_number.encode(string_printf("%08" PRIX32 "", ses->license->serial_number)); + cmd.access_key.encode(ses->license->access_key); + cmd.access_key.clear_after(8); + cmd.hardware_id.encode(ses->hardware_id); + cmd.name.encode(ses->character_name); + ses->server_channel.send(0x93, 0x00, &cmd, sizeof(cmd)); + return HandlerResult::Type::SUPPRESS; + } + } else { // DCv2 or PC + if (command == 0x17) { + C_Login_DC_PC_V3_9A cmd; + if (ses->remote_guild_card_number < 0) { + cmd.player_tag = 0xFFFF0000; + cmd.guild_card_number = 0xFFFFFFFF; + } else { + cmd.player_tag = 0x00010000; + cmd.guild_card_number = ses->remote_guild_card_number; + } + cmd.sub_version = ses->sub_version; + cmd.serial_number.encode(string_printf("%08" PRIX32 "", ses->license->serial_number)); + cmd.access_key.encode(ses->license->access_key); + cmd.access_key.clear_after(8); + cmd.serial_number2 = cmd.serial_number; + cmd.access_key2 = cmd.access_key; + // TODO: We probably should set email_address, but we currently don't + // keep that value anywhere in the session object, nor is it saved in + // the License object. + ses->server_channel.send(0x9A, 0x00, &cmd, sizeof(cmd)); + return HandlerResult::Type::SUPPRESS; + } else { + C_Login_DC_PC_GC_9D cmd; + if (ses->remote_guild_card_number < 0) { + cmd.player_tag = 0xFFFF0000; + cmd.guild_card_number = 0xFFFFFFFF; + } else { + cmd.player_tag = 0x00010000; + cmd.guild_card_number = ses->remote_guild_card_number; + } + cmd.unused1 = 0; + cmd.unused2 = 0; + cmd.sub_version = ses->sub_version; + cmd.is_extended = 0; + cmd.language = ses->language(); + cmd.serial_number.encode(string_printf("%08" PRIX32 "", ses->license->serial_number)); + cmd.access_key.encode(ses->license->access_key); + cmd.access_key.clear_after(8); + cmd.serial_number2 = cmd.serial_number; + cmd.access_key2 = cmd.access_key; + if (ses->config.check_flag(Client::Flag::PROXY_BLANK_NAME_ENABLED)) { + cmd.name.encode(" ", ses->language()); + } else { + cmd.name.encode(ses->character_name); + } + ses->server_channel.send(0x9D, 0x00, &cmd, sizeof(cmd)); + return HandlerResult::Type::SUPPRESS; } - cmd.unknown_a1 = 0; - cmd.unknown_a2 = 0; - cmd.sub_version = ses->sub_version; - cmd.is_extended = 0; - cmd.language = ses->language(); - cmd.serial_number.encode(string_printf("%08" PRIX32 "", ses->license->serial_number)); - cmd.access_key.encode(ses->license->access_key); - cmd.access_key.clear_after(8); - cmd.hardware_id.encode(ses->hardware_id); - cmd.name.encode(ses->character_name); - ses->server_channel.send(0x93, 0x00, &cmd, sizeof(cmd)); - return HandlerResult::Type::SUPPRESS; } - } else { // DCv2 or PC + throw logic_error("DC/PC init command not handled"); + case GameVersion::GC: if (command == 0x17) { - C_Login_DC_PC_V3_9A cmd; - if (ses->remote_guild_card_number < 0) { - cmd.player_tag = 0xFFFF0000; - cmd.guild_card_number = 0xFFFFFFFF; - } else { - cmd.player_tag = 0x00010000; - cmd.guild_card_number = ses->remote_guild_card_number; - } - cmd.sub_version = ses->sub_version; + C_VerifyLicense_V3_DB cmd; cmd.serial_number.encode(string_printf("%08" PRIX32 "", ses->license->serial_number)); cmd.access_key.encode(ses->license->access_key); - cmd.access_key.clear_after(8); + cmd.sub_version = ses->sub_version; cmd.serial_number2 = cmd.serial_number; cmd.access_key2 = cmd.access_key; - // TODO: We probably should set email_address, but we currently don't - // keep that value anywhere in the session object, nor is it saved in - // the License object. - ses->server_channel.send(0x9A, 0x00, &cmd, sizeof(cmd)); + cmd.password.encode(ses->license->gc_password); + ses->server_channel.send(0xDB, 0x00, &cmd, sizeof(cmd)); return HandlerResult::Type::SUPPRESS; - } else { - C_Login_DC_PC_GC_9D cmd; - if (ses->remote_guild_card_number < 0) { - cmd.player_tag = 0xFFFF0000; - cmd.guild_card_number = 0xFFFFFFFF; + + } else if (ses->config.check_flag(Client::Flag::PROXY_SUPPRESS_REMOTE_LOGIN)) { + uint32_t guild_card_number; + if (ses->remote_guild_card_number >= 0) { + guild_card_number = ses->remote_guild_card_number; + log_info("Using Guild Card number %" PRIu32 " from session", guild_card_number); } else { - cmd.player_tag = 0x00010000; - cmd.guild_card_number = ses->remote_guild_card_number; + guild_card_number = random_object(); + log_info("Using Guild Card number %" PRIu32 " from random generator", guild_card_number); } + + uint32_t fake_serial_number = random_object() & 0x7FFFFFFF; + uint64_t fake_access_key = random_object(); + string fake_access_key_str = string_printf("00000000000%" PRIu64, fake_access_key); + if (fake_access_key_str.size() > 12) { + fake_access_key_str = fake_access_key_str.substr(fake_access_key_str.size() - 12); + } + + C_LoginExtended_GC_9E cmd; + cmd.player_tag = 0x00010000; + cmd.guild_card_number = guild_card_number; cmd.unused1 = 0; cmd.unused2 = 0; cmd.sub_version = ses->sub_version; cmd.is_extended = 0; cmd.language = ses->language(); - cmd.serial_number.encode(string_printf("%08" PRIX32 "", ses->license->serial_number)); - cmd.access_key.encode(ses->license->access_key); - cmd.access_key.clear_after(8); + cmd.serial_number.encode(string_printf("%08" PRIX32, fake_serial_number)); + cmd.access_key.encode(fake_access_key_str); cmd.serial_number2 = cmd.serial_number; cmd.access_key2 = cmd.access_key; if (ses->config.check_flag(Client::Flag::PROXY_BLANK_NAME_ENABLED)) { cmd.name.encode(" ", ses->language()); } else { - cmd.name.encode(ses->character_name); + cmd.name.encode(ses->character_name, ses->language()); } - ses->server_channel.send(0x9D, 0x00, &cmd, sizeof(cmd)); + cmd.client_config = ses->remote_client_config_data; + ses->server_channel.send(0x9E, 0x01, &cmd, sizeof(C_Login_GC_9E)); return HandlerResult::Type::SUPPRESS; - } - } - } else if (ses->version() == GameVersion::GC) { - if (command == 0x17) { - C_VerifyLicense_V3_DB cmd; - cmd.serial_number.encode(string_printf("%08" PRIX32 "", ses->license->serial_number)); - cmd.access_key.encode(ses->license->access_key); - cmd.sub_version = ses->sub_version; - cmd.serial_number2 = cmd.serial_number; - cmd.access_key2 = cmd.access_key; - cmd.password.encode(ses->license->gc_password); - ses->server_channel.send(0xDB, 0x00, &cmd, sizeof(cmd)); - return HandlerResult::Type::SUPPRESS; - - } else if (ses->config.check_flag(Client::Flag::PROXY_SUPPRESS_REMOTE_LOGIN)) { - uint32_t guild_card_number; - if (ses->remote_guild_card_number >= 0) { - guild_card_number = ses->remote_guild_card_number; - log_info("Using Guild Card number %" PRIu32 " from session", guild_card_number); } else { - guild_card_number = random_object(); - log_info("Using Guild Card number %" PRIu32 " from random generator", guild_card_number); + // For command 02, send the same as if we had received 9A from the server + return S_G_9A(ses, command, flag, data); } - - uint32_t fake_serial_number = random_object() & 0x7FFFFFFF; - uint64_t fake_access_key = random_object(); - string fake_access_key_str = string_printf("00000000000%" PRIu64, fake_access_key); - if (fake_access_key_str.size() > 12) { - fake_access_key_str = fake_access_key_str.substr(fake_access_key_str.size() - 12); + throw logic_error("GC init command not handled"); + case GameVersion::XB: { + C_LoginExtended_XB_9E cmd; + if (ses->remote_guild_card_number < 0) { + cmd.player_tag = 0xFFFF0000; + cmd.guild_card_number = 0xFFFFFFFF; + } else { + cmd.player_tag = 0x00010000; + cmd.guild_card_number = ses->remote_guild_card_number; } - - C_LoginExtended_GC_9E cmd; - cmd.player_tag = 0x00010000; - cmd.guild_card_number = guild_card_number; cmd.unused1 = 0; cmd.unused2 = 0; cmd.sub_version = ses->sub_version; - cmd.is_extended = 0; + cmd.is_extended = (ses->remote_guild_card_number < 0) ? 1 : 0; cmd.language = ses->language(); - cmd.serial_number.encode(string_printf("%08" PRIX32, fake_serial_number)); - cmd.access_key.encode(fake_access_key_str); + cmd.serial_number.encode(ses->license->xb_gamertag); + cmd.access_key.encode(string_printf("%016" PRIX64, ses->license->xb_user_id)); cmd.serial_number2 = cmd.serial_number; cmd.access_key2 = cmd.access_key; if (ses->config.check_flag(Client::Flag::PROXY_BLANK_NAME_ENABLED)) { @@ -402,19 +435,21 @@ static HandlerResult S_V123P_02_17( cmd.name.encode(ses->character_name, ses->language()); } cmd.client_config = ses->remote_client_config_data; - ses->server_channel.send(0x9E, 0x01, &cmd, sizeof(C_Login_GC_9E)); + if (ses->wrapped_client && ses->wrapped_client->xb_netloc) { + cmd.netloc = *ses->wrapped_client->xb_netloc; + cmd.unknown_a1a = ses->wrapped_client->xb_9E_unknown_a1a; + } else { + cmd.netloc.account_id = ses->license->xb_account_id; + } + cmd.xb_user_id_high = (ses->license->xb_user_id >> 32) & 0xFFFFFFFF; + cmd.xb_user_id_low = ses->license->xb_user_id & 0xFFFFFFFF; + ses->server_channel.send( + 0x9E, 0x01, &cmd, + cmd.is_extended ? sizeof(C_LoginExtended_XB_9E) : sizeof(C_Login_XB_9E)); return HandlerResult::Type::SUPPRESS; - - } else { - // For command 02, send the same as if we had received 9A from the server - return S_G_9A(ses, command, flag, data); } - - } else if (ses->version() == GameVersion::XB) { - throw runtime_error("xbox licenses are not implemented"); - - } else { - throw logic_error("invalid game version in server init handler"); + default: + throw logic_error("invalid game version in server init handler"); } } @@ -1679,7 +1714,8 @@ static HandlerResult C_6x(shared_ptr ses, uint16_t c constexpr on_command_t C_D_6x = &C_6x; constexpr on_command_t C_P_6x = &C_6x; -constexpr on_command_t C_GX_6x = &C_6x; +constexpr on_command_t C_G_6x = &C_6x; +constexpr on_command_t C_X_6x = &C_6x; constexpr on_command_t C_B_6x = &C_6x; template <> @@ -1818,9 +1854,9 @@ static on_command_t handlers[0x100][6][2] = { /* 5E */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}}, /* 5F */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}}, // CMD S-PATCH C-PATCH S-DC C-DC S-PC C-PC S-GC C-GC S-XB C-XB S-BB C-BB -/* 60 */ {{S_invalid, nullptr}, {S_6x, C_D_6x}, {S_6x, C_P_6x}, {S_6x, C_GX_6x}, {S_6x, C_GX_6x}, {S_6x, C_B_6x}}, +/* 60 */ {{S_invalid, nullptr}, {S_6x, C_D_6x}, {S_6x, C_P_6x}, {S_6x, C_G_6x}, {S_6x, C_X_6x}, {S_6x, C_B_6x}}, /* 61 */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, C_GXB_61}, {S_invalid, C_GXB_61}, {S_invalid, C_GXB_61}}, -/* 62 */ {{S_invalid, nullptr}, {S_6x, C_D_6x}, {S_6x, C_P_6x}, {S_6x, C_GX_6x}, {S_6x, C_GX_6x}, {S_6x, C_B_6x}}, +/* 62 */ {{S_invalid, nullptr}, {S_6x, C_D_6x}, {S_6x, C_P_6x}, {S_6x, C_G_6x}, {S_6x, C_X_6x}, {S_6x, C_B_6x}}, /* 63 */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}}, /* 64 */ {{S_invalid, nullptr}, {S_D_64, nullptr}, {S_P_64, nullptr}, {S_G_64, nullptr}, {S_X_64, nullptr}, {S_B_64, nullptr}}, /* 65 */ {{S_invalid, nullptr}, {S_DG_65_67_68_EB, nullptr}, {S_P_65_67_68, nullptr}, {S_DG_65_67_68_EB, nullptr}, {S_X_65_67_68, nullptr}, {S_B_65_67_68, nullptr}}, @@ -1830,8 +1866,8 @@ static on_command_t handlers[0x100][6][2] = { /* 69 */ {{S_invalid, nullptr}, {S_66_69_E9, nullptr}, {S_66_69_E9, nullptr}, {S_66_69_E9, nullptr}, {S_66_69_E9, nullptr}, {S_66_69_E9, nullptr}}, /* 6A */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}}, /* 6B */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}}, -/* 6C */ {{S_invalid, nullptr}, {S_6x, C_D_6x}, {S_6x, C_P_6x}, {S_6x, C_GX_6x}, {S_6x, C_GX_6x}, {S_6x, C_B_6x}}, -/* 6D */ {{S_invalid, nullptr}, {S_6x, C_D_6x}, {S_6x, C_P_6x}, {S_6x, C_GX_6x}, {S_6x, C_GX_6x}, {S_6x, C_B_6x}}, +/* 6C */ {{S_invalid, nullptr}, {S_6x, C_D_6x}, {S_6x, C_P_6x}, {S_6x, C_G_6x}, {S_6x, C_X_6x}, {S_6x, C_B_6x}}, +/* 6D */ {{S_invalid, nullptr}, {S_6x, C_D_6x}, {S_6x, C_P_6x}, {S_6x, C_G_6x}, {S_6x, C_X_6x}, {S_6x, C_B_6x}}, /* 6E */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}}, /* 6F */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}}, /* 70 */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}}, diff --git a/src/ProxyServer.cc b/src/ProxyServer.cc index d9369814..e014c7cb 100644 --- a/src/ProxyServer.cc +++ b/src/ProxyServer.cc @@ -526,6 +526,15 @@ std::shared_ptr ProxyServer::LinkedSession::require_server_state() return this->require_server()->state; } +void ProxyServer::LinkedSession::resume_xb(shared_ptr c) { + this->sub_version = c->sub_version; + this->character_name = c->game_data.player()->disp.name.decode(); + this->config = c->config; + this->wrapped_client = c; + this->resume_inner(std::move(c->channel), detector_crypt); + c->suspend_timeouts(); +} + void ProxyServer::LinkedSession::resume( Channel&& client_channel, shared_ptr detector_crypt, @@ -711,31 +720,43 @@ void ProxyServer::LinkedSession::send_to_game_server(const char* error_message) this->client_channel.send(0x04, 0x00, &update_client_config_cmd, sizeof(update_client_config_cmd)); } - const auto& port_name = version_to_login_port_name.at(static_cast(this->version())); - - S_Reconnect_19 reconnect_cmd = {{0, s->name_to_port_config.at(port_name)->port, 0}}; - - // If the client is on a virtual connection, we can use any address - // here and they should be able to connect back to the game server. If - // the client is on a real connection, we'll use the sockname of the - // existing connection (like we do in the server 19 command handler). - if (this->client_channel.is_virtual_connection) { - struct sockaddr_in* dest_sin = reinterpret_cast(&this->next_destination); - if (dest_sin->sin_family != AF_INET) { - throw logic_error("ss not AF_INET"); + if (this->version() == GameVersion::XB) { + if (!this->wrapped_client) { + throw logic_error("wrapped client is missing from XB proxy session"); } - reconnect_cmd.address.store_raw(dest_sin->sin_addr.s_addr); + this->wrapped_client->should_disconnect = false; + s->game_server->connect_client(this->wrapped_client, std::move(this->client_channel)); + on_login_complete(this->wrapped_client); + this->disconnect_action = DisconnectAction::CLOSE_IMMEDIATELY; + this->disconnect(); + } else { - const struct sockaddr_in* sin = reinterpret_cast( - &this->client_channel.local_addr); - if (sin->sin_family != AF_INET) { - throw logic_error("existing connection is not ipv4"); - } - reconnect_cmd.address.store_raw(sin->sin_addr.s_addr); - } + const auto& port_name = version_to_login_port_name.at(static_cast(this->version())); - this->client_channel.send(0x19, 0x00, &reconnect_cmd, sizeof(reconnect_cmd)); - this->disconnect_action = DisconnectAction::CLOSE_IMMEDIATELY; + S_Reconnect_19 reconnect_cmd = {{0, s->name_to_port_config.at(port_name)->port, 0}}; + + // If the client is on a virtual connection, we can use any address + // here and they should be able to connect back to the game server. If + // the client is on a real connection, we'll use the sockname of the + // existing connection (like we do in the server 19 command handler). + if (this->client_channel.is_virtual_connection) { + struct sockaddr_in* dest_sin = reinterpret_cast(&this->next_destination); + if (dest_sin->sin_family != AF_INET) { + throw logic_error("ss not AF_INET"); + } + reconnect_cmd.address.store_raw(dest_sin->sin_addr.s_addr); + } else { + const struct sockaddr_in* sin = reinterpret_cast( + &this->client_channel.local_addr); + if (sin->sin_family != AF_INET) { + throw logic_error("existing connection is not ipv4"); + } + reconnect_cmd.address.store_raw(sin->sin_addr.s_addr); + } + + this->client_channel.send(0x19, 0x00, &reconnect_cmd, sizeof(reconnect_cmd)); + this->disconnect_action = DisconnectAction::CLOSE_IMMEDIATELY; + } } } @@ -762,8 +783,7 @@ void ProxyServer::LinkedSession::disconnect() { // Set a timeout to delete the session entirely (in case the client doesn't // reconnect) - struct timeval tv = usecs_to_timeval(this->timeout_for_disconnect_action( - this->disconnect_action)); + struct timeval tv = usecs_to_timeval(this->timeout_for_disconnect_action(this->disconnect_action)); event_add(this->timeout_event.get(), &tv); } @@ -818,8 +838,7 @@ shared_ptr ProxyServer::get_session_by_name( shared_ptr ProxyServer::create_licensed_session( shared_ptr l, uint16_t local_port, GameVersion version, const Client::Config& config) { - shared_ptr session(new LinkedSession( - this->shared_from_this(), local_port, version, l, config)); + shared_ptr session(new LinkedSession(this->shared_from_this(), local_port, version, l, config)); auto emplace_ret = this->id_to_session.emplace(session->id, session); if (!emplace_ret.second) { throw runtime_error("session already exists for this license"); diff --git a/src/ProxyServer.hh b/src/ProxyServer.hh index 98db97d9..1dbc9bc7 100644 --- a/src/ProxyServer.hh +++ b/src/ProxyServer.hh @@ -75,8 +75,9 @@ public: struct LobbyPlayer { uint32_t guild_card_number = 0; + uint64_t xb_user_id = 0; std::string name; - uint8_t language; + uint8_t language = 0; uint8_t section_id = 0; uint8_t char_class = 0; }; @@ -90,6 +91,7 @@ public: bool is_in_quest; std::shared_ptr detector_crypt; + std::shared_ptr wrapped_client; struct SavingFile { std::string basename; @@ -143,6 +145,7 @@ public: return this->client_channel.language; } + void resume_xb(std::shared_ptr wrapped_client); void resume( Channel&& client_channel, std::shared_ptr detector_crypt, diff --git a/src/Quest.cc b/src/Quest.cc index c934975a..4929f423 100644 --- a/src/Quest.cc +++ b/src/Quest.cc @@ -352,7 +352,7 @@ string VersionedQuest::bin_filename() const { if (this->episode == Episode::EP3) { return string_printf("m%06" PRIu32 "p_e.bin", this->quest_number); } else { - return string_printf("q%" PRIu32 ".bin", this->quest_number); + return string_printf("quest%" PRIu32 ".bin", this->quest_number); } } @@ -360,7 +360,15 @@ string VersionedQuest::dat_filename() const { if (this->episode == Episode::EP3) { throw logic_error("Episode 3 quests do not have .dat files"); } else { - return string_printf("q%" PRIu32 ".dat", this->quest_number); + return string_printf("quest%" PRIu32 ".dat", this->quest_number); + } +} + +string VersionedQuest::xb_filename() const { + if (this->episode == Episode::EP3) { + throw logic_error("Episode 3 quests do not have Xbox filenames"); + } else { + return string_printf("quest%" PRIu32 "_%c.dat", this->quest_number, tolower(char_for_language_code(this->language))); } } @@ -370,6 +378,7 @@ string VersionedQuest::encode_qst() const { *this->dat_contents, this->name, this->quest_number, + this->language, this->version, this->is_dlq_encoded); } @@ -1115,14 +1124,15 @@ pair decode_qst_data(const string& data) { // 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 + // - DC/GC: 44 ?? 3C 00 or A6 ?? 3C 00 + // - XB: 44 ?? 54 00 or A6 ?? 54 00 StringReader r(data); uint32_t signature = r.get_u32b(); - if (signature == 0x58004400 || signature == 0x5800A600) { + if ((signature == 0x58004400) || (signature == 0x5800A600)) { return decode_qst_data_t(data); - } else if ((signature & 0xFFFFFF00) == 0x3C004400 || (signature & 0xFFFFFF00) == 0x3C00A600) { + } else if (((signature & 0xFFFFFF00) == 0x3C004400) || ((signature & 0xFFFFFF00) == 0x3C00A600)) { return decode_qst_data_t(data); - } else if ((signature & 0xFF00FFFF) == 0x44003C00 || (signature & 0xFF00FFFF) == 0xA6003C00) { + } else if (((signature & 0xFF00FFFF) == 0x44003C00) || ((signature & 0xFF00FFFF) == 0xA6003C00)) { // In PSO DC, the type field is only one byte, but in V3 it's two bytes and // the filename was shifted over by one byte. To detect this, we check if // the V3 type field has a reasonable value, and if not, we assume the file @@ -1132,7 +1142,7 @@ pair decode_qst_data(const string& data) { } else { return decode_qst_data_t(data); } - } else if ((signature & 0xFF00FFFF) == 0x44005400 || (signature & 0xFF00FFFF) == 0xA6005400) { + } else if (((signature & 0xFF00FFFF) == 0x44005400) || ((signature & 0xFF00FFFF) == 0xA6005400)) { return decode_qst_data_t(data); } else { throw runtime_error("invalid qst file format"); @@ -1150,7 +1160,14 @@ void add_command_header( } template -void add_open_file_command(StringWriter& w, const std::string& name, const std::string& filename, size_t file_size, bool is_download) { +void add_open_file_command_t( + StringWriter& w, + const std::string& name, + const std::string& filename, + const std::string&, + uint32_t, + size_t file_size, + bool is_download) { add_command_header(w, is_download ? 0xA6 : 0x44, 0x00, sizeof(CmdT)); CmdT cmd; cmd.name.assign_raw("PSO/" + name); @@ -1162,8 +1179,28 @@ void add_open_file_command(StringWriter& w, const std::string& name, const std:: w.put(cmd); } +template <> +void add_open_file_command_t( + StringWriter& w, + const std::string& name, + const std::string& filename, + const std::string& xb_filename, + uint32_t quest_number, + size_t file_size, + bool is_download) { + add_command_header(w, is_download ? 0xA6 : 0x44, 0x00, sizeof(S_OpenFile_XB_44_A6)); + S_OpenFile_XB_44_A6 cmd; + cmd.name.assign_raw("PSO/" + name); + cmd.filename.encode(filename); + cmd.type = 0; + cmd.file_size = file_size; + cmd.xb_filename.encode(xb_filename); + cmd.content_meta = 0x30000000 | quest_number; + w.put(cmd); +} + template -void add_write_file_commands( +void add_write_file_commands_t( StringWriter& w, const string& filename, const string& data, @@ -1191,12 +1228,14 @@ string encode_qst_file( const string& dat_data, const string& name, uint32_t quest_number, + uint8_t language, QuestScriptVersion version, bool is_dlq_encoded) { StringWriter w; - string bin_filename = string_printf("q%" PRIu32 ".bin", quest_number); - string dat_filename = string_printf("q%" PRIu32 ".dat", quest_number); + string bin_filename = string_printf("quest%" PRIu32 ".bin", quest_number); + string dat_filename = string_printf("quest%" PRIu32 ".dat", quest_number); + string xb_filename = string_printf("quest%" PRIu32 "_%c.dat", quest_number, tolower(char_for_language_code(language))); // Some tools expect both open file commands at the beginning, hence this // unfortunate abstraction-breaking. @@ -1204,39 +1243,39 @@ string encode_qst_file( case QuestScriptVersion::DC_NTE: case QuestScriptVersion::DC_V1: case QuestScriptVersion::DC_V2: - add_open_file_command(w, name, bin_filename, bin_data.size(), is_dlq_encoded); - add_open_file_command(w, name, dat_filename, dat_data.size(), is_dlq_encoded); - add_write_file_commands(w, bin_filename, bin_data, is_dlq_encoded, false); - add_write_file_commands(w, dat_filename, dat_data, is_dlq_encoded, false); + add_open_file_command_t(w, name, bin_filename, xb_filename, quest_number, bin_data.size(), is_dlq_encoded); + add_open_file_command_t(w, name, dat_filename, xb_filename, quest_number, dat_data.size(), is_dlq_encoded); + add_write_file_commands_t(w, bin_filename, bin_data, is_dlq_encoded, false); + add_write_file_commands_t(w, dat_filename, dat_data, is_dlq_encoded, false); break; case QuestScriptVersion::PC_V2: - add_open_file_command(w, name, bin_filename, bin_data.size(), is_dlq_encoded); - add_open_file_command(w, name, dat_filename, dat_data.size(), is_dlq_encoded); - add_write_file_commands(w, bin_filename, bin_data, is_dlq_encoded, false); - add_write_file_commands(w, dat_filename, dat_data, is_dlq_encoded, false); + add_open_file_command_t(w, name, bin_filename, xb_filename, quest_number, bin_data.size(), is_dlq_encoded); + add_open_file_command_t(w, name, dat_filename, xb_filename, quest_number, dat_data.size(), is_dlq_encoded); + add_write_file_commands_t(w, bin_filename, bin_data, is_dlq_encoded, false); + add_write_file_commands_t(w, dat_filename, dat_data, is_dlq_encoded, false); break; case QuestScriptVersion::GC_NTE: case QuestScriptVersion::GC_V3: - add_open_file_command(w, name, bin_filename, bin_data.size(), is_dlq_encoded); - add_open_file_command(w, name, dat_filename, dat_data.size(), is_dlq_encoded); - add_write_file_commands(w, bin_filename, bin_data, is_dlq_encoded, false); - add_write_file_commands(w, dat_filename, dat_data, is_dlq_encoded, false); + add_open_file_command_t(w, name, bin_filename, xb_filename, quest_number, bin_data.size(), is_dlq_encoded); + add_open_file_command_t(w, name, dat_filename, xb_filename, quest_number, dat_data.size(), is_dlq_encoded); + add_write_file_commands_t(w, bin_filename, bin_data, is_dlq_encoded, false); + add_write_file_commands_t(w, dat_filename, dat_data, is_dlq_encoded, false); break; case QuestScriptVersion::GC_EP3: - add_open_file_command(w, name, bin_filename, bin_data.size(), is_dlq_encoded); - add_write_file_commands(w, bin_filename, bin_data, is_dlq_encoded, false); + add_open_file_command_t(w, name, bin_filename, xb_filename, quest_number, bin_data.size(), is_dlq_encoded); + add_write_file_commands_t(w, bin_filename, bin_data, is_dlq_encoded, false); break; case QuestScriptVersion::XB_V3: - add_open_file_command(w, name, bin_filename, bin_data.size(), is_dlq_encoded); - add_open_file_command(w, name, dat_filename, dat_data.size(), is_dlq_encoded); - add_write_file_commands(w, bin_filename, bin_data, is_dlq_encoded, false); - add_write_file_commands(w, dat_filename, dat_data, is_dlq_encoded, false); + add_open_file_command_t(w, name, bin_filename, xb_filename, quest_number, bin_data.size(), is_dlq_encoded); + add_open_file_command_t(w, name, dat_filename, xb_filename, quest_number, dat_data.size(), is_dlq_encoded); + add_write_file_commands_t(w, bin_filename, bin_data, is_dlq_encoded, false); + add_write_file_commands_t(w, dat_filename, dat_data, is_dlq_encoded, false); break; case QuestScriptVersion::BB_V4: - add_open_file_command(w, name, bin_filename, bin_data.size(), is_dlq_encoded); - add_open_file_command(w, name, dat_filename, dat_data.size(), is_dlq_encoded); - add_write_file_commands(w, bin_filename, bin_data, is_dlq_encoded, true); - add_write_file_commands(w, dat_filename, dat_data, is_dlq_encoded, true); + add_open_file_command_t(w, name, bin_filename, xb_filename, quest_number, bin_data.size(), is_dlq_encoded); + add_open_file_command_t(w, name, dat_filename, xb_filename, quest_number, dat_data.size(), is_dlq_encoded); + add_write_file_commands_t(w, bin_filename, bin_data, is_dlq_encoded, true); + add_write_file_commands_t(w, dat_filename, dat_data, is_dlq_encoded, true); break; default: throw logic_error("invalid game version"); diff --git a/src/Quest.hh b/src/Quest.hh index 13179bb9..30e5728a 100644 --- a/src/Quest.hh +++ b/src/Quest.hh @@ -81,6 +81,7 @@ struct VersionedQuest { std::string bin_filename() const; std::string dat_filename() const; + std::string xb_filename() const; std::shared_ptr create_download_quest(uint8_t override_language = 0xFF) const; std::string encode_qst() const; @@ -149,5 +150,6 @@ std::string encode_qst_file( const std::string& dat_data, const std::string& name, uint32_t quest_number, + uint8_t language, QuestScriptVersion version, bool is_dlq_encoded); diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index ea40e99c..d9b34c06 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -30,6 +30,8 @@ const char* BATTLE_TABLE_DISCONNECT_HOOK_NAME = "battle_table_state"; const char* QUEST_BARRIER_DISCONNECT_HOOK_NAME = "quest_barrier"; const char* ADD_NEXT_CLIENT_DISCONNECT_HOOK_NAME = "add_next_game_client"; +void on_login_complete(shared_ptr c); + static shared_ptr proxy_options_menu_for_client(shared_ptr c) { auto s = c->require_server_state(); @@ -91,14 +93,32 @@ static shared_ptr proxy_options_menu_for_client(shared_ptr c) { - auto s = c->require_server_state(); - const auto& port_name = version_to_lobby_port_name.at(static_cast(c->version())); - send_reconnect(c, s->connect_address_for_client(c), - s->name_to_port_config.at(port_name)->port); +void send_client_to_login_server(shared_ptr c) { + if (c->version() == GameVersion::XB) { + c->server_behavior = ServerBehavior::LOGIN_SERVER; + on_login_complete(c); + + } else { + const auto& port_name = version_to_login_port_name.at(static_cast(c->version())); + auto s = c->require_server_state(); + send_reconnect(c, s->connect_address_for_client(c), s->name_to_port_config.at(port_name)->port); + } } -static void send_client_to_proxy_server(shared_ptr c) { +void send_client_to_lobby_server(shared_ptr c) { + if (c->version() == GameVersion::XB) { + c->server_behavior = ServerBehavior::LOBBY_SERVER; + on_login_complete(c); + + } else { + auto s = c->require_server_state(); + const auto& port_name = version_to_lobby_port_name.at(static_cast(c->version())); + send_reconnect(c, s->connect_address_for_client(c), + s->name_to_port_config.at(port_name)->port); + } +} + +void send_client_to_proxy_server(shared_ptr c) { auto s = c->require_server_state(); const auto& port_name = version_to_proxy_port_name.at(static_cast(c->version())); @@ -117,7 +137,12 @@ static void send_client_to_proxy_server(shared_ptr c) { ses->remote_guild_card_number = 0; } - send_reconnect(c, s->connect_address_for_client(c), local_port); + if (c->version() == GameVersion::XB) { + ses->resume_xb(c); + c->should_disconnect = true; + } else { + send_reconnect(c, s->connect_address_for_client(c), local_port); + } } static void send_proxy_destinations_menu(shared_ptr c) { @@ -239,7 +264,7 @@ static void send_main_menu(shared_ptr c) { "Disconnect", 0); main_menu->items.emplace_back(MainMenuItemID::CLEAR_LICENSE, "Clear license", "Disconnect with an\ninvalid license error\nso you can enter a\ndifferent serial\nnumber, access key,\nor password", - MenuItem::Flag::INVISIBLE_ON_DCNTE | MenuItem::Flag::INVISIBLE_ON_BB); + MenuItem::Flag::INVISIBLE_ON_DCNTE | MenuItem::Flag::INVISIBLE_ON_XB | MenuItem::Flag::INVISIBLE_ON_BB); send_menu(c, main_menu); } @@ -312,6 +337,10 @@ void on_disconnect(shared_ptr c) { //////////////////////////////////////////////////////////////////////////////// +static void on_05(shared_ptr c, uint16_t, uint32_t, string&) { + c->should_disconnect = true; +} + static void set_console_client_flags(shared_ptr c, uint32_t sub_version) { if (c->channel.crypt_in->type() == PSOEncryption::Type::V2) { if (sub_version <= 0x28) { @@ -323,6 +352,7 @@ static void set_console_client_flags(shared_ptr c, uint32_t sub_version) } } c->config.set_flags_for_version(c->version(), sub_version); + c->sub_version = sub_version; if (c->config.specific_version == default_specific_version_for_version(c->version(), -1)) { c->config.specific_version = default_specific_version_for_version(c->version(), sub_version); } @@ -747,21 +777,7 @@ static void on_9D_9E(shared_ptr c, uint16_t command, uint32_t, string& d } } else if (command == 0x9E) { - // GC and XB send different amounts of data in this command. This is how - // newserv determines if a V3 client is GC or XB. - const auto& cmd = check_size_t(data, sizeof(C_LoginExtended_XB_9E)); - switch (data.size()) { - case sizeof(C_Login_GC_9E): - case sizeof(C_LoginExtended_GC_9E): - break; - case sizeof(C_Login_XB_9E): - case sizeof(C_LoginExtended_XB_9E): - c->channel.version = GameVersion::XB; - c->log.info("Game version set to XB"); - break; - default: - throw runtime_error("invalid size for 9E command"); - } + const auto& cmd = check_size_t(data, sizeof(C_LoginExtended_GC_9E)); base_cmd = &cmd; if (cmd.is_extended) { const auto& cmd = check_size_t(data); @@ -832,12 +848,11 @@ static void on_9D_9E(shared_ptr c, uint16_t command, uint32_t, string& d return; } catch (const LicenseIndex::missing_license& e) { - // On V3, the client should have sent a different command containing the + // On GC, the client should have sent a different command containing the // password already, which should have created and added a license. So, if // no license exists at this point, disconnect the client even if // unregistered clients are allowed. - shared_ptr l; - if ((c->version() == GameVersion::GC) || (c->version() == GameVersion::XB)) { + if (c->version() == GameVersion::GC) { send_command(c, 0x04, 0x04); c->should_disconnect = true; return; @@ -861,6 +876,81 @@ static void on_9D_9E(shared_ptr c, uint16_t command, uint32_t, string& d on_login_complete(c); } +static void on_9E_XB(shared_ptr c, uint16_t, uint32_t, string& data) { + auto s = c->require_server_state(); + + const auto& cmd = check_size_t(data, sizeof(C_LoginExtended_XB_9E)); + if (cmd.is_extended) { + const auto& cmd = check_size_t(data); + if (cmd.extension.lobby_refs[0].menu_id == MenuID::LOBBY) { + c->preferred_lobby_id = cmd.extension.lobby_refs[0].item_id; + } + } + + try { + c->config.parse_from(cmd.client_config); + } catch (const invalid_argument&) { + // If we can't import the config, assume that the client was not connected + // to newserv before, so we should show the welcome message. + c->config.set_flag(Client::Flag::AT_WELCOME_MESSAGE); + } + c->xb_netloc.reset(new XBNetworkLocation(cmd.netloc)); + c->xb_9E_unknown_a1a = cmd.unknown_a1a; + + c->channel.language = cmd.language; + c->config.set_flags_for_version(c->version(), -1); + set_console_client_flags(c, cmd.sub_version); + + string xb_gamertag = cmd.serial_number.decode(); + uint64_t xb_user_id = stoull(cmd.access_key.decode(), nullptr, 16); + uint64_t xb_account_id = cmd.netloc.account_id; + try { + shared_ptr l = s->license_index->verify_xb(xb_gamertag, xb_user_id, xb_account_id); + bool should_save = false; + if (l->xb_user_id == 0) { + l->xb_user_id = xb_user_id; + c->log.info("Set license XB user ID to %016" PRIX64, l->xb_user_id); + should_save = true; + } + if (l->xb_account_id == 0) { + l->xb_account_id = xb_account_id; + c->log.info("Set license XB account ID to %016" PRIX64, l->xb_account_id); + should_save = true; + } + if (should_save && !s->is_replay) { + l->save(); + } + c->set_license(l); + + } catch (const LicenseIndex::no_username& e) { + send_command(c, 0x04, 0x03); + c->should_disconnect = true; + return; + + } catch (const LicenseIndex::incorrect_access_key& e) { + send_command(c, 0x04, 0x03); + c->should_disconnect = true; + return; + + } catch (const LicenseIndex::missing_license& e) { + shared_ptr l(new License()); + l->serial_number = fnv1a32(xb_gamertag) & 0x7FFFFFFF; + l->xb_gamertag = xb_gamertag; + l->xb_user_id = xb_user_id; + l->xb_account_id = xb_account_id; + s->license_index->add(l); + if (!s->is_replay) { + l->save(); + } + c->set_license(l); + string l_str = l->str(); + c->log.info("Created license %s", l_str.c_str()); + } + + send_update_client_config(c); + on_login_complete(c); +} + static void on_93_BB(shared_ptr c, uint16_t, uint32_t, string& data) { const auto& cmd = check_size_t(data, sizeof(C_Login_BB_93) - 8, sizeof(C_Login_BB_93)); auto s = c->require_server_state(); @@ -1784,6 +1874,9 @@ static void on_10(shared_ptr c, uint16_t, uint32_t, string& data) { } case MainMenuItemID::PROXY_DESTINATIONS: + if (!c->game_data.player(false, false)) { + send_get_player_info(c); + } send_proxy_destinations_menu(c); break; @@ -1851,6 +1944,11 @@ static void on_10(shared_ptr c, uint16_t, uint32_t, string& data) { break; case MainMenuItemID::DISCONNECT: + if (c->version() == GameVersion::XB) { + // On XB (at least via Insignia) the server has to explicitly tell + // the client to disconnect by sending this command. + send_command(c, 0x05, 0x00); + } c->should_disconnect = true; break; @@ -2140,8 +2238,9 @@ static void on_10(shared_ptr c, uint16_t, uint32_t, string& data) { string bin_filename = vq->bin_filename(); string dat_filename = vq->dat_filename(); - 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); + string xb_filename = vq->xb_filename(); + send_open_quest_file(lc, bin_filename, bin_filename, xb_filename, vq->quest_number, QuestFileType::ONLINE, vq->bin_contents); + send_open_quest_file(lc, dat_filename, dat_filename, xb_filename, vq->quest_number, QuestFileType::ONLINE, vq->dat_contents); // 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 @@ -2171,11 +2270,12 @@ static void on_10(shared_ptr c, uint16_t, uint32_t, 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, q->name, vq->bin_filename(), vq->bin_contents, QuestFileType::EPISODE_3); + send_open_quest_file(c, q->name, vq->bin_filename(), "", vq->quest_number, QuestFileType::EPISODE_3, vq->bin_contents); } else { vq = vq->create_download_quest(c->language()); - send_open_quest_file(c, q->name, vq->bin_filename(), vq->bin_contents, QuestFileType::DOWNLOAD); - send_open_quest_file(c, q->name, vq->dat_filename(), vq->dat_contents, QuestFileType::DOWNLOAD); + string xb_filename = vq->xb_filename(); + send_open_quest_file(c, q->name, vq->bin_filename(), xb_filename, vq->quest_number, QuestFileType::DOWNLOAD, vq->bin_contents); + send_open_quest_file(c, q->name, vq->dat_filename(), xb_filename, vq->quest_number, QuestFileType::DOWNLOAD, vq->dat_contents); } } break; @@ -2354,11 +2454,7 @@ static void on_A0(shared_ptr c, uint16_t, uint32_t, string&) { send_message_box(c, ""); } - const auto& port_name = version_to_login_port_name.at(static_cast(c->version())); - - auto s = c->require_server_state(); - send_reconnect(c, s->connect_address_for_client(c), - s->name_to_port_config.at(port_name)->port); + send_client_to_login_server(c); } static void on_A1(shared_ptr c, uint16_t command, uint32_t flag, string& data) { @@ -2555,7 +2651,7 @@ static void on_D7_GC(shared_ptr c, uint16_t, uint32_t, string& data) { try { static FileContentsCache gba_file_cache(300 * 1000 * 1000); auto f = gba_file_cache.get_or_load("system/gba/" + filename).file; - send_open_quest_file(c, "", filename, f->data, QuestFileType::GBA_DEMO); + send_open_quest_file(c, "", filename, "", 0, QuestFileType::GBA_DEMO, f->data); } catch (const out_of_range&) { send_command(c, 0xD7, 0x00); } catch (const cannot_open_file&) { @@ -3281,6 +3377,11 @@ static void on_C6(shared_ptr c, uint16_t, uint32_t, string& data) { } } +static void on_C9_XB(shared_ptr c, uint16_t, uint32_t flag, string& data) { + check_size_v(data.size(), 0); + c->log.warning("Ignoring connection status change command (%02" PRIX32 ")", flag); +} + shared_ptr create_game_generic( shared_ptr s, shared_ptr c, @@ -3681,12 +3782,13 @@ static void on_6F(shared_ptr c, uint16_t command, uint32_t, string& data 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(); - string dat_basename = vq->dat_filename(); + string bin_filename = vq->bin_filename(); + string dat_filename = vq->dat_filename(); - 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); + send_open_quest_file(c, bin_filename, bin_filename, "", vq->quest_number, QuestFileType::ONLINE, vq->bin_contents); + send_open_quest_file(c, dat_filename, dat_filename, "", vq->quest_number, QuestFileType::ONLINE, vq->dat_contents); c->config.set_flag(Client::Flag::LOADING_RUNNING_JOINABLE_QUEST); + } else if (l->map) { send_rare_enemy_index_list(c, l->map->rare_enemy_indexes); } @@ -4127,7 +4229,7 @@ static on_command_t handlers[0x100][6] = { /* 02 */ {on_02_P, nullptr, nullptr, nullptr, nullptr, nullptr}, /* 03 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}, /* 04 */ {on_04_P, nullptr, nullptr, nullptr, nullptr, nullptr}, - /* 05 */ {nullptr, on_ignored, on_ignored, on_ignored, on_ignored, on_ignored}, + /* 05 */ {nullptr, on_05, on_05, on_05, on_05, on_05}, /* 06 */ {nullptr, on_06, on_06, on_06, on_06, on_06}, /* 07 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}, /* 08 */ {nullptr, on_08_E6, on_08_E6, on_08_E6, on_08_E6, on_08_E6}, @@ -4284,7 +4386,7 @@ static on_command_t handlers[0x100][6] = { /* 9B */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}, /* 9C */ {nullptr, on_9C, on_9C, on_9C, on_9C, nullptr}, /* 9D */ {nullptr, on_9D_9E, on_9D_9E, on_9D_9E, on_9D_9E, nullptr}, - /* 9E */ {nullptr, nullptr, on_9D_9E, on_9D_9E, on_9D_9E, nullptr}, + /* 9E */ {nullptr, nullptr, on_9D_9E, on_9D_9E, on_9E_XB, nullptr}, /* 9F */ {nullptr, nullptr, nullptr, on_9F_V3, on_9F_V3, nullptr}, // PATCH DC PC GC XB BB /* A0 */ {nullptr, on_A0, on_A0, on_A0, on_A0, on_A0}, @@ -4329,7 +4431,7 @@ static on_command_t handlers[0x100][6] = { /* C6 */ {nullptr, nullptr, on_C6, on_C6, on_C6, on_C6}, /* C7 */ {nullptr, nullptr, on_C7, on_C7, on_C7, on_C7}, /* C8 */ {nullptr, nullptr, on_C8, on_C8, on_C8, on_C8}, - /* C9 */ {nullptr, nullptr, nullptr, on_6x_C9_CB, nullptr, nullptr}, + /* C9 */ {nullptr, nullptr, nullptr, on_6x_C9_CB, on_C9_XB, nullptr}, /* CA */ {nullptr, nullptr, nullptr, on_CA_Ep3, nullptr, nullptr}, /* CB */ {nullptr, nullptr, nullptr, on_6x_C9_CB, nullptr, nullptr}, /* CC */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}, diff --git a/src/ReceiveCommands.hh b/src/ReceiveCommands.hh index 85003352..04df2458 100644 --- a/src/ReceiveCommands.hh +++ b/src/ReceiveCommands.hh @@ -18,5 +18,11 @@ std::shared_ptr create_game_generic( void on_connect(std::shared_ptr c); void on_disconnect(std::shared_ptr c); +void on_login_complete(std::shared_ptr c); + void on_command(std::shared_ptr c, uint16_t command, uint32_t flag, std::string& data); void on_command_with_header(std::shared_ptr c, const std::string& data); + +void send_client_to_login_server(std::shared_ptr c); +void send_client_to_lobby_server(std::shared_ptr c); +void send_client_to_proxy_server(std::shared_ptr c); diff --git a/src/ReceiveSubcommands.cc b/src/ReceiveSubcommands.cc index 38bbef37..4d123811 100644 --- a/src/ReceiveSubcommands.cc +++ b/src/ReceiveSubcommands.cc @@ -249,9 +249,11 @@ static void on_sync_joining_player_item_state(shared_ptr c, uint8_t comm static void on_sync_joining_player_disp_and_inventory( shared_ptr c, uint8_t command, uint8_t flag, const void* data, size_t size) { - auto l = c->require_lobby(); + auto s = c->require_server_state(); + // In V1/V2 games, this command sometimes is sent after the new client has // finished loading, so we don't check l->any_client_loading() here. + auto l = c->require_lobby(); if (!l->is_game()) { return; } @@ -283,15 +285,34 @@ static void on_sync_joining_player_disp_and_inventory( bool target_is_gc = (target->version() == GameVersion::GC); if (target_is_gc == sender_is_gc) { send_command(target, command, flag, data, size); - } else { - auto out_cmd = check_size_t(data, size); - for (size_t z = 0; z < 30; z++) { - // NOTE: If we use this codepath for non-V3 in the future, we'll need to - // change this hardcoded version. This only works because GC's mag - // encoding/decoding is symmetric (encode and decode do the same thing). + + } else if (sender_is_gc) { + // Convert GC command to XB command + G_SyncPlayerDispAndInventory_XB_6x70 out_cmd = {check_size_t(data, size), 0, 0, 0}; + if (c->license->xb_user_id) { + out_cmd.xb_user_id_high = static_cast((c->license->xb_user_id >> 32) & 0xFFFFFFFF); + out_cmd.xb_user_id_low = static_cast(c->license->xb_user_id & 0xFFFFFFFF); + } else { + out_cmd.xb_user_id_high = 0xAE000000; + out_cmd.xb_user_id_low = c->license->serial_number; + } + for (size_t z = 0; z < out_cmd.inventory.num_items; z++) { out_cmd.inventory.items[z].data.decode_for_version(GameVersion::GC); + out_cmd.inventory.items[z].data.encode_for_version(GameVersion::XB, s->item_parameter_table_for_version(GameVersion::XB)); } send_command_t(target, command, flag, out_cmd); + + } else { + // Comvert XB command to GC command + static_assert( + sizeof(G_SyncPlayerDispAndInventory_DC_PC_GC_6x70) < sizeof(G_SyncPlayerDispAndInventory_XB_6x70), + "GC 6x70 command is larger than XB 6x70 command"); + auto out_cmd = check_size_t(data, size); + for (size_t z = 0; z < out_cmd.inventory.num_items; z++) { + out_cmd.inventory.items[z].data.decode_for_version(GameVersion::XB); + out_cmd.inventory.items[z].data.encode_for_version(GameVersion::GC, s->item_parameter_table_for_version(GameVersion::GC)); + } + send_command(target, command, flag, &out_cmd, sizeof(G_SyncPlayerDispAndInventory_DC_PC_GC_6x70)); } } @@ -417,9 +438,13 @@ static void on_send_guild_card(shared_ptr c, uint8_t command, uint8_t fl c->game_data.player(true, false)->guild_card_description = cmd.guild_card.description; break; } - case GameVersion::GC: + case GameVersion::GC: { + const auto& cmd = check_size_t(data, size); + c->game_data.player(true, false)->guild_card_description.encode(cmd.guild_card.description.decode(c->language()), c->language()); + break; + } case GameVersion::XB: { - const auto& cmd = check_size_t(data, size); + const auto& cmd = check_size_t(data, size); c->game_data.player(true, false)->guild_card_description.encode(cmd.guild_card.description.decode(c->language()), c->language()); break; } @@ -882,6 +907,7 @@ static void on_buy_shop_item(shared_ptr c, uint8_t command, uint8_t flag if (l->check_flag(Lobby::Flag::ITEM_TRACKING_ENABLED)) { auto p = c->game_data.player(); ItemData item = cmd.item_data; + item.data2d = 0; // Clear the price field item.decode_for_version(c->version()); l->on_item_id_generated_externally(item.id); p->add_item(item); diff --git a/src/ReplaySession.cc b/src/ReplaySession.cc index 82dc17e0..789f28e5 100644 --- a/src/ReplaySession.cc +++ b/src/ReplaySession.cc @@ -273,9 +273,12 @@ void ReplaySession::apply_default_mask(shared_ptr ev) { auto& mask = check_size_t(mask_data, mask_size); mask.variations.clear(0); mask.rare_seed = 0; - } else { // V3 - auto& mask = check_size_t( - mask_data, mask_size, sizeof(S_JoinGame_GC_Ep3_64)); + } else if (version == GameVersion::XB) { + auto& mask = check_size_t(mask_data, mask_size); + mask.variations.clear(0); + mask.rare_seed = 0; + } else if (version == GameVersion::DC || version == GameVersion::GC) { + auto& mask = check_size_t(mask_data, mask_size, sizeof(S_JoinGame_GC_Ep3_64)); mask.variations.clear(0); mask.rare_seed = 0; for (size_t offset = sizeof(S_JoinGame_GC_64) + diff --git a/src/SaveFileFormats.hh b/src/SaveFileFormats.hh index 78dafdda..93af7ce5 100644 --- a/src/SaveFileFormats.hh +++ b/src/SaveFileFormats.hh @@ -256,7 +256,7 @@ struct PSOGCCharacterFile { /* 0460:0044 */ parray, 4> quest_flags; /* 0660:0244 */ be_uint32_t death_count; /* 0664:0248 */ PlayerBank bank; - /* 192C:1510 */ GuildCardV3 guild_card; + /* 192C:1510 */ GuildCardGC guild_card; /* 19BC:15A0 */ parray symbol_chats; /* 1DDC:19C0 */ parray chat_shortcuts; /* 246C:2050 */ pstring auto_reply; @@ -313,7 +313,7 @@ struct PSOGCEp3CharacterFile { /* 0864:0448 */ be_uint32_t num_bank_items; /* 0868:044C */ be_uint32_t bank_meseta; /* 086C:0450 */ parray bank_items; - /* 08CC:04B0 */ GuildCardV3 guild_card; + /* 08CC:04B0 */ GuildCardGC guild_card; /* 095C:0540 */ parray symbol_chats; /* 0D7C:0960 */ parray chat_shortcuts; /* 140C:0FF0 */ pstring auto_reply; @@ -356,12 +356,12 @@ struct PSOGCGuildCardFile { /* 0000 */ be_uint32_t checksum; /* 0004 */ parray unknown_a1; struct GuildCardBE { - // Note: This struct (up through offset 0x90) is identical to GuildCardV3 - // except for 32-bit fields, which are big-endian here. + // Note: This struct (up through offset 0x90) is identical to GuildCardGC + // except for the 32-bit fields, which are big-endian here. /* 0000 */ be_uint32_t player_tag; // == 0x00000001 (not 0x00010000) /* 0004 */ be_uint32_t guild_card_number; - /* 0008 */ pstring name; - /* 0020 */ pstring description; + /* 0008 */ pstring name; + /* 0020 */ pstring description; /* 008C */ uint8_t present; /* 008D */ uint8_t language; /* 008E */ uint8_t section_id; @@ -374,7 +374,7 @@ struct PSOGCGuildCardFile { /* 0091 */ uint8_t unknown_a2; /* 0092 */ uint8_t unknown_a3; /* 0093 */ uint8_t unknown_a4; - /* 0094 */ pstring comment; + /* 0094 */ pstring comment; /* 0100 */ } __attribute__((packed)); /* 00C4 */ parray entries; @@ -396,7 +396,7 @@ struct PSOGCSnapshotFile { /* 1800A */ be_int16_t max_players; /* 1800C */ parray players_present; /* 1803C */ parray player_levels; - /* 1806C */ parray, 12> player_names; + /* 1806C */ parray, 12> player_names; /* 1818C */ bool checksum_correct() const; diff --git a/src/SendCommands.cc b/src/SendCommands.cc index bf8ec720..2c918001 100644 --- a/src/SendCommands.cc +++ b/src/SendCommands.cc @@ -163,14 +163,17 @@ void send_server_init_dc_pc_v3(shared_ptr c, uint8_t flags) { c->channel.crypt_out.reset(new PSOV2Encryption(server_key)); break; case GameVersion::DC: - case GameVersion::GC: - case GameVersion::XB: { + case GameVersion::GC: { shared_ptr det_crypt(new PSOV2OrV3DetectorEncryption( client_key, v2_crypt_initial_client_commands, v3_crypt_initial_client_commands)); c->channel.crypt_in = det_crypt; c->channel.crypt_out.reset(new PSOV2OrV3ImitatorEncryption(server_key, det_crypt)); break; } + case GameVersion::XB: + c->channel.crypt_in.reset(new PSOV3Encryption(client_key)); + c->channel.crypt_out.reset(new PSOV3Encryption(server_key)); + break; default: throw invalid_argument("incorrect client version"); } @@ -273,44 +276,6 @@ void send_update_client_config(shared_ptr c) { } } -template -void send_quest_open_file_t( - shared_ptr c, - const string& quest_name, - const string& filename, - uint32_t file_size, - QuestFileType type) { - CommandT cmd; - uint8_t command_num; - switch (type) { - case QuestFileType::ONLINE: - command_num = 0x44; - cmd.name.encode("PSO/" + quest_name); - cmd.type = 0; - break; - case QuestFileType::GBA_DEMO: - command_num = 0xA6; - cmd.name.encode("GBA Demo"); - cmd.type = 2; - break; - case QuestFileType::DOWNLOAD: - command_num = 0xA6; - cmd.name.encode("PSO/" + quest_name); - cmd.type = 0; - break; - case QuestFileType::EPISODE_3: - command_num = 0xA6; - cmd.name.encode("PSO/" + quest_name); - cmd.type = 3; - break; - default: - throw logic_error("invalid quest file type"); - } - cmd.file_size = file_size; - cmd.filename.encode(filename); - send_command_t(c, command_num, 0x00, cmd); -} - void send_quest_buffer_overflow(shared_ptr c) { // PSO Episode 3 USA doesn't natively support the B2 command, but we can add // it back to the game with some tricky commands. For details on how this @@ -320,18 +285,21 @@ void send_quest_buffer_overflow(shared_ptr c) { throw runtime_error("Episode 3 buffer overflow code must be a single segment"); } - static const string filename = "m999999p_e.bin"; - send_quest_open_file_t( - c, "BufferOverflow", filename, 0x18, QuestFileType::EPISODE_3); + S_OpenFile_PC_GC_44_A6 open_cmd; + open_cmd.name.encode("PSO/BufferOverflow"); + open_cmd.type = 3; + open_cmd.file_size = 0x18; + open_cmd.filename.encode("m999999p_e.bin"); + send_command_t(c, 0xA6, 0x00, open_cmd); - S_WriteFile_13_A7 cmd; - cmd.filename.encode(filename); - memcpy(cmd.data.data(), fn->code.data(), fn->code.size()); + S_WriteFile_13_A7 write_cmd; + write_cmd.filename.encode("m999999p_e.bin"); + memcpy(write_cmd.data.data(), fn->code.data(), fn->code.size()); if (fn->code.size() < 0x400) { - memset(&cmd.data[fn->code.size()], 0, 0x400 - fn->code.size()); + memset(&write_cmd.data[fn->code.size()], 0, 0x400 - fn->code.size()); } - cmd.data_size = fn->code.size(); - send_command_t(c, 0xA7, 0x00, cmd); + write_cmd.data_size = fn->code.size(); + send_command_t(c, 0xA7, 0x00, write_cmd); } void empty_function_call_response_handler(uint32_t, uint32_t) {} @@ -1054,7 +1022,7 @@ void send_card_search_result( } template -void send_guild_card_dc_pc_v3_t( +void send_guild_card_dc_pc_gc_t( Channel& ch, uint32_t guild_card_number, const string& name, @@ -1077,6 +1045,32 @@ void send_guild_card_dc_pc_v3_t( ch.send(0x60, 0x00, &cmd, sizeof(cmd)); } +void send_guild_card_xb( + Channel& ch, + uint32_t guild_card_number, + uint64_t xb_user_id, + const string& name, + const string& description, + uint8_t language, + uint8_t section_id, + uint8_t char_class) { + G_SendGuildCard_XB_6x06 cmd; + cmd.header.subcommand = 0x06; + cmd.header.size = sizeof(G_SendGuildCard_XB_6x06) / 4; + cmd.header.unused = 0x0000; + cmd.guild_card.player_tag = 0x00010000; + cmd.guild_card.guild_card_number = guild_card_number; + cmd.guild_card.xb_user_id_high = (xb_user_id >> 32) & 0xFFFFFFFF; + cmd.guild_card.xb_user_id_low = xb_user_id & 0xFFFFFFFF; + cmd.guild_card.name.encode(name, ch.language); + cmd.guild_card.description.encode(description, ch.language); + cmd.guild_card.present = 1; + cmd.guild_card.language = language; + cmd.guild_card.section_id = section_id; + cmd.guild_card.char_class = char_class; + ch.send(0x60, 0x00, &cmd, sizeof(cmd)); +} + static void send_guild_card_bb( Channel& ch, uint32_t guild_card_number, @@ -1104,6 +1098,7 @@ static void send_guild_card_bb( void send_guild_card( Channel& ch, uint32_t guild_card_number, + uint64_t xb_user_id, const string& name, const string& team_name, const string& description, @@ -1112,18 +1107,21 @@ void send_guild_card( uint8_t char_class) { switch (ch.version) { case GameVersion::DC: - send_guild_card_dc_pc_v3_t( + send_guild_card_dc_pc_gc_t( ch, guild_card_number, name, description, language, section_id, char_class); break; case GameVersion::PC: - send_guild_card_dc_pc_v3_t( + send_guild_card_dc_pc_gc_t( ch, guild_card_number, name, description, language, section_id, char_class); break; case GameVersion::GC: - case GameVersion::XB: - send_guild_card_dc_pc_v3_t( + send_guild_card_dc_pc_gc_t( ch, guild_card_number, name, description, language, section_id, char_class); break; + case GameVersion::XB: + send_guild_card_xb( + ch, guild_card_number, xb_user_id, name, description, language, section_id, char_class); + break; case GameVersion::BB: send_guild_card_bb(ch, guild_card_number, name, team_name, description, language, section_id, char_class); break; @@ -1139,13 +1137,16 @@ void send_guild_card(shared_ptr c, shared_ptr source) { auto source_p = source->game_data.player(true, false); uint32_t guild_card_number = source->license->serial_number; + uint64_t xb_user_id = source->license->xb_user_id + ? source->license->xb_user_id + : (0xAE00000000000000 | guild_card_number); uint8_t language = source_p->inventory.language; string name = source_p->disp.name.decode(language); string description = source_p->guild_card_description.decode(language); uint8_t section_id = source_p->disp.visual.section_id; uint8_t char_class = source_p->disp.visual.char_class; - send_guild_card(c->channel, guild_card_number, name, "", description, language, section_id, char_class); + send_guild_card(c->channel, guild_card_number, xb_user_id, name, "", description, language, section_id, char_class); } //////////////////////////////////////////////////////////////////////////////// @@ -1694,6 +1695,16 @@ void send_join_game(shared_ptr c, shared_ptr l) { case GameVersion::XB: { S_JoinGame_XB_64 cmd; size_t player_count = populate_v3_cmd(cmd); + for (size_t x = 0; x < 4; x++) { + auto lc = l->clients[x]; + if (lc) { + if (lc->xb_netloc) { + cmd.lobby_data[x].netloc = *lc->xb_netloc; + } else { + cmd.lobby_data[x].netloc.account_id = 0xAE00000000000000 | lc->license->serial_number; + } + } + } send_command_t(c, 0x64, player_count, cmd); break; } @@ -1802,6 +1813,79 @@ void send_join_lobby_t(shared_ptr c, shared_ptr l, shared_ptr c, shared_ptr l, shared_ptr joining_client = nullptr) { + auto s = c->require_server_state(); + + uint8_t command; + if (l->is_game()) { + if (joining_client) { + command = 0x65; + } else { + throw logic_error("send_join_lobby_xb should not be used for primary game join command"); + } + } else { + command = joining_client ? 0x68 : 0x67; + } + + send_player_records_t(c, l, joining_client); + + uint8_t lobby_type; + if (c->config.override_lobby_number != 0x80) { + lobby_type = c->config.override_lobby_number; + } else if (l->check_flag(Lobby::Flag::IS_OVERFLOW)) { + lobby_type = c->config.check_flag(Client::Flag::IS_EPISODE_3) ? 15 : 0; + } else { + lobby_type = l->block - 1; + } + + if ((lobby_type > 0x11) && (lobby_type != 0x67) && (lobby_type != 0xD4) && (lobby_type < 0xFC)) { + lobby_type = l->block - 1; + } + + S_JoinLobby_XB_65_67_68 cmd; + cmd.lobby_flags.client_id = c->lobby_client_id; + cmd.lobby_flags.leader_id = l->leader_id; + cmd.lobby_flags.disable_udp = 0x01; + cmd.lobby_flags.lobby_number = lobby_type; + cmd.lobby_flags.block_number = l->block; + cmd.lobby_flags.unknown_a1 = 0; + cmd.lobby_flags.event = l->event; + cmd.lobby_flags.unknown_a2 = 0; + cmd.lobby_flags.unused = 0; + + vector> lobby_clients; + if (joining_client) { + lobby_clients.emplace_back(joining_client); + } else { + for (auto lc : l->clients) { + if (lc) { + lobby_clients.emplace_back(lc); + } + } + } + + size_t used_entries = 0; + for (const auto& lc : lobby_clients) { + auto lp = lc->game_data.player(); + auto& e = cmd.entries[used_entries++]; + e.lobby_data.player_tag = 0x00010000; + e.lobby_data.guild_card_number = lc->license->serial_number; + if (lc->xb_netloc) { + e.lobby_data.netloc = *lc->xb_netloc; + } else { + e.lobby_data.netloc.account_id = 0xAE00000000000000 | lc->license->serial_number; + } + e.lobby_data.client_id = lc->lobby_client_id; + e.lobby_data.name.encode(lp->disp.name.decode(lp->inventory.language), c->language()); + e.inventory = lp->inventory; + e.inventory.encode_for_version(c->version(), s->item_parameter_table_for_version(c->version())); + e.disp = convert_player_disp_data(lp->disp, c->language(), lp->inventory.language); + e.disp.enforce_lobby_join_limits(c->version()); + } + + send_command(c, command, used_entries, &cmd, cmd.size(used_entries)); +} + void send_join_lobby_dc_nte(shared_ptr c, shared_ptr l, shared_ptr joining_client = nullptr) { uint8_t command; @@ -1869,7 +1953,7 @@ void send_join_lobby(shared_ptr c, shared_ptr l) { send_join_lobby_t(c, l); break; case GameVersion::XB: - send_join_lobby_t(c, l); + send_join_lobby_xb(c, l); break; case GameVersion::BB: send_join_lobby_t(c, l); @@ -1904,7 +1988,7 @@ void send_player_join_notification(shared_ptr c, send_join_lobby_t(c, l, joining_client); break; case GameVersion::XB: - send_join_lobby_t(c, l, joining_client); + send_join_lobby_xb(c, l, joining_client); break; case GameVersion::BB: send_join_lobby_t(c, l, joining_client); @@ -2830,26 +2914,87 @@ void send_quest_file_chunk( send_command_t(c, is_download_quest ? 0xA7 : 0x13, chunk_index, cmd); } -void send_open_quest_file(shared_ptr c, const string& quest_name, - const string& basename, shared_ptr contents, QuestFileType type) { +template +void send_open_quest_file_t( + shared_ptr c, + const string& quest_name, + const string& filename, + const string&, + uint32_t file_size, + uint32_t, + QuestFileType type) { + CommandT cmd; + uint8_t command_num; + switch (type) { + case QuestFileType::ONLINE: + command_num = 0x44; + cmd.name.encode("PSO/" + quest_name); + cmd.type = 0; + break; + case QuestFileType::GBA_DEMO: + command_num = 0xA6; + cmd.name.encode("GBA Demo"); + cmd.type = 2; + break; + case QuestFileType::DOWNLOAD: + command_num = 0xA6; + cmd.name.encode("PSO/" + quest_name); + cmd.type = 0; + break; + case QuestFileType::EPISODE_3: + command_num = 0xA6; + cmd.name.encode("PSO/" + quest_name); + cmd.type = 3; + break; + default: + throw logic_error("invalid quest file type"); + } + cmd.file_size = file_size; + cmd.filename.encode(filename); + send_command_t(c, command_num, 0x00, cmd); +} + +template <> +void send_open_quest_file_t( + shared_ptr c, + const string& quest_name, + const string& filename, + const string& xb_filename, + uint32_t file_size, + uint32_t quest_number, + QuestFileType type) { + S_OpenFile_XB_44_A6 cmd; + cmd.name.encode("PSO/" + quest_name); + cmd.type = 0; + cmd.file_size = file_size; + cmd.filename.encode(filename); + cmd.xb_filename.encode(xb_filename); + cmd.content_meta = 0x30000000 | quest_number; + send_command_t(c, (type == QuestFileType::ONLINE) ? 0x44 : 0xA6, 0x00, cmd); +} + +void send_open_quest_file( + shared_ptr c, + const string& quest_name, + const string& filename, + const string& xb_filename, + uint32_t quest_number, + QuestFileType type, + shared_ptr contents) { switch (c->version()) { case GameVersion::DC: - send_quest_open_file_t( - c, quest_name, basename, contents->size(), type); + send_open_quest_file_t(c, quest_name, filename, xb_filename, contents->size(), quest_number, type); break; case GameVersion::PC: case GameVersion::GC: - send_quest_open_file_t( - c, quest_name, basename, contents->size(), type); + send_open_quest_file_t(c, quest_name, filename, xb_filename, contents->size(), quest_number, type); break; case GameVersion::XB: - send_quest_open_file_t( - c, quest_name, basename, contents->size(), type); + send_open_quest_file_t(c, quest_name, filename, xb_filename, contents->size(), quest_number, type); break; case GameVersion::BB: - send_quest_open_file_t( - c, quest_name, basename, contents->size(), type); + send_open_quest_file_t(c, quest_name, filename, xb_filename, contents->size(), quest_number, type); break; default: throw logic_error("cannot send quest files to this version of client"); @@ -2863,12 +3008,12 @@ void send_open_quest_file(shared_ptr c, const string& quest_name, if (chunk_bytes > 0x400) { chunk_bytes = 0x400; } - send_quest_file_chunk(c, basename.c_str(), offset / 0x400, + send_quest_file_chunk(c, filename.c_str(), offset / 0x400, contents->data() + offset, chunk_bytes, (type != QuestFileType::ONLINE)); } } else { - c->sending_files.emplace(basename, contents); - c->log.info("Opened file %s", basename.c_str()); + c->sending_files.emplace(filename, contents); + c->log.info("Opened file %s", filename.c_str()); } } diff --git a/src/SendCommands.hh b/src/SendCommands.hh index 398b8b16..7c82c504 100644 --- a/src/SendCommands.hh +++ b/src/SendCommands.hh @@ -242,6 +242,7 @@ void send_card_search_result( void send_guild_card( Channel& ch, uint32_t guild_card_number, + uint64_t xb_user_id, const std::string& name, const std::string& team_name, const std::string& description, @@ -362,9 +363,11 @@ enum class QuestFileType { void send_open_quest_file( std::shared_ptr c, const std::string& quest_name, - const std::string& basename, - std::shared_ptr contents, - QuestFileType type); + const std::string& filename, + const std::string& xb_filename, + uint32_t quest_number, + QuestFileType type, + std::shared_ptr contents); void send_quest_file_chunk( std::shared_ptr c, const std::string& filename, diff --git a/src/Server.cc b/src/Server.cc index f6fe0429..f0b78aa0 100644 --- a/src/Server.cc +++ b/src/Server.cc @@ -29,13 +29,11 @@ using namespace std::placeholders; void Server::disconnect_client(shared_ptr c) { if (c->channel.is_virtual_connection) { - server_log.info( - "Client disconnected: C-%" PRIX64 " on virtual connection %p", - c->id, c->channel.bev.get()); + server_log.info("Client disconnected: C-%" PRIX64 " on virtual connection %p", c->id, c->channel.bev.get()); + } else if (c->channel.bev) { + server_log.info("Client disconnected: C-%" PRIX64 " on fd %d", c->id, bufferevent_getfd(c->channel.bev.get())); } else { - server_log.info( - "Client disconnected: C-%" PRIX64 " on fd %d", - c->id, bufferevent_getfd(c->channel.bev.get())); + server_log.info("Client C-%" PRIX64 " removed from game server", c->id); } this->state->channel_to_client.erase(&c->channel); @@ -165,6 +163,12 @@ void Server::connect_client( } } +void Server::connect_client(shared_ptr c, Channel&& ch) { + c->channel.replace_with(std::move(ch), Server::on_client_input, Server::on_client_error, this, string_printf("C-%" PRIX64, c->id)); + this->state->channel_to_client.emplace(&c->channel, c); + server_log.info("Client C-%" PRIX64 " added to game server", c->id); +} + void Server::on_listen_error(struct evconnlistener* listener) { int err = EVUTIL_SOCKET_ERROR(); server_log.error("Failure on listening socket %d: %d (%s)", diff --git a/src/Server.hh b/src/Server.hh index 98bf45c4..67860743 100644 --- a/src/Server.hh +++ b/src/Server.hh @@ -15,8 +15,7 @@ public: Server() = delete; Server(const Server&) = delete; Server(Server&&) = delete; - Server(std::shared_ptr base, - std::shared_ptr state); + Server(std::shared_ptr base, std::shared_ptr state); virtual ~Server() = default; void listen(const std::string& addr_str, const std::string& socket_path, GameVersion version, ServerBehavior initial_state); @@ -27,6 +26,7 @@ public: void connect_client(struct bufferevent* bev, uint32_t address, uint16_t client_port, uint16_t server_port, GameVersion version, ServerBehavior initial_state); + void connect_client(std::shared_ptr c, Channel&& ch); void disconnect_client(std::shared_ptr c); std::shared_ptr get_client() const; diff --git a/src/ServerShell.cc b/src/ServerShell.cc index 26ab3022..030f1034 100644 --- a/src/ServerShell.cc +++ b/src/ServerShell.cc @@ -141,6 +141,9 @@ Server commands:\n\ Add a license to the server. is some subset of the following:\n\ bb-username= (BB username)\n\ bb-password= (BB password)\n\ + xb-gamertag= (Xbox gamertag)\n\ + xb-user-id= (Xbox user ID)\n\ + xb-account-id= (Xbox account ID)\n\ gc-password= (GC password)\n\ access-key= (DC/GC/PC access key)\n\ serial= (decimal serial number; required for all licenses)\n\ @@ -319,31 +322,21 @@ Proxy session commands:\n\ for (const string& token : split(command_args, ' ')) { if (starts_with(token, "bb-username=")) { - if (token.size() >= 32) { - throw invalid_argument("username too long"); - } l->bb_username = token.substr(12); - } else if (starts_with(token, "bb-password=")) { - if (token.size() >= 32) { - throw invalid_argument("bb-password too long"); - } l->bb_password = token.substr(12); - + } else if (starts_with(token, "xb-gamertag=")) { + l->xb_gamertag = token.substr(12); + } else if (starts_with(token, "xb-user-id=")) { + l->xb_user_id = stoull(token.substr(11), nullptr, 16); + } else if (starts_with(token, "xb-account-id=")) { + l->xb_account_id = stoull(token.substr(14), nullptr, 16); } else if (starts_with(token, "gc-password=")) { - if (token.size() > 20) { - throw invalid_argument("gc-password too long"); - } l->gc_password = token.substr(12); - } else if (starts_with(token, "access-key=")) { - if (token.size() > 23) { - throw invalid_argument("access-key is too long"); - } l->access_key = token.substr(11); - } else if (starts_with(token, "serial=")) { - l->serial_number = stoul(token.substr(7)); + l->serial_number = stoul(token.substr(7), nullptr, 0); } else if (starts_with(token, "flags=")) { string mask = token.substr(6); @@ -386,31 +379,21 @@ Proxy session commands:\n\ try { for (const string& token : tokens) { if (starts_with(token, "bb-username=")) { - if (token.size() >= 32) { - throw invalid_argument("username too long"); - } l->bb_username = token.substr(12); - } else if (starts_with(token, "bb-password=")) { - if (token.size() >= 32) { - throw invalid_argument("bb-password too long"); - } l->bb_password = token.substr(12); - + } else if (starts_with(token, "xb-gamertag=")) { + l->xb_gamertag = token.substr(12); + } else if (starts_with(token, "xb-user-id=")) { + l->xb_user_id = stoull(token.substr(11), nullptr, 16); + } else if (starts_with(token, "xb-account-id=")) { + l->xb_account_id = stoull(token.substr(14), nullptr, 16); } else if (starts_with(token, "gc-password=")) { - if (token.size() > 20) { - throw invalid_argument("gc-password too long"); - } l->gc_password = token.substr(12); - } else if (starts_with(token, "access-key=")) { - if (token.size() > 23) { - throw invalid_argument("access-key is too long"); - } l->access_key = token.substr(11); - } else if (starts_with(token, "serial=")) { - l->serial_number = stoul(token.substr(7)); + l->serial_number = stoul(token.substr(7), nullptr, 0); } else if (starts_with(token, "flags=")) { string mask = token.substr(6); diff --git a/src/Version.cc b/src/Version.cc index dc0b1184..7c775aec 100644 --- a/src/Version.cc +++ b/src/Version.cc @@ -13,7 +13,7 @@ const vector version_to_login_port_name = { const vector version_to_lobby_port_name = { "bb-patch", "console-lobby", "pc-lobby", "console-lobby", "console-lobby", "bb-lobby"}; const vector version_to_proxy_port_name = { - "", "dc-proxy", "pc-proxy", "gc-proxy", "xb-proxy", "bb-proxy"}; + "", "dc-proxy", "pc-proxy", "gc-proxy", "xb", "bb-proxy"}; const char* name_for_version(GameVersion version) { switch (version) { diff --git a/system/quests/b88001-xb-e.bin b/system/quests/b88001-xb-e.bin new file mode 120000 index 00000000..87ee6c20 --- /dev/null +++ b/system/quests/b88001-xb-e.bin @@ -0,0 +1 @@ +b88001-gc-e.bin \ No newline at end of file diff --git a/system/quests/b88001-xb-f.bin b/system/quests/b88001-xb-f.bin new file mode 120000 index 00000000..b00dfca0 --- /dev/null +++ b/system/quests/b88001-xb-f.bin @@ -0,0 +1 @@ +b88001-gc-f.bin \ No newline at end of file diff --git a/system/quests/b88001-xb-g.bin b/system/quests/b88001-xb-g.bin new file mode 120000 index 00000000..8b80b089 --- /dev/null +++ b/system/quests/b88001-xb-g.bin @@ -0,0 +1 @@ +b88001-gc-g.bin \ No newline at end of file diff --git a/system/quests/b88001-xb-j.bin b/system/quests/b88001-xb-j.bin new file mode 120000 index 00000000..aa5030a9 --- /dev/null +++ b/system/quests/b88001-xb-j.bin @@ -0,0 +1 @@ +b88001-gc-j.bin \ No newline at end of file diff --git a/system/quests/b88001-xb-s.bin b/system/quests/b88001-xb-s.bin new file mode 120000 index 00000000..49c79d0a --- /dev/null +++ b/system/quests/b88001-xb-s.bin @@ -0,0 +1 @@ +b88001-gc-s.bin \ No newline at end of file diff --git a/system/quests/b88001-xb.dat b/system/quests/b88001-xb.dat new file mode 120000 index 00000000..01c660ce --- /dev/null +++ b/system/quests/b88001-xb.dat @@ -0,0 +1 @@ +b88001-gc.dat \ No newline at end of file diff --git a/system/quests/b88002-xb-e.bin b/system/quests/b88002-xb-e.bin new file mode 120000 index 00000000..fc0f71ff --- /dev/null +++ b/system/quests/b88002-xb-e.bin @@ -0,0 +1 @@ +b88002-gc-e.bin \ No newline at end of file diff --git a/system/quests/b88002-xb-f.bin b/system/quests/b88002-xb-f.bin new file mode 120000 index 00000000..c857f357 --- /dev/null +++ b/system/quests/b88002-xb-f.bin @@ -0,0 +1 @@ +b88002-gc-f.bin \ No newline at end of file diff --git a/system/quests/b88002-xb-g.bin b/system/quests/b88002-xb-g.bin new file mode 120000 index 00000000..f56b8696 --- /dev/null +++ b/system/quests/b88002-xb-g.bin @@ -0,0 +1 @@ +b88002-gc-g.bin \ No newline at end of file diff --git a/system/quests/b88002-xb-j.bin b/system/quests/b88002-xb-j.bin new file mode 120000 index 00000000..3797b574 --- /dev/null +++ b/system/quests/b88002-xb-j.bin @@ -0,0 +1 @@ +b88002-gc-j.bin \ No newline at end of file diff --git a/system/quests/b88002-xb-s.bin b/system/quests/b88002-xb-s.bin new file mode 120000 index 00000000..62bf5dc3 --- /dev/null +++ b/system/quests/b88002-xb-s.bin @@ -0,0 +1 @@ +b88002-gc-s.bin \ No newline at end of file diff --git a/system/quests/b88002-xb.dat b/system/quests/b88002-xb.dat new file mode 120000 index 00000000..fe680581 --- /dev/null +++ b/system/quests/b88002-xb.dat @@ -0,0 +1 @@ +b88002-gc.dat \ No newline at end of file diff --git a/system/quests/b88003-xb-e.bin b/system/quests/b88003-xb-e.bin new file mode 120000 index 00000000..67bd7f16 --- /dev/null +++ b/system/quests/b88003-xb-e.bin @@ -0,0 +1 @@ +b88003-gc-e.bin \ No newline at end of file diff --git a/system/quests/b88003-xb-f.bin b/system/quests/b88003-xb-f.bin new file mode 120000 index 00000000..5c818426 --- /dev/null +++ b/system/quests/b88003-xb-f.bin @@ -0,0 +1 @@ +b88003-gc-f.bin \ No newline at end of file diff --git a/system/quests/b88003-xb-g.bin b/system/quests/b88003-xb-g.bin new file mode 120000 index 00000000..56dc6d87 --- /dev/null +++ b/system/quests/b88003-xb-g.bin @@ -0,0 +1 @@ +b88003-gc-g.bin \ No newline at end of file diff --git a/system/quests/b88003-xb-j.bin b/system/quests/b88003-xb-j.bin new file mode 120000 index 00000000..f7b60645 --- /dev/null +++ b/system/quests/b88003-xb-j.bin @@ -0,0 +1 @@ +b88003-gc-j.bin \ No newline at end of file diff --git a/system/quests/b88003-xb-s.bin b/system/quests/b88003-xb-s.bin new file mode 120000 index 00000000..7f89b5e4 --- /dev/null +++ b/system/quests/b88003-xb-s.bin @@ -0,0 +1 @@ +b88003-gc-s.bin \ No newline at end of file diff --git a/system/quests/b88003-xb.dat b/system/quests/b88003-xb.dat new file mode 120000 index 00000000..7c1be99e --- /dev/null +++ b/system/quests/b88003-xb.dat @@ -0,0 +1 @@ +b88003-gc.dat \ No newline at end of file diff --git a/system/quests/b88004-xb-e.bin b/system/quests/b88004-xb-e.bin new file mode 120000 index 00000000..82c910cb --- /dev/null +++ b/system/quests/b88004-xb-e.bin @@ -0,0 +1 @@ +b88004-gc-e.bin \ No newline at end of file diff --git a/system/quests/b88004-xb-f.bin b/system/quests/b88004-xb-f.bin new file mode 120000 index 00000000..e0448305 --- /dev/null +++ b/system/quests/b88004-xb-f.bin @@ -0,0 +1 @@ +b88004-gc-f.bin \ No newline at end of file diff --git a/system/quests/b88004-xb-g.bin b/system/quests/b88004-xb-g.bin new file mode 120000 index 00000000..089efd67 --- /dev/null +++ b/system/quests/b88004-xb-g.bin @@ -0,0 +1 @@ +b88004-gc-g.bin \ No newline at end of file diff --git a/system/quests/b88004-xb-j.bin b/system/quests/b88004-xb-j.bin new file mode 120000 index 00000000..8889d990 --- /dev/null +++ b/system/quests/b88004-xb-j.bin @@ -0,0 +1 @@ +b88004-gc-j.bin \ No newline at end of file diff --git a/system/quests/b88004-xb-s.bin b/system/quests/b88004-xb-s.bin new file mode 120000 index 00000000..411da56f --- /dev/null +++ b/system/quests/b88004-xb-s.bin @@ -0,0 +1 @@ +b88004-gc-s.bin \ No newline at end of file diff --git a/system/quests/b88004-xb.dat b/system/quests/b88004-xb.dat new file mode 120000 index 00000000..30f627fe --- /dev/null +++ b/system/quests/b88004-xb.dat @@ -0,0 +1 @@ +b88004-gc.dat \ No newline at end of file diff --git a/system/quests/b88005-xb-e.bin b/system/quests/b88005-xb-e.bin new file mode 120000 index 00000000..019768d8 --- /dev/null +++ b/system/quests/b88005-xb-e.bin @@ -0,0 +1 @@ +b88005-gc-e.bin \ No newline at end of file diff --git a/system/quests/b88005-xb-f.bin b/system/quests/b88005-xb-f.bin new file mode 120000 index 00000000..121eda59 --- /dev/null +++ b/system/quests/b88005-xb-f.bin @@ -0,0 +1 @@ +b88005-gc-f.bin \ No newline at end of file diff --git a/system/quests/b88005-xb-g.bin b/system/quests/b88005-xb-g.bin new file mode 120000 index 00000000..6d8375d9 --- /dev/null +++ b/system/quests/b88005-xb-g.bin @@ -0,0 +1 @@ +b88005-gc-g.bin \ No newline at end of file diff --git a/system/quests/b88005-xb-j.bin b/system/quests/b88005-xb-j.bin new file mode 120000 index 00000000..a3484086 --- /dev/null +++ b/system/quests/b88005-xb-j.bin @@ -0,0 +1 @@ +b88005-gc-j.bin \ No newline at end of file diff --git a/system/quests/b88005-xb-s.bin b/system/quests/b88005-xb-s.bin new file mode 120000 index 00000000..96c3e2ee --- /dev/null +++ b/system/quests/b88005-xb-s.bin @@ -0,0 +1 @@ +b88005-gc-s.bin \ No newline at end of file diff --git a/system/quests/b88005-xb.dat b/system/quests/b88005-xb.dat new file mode 120000 index 00000000..5d7d49da --- /dev/null +++ b/system/quests/b88005-xb.dat @@ -0,0 +1 @@ +b88005-gc.dat \ No newline at end of file diff --git a/system/quests/b88006-xb-e.bin b/system/quests/b88006-xb-e.bin new file mode 120000 index 00000000..d5d1c098 --- /dev/null +++ b/system/quests/b88006-xb-e.bin @@ -0,0 +1 @@ +b88006-gc-e.bin \ No newline at end of file diff --git a/system/quests/b88006-xb-f.bin b/system/quests/b88006-xb-f.bin new file mode 120000 index 00000000..88bd1471 --- /dev/null +++ b/system/quests/b88006-xb-f.bin @@ -0,0 +1 @@ +b88006-gc-f.bin \ No newline at end of file diff --git a/system/quests/b88006-xb-g.bin b/system/quests/b88006-xb-g.bin new file mode 120000 index 00000000..ca520045 --- /dev/null +++ b/system/quests/b88006-xb-g.bin @@ -0,0 +1 @@ +b88006-gc-g.bin \ No newline at end of file diff --git a/system/quests/b88006-xb-j.bin b/system/quests/b88006-xb-j.bin new file mode 120000 index 00000000..936c8e78 --- /dev/null +++ b/system/quests/b88006-xb-j.bin @@ -0,0 +1 @@ +b88006-gc-j.bin \ No newline at end of file diff --git a/system/quests/b88006-xb-s.bin b/system/quests/b88006-xb-s.bin new file mode 120000 index 00000000..cca81da9 --- /dev/null +++ b/system/quests/b88006-xb-s.bin @@ -0,0 +1 @@ +b88006-gc-s.bin \ No newline at end of file diff --git a/system/quests/b88006-xb.dat b/system/quests/b88006-xb.dat new file mode 120000 index 00000000..71c28232 --- /dev/null +++ b/system/quests/b88006-xb.dat @@ -0,0 +1 @@ +b88006-gc.dat \ No newline at end of file diff --git a/system/quests/b88007-xb-e.bin b/system/quests/b88007-xb-e.bin new file mode 120000 index 00000000..57fac8aa --- /dev/null +++ b/system/quests/b88007-xb-e.bin @@ -0,0 +1 @@ +b88007-gc-e.bin \ No newline at end of file diff --git a/system/quests/b88007-xb.dat b/system/quests/b88007-xb.dat new file mode 120000 index 00000000..81cd0152 --- /dev/null +++ b/system/quests/b88007-xb.dat @@ -0,0 +1 @@ +b88007-gc.dat \ No newline at end of file diff --git a/system/quests/b88008-xb-e.bin b/system/quests/b88008-xb-e.bin new file mode 120000 index 00000000..85d4a9c0 --- /dev/null +++ b/system/quests/b88008-xb-e.bin @@ -0,0 +1 @@ +b88008-gc-e.bin \ No newline at end of file diff --git a/system/quests/b88008-xb.dat b/system/quests/b88008-xb.dat new file mode 120000 index 00000000..60bb8157 --- /dev/null +++ b/system/quests/b88008-xb.dat @@ -0,0 +1 @@ +b88008-gc.dat \ No newline at end of file diff --git a/system/quests/c88101-xb-e.bin b/system/quests/c88101-xb-e.bin new file mode 120000 index 00000000..5af90ced --- /dev/null +++ b/system/quests/c88101-xb-e.bin @@ -0,0 +1 @@ +c88101-gc-e.bin \ No newline at end of file diff --git a/system/quests/c88101-xb-f.bin b/system/quests/c88101-xb-f.bin new file mode 120000 index 00000000..b4daf231 --- /dev/null +++ b/system/quests/c88101-xb-f.bin @@ -0,0 +1 @@ +c88101-gc-f.bin \ No newline at end of file diff --git a/system/quests/c88101-xb-g.bin b/system/quests/c88101-xb-g.bin new file mode 120000 index 00000000..7d706076 --- /dev/null +++ b/system/quests/c88101-xb-g.bin @@ -0,0 +1 @@ +c88101-gc-g.bin \ No newline at end of file diff --git a/system/quests/c88101-xb-j.bin b/system/quests/c88101-xb-j.bin new file mode 120000 index 00000000..4980c1bd --- /dev/null +++ b/system/quests/c88101-xb-j.bin @@ -0,0 +1 @@ +c88101-gc-j.bin \ No newline at end of file diff --git a/system/quests/c88101-xb-s.bin b/system/quests/c88101-xb-s.bin new file mode 120000 index 00000000..b5fd7f79 --- /dev/null +++ b/system/quests/c88101-xb-s.bin @@ -0,0 +1 @@ +c88101-gc-s.bin \ No newline at end of file diff --git a/system/quests/c88101-xb.dat b/system/quests/c88101-xb.dat new file mode 120000 index 00000000..063cf904 --- /dev/null +++ b/system/quests/c88101-xb.dat @@ -0,0 +1 @@ +c88101-gc.dat \ No newline at end of file diff --git a/system/quests/c88102-xb-e.bin b/system/quests/c88102-xb-e.bin new file mode 120000 index 00000000..463fc272 --- /dev/null +++ b/system/quests/c88102-xb-e.bin @@ -0,0 +1 @@ +c88102-gc-e.bin \ No newline at end of file diff --git a/system/quests/c88102-xb-f.bin b/system/quests/c88102-xb-f.bin new file mode 120000 index 00000000..9b432b89 --- /dev/null +++ b/system/quests/c88102-xb-f.bin @@ -0,0 +1 @@ +c88102-gc-f.bin \ No newline at end of file diff --git a/system/quests/c88102-xb-g.bin b/system/quests/c88102-xb-g.bin new file mode 120000 index 00000000..dcee1869 --- /dev/null +++ b/system/quests/c88102-xb-g.bin @@ -0,0 +1 @@ +c88102-gc-g.bin \ No newline at end of file diff --git a/system/quests/c88102-xb-j.bin b/system/quests/c88102-xb-j.bin new file mode 120000 index 00000000..19f48fa7 --- /dev/null +++ b/system/quests/c88102-xb-j.bin @@ -0,0 +1 @@ +c88102-gc-j.bin \ No newline at end of file diff --git a/system/quests/c88102-xb-s.bin b/system/quests/c88102-xb-s.bin new file mode 120000 index 00000000..55a894b4 --- /dev/null +++ b/system/quests/c88102-xb-s.bin @@ -0,0 +1 @@ +c88102-gc-s.bin \ No newline at end of file diff --git a/system/quests/c88102-xb.dat b/system/quests/c88102-xb.dat new file mode 120000 index 00000000..872bea46 --- /dev/null +++ b/system/quests/c88102-xb.dat @@ -0,0 +1 @@ +c88102-gc.dat \ No newline at end of file diff --git a/system/quests/c88103-xb-e.bin b/system/quests/c88103-xb-e.bin new file mode 120000 index 00000000..0aac18ab --- /dev/null +++ b/system/quests/c88103-xb-e.bin @@ -0,0 +1 @@ +c88103-gc-e.bin \ No newline at end of file diff --git a/system/quests/c88103-xb-f.bin b/system/quests/c88103-xb-f.bin new file mode 120000 index 00000000..f09e01c6 --- /dev/null +++ b/system/quests/c88103-xb-f.bin @@ -0,0 +1 @@ +c88103-gc-f.bin \ No newline at end of file diff --git a/system/quests/c88103-xb-g.bin b/system/quests/c88103-xb-g.bin new file mode 120000 index 00000000..48cffe7a --- /dev/null +++ b/system/quests/c88103-xb-g.bin @@ -0,0 +1 @@ +c88103-gc-g.bin \ No newline at end of file diff --git a/system/quests/c88103-xb-j.bin b/system/quests/c88103-xb-j.bin new file mode 120000 index 00000000..80e25d57 --- /dev/null +++ b/system/quests/c88103-xb-j.bin @@ -0,0 +1 @@ +c88103-gc-j.bin \ No newline at end of file diff --git a/system/quests/c88103-xb-s.bin b/system/quests/c88103-xb-s.bin new file mode 120000 index 00000000..ecbfa635 --- /dev/null +++ b/system/quests/c88103-xb-s.bin @@ -0,0 +1 @@ +c88103-gc-s.bin \ No newline at end of file diff --git a/system/quests/c88103-xb.dat b/system/quests/c88103-xb.dat new file mode 120000 index 00000000..93983356 --- /dev/null +++ b/system/quests/c88103-xb.dat @@ -0,0 +1 @@ +c88103-gc.dat \ No newline at end of file diff --git a/system/quests/c88104-xb-e.bin b/system/quests/c88104-xb-e.bin new file mode 120000 index 00000000..8b6c7b68 --- /dev/null +++ b/system/quests/c88104-xb-e.bin @@ -0,0 +1 @@ +c88104-gc-e.bin \ No newline at end of file diff --git a/system/quests/c88104-xb-f.bin b/system/quests/c88104-xb-f.bin new file mode 120000 index 00000000..e0c23036 --- /dev/null +++ b/system/quests/c88104-xb-f.bin @@ -0,0 +1 @@ +c88104-gc-f.bin \ No newline at end of file diff --git a/system/quests/c88104-xb-g.bin b/system/quests/c88104-xb-g.bin new file mode 120000 index 00000000..b4ee9822 --- /dev/null +++ b/system/quests/c88104-xb-g.bin @@ -0,0 +1 @@ +c88104-gc-g.bin \ No newline at end of file diff --git a/system/quests/c88104-xb-j.bin b/system/quests/c88104-xb-j.bin new file mode 120000 index 00000000..41787b5e --- /dev/null +++ b/system/quests/c88104-xb-j.bin @@ -0,0 +1 @@ +c88104-gc-j.bin \ No newline at end of file diff --git a/system/quests/c88104-xb-s.bin b/system/quests/c88104-xb-s.bin new file mode 120000 index 00000000..a1f538c3 --- /dev/null +++ b/system/quests/c88104-xb-s.bin @@ -0,0 +1 @@ +c88104-gc-s.bin \ No newline at end of file diff --git a/system/quests/c88104-xb.dat b/system/quests/c88104-xb.dat new file mode 120000 index 00000000..27859a25 --- /dev/null +++ b/system/quests/c88104-xb.dat @@ -0,0 +1 @@ +c88104-gc.dat \ No newline at end of file diff --git a/system/quests/c88105-xb-e.bin b/system/quests/c88105-xb-e.bin new file mode 120000 index 00000000..985fcb71 --- /dev/null +++ b/system/quests/c88105-xb-e.bin @@ -0,0 +1 @@ +c88105-gc-e.bin \ No newline at end of file diff --git a/system/quests/c88105-xb-f.bin b/system/quests/c88105-xb-f.bin new file mode 120000 index 00000000..5e2746d3 --- /dev/null +++ b/system/quests/c88105-xb-f.bin @@ -0,0 +1 @@ +c88105-gc-f.bin \ No newline at end of file diff --git a/system/quests/c88105-xb-g.bin b/system/quests/c88105-xb-g.bin new file mode 120000 index 00000000..0ad7734c --- /dev/null +++ b/system/quests/c88105-xb-g.bin @@ -0,0 +1 @@ +c88105-gc-g.bin \ No newline at end of file diff --git a/system/quests/c88105-xb-j.bin b/system/quests/c88105-xb-j.bin new file mode 120000 index 00000000..50233bf2 --- /dev/null +++ b/system/quests/c88105-xb-j.bin @@ -0,0 +1 @@ +c88105-gc-j.bin \ No newline at end of file diff --git a/system/quests/c88105-xb-s.bin b/system/quests/c88105-xb-s.bin new file mode 120000 index 00000000..7c246380 --- /dev/null +++ b/system/quests/c88105-xb-s.bin @@ -0,0 +1 @@ +c88105-gc-s.bin \ No newline at end of file diff --git a/system/quests/c88105-xb.dat b/system/quests/c88105-xb.dat new file mode 120000 index 00000000..f74a56b0 --- /dev/null +++ b/system/quests/c88105-xb.dat @@ -0,0 +1 @@ +c88105-gc.dat \ No newline at end of file diff --git a/system/quests/c88106-xb-e.bin b/system/quests/c88106-xb-e.bin new file mode 120000 index 00000000..bb48c5c7 --- /dev/null +++ b/system/quests/c88106-xb-e.bin @@ -0,0 +1 @@ +c88106-gc-e.bin \ No newline at end of file diff --git a/system/quests/c88106-xb-f.bin b/system/quests/c88106-xb-f.bin new file mode 120000 index 00000000..11182f6d --- /dev/null +++ b/system/quests/c88106-xb-f.bin @@ -0,0 +1 @@ +c88106-gc-f.bin \ No newline at end of file diff --git a/system/quests/c88106-xb-g.bin b/system/quests/c88106-xb-g.bin new file mode 120000 index 00000000..fb4c6833 --- /dev/null +++ b/system/quests/c88106-xb-g.bin @@ -0,0 +1 @@ +c88106-gc-g.bin \ No newline at end of file diff --git a/system/quests/c88106-xb-j.bin b/system/quests/c88106-xb-j.bin new file mode 120000 index 00000000..3e86b5ce --- /dev/null +++ b/system/quests/c88106-xb-j.bin @@ -0,0 +1 @@ +c88106-gc-j.bin \ No newline at end of file diff --git a/system/quests/c88106-xb-s.bin b/system/quests/c88106-xb-s.bin new file mode 120000 index 00000000..c1b32c68 --- /dev/null +++ b/system/quests/c88106-xb-s.bin @@ -0,0 +1 @@ +c88106-gc-s.bin \ No newline at end of file diff --git a/system/quests/c88106-xb.dat b/system/quests/c88106-xb.dat new file mode 120000 index 00000000..acb995ad --- /dev/null +++ b/system/quests/c88106-xb.dat @@ -0,0 +1 @@ +c88106-gc.dat \ No newline at end of file diff --git a/system/quests/c88107-xb-e.bin b/system/quests/c88107-xb-e.bin new file mode 120000 index 00000000..409251fd --- /dev/null +++ b/system/quests/c88107-xb-e.bin @@ -0,0 +1 @@ +c88107-gc-e.bin \ No newline at end of file diff --git a/system/quests/c88107-xb-f.bin b/system/quests/c88107-xb-f.bin new file mode 120000 index 00000000..255bb85f --- /dev/null +++ b/system/quests/c88107-xb-f.bin @@ -0,0 +1 @@ +c88107-gc-f.bin \ No newline at end of file diff --git a/system/quests/c88107-xb-g.bin b/system/quests/c88107-xb-g.bin new file mode 120000 index 00000000..a5cba825 --- /dev/null +++ b/system/quests/c88107-xb-g.bin @@ -0,0 +1 @@ +c88107-gc-g.bin \ No newline at end of file diff --git a/system/quests/c88107-xb-j.bin b/system/quests/c88107-xb-j.bin new file mode 120000 index 00000000..b3564e2d --- /dev/null +++ b/system/quests/c88107-xb-j.bin @@ -0,0 +1 @@ +c88107-gc-j.bin \ No newline at end of file diff --git a/system/quests/c88107-xb-s.bin b/system/quests/c88107-xb-s.bin new file mode 120000 index 00000000..eeefd934 --- /dev/null +++ b/system/quests/c88107-xb-s.bin @@ -0,0 +1 @@ +c88107-gc-s.bin \ No newline at end of file diff --git a/system/quests/c88107-xb.dat b/system/quests/c88107-xb.dat new file mode 120000 index 00000000..21bd2bd6 --- /dev/null +++ b/system/quests/c88107-xb.dat @@ -0,0 +1 @@ +c88107-gc.dat \ No newline at end of file diff --git a/system/quests/c88108-xb-e.bin b/system/quests/c88108-xb-e.bin new file mode 120000 index 00000000..0f351f94 --- /dev/null +++ b/system/quests/c88108-xb-e.bin @@ -0,0 +1 @@ +c88108-gc-e.bin \ No newline at end of file diff --git a/system/quests/c88108-xb-f.bin b/system/quests/c88108-xb-f.bin new file mode 120000 index 00000000..5e011875 --- /dev/null +++ b/system/quests/c88108-xb-f.bin @@ -0,0 +1 @@ +c88108-gc-f.bin \ No newline at end of file diff --git a/system/quests/c88108-xb-g.bin b/system/quests/c88108-xb-g.bin new file mode 120000 index 00000000..9c701e6f --- /dev/null +++ b/system/quests/c88108-xb-g.bin @@ -0,0 +1 @@ +c88108-gc-g.bin \ No newline at end of file diff --git a/system/quests/c88108-xb-j.bin b/system/quests/c88108-xb-j.bin new file mode 120000 index 00000000..156ac24d --- /dev/null +++ b/system/quests/c88108-xb-j.bin @@ -0,0 +1 @@ +c88108-gc-j.bin \ No newline at end of file diff --git a/system/quests/c88108-xb-s.bin b/system/quests/c88108-xb-s.bin new file mode 120000 index 00000000..e2558b3e --- /dev/null +++ b/system/quests/c88108-xb-s.bin @@ -0,0 +1 @@ +c88108-gc-s.bin \ No newline at end of file diff --git a/system/quests/c88108-xb.dat b/system/quests/c88108-xb.dat new file mode 120000 index 00000000..dc6bbdb1 --- /dev/null +++ b/system/quests/c88108-xb.dat @@ -0,0 +1 @@ +c88108-gc.dat \ No newline at end of file diff --git a/system/quests/c88109-xb-e.bin b/system/quests/c88109-xb-e.bin new file mode 120000 index 00000000..cb3507e2 --- /dev/null +++ b/system/quests/c88109-xb-e.bin @@ -0,0 +1 @@ +c88109-gc-e.bin \ No newline at end of file diff --git a/system/quests/c88109-xb-f.bin b/system/quests/c88109-xb-f.bin new file mode 120000 index 00000000..a28d7b4f --- /dev/null +++ b/system/quests/c88109-xb-f.bin @@ -0,0 +1 @@ +c88109-gc-f.bin \ No newline at end of file diff --git a/system/quests/c88109-xb-g.bin b/system/quests/c88109-xb-g.bin new file mode 120000 index 00000000..f34628ea --- /dev/null +++ b/system/quests/c88109-xb-g.bin @@ -0,0 +1 @@ +c88109-gc-g.bin \ No newline at end of file diff --git a/system/quests/c88109-xb-j.bin b/system/quests/c88109-xb-j.bin new file mode 120000 index 00000000..0f0dbd4a --- /dev/null +++ b/system/quests/c88109-xb-j.bin @@ -0,0 +1 @@ +c88109-gc-j.bin \ No newline at end of file diff --git a/system/quests/c88109-xb-s.bin b/system/quests/c88109-xb-s.bin new file mode 120000 index 00000000..8bbf1077 --- /dev/null +++ b/system/quests/c88109-xb-s.bin @@ -0,0 +1 @@ +c88109-gc-s.bin \ No newline at end of file diff --git a/system/quests/c88109-xb.dat b/system/quests/c88109-xb.dat new file mode 120000 index 00000000..43311dde --- /dev/null +++ b/system/quests/c88109-xb.dat @@ -0,0 +1 @@ +c88109-gc.dat \ No newline at end of file diff --git a/system/quests/d88201-xb-e.bin b/system/quests/d88201-xb-e.bin new file mode 120000 index 00000000..3b81ddbd --- /dev/null +++ b/system/quests/d88201-xb-e.bin @@ -0,0 +1 @@ +d88201-gc-e.bin \ No newline at end of file diff --git a/system/quests/d88201-xb-f.bin b/system/quests/d88201-xb-f.bin new file mode 120000 index 00000000..15e7fdd3 --- /dev/null +++ b/system/quests/d88201-xb-f.bin @@ -0,0 +1 @@ +d88201-gc-f.bin \ No newline at end of file diff --git a/system/quests/d88201-xb-g.bin b/system/quests/d88201-xb-g.bin new file mode 120000 index 00000000..e2b7f1e7 --- /dev/null +++ b/system/quests/d88201-xb-g.bin @@ -0,0 +1 @@ +d88201-gc-g.bin \ No newline at end of file diff --git a/system/quests/d88201-xb-j.bin b/system/quests/d88201-xb-j.bin new file mode 120000 index 00000000..ff5b4757 --- /dev/null +++ b/system/quests/d88201-xb-j.bin @@ -0,0 +1 @@ +d88201-gc-j.bin \ No newline at end of file diff --git a/system/quests/d88201-xb-s.bin b/system/quests/d88201-xb-s.bin new file mode 120000 index 00000000..00ccd6aa --- /dev/null +++ b/system/quests/d88201-xb-s.bin @@ -0,0 +1 @@ +d88201-gc-s.bin \ No newline at end of file diff --git a/system/quests/d88201-xb.dat b/system/quests/d88201-xb.dat new file mode 120000 index 00000000..5007139c --- /dev/null +++ b/system/quests/d88201-xb.dat @@ -0,0 +1 @@ +d88201-gc.dat \ No newline at end of file diff --git a/system/quests/d88202-xb-e.bin b/system/quests/d88202-xb-e.bin new file mode 120000 index 00000000..23709091 --- /dev/null +++ b/system/quests/d88202-xb-e.bin @@ -0,0 +1 @@ +d88202-gc-e.bin \ No newline at end of file diff --git a/system/quests/d88202-xb-f.bin b/system/quests/d88202-xb-f.bin new file mode 120000 index 00000000..054e0a46 --- /dev/null +++ b/system/quests/d88202-xb-f.bin @@ -0,0 +1 @@ +d88202-gc-f.bin \ No newline at end of file diff --git a/system/quests/d88202-xb-g.bin b/system/quests/d88202-xb-g.bin new file mode 120000 index 00000000..89d1ef24 --- /dev/null +++ b/system/quests/d88202-xb-g.bin @@ -0,0 +1 @@ +d88202-gc-g.bin \ No newline at end of file diff --git a/system/quests/d88202-xb-j.bin b/system/quests/d88202-xb-j.bin new file mode 120000 index 00000000..a23fd864 --- /dev/null +++ b/system/quests/d88202-xb-j.bin @@ -0,0 +1 @@ +d88202-gc-j.bin \ No newline at end of file diff --git a/system/quests/d88202-xb-s.bin b/system/quests/d88202-xb-s.bin new file mode 120000 index 00000000..9728ab36 --- /dev/null +++ b/system/quests/d88202-xb-s.bin @@ -0,0 +1 @@ +d88202-gc-s.bin \ No newline at end of file diff --git a/system/quests/d88202-xb.dat b/system/quests/d88202-xb.dat new file mode 120000 index 00000000..a2732957 --- /dev/null +++ b/system/quests/d88202-xb.dat @@ -0,0 +1 @@ +d88202-gc.dat \ No newline at end of file diff --git a/system/quests/d88203-xb-e.bin b/system/quests/d88203-xb-e.bin new file mode 120000 index 00000000..146a30de --- /dev/null +++ b/system/quests/d88203-xb-e.bin @@ -0,0 +1 @@ +d88203-gc-e.bin \ No newline at end of file diff --git a/system/quests/d88203-xb.dat b/system/quests/d88203-xb.dat new file mode 120000 index 00000000..20480d60 --- /dev/null +++ b/system/quests/d88203-xb.dat @@ -0,0 +1 @@ +d88203-gc.dat \ No newline at end of file diff --git a/system/quests/d88204-xb-e.bin b/system/quests/d88204-xb-e.bin new file mode 120000 index 00000000..474e140b --- /dev/null +++ b/system/quests/d88204-xb-e.bin @@ -0,0 +1 @@ +d88204-gc-e.bin \ No newline at end of file diff --git a/system/quests/d88204-xb.dat b/system/quests/d88204-xb.dat new file mode 120000 index 00000000..4813204f --- /dev/null +++ b/system/quests/d88204-xb.dat @@ -0,0 +1 @@ +d88204-gc.dat \ No newline at end of file diff --git a/system/quests/d88205-xb-e.bin b/system/quests/d88205-xb-e.bin new file mode 120000 index 00000000..f6995a27 --- /dev/null +++ b/system/quests/d88205-xb-e.bin @@ -0,0 +1 @@ +d88205-gc-e.bin \ No newline at end of file diff --git a/system/quests/d88205-xb.dat b/system/quests/d88205-xb.dat new file mode 120000 index 00000000..94f05a6e --- /dev/null +++ b/system/quests/d88205-xb.dat @@ -0,0 +1 @@ +d88205-gc.dat \ No newline at end of file diff --git a/system/quests/q000-dl-xb-e.bin b/system/quests/q000-dl-xb-e.bin new file mode 120000 index 00000000..dc038313 --- /dev/null +++ b/system/quests/q000-dl-xb-e.bin @@ -0,0 +1 @@ +q000-dl-gc-e.bin \ No newline at end of file diff --git a/system/quests/q000-dl-xb.dat b/system/quests/q000-dl-xb.dat new file mode 120000 index 00000000..621e1b68 --- /dev/null +++ b/system/quests/q000-dl-xb.dat @@ -0,0 +1 @@ +q000-dl-gc.dat \ No newline at end of file diff --git a/system/quests/q027-dl-xb-e.bin b/system/quests/q027-dl-xb-e.bin new file mode 120000 index 00000000..f195c228 --- /dev/null +++ b/system/quests/q027-dl-xb-e.bin @@ -0,0 +1 @@ +q027-dl-gc-e.bin \ No newline at end of file diff --git a/system/quests/q027-dl-xb.dat b/system/quests/q027-dl-xb.dat new file mode 120000 index 00000000..08fe7e88 --- /dev/null +++ b/system/quests/q027-dl-xb.dat @@ -0,0 +1 @@ +q027-dl-gc.dat \ No newline at end of file diff --git a/system/quests/q058-ret-xb-e.bin b/system/quests/q058-ret-xb-e.bin new file mode 120000 index 00000000..27953dc9 --- /dev/null +++ b/system/quests/q058-ret-xb-e.bin @@ -0,0 +1 @@ +q058-ret-gc-e.bin \ No newline at end of file diff --git a/system/quests/q058-ret-xb-f.bin b/system/quests/q058-ret-xb-f.bin new file mode 120000 index 00000000..5bf81f35 --- /dev/null +++ b/system/quests/q058-ret-xb-f.bin @@ -0,0 +1 @@ +q058-ret-gc-f.bin \ No newline at end of file diff --git a/system/quests/q058-ret-xb-g.bin b/system/quests/q058-ret-xb-g.bin new file mode 120000 index 00000000..c51c7b72 --- /dev/null +++ b/system/quests/q058-ret-xb-g.bin @@ -0,0 +1 @@ +q058-ret-gc-g.bin \ No newline at end of file diff --git a/system/quests/q058-ret-xb-j.bin b/system/quests/q058-ret-xb-j.bin new file mode 120000 index 00000000..680c90f2 --- /dev/null +++ b/system/quests/q058-ret-xb-j.bin @@ -0,0 +1 @@ +q058-ret-gc-j.bin \ No newline at end of file diff --git a/system/quests/q058-ret-xb-s.bin b/system/quests/q058-ret-xb-s.bin new file mode 120000 index 00000000..10b70495 --- /dev/null +++ b/system/quests/q058-ret-xb-s.bin @@ -0,0 +1 @@ +q058-ret-gc-s.bin \ No newline at end of file diff --git a/system/quests/q058-ret-xb.dat b/system/quests/q058-ret-xb.dat new file mode 120000 index 00000000..b658c989 --- /dev/null +++ b/system/quests/q058-ret-xb.dat @@ -0,0 +1 @@ +q058-ret-gc.dat \ No newline at end of file diff --git a/system/quests/q059-ret-xb-e.bin b/system/quests/q059-ret-xb-e.bin new file mode 120000 index 00000000..74274d03 --- /dev/null +++ b/system/quests/q059-ret-xb-e.bin @@ -0,0 +1 @@ +q059-ret-gc-e.bin \ No newline at end of file diff --git a/system/quests/q059-ret-xb-f.bin b/system/quests/q059-ret-xb-f.bin new file mode 120000 index 00000000..5eb43b51 --- /dev/null +++ b/system/quests/q059-ret-xb-f.bin @@ -0,0 +1 @@ +q059-ret-gc-f.bin \ No newline at end of file diff --git a/system/quests/q059-ret-xb-g.bin b/system/quests/q059-ret-xb-g.bin new file mode 120000 index 00000000..8467d5a3 --- /dev/null +++ b/system/quests/q059-ret-xb-g.bin @@ -0,0 +1 @@ +q059-ret-gc-g.bin \ No newline at end of file diff --git a/system/quests/q059-ret-xb-j.bin b/system/quests/q059-ret-xb-j.bin new file mode 120000 index 00000000..0ffbc969 --- /dev/null +++ b/system/quests/q059-ret-xb-j.bin @@ -0,0 +1 @@ +q059-ret-gc-j.bin \ No newline at end of file diff --git a/system/quests/q059-ret-xb-s.bin b/system/quests/q059-ret-xb-s.bin new file mode 120000 index 00000000..ae751bce --- /dev/null +++ b/system/quests/q059-ret-xb-s.bin @@ -0,0 +1 @@ +q059-ret-gc-s.bin \ No newline at end of file diff --git a/system/quests/q059-ret-xb.dat b/system/quests/q059-ret-xb.dat new file mode 120000 index 00000000..b38f4227 --- /dev/null +++ b/system/quests/q059-ret-xb.dat @@ -0,0 +1 @@ +q059-ret-gc.dat \ No newline at end of file diff --git a/system/quests/q060-ret-xb-e.bin b/system/quests/q060-ret-xb-e.bin new file mode 120000 index 00000000..e88d1aaf --- /dev/null +++ b/system/quests/q060-ret-xb-e.bin @@ -0,0 +1 @@ +q060-ret-gc-e.bin \ No newline at end of file diff --git a/system/quests/q060-ret-xb-f.bin b/system/quests/q060-ret-xb-f.bin new file mode 120000 index 00000000..a87d1808 --- /dev/null +++ b/system/quests/q060-ret-xb-f.bin @@ -0,0 +1 @@ +q060-ret-gc-f.bin \ No newline at end of file diff --git a/system/quests/q060-ret-xb-g.bin b/system/quests/q060-ret-xb-g.bin new file mode 120000 index 00000000..251142e2 --- /dev/null +++ b/system/quests/q060-ret-xb-g.bin @@ -0,0 +1 @@ +q060-ret-gc-g.bin \ No newline at end of file diff --git a/system/quests/q060-ret-xb-j.bin b/system/quests/q060-ret-xb-j.bin new file mode 120000 index 00000000..1b7f5992 --- /dev/null +++ b/system/quests/q060-ret-xb-j.bin @@ -0,0 +1 @@ +q060-ret-gc-j.bin \ No newline at end of file diff --git a/system/quests/q060-ret-xb-s.bin b/system/quests/q060-ret-xb-s.bin new file mode 120000 index 00000000..b5e50fdc --- /dev/null +++ b/system/quests/q060-ret-xb-s.bin @@ -0,0 +1 @@ +q060-ret-gc-s.bin \ No newline at end of file diff --git a/system/quests/q060-ret-xb.dat b/system/quests/q060-ret-xb.dat new file mode 120000 index 00000000..febb4dbc --- /dev/null +++ b/system/quests/q060-ret-xb.dat @@ -0,0 +1 @@ +q060-ret-gc.dat \ No newline at end of file diff --git a/system/quests/q068-ret-xb-e.bin b/system/quests/q068-ret-xb-e.bin new file mode 120000 index 00000000..852cc7fa --- /dev/null +++ b/system/quests/q068-ret-xb-e.bin @@ -0,0 +1 @@ +q068-ret-gc-e.bin \ No newline at end of file diff --git a/system/quests/q068-ret-xb-f.bin b/system/quests/q068-ret-xb-f.bin new file mode 120000 index 00000000..39956bfd --- /dev/null +++ b/system/quests/q068-ret-xb-f.bin @@ -0,0 +1 @@ +q068-ret-gc-f.bin \ No newline at end of file diff --git a/system/quests/q068-ret-xb-g.bin b/system/quests/q068-ret-xb-g.bin new file mode 120000 index 00000000..29393b25 --- /dev/null +++ b/system/quests/q068-ret-xb-g.bin @@ -0,0 +1 @@ +q068-ret-gc-g.bin \ No newline at end of file diff --git a/system/quests/q068-ret-xb-j.bin b/system/quests/q068-ret-xb-j.bin new file mode 120000 index 00000000..9095e9a3 --- /dev/null +++ b/system/quests/q068-ret-xb-j.bin @@ -0,0 +1 @@ +q068-ret-gc-j.bin \ No newline at end of file diff --git a/system/quests/q068-ret-xb-s.bin b/system/quests/q068-ret-xb-s.bin new file mode 120000 index 00000000..07d3132b --- /dev/null +++ b/system/quests/q068-ret-xb-s.bin @@ -0,0 +1 @@ +q068-ret-gc-s.bin \ No newline at end of file diff --git a/system/quests/q068-ret-xb.dat b/system/quests/q068-ret-xb.dat new file mode 120000 index 00000000..3b8c45c5 --- /dev/null +++ b/system/quests/q068-ret-xb.dat @@ -0,0 +1 @@ +q068-ret-gc.dat \ No newline at end of file diff --git a/system/quests/q073-evt-xb-e.bin b/system/quests/q073-evt-xb-e.bin new file mode 120000 index 00000000..6ebafaea --- /dev/null +++ b/system/quests/q073-evt-xb-e.bin @@ -0,0 +1 @@ +q073-evt-gc-e.bin \ No newline at end of file diff --git a/system/quests/q073-evt-xb-f.bin b/system/quests/q073-evt-xb-f.bin new file mode 120000 index 00000000..036041c4 --- /dev/null +++ b/system/quests/q073-evt-xb-f.bin @@ -0,0 +1 @@ +q073-evt-gc-f.bin \ No newline at end of file diff --git a/system/quests/q073-evt-xb-g.bin b/system/quests/q073-evt-xb-g.bin new file mode 120000 index 00000000..6ed4aa39 --- /dev/null +++ b/system/quests/q073-evt-xb-g.bin @@ -0,0 +1 @@ +q073-evt-gc-g.bin \ No newline at end of file diff --git a/system/quests/q073-evt-xb-j.bin b/system/quests/q073-evt-xb-j.bin new file mode 120000 index 00000000..af25e6e9 --- /dev/null +++ b/system/quests/q073-evt-xb-j.bin @@ -0,0 +1 @@ +q073-evt-gc-j.bin \ No newline at end of file diff --git a/system/quests/q073-evt-xb-s.bin b/system/quests/q073-evt-xb-s.bin new file mode 120000 index 00000000..85510eb4 --- /dev/null +++ b/system/quests/q073-evt-xb-s.bin @@ -0,0 +1 @@ +q073-evt-gc-s.bin \ No newline at end of file diff --git a/system/quests/q073-evt-xb.dat b/system/quests/q073-evt-xb.dat new file mode 120000 index 00000000..71face17 --- /dev/null +++ b/system/quests/q073-evt-xb.dat @@ -0,0 +1 @@ +q073-evt-gc.dat \ No newline at end of file diff --git a/system/quests/q086-ret-xb-j.bin b/system/quests/q086-ret-xb-j.bin new file mode 120000 index 00000000..4eb99b9a --- /dev/null +++ b/system/quests/q086-ret-xb-j.bin @@ -0,0 +1 @@ +q086-ret-gc-j.bin \ No newline at end of file diff --git a/system/quests/q086-ret-xb.dat b/system/quests/q086-ret-xb.dat new file mode 120000 index 00000000..3f4372b1 --- /dev/null +++ b/system/quests/q086-ret-xb.dat @@ -0,0 +1 @@ +q086-ret-gc.dat \ No newline at end of file diff --git a/system/quests/q087-ret-xb-j.bin b/system/quests/q087-ret-xb-j.bin new file mode 120000 index 00000000..566754b5 --- /dev/null +++ b/system/quests/q087-ret-xb-j.bin @@ -0,0 +1 @@ +q087-ret-gc-j.bin \ No newline at end of file diff --git a/system/quests/q087-ret-xb.dat b/system/quests/q087-ret-xb.dat new file mode 120000 index 00000000..aaeec9ce --- /dev/null +++ b/system/quests/q087-ret-xb.dat @@ -0,0 +1 @@ +q087-ret-gc.dat \ No newline at end of file diff --git a/system/quests/q096-evt-xb-e.bin b/system/quests/q096-evt-xb-e.bin new file mode 120000 index 00000000..902159fe --- /dev/null +++ b/system/quests/q096-evt-xb-e.bin @@ -0,0 +1 @@ +q096-evt-gc-e.bin \ No newline at end of file diff --git a/system/quests/q096-evt-xb.dat b/system/quests/q096-evt-xb.dat new file mode 120000 index 00000000..430363b8 --- /dev/null +++ b/system/quests/q096-evt-xb.dat @@ -0,0 +1 @@ +q096-evt-gc.dat \ No newline at end of file diff --git a/system/quests/q101-ext-xb-e.bin b/system/quests/q101-ext-xb-e.bin new file mode 120000 index 00000000..b7e40c1f --- /dev/null +++ b/system/quests/q101-ext-xb-e.bin @@ -0,0 +1 @@ +q101-ext-gc-e.bin \ No newline at end of file diff --git a/system/quests/q101-ext-xb-f.bin b/system/quests/q101-ext-xb-f.bin new file mode 120000 index 00000000..b41cb920 --- /dev/null +++ b/system/quests/q101-ext-xb-f.bin @@ -0,0 +1 @@ +q101-ext-gc-f.bin \ No newline at end of file diff --git a/system/quests/q101-ext-xb-g.bin b/system/quests/q101-ext-xb-g.bin new file mode 120000 index 00000000..88d3ad44 --- /dev/null +++ b/system/quests/q101-ext-xb-g.bin @@ -0,0 +1 @@ +q101-ext-gc-g.bin \ No newline at end of file diff --git a/system/quests/q101-ext-xb-j.bin b/system/quests/q101-ext-xb-j.bin new file mode 120000 index 00000000..01d5664a --- /dev/null +++ b/system/quests/q101-ext-xb-j.bin @@ -0,0 +1 @@ +q101-ext-gc-j.bin \ No newline at end of file diff --git a/system/quests/q101-ext-xb-s.bin b/system/quests/q101-ext-xb-s.bin new file mode 120000 index 00000000..266a74c5 --- /dev/null +++ b/system/quests/q101-ext-xb-s.bin @@ -0,0 +1 @@ +q101-ext-gc-s.bin \ No newline at end of file diff --git a/system/quests/q101-ext-xb.dat b/system/quests/q101-ext-xb.dat new file mode 120000 index 00000000..05d2f562 --- /dev/null +++ b/system/quests/q101-ext-xb.dat @@ -0,0 +1 @@ +q101-ext-gc.dat \ No newline at end of file diff --git a/system/quests/q102-ext-xb-e.bin b/system/quests/q102-ext-xb-e.bin new file mode 120000 index 00000000..6a67cd38 --- /dev/null +++ b/system/quests/q102-ext-xb-e.bin @@ -0,0 +1 @@ +q102-ext-gc-e.bin \ No newline at end of file diff --git a/system/quests/q102-ext-xb-f.bin b/system/quests/q102-ext-xb-f.bin new file mode 120000 index 00000000..d2e04295 --- /dev/null +++ b/system/quests/q102-ext-xb-f.bin @@ -0,0 +1 @@ +q102-ext-gc-f.bin \ No newline at end of file diff --git a/system/quests/q102-ext-xb-g.bin b/system/quests/q102-ext-xb-g.bin new file mode 120000 index 00000000..68b35c6a --- /dev/null +++ b/system/quests/q102-ext-xb-g.bin @@ -0,0 +1 @@ +q102-ext-gc-g.bin \ No newline at end of file diff --git a/system/quests/q102-ext-xb-j.bin b/system/quests/q102-ext-xb-j.bin new file mode 120000 index 00000000..d8e40211 --- /dev/null +++ b/system/quests/q102-ext-xb-j.bin @@ -0,0 +1 @@ +q102-ext-gc-j.bin \ No newline at end of file diff --git a/system/quests/q102-ext-xb-s.bin b/system/quests/q102-ext-xb-s.bin new file mode 120000 index 00000000..adaa79a4 --- /dev/null +++ b/system/quests/q102-ext-xb-s.bin @@ -0,0 +1 @@ +q102-ext-gc-s.bin \ No newline at end of file diff --git a/system/quests/q102-ext-xb.dat b/system/quests/q102-ext-xb.dat new file mode 120000 index 00000000..2b31fa7b --- /dev/null +++ b/system/quests/q102-ext-xb.dat @@ -0,0 +1 @@ +q102-ext-gc.dat \ No newline at end of file diff --git a/system/quests/q103-ext-xb-e.bin b/system/quests/q103-ext-xb-e.bin new file mode 120000 index 00000000..e37ac56d --- /dev/null +++ b/system/quests/q103-ext-xb-e.bin @@ -0,0 +1 @@ +q103-ext-gc-e.bin \ No newline at end of file diff --git a/system/quests/q103-ext-xb-f.bin b/system/quests/q103-ext-xb-f.bin new file mode 120000 index 00000000..951f1700 --- /dev/null +++ b/system/quests/q103-ext-xb-f.bin @@ -0,0 +1 @@ +q103-ext-gc-f.bin \ No newline at end of file diff --git a/system/quests/q103-ext-xb-g.bin b/system/quests/q103-ext-xb-g.bin new file mode 120000 index 00000000..10b4f34b --- /dev/null +++ b/system/quests/q103-ext-xb-g.bin @@ -0,0 +1 @@ +q103-ext-gc-g.bin \ No newline at end of file diff --git a/system/quests/q103-ext-xb-j.bin b/system/quests/q103-ext-xb-j.bin new file mode 120000 index 00000000..7a287c5a --- /dev/null +++ b/system/quests/q103-ext-xb-j.bin @@ -0,0 +1 @@ +q103-ext-gc-j.bin \ No newline at end of file diff --git a/system/quests/q103-ext-xb-s.bin b/system/quests/q103-ext-xb-s.bin new file mode 120000 index 00000000..9fff57a1 --- /dev/null +++ b/system/quests/q103-ext-xb-s.bin @@ -0,0 +1 @@ +q103-ext-gc-s.bin \ No newline at end of file diff --git a/system/quests/q103-ext-xb.dat b/system/quests/q103-ext-xb.dat new file mode 120000 index 00000000..d449c560 --- /dev/null +++ b/system/quests/q103-ext-xb.dat @@ -0,0 +1 @@ +q103-ext-gc.dat \ No newline at end of file diff --git a/system/quests/q104-ext-xb-e.bin b/system/quests/q104-ext-xb-e.bin new file mode 120000 index 00000000..313fb438 --- /dev/null +++ b/system/quests/q104-ext-xb-e.bin @@ -0,0 +1 @@ +q104-ext-gc-e.bin \ No newline at end of file diff --git a/system/quests/q104-ext-xb-f.bin b/system/quests/q104-ext-xb-f.bin new file mode 120000 index 00000000..eaaa426c --- /dev/null +++ b/system/quests/q104-ext-xb-f.bin @@ -0,0 +1 @@ +q104-ext-gc-f.bin \ No newline at end of file diff --git a/system/quests/q104-ext-xb-g.bin b/system/quests/q104-ext-xb-g.bin new file mode 120000 index 00000000..8a7be0fa --- /dev/null +++ b/system/quests/q104-ext-xb-g.bin @@ -0,0 +1 @@ +q104-ext-gc-g.bin \ No newline at end of file diff --git a/system/quests/q104-ext-xb-j.bin b/system/quests/q104-ext-xb-j.bin new file mode 120000 index 00000000..e2d0aa66 --- /dev/null +++ b/system/quests/q104-ext-xb-j.bin @@ -0,0 +1 @@ +q104-ext-gc-j.bin \ No newline at end of file diff --git a/system/quests/q104-ext-xb-s.bin b/system/quests/q104-ext-xb-s.bin new file mode 120000 index 00000000..99cebf47 --- /dev/null +++ b/system/quests/q104-ext-xb-s.bin @@ -0,0 +1 @@ +q104-ext-gc-s.bin \ No newline at end of file diff --git a/system/quests/q104-ext-xb.dat b/system/quests/q104-ext-xb.dat new file mode 120000 index 00000000..71062502 --- /dev/null +++ b/system/quests/q104-ext-xb.dat @@ -0,0 +1 @@ +q104-ext-gc.dat \ No newline at end of file diff --git a/system/quests/q108-ext-xb-e.bin b/system/quests/q108-ext-xb-e.bin new file mode 120000 index 00000000..4bf78bf0 --- /dev/null +++ b/system/quests/q108-ext-xb-e.bin @@ -0,0 +1 @@ +q108-ext-gc-e.bin \ No newline at end of file diff --git a/system/quests/q108-ext-xb-f.bin b/system/quests/q108-ext-xb-f.bin new file mode 120000 index 00000000..52d5454c --- /dev/null +++ b/system/quests/q108-ext-xb-f.bin @@ -0,0 +1 @@ +q108-ext-gc-f.bin \ No newline at end of file diff --git a/system/quests/q108-ext-xb-g.bin b/system/quests/q108-ext-xb-g.bin new file mode 120000 index 00000000..3ddaab41 --- /dev/null +++ b/system/quests/q108-ext-xb-g.bin @@ -0,0 +1 @@ +q108-ext-gc-g.bin \ No newline at end of file diff --git a/system/quests/q108-ext-xb-j.bin b/system/quests/q108-ext-xb-j.bin new file mode 120000 index 00000000..bed9e41c --- /dev/null +++ b/system/quests/q108-ext-xb-j.bin @@ -0,0 +1 @@ +q108-ext-gc-j.bin \ No newline at end of file diff --git a/system/quests/q108-ext-xb-s.bin b/system/quests/q108-ext-xb-s.bin new file mode 120000 index 00000000..87c5277b --- /dev/null +++ b/system/quests/q108-ext-xb-s.bin @@ -0,0 +1 @@ +q108-ext-gc-s.bin \ No newline at end of file diff --git a/system/quests/q108-ext-xb.dat b/system/quests/q108-ext-xb.dat new file mode 120000 index 00000000..b9c45686 --- /dev/null +++ b/system/quests/q108-ext-xb.dat @@ -0,0 +1 @@ +q108-ext-gc.dat \ No newline at end of file diff --git a/system/quests/q109-ext-xb-e.bin b/system/quests/q109-ext-xb-e.bin new file mode 120000 index 00000000..58ca69dd --- /dev/null +++ b/system/quests/q109-ext-xb-e.bin @@ -0,0 +1 @@ +q109-ext-gc-e.bin \ No newline at end of file diff --git a/system/quests/q109-ext-xb-f.bin b/system/quests/q109-ext-xb-f.bin new file mode 120000 index 00000000..2d754f04 --- /dev/null +++ b/system/quests/q109-ext-xb-f.bin @@ -0,0 +1 @@ +q109-ext-gc-f.bin \ No newline at end of file diff --git a/system/quests/q109-ext-xb-g.bin b/system/quests/q109-ext-xb-g.bin new file mode 120000 index 00000000..e1a9a7b7 --- /dev/null +++ b/system/quests/q109-ext-xb-g.bin @@ -0,0 +1 @@ +q109-ext-gc-g.bin \ No newline at end of file diff --git a/system/quests/q109-ext-xb-j.bin b/system/quests/q109-ext-xb-j.bin new file mode 120000 index 00000000..1bf0b58b --- /dev/null +++ b/system/quests/q109-ext-xb-j.bin @@ -0,0 +1 @@ +q109-ext-gc-j.bin \ No newline at end of file diff --git a/system/quests/q109-ext-xb-s.bin b/system/quests/q109-ext-xb-s.bin new file mode 120000 index 00000000..a125edef --- /dev/null +++ b/system/quests/q109-ext-xb-s.bin @@ -0,0 +1 @@ +q109-ext-gc-s.bin \ No newline at end of file diff --git a/system/quests/q109-ext-xb.dat b/system/quests/q109-ext-xb.dat new file mode 120000 index 00000000..644dc494 --- /dev/null +++ b/system/quests/q109-ext-xb.dat @@ -0,0 +1 @@ +q109-ext-gc.dat \ No newline at end of file diff --git a/system/quests/q110-ext-xb-e.bin b/system/quests/q110-ext-xb-e.bin new file mode 120000 index 00000000..e12343b3 --- /dev/null +++ b/system/quests/q110-ext-xb-e.bin @@ -0,0 +1 @@ +q110-ext-gc-e.bin \ No newline at end of file diff --git a/system/quests/q110-ext-xb-f.bin b/system/quests/q110-ext-xb-f.bin new file mode 120000 index 00000000..b34d20a8 --- /dev/null +++ b/system/quests/q110-ext-xb-f.bin @@ -0,0 +1 @@ +q110-ext-gc-f.bin \ No newline at end of file diff --git a/system/quests/q110-ext-xb-g.bin b/system/quests/q110-ext-xb-g.bin new file mode 120000 index 00000000..faf76aca --- /dev/null +++ b/system/quests/q110-ext-xb-g.bin @@ -0,0 +1 @@ +q110-ext-gc-g.bin \ No newline at end of file diff --git a/system/quests/q110-ext-xb-j.bin b/system/quests/q110-ext-xb-j.bin new file mode 120000 index 00000000..c0b55fac --- /dev/null +++ b/system/quests/q110-ext-xb-j.bin @@ -0,0 +1 @@ +q110-ext-gc-j.bin \ No newline at end of file diff --git a/system/quests/q110-ext-xb-s.bin b/system/quests/q110-ext-xb-s.bin new file mode 120000 index 00000000..63a26b0d --- /dev/null +++ b/system/quests/q110-ext-xb-s.bin @@ -0,0 +1 @@ +q110-ext-gc-s.bin \ No newline at end of file diff --git a/system/quests/q110-ext-xb.dat b/system/quests/q110-ext-xb.dat new file mode 120000 index 00000000..aab03510 --- /dev/null +++ b/system/quests/q110-ext-xb.dat @@ -0,0 +1 @@ +q110-ext-gc.dat \ No newline at end of file diff --git a/system/quests/q111-ext-xb-e.bin b/system/quests/q111-ext-xb-e.bin new file mode 120000 index 00000000..46fe91ff --- /dev/null +++ b/system/quests/q111-ext-xb-e.bin @@ -0,0 +1 @@ +q111-ext-gc-e.bin \ No newline at end of file diff --git a/system/quests/q111-ext-xb-f.bin b/system/quests/q111-ext-xb-f.bin new file mode 120000 index 00000000..c48a4c43 --- /dev/null +++ b/system/quests/q111-ext-xb-f.bin @@ -0,0 +1 @@ +q111-ext-gc-f.bin \ No newline at end of file diff --git a/system/quests/q111-ext-xb-g.bin b/system/quests/q111-ext-xb-g.bin new file mode 120000 index 00000000..d7b69d6e --- /dev/null +++ b/system/quests/q111-ext-xb-g.bin @@ -0,0 +1 @@ +q111-ext-gc-g.bin \ No newline at end of file diff --git a/system/quests/q111-ext-xb-j.bin b/system/quests/q111-ext-xb-j.bin new file mode 120000 index 00000000..2bb4dc30 --- /dev/null +++ b/system/quests/q111-ext-xb-j.bin @@ -0,0 +1 @@ +q111-ext-gc-j.bin \ No newline at end of file diff --git a/system/quests/q111-ext-xb-s.bin b/system/quests/q111-ext-xb-s.bin new file mode 120000 index 00000000..a762c5ec --- /dev/null +++ b/system/quests/q111-ext-xb-s.bin @@ -0,0 +1 @@ +q111-ext-gc-s.bin \ No newline at end of file diff --git a/system/quests/q111-ext-xb.dat b/system/quests/q111-ext-xb.dat new file mode 120000 index 00000000..541005cd --- /dev/null +++ b/system/quests/q111-ext-xb.dat @@ -0,0 +1 @@ +q111-ext-gc.dat \ No newline at end of file diff --git a/system/quests/q117-ext-xb-e.bin b/system/quests/q117-ext-xb-e.bin new file mode 120000 index 00000000..1d37c4d6 --- /dev/null +++ b/system/quests/q117-ext-xb-e.bin @@ -0,0 +1 @@ +q117-ext-gc-e.bin \ No newline at end of file diff --git a/system/quests/q117-ext-xb-f.bin b/system/quests/q117-ext-xb-f.bin new file mode 120000 index 00000000..7bd4878d --- /dev/null +++ b/system/quests/q117-ext-xb-f.bin @@ -0,0 +1 @@ +q117-ext-gc-f.bin \ No newline at end of file diff --git a/system/quests/q117-ext-xb-g.bin b/system/quests/q117-ext-xb-g.bin new file mode 120000 index 00000000..f0476698 --- /dev/null +++ b/system/quests/q117-ext-xb-g.bin @@ -0,0 +1 @@ +q117-ext-gc-g.bin \ No newline at end of file diff --git a/system/quests/q117-ext-xb-j.bin b/system/quests/q117-ext-xb-j.bin new file mode 120000 index 00000000..da6944d0 --- /dev/null +++ b/system/quests/q117-ext-xb-j.bin @@ -0,0 +1 @@ +q117-ext-gc-j.bin \ No newline at end of file diff --git a/system/quests/q117-ext-xb-s.bin b/system/quests/q117-ext-xb-s.bin new file mode 120000 index 00000000..1487c9de --- /dev/null +++ b/system/quests/q117-ext-xb-s.bin @@ -0,0 +1 @@ +q117-ext-gc-s.bin \ No newline at end of file diff --git a/system/quests/q117-ext-xb.dat b/system/quests/q117-ext-xb.dat new file mode 120000 index 00000000..9638e156 --- /dev/null +++ b/system/quests/q117-ext-xb.dat @@ -0,0 +1 @@ +q117-ext-gc.dat \ No newline at end of file diff --git a/system/quests/q118-vr-xb-e.bin b/system/quests/q118-vr-xb-e.bin new file mode 120000 index 00000000..dc192699 --- /dev/null +++ b/system/quests/q118-vr-xb-e.bin @@ -0,0 +1 @@ +q118-vr-gc-e.bin \ No newline at end of file diff --git a/system/quests/q118-vr-xb-f.bin b/system/quests/q118-vr-xb-f.bin new file mode 120000 index 00000000..8393622b --- /dev/null +++ b/system/quests/q118-vr-xb-f.bin @@ -0,0 +1 @@ +q118-vr-gc-f.bin \ No newline at end of file diff --git a/system/quests/q118-vr-xb-g.bin b/system/quests/q118-vr-xb-g.bin new file mode 120000 index 00000000..99db2e3f --- /dev/null +++ b/system/quests/q118-vr-xb-g.bin @@ -0,0 +1 @@ +q118-vr-gc-g.bin \ No newline at end of file diff --git a/system/quests/q118-vr-xb-j.bin b/system/quests/q118-vr-xb-j.bin new file mode 120000 index 00000000..8e677af3 --- /dev/null +++ b/system/quests/q118-vr-xb-j.bin @@ -0,0 +1 @@ +q118-vr-gc-j.bin \ No newline at end of file diff --git a/system/quests/q118-vr-xb-s.bin b/system/quests/q118-vr-xb-s.bin new file mode 120000 index 00000000..8116ac9f --- /dev/null +++ b/system/quests/q118-vr-xb-s.bin @@ -0,0 +1 @@ +q118-vr-gc-s.bin \ No newline at end of file diff --git a/system/quests/q118-vr-xb.dat b/system/quests/q118-vr-xb.dat new file mode 120000 index 00000000..0e2a7708 --- /dev/null +++ b/system/quests/q118-vr-xb.dat @@ -0,0 +1 @@ +q118-vr-gc.dat \ No newline at end of file diff --git a/system/quests/q124-evt-xb-e.bin b/system/quests/q124-evt-xb-e.bin new file mode 120000 index 00000000..11021113 --- /dev/null +++ b/system/quests/q124-evt-xb-e.bin @@ -0,0 +1 @@ +q124-evt-gc-e.bin \ No newline at end of file diff --git a/system/quests/q124-evt-xb-j.bin b/system/quests/q124-evt-xb-j.bin new file mode 120000 index 00000000..c12eb5ba --- /dev/null +++ b/system/quests/q124-evt-xb-j.bin @@ -0,0 +1 @@ +q124-evt-gc-j.bin \ No newline at end of file diff --git a/system/quests/q124-evt-xb.dat b/system/quests/q124-evt-xb.dat new file mode 120000 index 00000000..c377f625 --- /dev/null +++ b/system/quests/q124-evt-xb.dat @@ -0,0 +1 @@ +q124-evt-gc.dat \ No newline at end of file diff --git a/system/quests/q137-evt-xb-e.bin b/system/quests/q137-evt-xb-e.bin new file mode 120000 index 00000000..8391254c --- /dev/null +++ b/system/quests/q137-evt-xb-e.bin @@ -0,0 +1 @@ +q137-evt-gc-e.bin \ No newline at end of file diff --git a/system/quests/q137-evt-xb-f.bin b/system/quests/q137-evt-xb-f.bin new file mode 120000 index 00000000..f125a559 --- /dev/null +++ b/system/quests/q137-evt-xb-f.bin @@ -0,0 +1 @@ +q137-evt-gc-f.bin \ No newline at end of file diff --git a/system/quests/q137-evt-xb-g.bin b/system/quests/q137-evt-xb-g.bin new file mode 120000 index 00000000..0152603b --- /dev/null +++ b/system/quests/q137-evt-xb-g.bin @@ -0,0 +1 @@ +q137-evt-gc-g.bin \ No newline at end of file diff --git a/system/quests/q137-evt-xb-j.bin b/system/quests/q137-evt-xb-j.bin new file mode 120000 index 00000000..18d9455a --- /dev/null +++ b/system/quests/q137-evt-xb-j.bin @@ -0,0 +1 @@ +q137-evt-gc-j.bin \ No newline at end of file diff --git a/system/quests/q137-evt-xb-s.bin b/system/quests/q137-evt-xb-s.bin new file mode 120000 index 00000000..a0445862 --- /dev/null +++ b/system/quests/q137-evt-xb-s.bin @@ -0,0 +1 @@ +q137-evt-gc-s.bin \ No newline at end of file diff --git a/system/quests/q137-evt-xb.dat b/system/quests/q137-evt-xb.dat new file mode 120000 index 00000000..67f1c022 --- /dev/null +++ b/system/quests/q137-evt-xb.dat @@ -0,0 +1 @@ +q137-evt-gc.dat \ No newline at end of file diff --git a/system/quests/q138-evt-xb-e.bin b/system/quests/q138-evt-xb-e.bin new file mode 120000 index 00000000..f1227aa9 --- /dev/null +++ b/system/quests/q138-evt-xb-e.bin @@ -0,0 +1 @@ +q138-evt-gc-e.bin \ No newline at end of file diff --git a/system/quests/q138-evt-xb-f.bin b/system/quests/q138-evt-xb-f.bin new file mode 120000 index 00000000..2000d2cf --- /dev/null +++ b/system/quests/q138-evt-xb-f.bin @@ -0,0 +1 @@ +q138-evt-gc-f.bin \ No newline at end of file diff --git a/system/quests/q138-evt-xb-g.bin b/system/quests/q138-evt-xb-g.bin new file mode 120000 index 00000000..6444c43f --- /dev/null +++ b/system/quests/q138-evt-xb-g.bin @@ -0,0 +1 @@ +q138-evt-gc-g.bin \ No newline at end of file diff --git a/system/quests/q138-evt-xb-j.bin b/system/quests/q138-evt-xb-j.bin new file mode 120000 index 00000000..4351079f --- /dev/null +++ b/system/quests/q138-evt-xb-j.bin @@ -0,0 +1 @@ +q138-evt-gc-j.bin \ No newline at end of file diff --git a/system/quests/q138-evt-xb-s.bin b/system/quests/q138-evt-xb-s.bin new file mode 120000 index 00000000..6865b63f --- /dev/null +++ b/system/quests/q138-evt-xb-s.bin @@ -0,0 +1 @@ +q138-evt-gc-s.bin \ No newline at end of file diff --git a/system/quests/q138-evt-xb.dat b/system/quests/q138-evt-xb.dat new file mode 120000 index 00000000..e4f46d1d --- /dev/null +++ b/system/quests/q138-evt-xb.dat @@ -0,0 +1 @@ +q138-evt-gc.dat \ No newline at end of file diff --git a/system/quests/q141-vr-xb-e.bin b/system/quests/q141-vr-xb-e.bin new file mode 120000 index 00000000..29600209 --- /dev/null +++ b/system/quests/q141-vr-xb-e.bin @@ -0,0 +1 @@ +q141-vr-gc-e.bin \ No newline at end of file diff --git a/system/quests/q141-vr-xb-f.bin b/system/quests/q141-vr-xb-f.bin new file mode 120000 index 00000000..96c12c2e --- /dev/null +++ b/system/quests/q141-vr-xb-f.bin @@ -0,0 +1 @@ +q141-vr-gc-f.bin \ No newline at end of file diff --git a/system/quests/q141-vr-xb-g.bin b/system/quests/q141-vr-xb-g.bin new file mode 120000 index 00000000..bba61e90 --- /dev/null +++ b/system/quests/q141-vr-xb-g.bin @@ -0,0 +1 @@ +q141-vr-gc-g.bin \ No newline at end of file diff --git a/system/quests/q141-vr-xb-j.bin b/system/quests/q141-vr-xb-j.bin new file mode 120000 index 00000000..0043e5d8 --- /dev/null +++ b/system/quests/q141-vr-xb-j.bin @@ -0,0 +1 @@ +q141-vr-gc-j.bin \ No newline at end of file diff --git a/system/quests/q141-vr-xb-s.bin b/system/quests/q141-vr-xb-s.bin new file mode 120000 index 00000000..70491c34 --- /dev/null +++ b/system/quests/q141-vr-xb-s.bin @@ -0,0 +1 @@ +q141-vr-gc-s.bin \ No newline at end of file diff --git a/system/quests/q141-vr-xb.dat b/system/quests/q141-vr-xb.dat new file mode 120000 index 00000000..caac30ee --- /dev/null +++ b/system/quests/q141-vr-xb.dat @@ -0,0 +1 @@ +q141-vr-gc.dat \ No newline at end of file diff --git a/system/quests/q201-evt-xb-e.bin b/system/quests/q201-evt-xb-e.bin new file mode 120000 index 00000000..71b4a107 --- /dev/null +++ b/system/quests/q201-evt-xb-e.bin @@ -0,0 +1 @@ +q201-evt-gc-e.bin \ No newline at end of file diff --git a/system/quests/q201-evt-xb-f.bin b/system/quests/q201-evt-xb-f.bin new file mode 120000 index 00000000..baf43f8a --- /dev/null +++ b/system/quests/q201-evt-xb-f.bin @@ -0,0 +1 @@ +q201-evt-gc-f.bin \ No newline at end of file diff --git a/system/quests/q201-evt-xb-g.bin b/system/quests/q201-evt-xb-g.bin new file mode 120000 index 00000000..254b7c91 --- /dev/null +++ b/system/quests/q201-evt-xb-g.bin @@ -0,0 +1 @@ +q201-evt-gc-g.bin \ No newline at end of file diff --git a/system/quests/q201-evt-xb-j.bin b/system/quests/q201-evt-xb-j.bin new file mode 120000 index 00000000..6cce43d4 --- /dev/null +++ b/system/quests/q201-evt-xb-j.bin @@ -0,0 +1 @@ +q201-evt-gc-j.bin \ No newline at end of file diff --git a/system/quests/q201-evt-xb-s.bin b/system/quests/q201-evt-xb-s.bin new file mode 120000 index 00000000..036a12a2 --- /dev/null +++ b/system/quests/q201-evt-xb-s.bin @@ -0,0 +1 @@ +q201-evt-gc-s.bin \ No newline at end of file diff --git a/system/quests/q201-evt-xb.dat b/system/quests/q201-evt-xb.dat new file mode 120000 index 00000000..c0cc4188 --- /dev/null +++ b/system/quests/q201-evt-xb.dat @@ -0,0 +1 @@ +q201-evt-gc.dat \ No newline at end of file diff --git a/system/quests/q202-shp-xb-e.bin b/system/quests/q202-shp-xb-e.bin new file mode 120000 index 00000000..512fdb59 --- /dev/null +++ b/system/quests/q202-shp-xb-e.bin @@ -0,0 +1 @@ +q202-shp-gc-e.bin \ No newline at end of file diff --git a/system/quests/q202-shp-xb-f.bin b/system/quests/q202-shp-xb-f.bin new file mode 120000 index 00000000..2e035ec0 --- /dev/null +++ b/system/quests/q202-shp-xb-f.bin @@ -0,0 +1 @@ +q202-shp-gc-f.bin \ No newline at end of file diff --git a/system/quests/q202-shp-xb-g.bin b/system/quests/q202-shp-xb-g.bin new file mode 120000 index 00000000..29856c9e --- /dev/null +++ b/system/quests/q202-shp-xb-g.bin @@ -0,0 +1 @@ +q202-shp-gc-g.bin \ No newline at end of file diff --git a/system/quests/q202-shp-xb-j.bin b/system/quests/q202-shp-xb-j.bin new file mode 120000 index 00000000..6366602d --- /dev/null +++ b/system/quests/q202-shp-xb-j.bin @@ -0,0 +1 @@ +q202-shp-gc-j.bin \ No newline at end of file diff --git a/system/quests/q202-shp-xb-s.bin b/system/quests/q202-shp-xb-s.bin new file mode 120000 index 00000000..bd23dcaf --- /dev/null +++ b/system/quests/q202-shp-xb-s.bin @@ -0,0 +1 @@ +q202-shp-gc-s.bin \ No newline at end of file diff --git a/system/quests/q202-shp-xb.dat b/system/quests/q202-shp-xb.dat new file mode 120000 index 00000000..f1bbe325 --- /dev/null +++ b/system/quests/q202-shp-xb.dat @@ -0,0 +1 @@ +q202-shp-gc.dat \ No newline at end of file diff --git a/system/quests/q203-vr-xb-e.bin b/system/quests/q203-vr-xb-e.bin new file mode 120000 index 00000000..6f95faa5 --- /dev/null +++ b/system/quests/q203-vr-xb-e.bin @@ -0,0 +1 @@ +q203-vr-gc-e.bin \ No newline at end of file diff --git a/system/quests/q203-vr-xb-f.bin b/system/quests/q203-vr-xb-f.bin new file mode 120000 index 00000000..5223b0ae --- /dev/null +++ b/system/quests/q203-vr-xb-f.bin @@ -0,0 +1 @@ +q203-vr-gc-f.bin \ No newline at end of file diff --git a/system/quests/q203-vr-xb-g.bin b/system/quests/q203-vr-xb-g.bin new file mode 120000 index 00000000..861d8f4b --- /dev/null +++ b/system/quests/q203-vr-xb-g.bin @@ -0,0 +1 @@ +q203-vr-gc-g.bin \ No newline at end of file diff --git a/system/quests/q203-vr-xb-j.bin b/system/quests/q203-vr-xb-j.bin new file mode 120000 index 00000000..1fd190df --- /dev/null +++ b/system/quests/q203-vr-xb-j.bin @@ -0,0 +1 @@ +q203-vr-gc-j.bin \ No newline at end of file diff --git a/system/quests/q203-vr-xb-s.bin b/system/quests/q203-vr-xb-s.bin new file mode 120000 index 00000000..64500d56 --- /dev/null +++ b/system/quests/q203-vr-xb-s.bin @@ -0,0 +1 @@ +q203-vr-gc-s.bin \ No newline at end of file diff --git a/system/quests/q203-vr-xb.dat b/system/quests/q203-vr-xb.dat new file mode 120000 index 00000000..455ce719 --- /dev/null +++ b/system/quests/q203-vr-xb.dat @@ -0,0 +1 @@ +q203-vr-gc.dat \ No newline at end of file diff --git a/system/quests/q204-shp-xb-e.bin b/system/quests/q204-shp-xb-e.bin new file mode 120000 index 00000000..865c77fe --- /dev/null +++ b/system/quests/q204-shp-xb-e.bin @@ -0,0 +1 @@ +q204-shp-gc-e.bin \ No newline at end of file diff --git a/system/quests/q204-shp-xb.dat b/system/quests/q204-shp-xb.dat new file mode 120000 index 00000000..38d42fd8 --- /dev/null +++ b/system/quests/q204-shp-xb.dat @@ -0,0 +1 @@ +q204-shp-gc.dat \ No newline at end of file diff --git a/system/quests/q213-evt-xb-e.bin b/system/quests/q213-evt-xb-e.bin new file mode 120000 index 00000000..b857fff5 --- /dev/null +++ b/system/quests/q213-evt-xb-e.bin @@ -0,0 +1 @@ +q213-evt-gc-e.bin \ No newline at end of file diff --git a/system/quests/q213-evt-xb-j.bin b/system/quests/q213-evt-xb-j.bin new file mode 120000 index 00000000..31046468 --- /dev/null +++ b/system/quests/q213-evt-xb-j.bin @@ -0,0 +1 @@ +q213-evt-gc-j.bin \ No newline at end of file diff --git a/system/quests/q213-evt-xb.dat b/system/quests/q213-evt-xb.dat new file mode 120000 index 00000000..28c844ff --- /dev/null +++ b/system/quests/q213-evt-xb.dat @@ -0,0 +1 @@ +q213-evt-gc.dat \ No newline at end of file diff --git a/system/quests/q220-evt-xb-e.bin b/system/quests/q220-evt-xb-e.bin new file mode 120000 index 00000000..30282cb7 --- /dev/null +++ b/system/quests/q220-evt-xb-e.bin @@ -0,0 +1 @@ +q220-evt-gc-e.bin \ No newline at end of file diff --git a/system/quests/q220-evt-xb-f.bin b/system/quests/q220-evt-xb-f.bin new file mode 120000 index 00000000..0c43d59f --- /dev/null +++ b/system/quests/q220-evt-xb-f.bin @@ -0,0 +1 @@ +q220-evt-gc-f.bin \ No newline at end of file diff --git a/system/quests/q220-evt-xb-g.bin b/system/quests/q220-evt-xb-g.bin new file mode 120000 index 00000000..5e512bfc --- /dev/null +++ b/system/quests/q220-evt-xb-g.bin @@ -0,0 +1 @@ +q220-evt-gc-g.bin \ No newline at end of file diff --git a/system/quests/q220-evt-xb-j.bin b/system/quests/q220-evt-xb-j.bin new file mode 120000 index 00000000..18222dae --- /dev/null +++ b/system/quests/q220-evt-xb-j.bin @@ -0,0 +1 @@ +q220-evt-gc-j.bin \ No newline at end of file diff --git a/system/quests/q220-evt-xb-s.bin b/system/quests/q220-evt-xb-s.bin new file mode 120000 index 00000000..b0492cc7 --- /dev/null +++ b/system/quests/q220-evt-xb-s.bin @@ -0,0 +1 @@ +q220-evt-gc-s.bin \ No newline at end of file diff --git a/system/quests/q220-evt-xb.dat b/system/quests/q220-evt-xb.dat new file mode 120000 index 00000000..550e3aaf --- /dev/null +++ b/system/quests/q220-evt-xb.dat @@ -0,0 +1 @@ +q220-evt-gc.dat \ No newline at end of file diff --git a/system/quests/q222-vr-xb-e.bin b/system/quests/q222-vr-xb-e.bin new file mode 120000 index 00000000..281ad19f --- /dev/null +++ b/system/quests/q222-vr-xb-e.bin @@ -0,0 +1 @@ +q222-vr-gc-e.bin \ No newline at end of file diff --git a/system/quests/q222-vr-xb-f.bin b/system/quests/q222-vr-xb-f.bin new file mode 120000 index 00000000..79656a6d --- /dev/null +++ b/system/quests/q222-vr-xb-f.bin @@ -0,0 +1 @@ +q222-vr-gc-f.bin \ No newline at end of file diff --git a/system/quests/q222-vr-xb-g.bin b/system/quests/q222-vr-xb-g.bin new file mode 120000 index 00000000..32252022 --- /dev/null +++ b/system/quests/q222-vr-xb-g.bin @@ -0,0 +1 @@ +q222-vr-gc-g.bin \ No newline at end of file diff --git a/system/quests/q222-vr-xb-j.bin b/system/quests/q222-vr-xb-j.bin new file mode 120000 index 00000000..fd3ff894 --- /dev/null +++ b/system/quests/q222-vr-xb-j.bin @@ -0,0 +1 @@ +q222-vr-gc-j.bin \ No newline at end of file diff --git a/system/quests/q222-vr-xb-s.bin b/system/quests/q222-vr-xb-s.bin new file mode 120000 index 00000000..1c5d1a68 --- /dev/null +++ b/system/quests/q222-vr-xb-s.bin @@ -0,0 +1 @@ +q222-vr-gc-s.bin \ No newline at end of file diff --git a/system/quests/q222-vr-xb.dat b/system/quests/q222-vr-xb.dat new file mode 120000 index 00000000..4cc622a4 --- /dev/null +++ b/system/quests/q222-vr-xb.dat @@ -0,0 +1 @@ +q222-vr-gc.dat \ No newline at end of file diff --git a/system/quests/q223-twr-xb-e.bin b/system/quests/q223-twr-xb-e.bin new file mode 120000 index 00000000..06f55806 --- /dev/null +++ b/system/quests/q223-twr-xb-e.bin @@ -0,0 +1 @@ +q223-twr-gc-e.bin \ No newline at end of file diff --git a/system/quests/q223-twr-xb-f.bin b/system/quests/q223-twr-xb-f.bin new file mode 120000 index 00000000..35643c61 --- /dev/null +++ b/system/quests/q223-twr-xb-f.bin @@ -0,0 +1 @@ +q223-twr-gc-f.bin \ No newline at end of file diff --git a/system/quests/q223-twr-xb-g.bin b/system/quests/q223-twr-xb-g.bin new file mode 120000 index 00000000..fc6dbc83 --- /dev/null +++ b/system/quests/q223-twr-xb-g.bin @@ -0,0 +1 @@ +q223-twr-gc-g.bin \ No newline at end of file diff --git a/system/quests/q223-twr-xb-j.bin b/system/quests/q223-twr-xb-j.bin new file mode 120000 index 00000000..ab825747 --- /dev/null +++ b/system/quests/q223-twr-xb-j.bin @@ -0,0 +1 @@ +q223-twr-gc-j.bin \ No newline at end of file diff --git a/system/quests/q223-twr-xb-s.bin b/system/quests/q223-twr-xb-s.bin new file mode 120000 index 00000000..ad3c42d4 --- /dev/null +++ b/system/quests/q223-twr-xb-s.bin @@ -0,0 +1 @@ +q223-twr-gc-s.bin \ No newline at end of file diff --git a/system/quests/q223-twr-xb.dat b/system/quests/q223-twr-xb.dat new file mode 120000 index 00000000..7e31cd79 --- /dev/null +++ b/system/quests/q223-twr-xb.dat @@ -0,0 +1 @@ +q223-twr-gc.dat \ No newline at end of file diff --git a/system/quests/q224-twr-xb-e.bin b/system/quests/q224-twr-xb-e.bin new file mode 120000 index 00000000..f792f0b7 --- /dev/null +++ b/system/quests/q224-twr-xb-e.bin @@ -0,0 +1 @@ +q224-twr-gc-e.bin \ No newline at end of file diff --git a/system/quests/q224-twr-xb-f.bin b/system/quests/q224-twr-xb-f.bin new file mode 120000 index 00000000..c713b1a7 --- /dev/null +++ b/system/quests/q224-twr-xb-f.bin @@ -0,0 +1 @@ +q224-twr-gc-f.bin \ No newline at end of file diff --git a/system/quests/q224-twr-xb-g.bin b/system/quests/q224-twr-xb-g.bin new file mode 120000 index 00000000..c2b3b526 --- /dev/null +++ b/system/quests/q224-twr-xb-g.bin @@ -0,0 +1 @@ +q224-twr-gc-g.bin \ No newline at end of file diff --git a/system/quests/q224-twr-xb-j.bin b/system/quests/q224-twr-xb-j.bin new file mode 120000 index 00000000..2f0243bb --- /dev/null +++ b/system/quests/q224-twr-xb-j.bin @@ -0,0 +1 @@ +q224-twr-gc-j.bin \ No newline at end of file diff --git a/system/quests/q224-twr-xb-s.bin b/system/quests/q224-twr-xb-s.bin new file mode 120000 index 00000000..1151fa1a --- /dev/null +++ b/system/quests/q224-twr-xb-s.bin @@ -0,0 +1 @@ +q224-twr-gc-s.bin \ No newline at end of file diff --git a/system/quests/q224-twr-xb.dat b/system/quests/q224-twr-xb.dat new file mode 120000 index 00000000..aa368631 --- /dev/null +++ b/system/quests/q224-twr-xb.dat @@ -0,0 +1 @@ +q224-twr-gc.dat \ No newline at end of file diff --git a/system/quests/q229-evt-xb-e.bin b/system/quests/q229-evt-xb-e.bin new file mode 120000 index 00000000..65c3328c --- /dev/null +++ b/system/quests/q229-evt-xb-e.bin @@ -0,0 +1 @@ +q229-evt-gc-e.bin \ No newline at end of file diff --git a/system/quests/q229-evt-xb-j.bin b/system/quests/q229-evt-xb-j.bin new file mode 120000 index 00000000..430cca44 --- /dev/null +++ b/system/quests/q229-evt-xb-j.bin @@ -0,0 +1 @@ +q229-evt-gc-j.bin \ No newline at end of file diff --git a/system/quests/q229-evt-xb.dat b/system/quests/q229-evt-xb.dat new file mode 120000 index 00000000..58acb5af --- /dev/null +++ b/system/quests/q229-evt-xb.dat @@ -0,0 +1 @@ +q229-evt-gc.dat \ No newline at end of file diff --git a/system/quests/q230-vr-xb-e.bin b/system/quests/q230-vr-xb-e.bin new file mode 120000 index 00000000..e7e1fdbc --- /dev/null +++ b/system/quests/q230-vr-xb-e.bin @@ -0,0 +1 @@ +q230-vr-gc-e.bin \ No newline at end of file diff --git a/system/quests/q230-vr-xb.dat b/system/quests/q230-vr-xb.dat new file mode 120000 index 00000000..edeebc75 --- /dev/null +++ b/system/quests/q230-vr-xb.dat @@ -0,0 +1 @@ +q230-vr-gc.dat \ No newline at end of file diff --git a/system/quests/q231-vr-xb-e.bin b/system/quests/q231-vr-xb-e.bin new file mode 120000 index 00000000..99e5082a --- /dev/null +++ b/system/quests/q231-vr-xb-e.bin @@ -0,0 +1 @@ +q231-vr-gc-e.bin \ No newline at end of file diff --git a/system/quests/q231-vr-xb.dat b/system/quests/q231-vr-xb.dat new file mode 120000 index 00000000..ef33309d --- /dev/null +++ b/system/quests/q231-vr-xb.dat @@ -0,0 +1 @@ +q231-vr-gc.dat \ No newline at end of file diff --git a/system/quests/q232-evt-xb-e.bin b/system/quests/q232-evt-xb-e.bin new file mode 120000 index 00000000..7c5a98d1 --- /dev/null +++ b/system/quests/q232-evt-xb-e.bin @@ -0,0 +1 @@ +q232-evt-gc-e.bin \ No newline at end of file diff --git a/system/quests/q232-evt-xb.dat b/system/quests/q232-evt-xb.dat new file mode 120000 index 00000000..9ace99cd --- /dev/null +++ b/system/quests/q232-evt-xb.dat @@ -0,0 +1 @@ +q232-evt-gc.dat \ No newline at end of file diff --git a/system/quests/q233-ext-xb-e.bin b/system/quests/q233-ext-xb-e.bin new file mode 120000 index 00000000..3ea762c4 --- /dev/null +++ b/system/quests/q233-ext-xb-e.bin @@ -0,0 +1 @@ +q233-ext-gc-e.bin \ No newline at end of file diff --git a/system/quests/q233-ext-xb.dat b/system/quests/q233-ext-xb.dat new file mode 120000 index 00000000..2a9cb704 --- /dev/null +++ b/system/quests/q233-ext-xb.dat @@ -0,0 +1 @@ +q233-ext-gc.dat \ No newline at end of file diff --git a/system/quests/q234-ext-xb-e.bin b/system/quests/q234-ext-xb-e.bin new file mode 120000 index 00000000..2e542363 --- /dev/null +++ b/system/quests/q234-ext-xb-e.bin @@ -0,0 +1 @@ +q234-ext-gc-e.bin \ No newline at end of file diff --git a/system/quests/q234-ext-xb.dat b/system/quests/q234-ext-xb.dat new file mode 120000 index 00000000..275eb410 --- /dev/null +++ b/system/quests/q234-ext-xb.dat @@ -0,0 +1 @@ +q234-ext-gc.dat \ No newline at end of file diff --git a/system/quests/q235-ext-xb-e.bin b/system/quests/q235-ext-xb-e.bin new file mode 120000 index 00000000..5b9b4644 --- /dev/null +++ b/system/quests/q235-ext-xb-e.bin @@ -0,0 +1 @@ +q235-ext-gc-e.bin \ No newline at end of file diff --git a/system/quests/q235-ext-xb.dat b/system/quests/q235-ext-xb.dat new file mode 120000 index 00000000..5459538b --- /dev/null +++ b/system/quests/q235-ext-xb.dat @@ -0,0 +1 @@ +q235-ext-gc.dat \ No newline at end of file diff --git a/system/quests/q236-ext-xb-e.bin b/system/quests/q236-ext-xb-e.bin new file mode 120000 index 00000000..eca4a0ad --- /dev/null +++ b/system/quests/q236-ext-xb-e.bin @@ -0,0 +1 @@ +q236-ext-gc-e.bin \ No newline at end of file diff --git a/system/quests/q236-ext-xb.dat b/system/quests/q236-ext-xb.dat new file mode 120000 index 00000000..f30071de --- /dev/null +++ b/system/quests/q236-ext-xb.dat @@ -0,0 +1 @@ +q236-ext-gc.dat \ No newline at end of file diff --git a/system/quests/q237-vr-xb-e.bin b/system/quests/q237-vr-xb-e.bin new file mode 120000 index 00000000..7ca7b58d --- /dev/null +++ b/system/quests/q237-vr-xb-e.bin @@ -0,0 +1 @@ +q237-vr-gc-e.bin \ No newline at end of file diff --git a/system/quests/q237-vr-xb.dat b/system/quests/q237-vr-xb.dat new file mode 120000 index 00000000..e39da820 --- /dev/null +++ b/system/quests/q237-vr-xb.dat @@ -0,0 +1 @@ +q237-vr-gc.dat \ No newline at end of file diff --git a/system/quests/q238-vr-xb-e.bin b/system/quests/q238-vr-xb-e.bin new file mode 120000 index 00000000..c6571ad8 --- /dev/null +++ b/system/quests/q238-vr-xb-e.bin @@ -0,0 +1 @@ +q238-vr-gc-e.bin \ No newline at end of file diff --git a/system/quests/q238-vr-xb.dat b/system/quests/q238-vr-xb.dat new file mode 120000 index 00000000..ab16c504 --- /dev/null +++ b/system/quests/q238-vr-xb.dat @@ -0,0 +1 @@ +q238-vr-gc.dat \ No newline at end of file diff --git a/system/quests/q239-evt-xb-e.bin b/system/quests/q239-evt-xb-e.bin new file mode 120000 index 00000000..bcefb904 --- /dev/null +++ b/system/quests/q239-evt-xb-e.bin @@ -0,0 +1 @@ +q239-evt-gc-e.bin \ No newline at end of file diff --git a/system/quests/q239-evt-xb.dat b/system/quests/q239-evt-xb.dat new file mode 120000 index 00000000..065ecc69 --- /dev/null +++ b/system/quests/q239-evt-xb.dat @@ -0,0 +1 @@ +q239-evt-gc.dat \ No newline at end of file diff --git a/system/quests/q335-evt-xb-e.bin b/system/quests/q335-evt-xb-e.bin new file mode 120000 index 00000000..ffddd18c --- /dev/null +++ b/system/quests/q335-evt-xb-e.bin @@ -0,0 +1 @@ +q335-evt-gc-e.bin \ No newline at end of file diff --git a/system/quests/q335-evt-xb.dat b/system/quests/q335-evt-xb.dat new file mode 120000 index 00000000..b3d7d41f --- /dev/null +++ b/system/quests/q335-evt-xb.dat @@ -0,0 +1 @@ +q335-evt-gc.dat \ No newline at end of file diff --git a/system/quests/q496-evt-xb-e.bin b/system/quests/q496-evt-xb-e.bin new file mode 120000 index 00000000..dfa210a3 --- /dev/null +++ b/system/quests/q496-evt-xb-e.bin @@ -0,0 +1 @@ +q496-evt-gc-e.bin \ No newline at end of file diff --git a/system/quests/q496-evt-xb.dat b/system/quests/q496-evt-xb.dat new file mode 120000 index 00000000..400166e5 --- /dev/null +++ b/system/quests/q496-evt-xb.dat @@ -0,0 +1 @@ +q496-evt-gc.dat \ No newline at end of file diff --git a/system/quests/q999-shp-xb-e.bin b/system/quests/q999-shp-xb-e.bin new file mode 120000 index 00000000..993f017c --- /dev/null +++ b/system/quests/q999-shp-xb-e.bin @@ -0,0 +1 @@ +q999-shp-gc-e.bin \ No newline at end of file diff --git a/system/quests/q999-shp-xb.dat b/system/quests/q999-shp-xb.dat new file mode 120000 index 00000000..f5c98e54 --- /dev/null +++ b/system/quests/q999-shp-xb.dat @@ -0,0 +1 @@ +q999-shp-gc.dat \ No newline at end of file diff --git a/tests/XB-ForestGame.test.txt b/tests/XB-ForestGame.test.txt new file mode 100644 index 00000000..d6113dc6 --- /dev/null +++ b/tests/XB-ForestGame.test.txt @@ -0,0 +1,1140 @@ +I 7323 2023-11-07 02:01:35 - [C-1] Created +I 7323 2023-11-07 02:01:35 - [Server] Client connected: C-1 on fd 41 via 11 (T-9500-XB-xb-login_server) +I 7323 2023-11-07 02:01:35 - [Commands] Sending to C-1 (version=XB command=17 flag=00) +0000 | 17 00 00 01 44 72 65 61 6D 43 61 73 74 20 50 6F | DreamCast Po +0010 | 72 74 20 4D 61 70 2E 20 43 6F 70 79 72 69 67 68 | rt Map. Copyrigh +0020 | 74 20 53 45 47 41 20 45 6E 74 65 72 70 72 69 73 | t SEGA Enterpris +0030 | 65 73 2E 20 31 39 39 39 00 00 00 00 00 00 00 00 | es. 1999 +0040 | 00 00 00 00 78 D5 64 6E 37 11 A5 82 54 68 69 73 | x dn7 This +0050 | 20 73 65 72 76 65 72 20 69 73 20 69 6E 20 6E 6F | server is in no +0060 | 20 77 61 79 20 61 66 66 69 6C 69 61 74 65 64 2C | way affiliated, +0070 | 20 73 70 6F 6E 73 6F 72 65 64 2C 20 6F 72 20 73 | sponsored, or s +0080 | 75 70 70 6F 72 74 65 64 20 62 79 20 53 45 47 41 | upported by SEGA +0090 | 20 45 6E 74 65 72 70 72 69 73 65 73 20 6F 72 20 | Enterprises or +00A0 | 53 4F 4E 49 43 54 45 41 4D 2E 20 54 68 65 20 70 | SONICTEAM. The p +00B0 | 72 65 63 65 64 69 6E 67 20 6D 65 73 73 61 67 65 | receding message +00C0 | 20 65 78 69 73 74 73 20 6F 6E 6C 79 20 74 6F 20 | exists only to +00D0 | 72 65 6D 61 69 6E 20 63 6F 6D 70 61 74 69 62 6C | remain compatibl +00E0 | 65 20 77 69 74 68 20 70 72 6F 67 72 61 6D 73 20 | e with programs +00F0 | 74 68 61 74 20 65 78 70 65 63 74 20 69 74 2E 00 | that expect it. +I 7323 2023-11-07 02:01:35 - [Commands] Received from C-1 (version=XB command=9E flag=01) +0000 | 9E 01 98 01 00 00 FF FF FF FF FF FF 00 00 00 00 | +0010 | 00 00 00 00 31 00 00 00 00 01 00 00 00 00 00 00 | 1 +0020 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0030 | 00 00 00 00 00 00 00 00 00 00 00 00 74 7A 72 6C | tzrl +0040 | 33 00 00 00 00 00 00 00 00 00 00 00 37 44 31 31 | 3 7D11 +0050 | 33 36 39 31 30 30 30 39 42 39 43 45 74 7A 72 6C | 36910009B9CEtzrl +0060 | 33 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 3 +0070 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0080 | 00 00 00 00 00 00 00 00 00 00 00 00 37 44 31 31 | 7D11 +0090 | 33 36 39 31 30 30 30 39 42 39 43 45 00 00 00 00 | 36910009B9CE +00A0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00B0 | 00 00 00 00 00 00 00 00 00 00 00 00 54 61 6C 69 | Tali +00C0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00D0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00E0 | 00 00 00 00 00 00 00 00 00 00 00 00 0A 00 02 0F | +00F0 | 17 7E B2 19 FE E5 00 50 F2 AF A8 DC 31 0D 39 65 | ~ P 1 9e +0100 | 00 0D 0E 89 24 48 A9 24 00 00 09 00 00 00 00 00 | $H $ +0110 | 87 AA 3F BE 5B B1 47 B3 5A 2F 1A B0 DD 73 27 5A | ? [ G Z/ s'Z +0120 | 45 23 2B D8 D5 04 F9 4F 91 36 11 7D CE B9 09 00 | E#+ O 6 } +0130 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0140 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0150 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0160 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0170 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0180 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0190 | 00 00 00 00 00 00 00 00 | +I 7323 2023-11-07 02:01:35 - [Commands] Sending to C-1 (version=XB command=04 flag=00) +0000 | 04 00 2C 00 00 00 01 00 E2 D4 45 39 32 AC 99 83 | , E92 +0010 | 00 00 00 34 00 81 00 42 60 00 00 00 00 00 00 00 | 4 B` +0020 | 00 00 00 00 00 00 FF FF 80 FF FF FF | +I 7323 2023-11-07 02:01:35 - [Commands] Sending to C-1 (version=XB command=D5 flag=00) +0000 | D5 00 2C 00 59 6F 75 20 61 72 65 20 63 6F 6E 6E | , You are conn +0010 | 65 63 74 65 64 20 74 6F 20 09 43 36 41 6C 65 78 | ected to C6Alex +0020 | 61 6E 64 72 69 61 09 43 37 2E 00 00 | andria C7. +I 7323 2023-11-07 02:01:36 - [Commands] Received from C-1 (version=XB command=96 flag=00) +0000 | 96 00 0C 00 7C 9C DA 2C 22 00 00 00 | | ," +I 7323 2023-11-07 02:01:36 - [Commands] Sending to C-1 (version=XB command=B1 flag=00) +0000 | B1 00 1C 00 32 30 32 33 3A 31 31 3A 30 37 3A 20 | 2023:11:07: +0010 | 30 32 3A 30 31 3A 33 36 2E 30 30 30 | 02:01:36.000 +I 7323 2023-11-07 02:01:36 - [Commands] Received from C-1 (version=XB command=99 flag=00) +0000 | 99 00 04 00 | +I 7323 2023-11-07 02:01:39 - [Commands] Received from C-1 (version=XB command=D6 flag=00) +0000 | D6 00 04 00 | +I 7323 2023-11-07 02:01:39 - [Commands] Sending to C-1 (version=XB command=04 flag=00) +0000 | 04 00 2C 00 00 00 01 00 E2 D4 45 39 32 AC 99 83 | , E92 +0010 | 00 00 00 34 00 81 00 40 60 00 00 00 00 00 00 00 | 4 @` +0020 | 00 00 00 00 00 00 FF FF 80 FF FF FF | +I 7323 2023-11-07 02:01:39 - [Commands] Sending to C-1 (version=XB command=07 flag=06) +0000 | 07 04 90 00 11 00 00 11 FF FF FF FF 04 00 41 6C | Al +0010 | 65 78 61 6E 64 72 69 61 00 00 00 00 00 00 00 00 | exandria +0020 | 11 00 00 11 11 22 22 11 04 0F 47 6F 20 74 6F 20 | "" Go to +0030 | 6C 6F 62 62 79 00 00 00 00 00 00 00 11 00 00 11 | lobby +0040 | 11 33 33 11 04 0F 49 6E 66 6F 72 6D 61 74 69 6F | 33 Informatio +0050 | 6E 00 00 00 00 00 00 00 11 00 00 11 11 44 44 11 | n DD +0060 | 04 0F 44 6F 77 6E 6C 6F 61 64 20 71 75 65 73 74 | Download quest +0070 | 73 00 00 00 11 00 00 11 11 88 88 11 04 0F 44 69 | s Di +0080 | 73 63 6F 6E 6E 65 63 74 00 00 00 00 00 00 00 00 | sconnect +I 7323 2023-11-07 02:01:41 - [Commands] Received from C-1 (version=XB command=10 flag=00) +0000 | 10 00 0C 00 11 00 00 11 11 22 22 11 | "" +I 7323 2023-11-07 02:01:41 - [Commands] Sending to C-1 (version=XB command=97 flag=01) +0000 | 97 01 04 00 | +I 7323 2023-11-07 02:01:41 - [Commands] Sending to C-1 (version=XB command=04 flag=00) +0000 | 04 00 2C 00 00 00 01 00 E2 D4 45 39 32 AC 99 83 | , E92 +0010 | 00 00 00 34 00 81 00 44 60 00 00 00 00 00 00 00 | 4 D` +0020 | 00 00 00 00 00 00 FF FF 80 FF FF FF | +I 7323 2023-11-07 02:01:42 - [Commands] Received from C-1 (version=XB command=B1 flag=00) +0000 | B1 00 04 00 | +I 7323 2023-11-07 02:01:42 - [Commands] Sending to C-1 (version=XB command=B1 flag=00) +0000 | B1 00 1C 00 32 30 32 33 3A 31 31 3A 30 37 3A 20 | 2023:11:07: +0010 | 30 32 3A 30 31 3A 34 32 2E 30 30 30 | 02:01:42.000 +I 7323 2023-11-07 02:01:42 - [Commands] Sending to C-1 (version=XB command=83 flag=0F) +0000 | 83 0F B8 00 33 00 00 33 01 00 00 00 00 00 00 00 | 3 3 +0010 | 33 00 00 33 02 00 00 00 00 00 00 00 33 00 00 33 | 3 3 3 3 +0020 | 03 00 00 00 00 00 00 00 33 00 00 33 04 00 00 00 | 3 3 +0030 | 00 00 00 00 33 00 00 33 05 00 00 00 00 00 00 00 | 3 3 +0040 | 33 00 00 33 06 00 00 00 00 00 00 00 33 00 00 33 | 3 3 3 3 +0050 | 07 00 00 00 00 00 00 00 33 00 00 33 08 00 00 00 | 3 3 +0060 | 00 00 00 00 33 00 00 33 09 00 00 00 00 00 00 00 | 3 3 +0070 | 33 00 00 33 0A 00 00 00 00 00 00 00 33 00 00 33 | 3 3 3 3 +0080 | 0B 00 00 00 00 00 00 00 33 00 00 33 0C 00 00 00 | 3 3 +0090 | 00 00 00 00 33 00 00 33 0D 00 00 00 00 00 00 00 | 3 3 +00A0 | 33 00 00 33 0E 00 00 00 00 00 00 00 33 00 00 33 | 3 3 3 3 +00B0 | 0F 00 00 00 00 00 00 00 | +I 7323 2023-11-07 02:01:42 - [Commands] Sending to C-1 (version=XB command=95 flag=00) +0000 | 95 00 04 00 | +I 7323 2023-11-07 02:01:42 - [Commands] Received from C-1 (version=XB command=99 flag=00) +0000 | 99 00 04 00 | +I 7323 2023-11-07 02:01:43 - [Commands] Received from C-1 (version=XB command=61 flag=03) +0000 | 61 03 80 06 03 00 00 01 02 00 00 00 4C 00 00 00 | a L +0010 | 02 00 05 00 F4 01 00 00 00 00 00 00 00 00 01 00 | +0020 | 12 00 00 09 02 00 00 00 4C 00 00 00 01 01 00 00 | L +0030 | 00 00 00 00 00 00 00 00 01 00 01 00 00 00 00 00 | +0040 | 02 00 00 00 4C 00 00 00 00 06 00 00 00 00 00 00 | L +0050 | 00 00 00 00 02 00 01 00 00 00 00 00 00 00 00 00 | +0060 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0070 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0080 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0090 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00A0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00B0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00C0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00D0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00E0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0100 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0110 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0120 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0130 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0140 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0150 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0160 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0170 | 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 | +0180 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0190 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01A0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01B0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01C0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01D0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01E0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0200 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0210 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0220 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0230 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0240 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0250 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0260 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0270 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0280 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0290 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02A0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02B0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02C0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02D0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02E0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0300 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0310 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0320 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0330 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0340 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0350 | 14 00 00 00 1F 00 11 00 17 00 2D 00 0A 00 28 00 | - ( +0360 | 00 00 98 41 00 00 20 41 00 00 00 00 00 00 00 00 | A A +0370 | 00 00 00 00 54 61 6C 69 00 00 00 00 00 00 00 00 | Tali +0380 | 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF | +0390 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +03A0 | 00 00 00 00 04 05 00 02 52 00 00 00 00 00 09 00 | R +03B0 | 00 00 03 00 00 00 00 00 00 00 00 00 AA 5F AC 3E | _ > +03C0 | 00 00 00 00 00 00 00 00 01 00 01 00 02 00 01 00 | +03D0 | 02 01 01 00 04 00 01 00 01 00 01 00 00 00 01 00 | +03E0 | 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 00 | +03F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0400 | 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF | +0410 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | +0420 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0430 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0440 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0450 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0460 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0470 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0480 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0490 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +04A0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +04B0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +04C0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +04D0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +04E0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +04F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0500 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0510 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0520 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0530 | 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 | +0540 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0550 | 00 00 00 00 09 45 77 6F 6F 20 24 43 32 78 62 6F | Ewoo $C2xbo +0560 | 78 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | x +0570 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0580 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0590 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +05A0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +05B0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +05C0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +05D0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +05E0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +05F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0600 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0610 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0620 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0630 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0640 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0650 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0660 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0670 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +I 7323 2023-11-07 02:01:43 - [Commands] Sending to C-1 (Tali) (version=XB command=C5 flag=01) +0000 | C5 01 20 01 00 00 00 00 00 00 00 00 00 00 00 00 | +0010 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0020 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0030 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0040 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0050 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0060 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0070 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0080 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0090 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00A0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00B0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00C0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00D0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00E0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0100 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0110 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +I 7323 2023-11-07 02:01:43 - [Commands] Sending to C-1 (Tali) (version=XB command=67 flag=01) +0000 | 67 01 90 04 00 00 01 00 01 00 00 00 00 00 00 00 | g +0010 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0020 | 00 00 00 00 00 00 00 00 00 00 01 00 E2 D4 45 39 | E9 +0030 | 0A 00 02 0F 17 7E B2 19 FE E5 00 50 F2 AF A8 DC | ~ P +0040 | 31 0D 39 65 00 0D 0E 89 24 48 A9 24 00 00 09 00 | 1 9e $H $ +0050 | 00 00 00 00 87 AA 3F BE 5B B1 47 B3 5A 2F 1A B0 | ? [ G Z/ +0060 | 00 00 00 00 54 61 6C 69 00 00 00 00 00 00 00 00 | Tali +0070 | 00 00 00 00 03 00 00 01 02 00 00 00 4C 00 00 00 | L +0080 | 02 00 05 00 F4 01 00 00 00 00 00 00 00 00 01 00 | +0090 | 12 00 00 09 02 00 00 00 4C 00 00 00 01 01 00 00 | L +00A0 | 00 00 00 00 00 00 00 00 01 00 01 00 00 00 00 00 | +00B0 | 02 00 00 00 4C 00 00 00 00 06 00 00 00 00 00 00 | L +00C0 | 00 00 00 00 02 00 01 00 00 00 00 00 00 00 00 00 | +00D0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00E0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0100 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0110 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0120 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0130 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0140 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0150 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0160 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0170 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0180 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0190 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01A0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01B0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01C0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01D0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01E0 | 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 | +01F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0200 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0210 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0220 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0230 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0240 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0250 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0260 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0270 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0280 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0290 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02A0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02B0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02C0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02D0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02E0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0300 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0310 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0320 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0330 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0340 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0350 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0360 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0370 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0380 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0390 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +03A0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +03B0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +03C0 | 14 00 00 00 1F 00 11 00 17 00 2D 00 0A 00 28 00 | - ( +03D0 | 00 00 98 41 00 00 20 41 00 00 00 00 00 00 00 00 | A A +03E0 | 00 00 00 00 54 61 6C 69 00 00 00 00 00 00 00 00 | Tali +03F0 | 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF | +0400 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0410 | 18 D9 67 26 04 05 00 02 52 00 00 00 00 00 09 00 | g& R +0420 | 00 00 03 00 00 00 00 00 00 00 00 00 AA 5F AC 3E | _ > +0430 | 00 00 00 00 00 00 00 00 01 00 01 00 02 00 01 00 | +0440 | 02 01 01 00 04 00 01 00 01 00 01 00 00 00 01 00 | +0450 | 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 00 | +0460 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0470 | 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF | +0480 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | +I 7323 2023-11-07 02:01:44 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 1C 00 3F 06 00 00 00 00 00 80 0F 00 FF FF | ` ? +0010 | 00 00 00 00 00 00 A0 41 00 00 07 43 | A C +I 7323 2023-11-07 02:01:44 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 0C 00 1F 02 00 00 0F 00 00 00 | ` +I 7323 2023-11-07 02:01:44 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 08 00 23 01 00 00 | ` # +I 7323 2023-11-07 02:01:44 - [Commands] Sending to C-1 (Tali) (version=XB command=88 flag=01) +0000 | 04 00 2C 00 00 00 01 00 E2 D4 45 39 32 AC 99 83 | , E92 +0010 | 00 00 00 34 00 83 00 44 60 00 00 00 00 00 00 00 | 4 D` +0020 | 00 00 00 00 00 00 FF FF 80 FF FF FF | +I 7323 2023-11-07 02:01:44 - [Commands] Sending to C-1 (Tali) (version=XB command=88 flag=01) +0000 | 88 01 10 00 00 00 01 00 E2 D4 45 39 00 00 00 00 | E9 +I 7323 2023-11-07 02:01:45 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 00 00 00 00 00 00 FE 42 | ` @ B +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:01:46 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 00 00 00 00 00 00 EE 42 | ` @ B +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:01:47 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 00 00 00 00 00 00 DE 42 | ` @ B +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:01:48 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 00 00 00 00 00 00 CE 42 | ` B B +I 7323 2023-11-07 02:01:48 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 00 00 00 00 00 00 BF 42 | ` B B +I 7323 2023-11-07 02:01:49 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 00 00 00 00 00 00 B0 42 | ` B B +I 7323 2023-11-07 02:01:49 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 00 00 00 00 00 00 A1 42 | ` B B +I 7323 2023-11-07 02:01:50 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 00 00 00 00 00 00 92 42 | ` B B +I 7323 2023-11-07 02:01:50 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 00 00 00 00 00 00 83 42 | ` B B +I 7323 2023-11-07 02:01:51 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 00 00 00 00 00 00 68 42 | ` B hB +I 7323 2023-11-07 02:01:51 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 1C 00 3E 06 00 00 00 00 00 80 0F 00 01 00 | ` > +0010 | 00 00 00 00 00 00 AC B4 00 00 6A 42 | jB +I 7323 2023-11-07 02:01:52 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 52 03 00 00 00 00 00 00 00 80 FF FF | ` R +I 7323 2023-11-07 02:02:02 - [Commands] Received from C-1 (Tali) (version=XB command=C1 flag=03) +0000 | C1 03 30 00 00 00 00 00 00 00 00 00 09 45 31 31 | 0 E11 +0010 | 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 1 +0020 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 | +I 7323 2023-11-07 02:02:02 - [Lobby:15] Created lobby +I 7323 2023-11-07 02:02:02 - [Lobby:15] Assigned item IDs for joining player 0 +[PlayerInventory] Meseta: 0 +[PlayerInventory] 3 items +[PlayerInventory] 0: 02000500 F4010000 00000000 (00010000) 12000009 (Mag LV5 5/0/0/0 18% 0IQ (orange)) +[PlayerInventory] 1: 01010000 00000000 00000000 (00010001) 00000000 (Frame) +[PlayerInventory] 2: 00060000 00000000 00000000 (00010002) 00000000 (Handgun) +I 7323 2023-11-07 02:02:02 - [Commands] Sending to C-1 (Tali) (version=XB command=64 flag=01) +0000 | 64 01 DC 01 00 00 00 00 00 00 00 00 00 00 00 00 | d +0010 | 02 00 00 00 00 00 00 00 01 00 00 00 02 00 00 00 | +0020 | 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 | +0030 | 01 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 | +0040 | 01 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 | +0050 | 00 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 | +0060 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0070 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0080 | 00 00 00 00 00 00 01 00 E2 D4 45 39 0A 00 02 0F | E9 +0090 | 17 7E B2 19 FE E5 00 50 F2 AF A8 DC 31 0D 39 65 | ~ P 1 9e +00A0 | 00 0D 0E 89 24 48 A9 24 00 00 09 00 00 00 00 00 | $H $ +00B0 | 87 AA 3F BE 5B B1 47 B3 5A 2F 1A B0 00 00 00 00 | ? [ G Z/ +00C0 | 54 61 6C 69 00 00 00 00 00 00 00 00 00 00 00 00 | Tali +00D0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00E0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0100 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0110 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0120 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0130 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0140 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0150 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0160 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0170 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0180 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0190 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01A0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01B0 | 00 00 00 00 00 00 01 00 00 00 04 00 2B EC 26 74 | + &t +01C0 | 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01D0 | 00 00 00 00 00 00 00 00 00 00 00 00 | +I 7323 2023-11-07 02:02:02 - [Commands] Received from C-1 (Tali) (version=XB command=8A flag=00) +0000 | 8A 00 04 00 | +I 7323 2023-11-07 02:02:02 - [Commands] Sending to C-1 (Tali) (version=XB command=8A flag=00) +0000 | 8A 00 08 00 31 31 31 00 | 111 +I 7323 2023-11-07 02:02:09 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 1C 00 3F 06 00 00 00 00 00 C0 0F 00 00 00 | ` ? +0010 | CE FE 64 43 00 00 00 00 B8 FF 7D 43 | dC }C +I 7323 2023-11-07 02:02:09 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 0C 00 1F 02 00 00 00 00 00 00 | ` +I 7323 2023-11-07 02:02:09 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 08 00 3B 01 00 00 | ` ; +I 7323 2023-11-07 02:02:09 - [Commands] Received from C-1 (Tali) (version=XB command=6F flag=00) +0000 | 6F 00 04 00 | o +I 7323 2023-11-07 02:02:09 - [Commands] Sending to C-1 (Tali) (version=XB command=B1 flag=00) +0000 | B1 00 1C 00 32 30 32 33 3A 31 31 3A 30 37 3A 20 | 2023:11:07: +0010 | 30 32 3A 30 32 3A 30 39 2E 30 30 30 | 02:02:09.000 +I 7323 2023-11-07 02:02:10 - [Commands] Received from C-1 (Tali) (version=XB command=99 flag=00) +0000 | 99 00 04 00 | +I 7323 2023-11-07 02:02:14 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 CE FE 5C 43 B8 FF 7D 43 | ` @ \C }C +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:14 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 A6 56 57 43 90 57 78 43 | ` @ VWC WxC +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:15 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 AD 4E 52 43 AE 48 72 43 | ` @ NRC HrC +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:15 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 1D 69 4E 43 0A 4C 6B 43 | ` B iNC LkC +I 7323 2023-11-07 02:02:16 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 5B 91 4B 43 37 5F 64 43 | ` B [ KC7_dC +I 7323 2023-11-07 02:02:16 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 A8 A2 49 43 7F 22 5D 43 | ` B IC "]C +I 7323 2023-11-07 02:02:16 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 E6 9A 48 43 16 B7 55 43 | ` B HC UC +I 7323 2023-11-07 02:02:17 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 3C DD 42 43 69 A4 50 43 | ` B < BCi PC +I 7323 2023-11-07 02:02:17 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 75 40 3E 43 7A C5 4A 43 | ` B u@>Cz JC +I 7323 2023-11-07 02:02:17 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 8A 03 3F 43 22 2D 43 43 | ` B ?C"-CC +I 7323 2023-11-07 02:02:18 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 8F 6C 3F 43 5D D1 3B 43 | ` B l?C] ;C +I 7323 2023-11-07 02:02:18 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 80 1C 41 43 F6 83 34 43 | ` B AC 4C +I 7323 2023-11-07 02:02:18 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 EE 96 43 43 9B 71 2D 43 | ` B CC q-C +I 7323 2023-11-07 02:02:19 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 E1 DC 46 43 2B B4 26 43 | ` B FC+ &C +I 7323 2023-11-07 02:02:19 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 01 E1 44 43 32 4E 1F 43 | ` B DC2N C +I 7323 2023-11-07 02:02:19 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 23 41 44 43 28 DE 17 43 | ` B #ADC( C +I 7323 2023-11-07 02:02:20 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 28 1F 43 43 41 74 10 43 | ` B ( CCAt C +I 7323 2023-11-07 02:02:20 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 3A 04 42 43 38 09 09 43 | ` B : BC8 C +I 7323 2023-11-07 02:02:20 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 37 DA 46 43 48 1A 03 43 | ` B 7 FCH C +I 7323 2023-11-07 02:02:21 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 F4 3D 4B 43 89 5D FA 42 | ` B =KC ] B +I 7323 2023-11-07 02:02:21 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 B3 12 4B 43 BD 0E EB 42 | ` B KC B +I 7323 2023-11-07 02:02:21 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 88 2F 4C 43 7C 4E DC 42 | ` B /LC|N B +I 7323 2023-11-07 02:02:22 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 B1 CD 4C 43 A5 5B CD 42 | ` B LC [ B +I 7323 2023-11-07 02:02:22 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 97 71 4D 43 AA 69 BE 42 | ` B qMC i B +I 7323 2023-11-07 02:02:22 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 FC 15 4E 43 C6 77 AF 42 | ` B NC w B +I 7323 2023-11-07 02:02:23 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 80 BA 4E 43 E7 85 A0 42 | ` B NC B +I 7323 2023-11-07 02:02:23 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 35 5F 4F 43 0D 94 91 42 | ` B 5_OC B +I 7323 2023-11-07 02:02:23 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 40 73 55 43 F7 45 88 42 | ` B @sUC E B +I 7323 2023-11-07 02:02:24 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 FB 16 5B 43 60 91 7D 42 | ` B [C` }B +I 7323 2023-11-07 02:02:24 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 DB B1 5C 43 42 A0 5F 42 | ` B \CB _B +I 7323 2023-11-07 02:02:24 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 72 7B 5F 43 B3 F3 43 42 | ` B r{_C CB +I 7323 2023-11-07 02:02:25 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 E8 72 66 43 06 6D 37 42 | ` B rfC m7B +I 7323 2023-11-07 02:02:25 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 0D 08 6D 43 EF 2B 2A 42 | ` B mC +*B +I 7323 2023-11-07 02:02:25 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 1B 34 74 43 D2 78 21 42 | ` B 4tC x!B +I 7323 2023-11-07 02:02:26 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 FE 91 7B 43 A8 FC 1B 42 | ` B {C B +I 7323 2023-11-07 02:02:26 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 CA 85 81 43 20 ED 19 42 | ` B C B +I 7323 2023-11-07 02:02:26 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 A5 43 85 43 99 63 1B 42 | ` B C C c B +I 7323 2023-11-07 02:02:26 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 16 F5 88 43 2F 67 20 42 | ` B C/g B +I 7323 2023-11-07 02:02:27 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 58 3C 8C 43 DD 8E 10 42 | ` B X< C B +I 7323 2023-11-07 02:02:27 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 4C B9 8F 43 80 EE 05 42 | ` B L C B +I 7323 2023-11-07 02:02:27 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 5A 21 93 43 4B C8 F2 41 | ` B Z! CK A +I 7323 2023-11-07 02:02:27 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 13 A6 96 43 B4 70 05 42 | ` B C p B +I 7323 2023-11-07 02:02:28 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 50 19 9A 43 B3 CA 0F 42 | ` B P C B +I 7323 2023-11-07 02:02:28 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 99 54 9D 43 1F F8 1E 42 | ` B T C B +I 7323 2023-11-07 02:02:28 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 3B 17 A1 43 06 2C 19 42 | ` B ; C , B +I 7323 2023-11-07 02:02:28 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 27 D2 A4 43 02 B8 18 42 | ` B ' C B +I 7323 2023-11-07 02:02:29 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 B3 44 A8 43 27 36 12 42 | ` B D C'6 B +I 7323 2023-11-07 02:02:29 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 8C 01 AC 43 61 C7 0F 42 | ` B Ca B +I 7323 2023-11-07 02:02:29 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 1C 00 3E 06 00 00 00 00 4E 43 00 00 00 00 | ` > NC +0010 | C4 C1 AB 43 FB FF 7F 3F BE F1 0F 42 | C ? B +I 7323 2023-11-07 02:02:30 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 0C 00 21 02 00 00 01 00 00 00 | ` ! +I 7323 2023-11-07 02:02:30 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 08 00 22 01 00 00 | ` " +I 7323 2023-11-07 02:02:35 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 75 03 53 00 14 00 00 00 00 00 00 00 | ` u S +I 7323 2023-11-07 02:02:35 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 1C 00 3F 06 00 00 00 00 00 DF 01 00 00 00 | ` ? +0010 | D0 5D 1B C1 82 1F B8 41 B0 A5 B6 41 | ] A A +I 7323 2023-11-07 02:02:35 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 0C 00 1F 02 00 00 01 00 00 00 | ` +I 7323 2023-11-07 02:02:35 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 08 00 3B 01 00 00 | ` ; +I 7323 2023-11-07 02:02:35 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 08 00 23 01 00 00 | ` # +I 7323 2023-11-07 02:02:37 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 B1 A0 73 C1 A0 4B 88 41 | ` @ s K A +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:37 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 E9 49 B9 C1 B2 CB 7F 41 | ` @ I A +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:38 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 1D F1 F4 C1 98 26 55 41 | ` @ &UA +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:38 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 51 D8 16 C2 C0 A7 1A 41 | ` B Q A +I 7323 2023-11-07 02:02:38 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 2E B1 34 C2 57 19 36 41 | ` B . 4 W 6A +I 7323 2023-11-07 02:02:39 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 D0 87 52 C2 DC 6D 3B 41 | ` B R m;A +I 7323 2023-11-07 02:02:39 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 C1 57 70 C2 BA C7 48 41 | ` B Wp HA +I 7323 2023-11-07 02:02:39 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 CB 15 87 C2 84 A1 55 41 | ` B UA +I 7323 2023-11-07 02:02:39 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 E9 FF 95 C2 A9 6C 62 41 | ` B lbA +I 7323 2023-11-07 02:02:39 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 25 EA A4 C2 36 2F 6F 41 | ` B % 6/oA +I 7323 2023-11-07 02:02:40 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 0C 00 43 02 00 00 15 C4 00 00 | ` C +I 7323 2023-11-07 02:02:40 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 46 03 00 00 01 00 00 00 73 40 00 00 | ` F s@ +I 7323 2023-11-07 02:02:40 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 0B 03 73 40 01 00 00 00 73 00 00 00 | ` s@ s +I 7323 2023-11-07 02:02:40 - [Commands] Received from C-1 (Tali) (version=XB command=62 flag=00) +0000 | 62 00 2C 00 A2 0A 00 00 01 30 73 00 2A A3 DF C2 | b , 0s * +0010 | 88 06 8F 41 0A 00 01 00 01 00 80 3F C0 FF 7F 3F | A ? ? +0020 | 05 00 00 00 00 00 00 00 01 00 00 00 | +I 7323 2023-11-07 02:02:40 - [Commands] Sending to C-1 (Tali) (version=XB command=62 flag=00) +0000 | 62 00 2C 00 A2 0A 00 00 01 30 73 00 2A A3 DF C2 | b , 0s * +0010 | 88 06 8F 41 0A 00 01 00 01 00 80 3F C0 FF 7F 3F | A ? ? +0020 | 05 00 00 00 00 00 00 00 01 00 00 00 | +I 7323 2023-11-07 02:02:41 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 1C 00 3E 06 00 00 00 00 15 C4 01 00 0A 00 | ` > +0010 | 48 F4 9D C2 4E AA A6 41 DA 3C 69 41 | H N A . +0010 | 43 B6 CB C2 DC 05 A4 41 3D 7A 87 41 | C A=z A +I 7323 2023-11-07 02:02:43 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 33 13 CA C2 42 24 C7 41 | ` @ 3 B$ A +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:44 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 1C 00 3E 06 00 00 00 00 FE 09 01 00 0A 00 | ` > +0010 | E4 9A CA C2 5D 10 A7 41 FA DA C5 41 | ] A A +I 7323 2023-11-07 02:02:44 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 F5 B6 D9 C2 3B E8 DA 41 | ` @ ; A +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:45 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 1C 00 3E 06 00 00 00 00 FA CF 01 00 0A 00 | ` > +0010 | 99 6D D1 C2 4A 42 A7 41 1A 21 D6 41 | m JB A ! A +I 7323 2023-11-07 02:02:45 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 0C 00 43 02 00 00 8E DA 00 00 | ` C +I 7323 2023-11-07 02:02:45 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 46 03 00 00 01 00 00 00 74 40 00 00 | ` F t@ +I 7323 2023-11-07 02:02:46 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 0B 03 74 40 01 00 00 00 74 00 00 00 | ` t@ t +I 7323 2023-11-07 02:02:46 - [Commands] Received from C-1 (Tali) (version=XB command=62 flag=00) +0000 | 62 00 2C 00 A2 0A 00 00 01 30 74 00 CD AC E8 C2 | b , 0t +0010 | F4 88 0E 42 0A 00 01 00 01 00 80 3F C0 FF 7F 3F | B ? ? +0020 | 05 00 00 00 00 00 00 00 01 00 00 00 | +I 7323 2023-11-07 02:02:46 - [Commands] Sending to C-1 (Tali) (version=XB command=62 flag=00) +0000 | 62 00 2C 00 A2 0A 00 00 01 30 74 00 CD AC E8 C2 | b , 0t +0010 | F4 88 0E 42 0A 00 01 00 01 00 80 3F C0 FF 7F 3F | B ? ? +0020 | 05 00 00 00 00 00 00 00 01 00 00 00 | +I 7323 2023-11-07 02:02:46 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 1C 00 3E 06 00 00 00 00 8D DA 01 00 0A 00 | ` > +0010 | 99 6D D1 C2 C7 4E A7 41 1A 21 D6 41 | m N A ! A +I 7323 2023-11-07 02:02:47 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 90 0D E0 C2 50 16 F0 41 | ` @ P A +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:47 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 08 8B EE C2 B7 85 05 42 | ` @ B +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:47 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 0C 1D F4 C2 CA 7E 23 42 | ` @ ~#B +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:48 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 1C 00 3E 06 00 00 00 00 27 F6 01 00 0A 00 | ` > ' +0010 | FA 55 F4 C2 11 E6 A9 41 80 DF 22 42 | U A "B +I 7323 2023-11-07 02:02:49 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 BE FD E9 C2 FF 48 3B 42 | ` @ H;B +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:49 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 FC 9A DE C2 7C BB 50 42 | ` @ | PB +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:49 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 B8 FD D0 C2 C9 8A 61 42 | ` @ aB +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:50 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 1C 00 3E 06 00 00 00 00 A0 2A 01 00 0A 00 | ` > * +0010 | FB 07 D1 C2 6B E3 B3 41 77 A0 61 42 | k Aw aB +I 7323 2023-11-07 02:02:50 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 67 A9 C1 C2 93 85 6A 42 | ` @ g jB +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:51 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 24 D9 B1 C2 21 EF 6E 42 | ` @ $ ! nB +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:51 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 CD 00 A6 C2 43 3F 82 42 | ` @ C? B +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:51 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 6E A5 98 C2 D1 DE 8A 42 | ` B n B +I 7323 2023-11-07 02:02:51 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 A0 EA 94 C2 49 D5 99 42 | ` B I B +I 7323 2023-11-07 02:02:52 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 70 B3 8E C2 4D 66 A7 42 | ` B p Mf B +I 7323 2023-11-07 02:02:52 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 24 56 89 C2 24 68 B5 42 | ` B $V $h B +I 7323 2023-11-07 02:02:52 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 D6 E3 83 C2 0E 62 C3 42 | ` B b B +I 7323 2023-11-07 02:02:52 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 39 D1 7C C2 7D 58 D1 42 | ` B 9 | }X B +I 7323 2023-11-07 02:02:53 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 0C 00 43 02 00 00 C3 0F 00 00 | ` C +I 7323 2023-11-07 02:02:53 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 46 03 00 00 01 00 00 00 72 40 00 00 | ` F r@ +I 7323 2023-11-07 02:02:53 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 0B 03 72 40 01 00 00 00 72 00 00 00 | ` r@ r +I 7323 2023-11-07 02:02:53 - [Commands] Received from C-1 (Tali) (version=XB command=62 flag=00) +0000 | 62 00 2C 00 A2 0A 00 00 01 30 72 00 58 12 05 C2 | b , 0r X +0010 | 24 F1 31 43 0A 00 01 00 01 00 80 3F C0 FF 7F 3F | $ 1C ? ? +0020 | 05 00 00 00 00 00 00 00 01 00 00 00 | +I 7323 2023-11-07 02:02:53 - [Commands] Sending to C-1 (Tali) (version=XB command=62 flag=00) +0000 | 62 00 2C 00 A2 0A 00 00 01 30 72 00 58 12 05 C2 | b , 0r X +0010 | 24 F1 31 43 0A 00 01 00 01 00 80 3F C0 FF 7F 3F | $ 1C ? ? +0020 | 05 00 00 00 00 00 00 00 01 00 00 00 | +I 7323 2023-11-07 02:02:53 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 0C 00 44 02 00 00 C2 0F 00 00 | ` D +I 7323 2023-11-07 02:02:53 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 30 00 5F 0B 04 D0 01 02 72 00 58 12 05 C2 | ` 0 _ r X +0010 | 24 F1 31 43 0A 00 00 00 01 01 00 00 00 00 01 00 | $ 1C +0020 | 00 00 00 00 72 01 01 06 00 00 00 00 02 00 00 00 | r +I 7323 2023-11-07 02:02:53 - [Lobby:15] Player 0 (leader) created floor item 06010172 (Frame +1DEF) at 1:(-33.2679, 177.942) +I 7323 2023-11-07 02:02:53 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 46 03 00 00 01 00 00 00 71 40 00 00 | ` F q@ +I 7323 2023-11-07 02:02:54 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 0B 03 71 40 01 00 00 00 71 00 00 00 | ` q@ q +I 7323 2023-11-07 02:02:54 - [Commands] Received from C-1 (Tali) (version=XB command=62 flag=00) +0000 | 62 00 2C 00 A2 0A 00 00 01 30 71 00 A8 6E C8 C1 | b , 0q n +0010 | 20 65 44 43 0A 00 01 00 01 00 80 3F C0 FF 7F 3F | eDC ? ? +0020 | 05 00 00 00 00 00 00 00 01 00 00 00 | +I 7323 2023-11-07 02:02:54 - [Commands] Sending to C-1 (Tali) (version=XB command=62 flag=00) +0000 | 62 00 2C 00 A2 0A 00 00 01 30 71 00 A8 6E C8 C1 | b , 0q n +0010 | 20 65 44 43 0A 00 01 00 01 00 80 3F C0 FF 7F 3F | eDC ? ? +0020 | 05 00 00 00 00 00 00 00 01 00 00 00 | +I 7323 2023-11-07 02:02:54 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 30 00 5F 0B 04 D0 01 02 71 00 A8 6E C8 C1 | ` 0 _ q n +0010 | 20 65 44 43 0A 00 00 00 04 00 00 00 00 00 00 00 | eDC +0020 | 00 00 00 00 71 01 01 06 04 00 00 00 02 00 00 00 | q +I 7323 2023-11-07 02:02:54 - [Lobby:15] Player 0 (leader) created floor item 06010171 (4 Meseta) at 1:(-25.054, 196.395) +I 7323 2023-11-07 02:02:54 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 1C 00 3E 06 00 00 00 00 C2 0F 01 00 0A 00 | ` > +0010 | C3 29 83 C2 03 54 D6 41 0C 3F C5 42 | ) T A ? B +I 7323 2023-11-07 02:02:55 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 63 62 7A C2 23 17 D4 42 | ` @ cbz # B +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:55 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 45 E3 5C C2 E0 4B DA 42 | ` @ E \ K B +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:55 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 C8 5D 4E C2 36 98 E8 42 | ` @ ]N 6 B +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:56 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 06 AE 3C C2 46 B2 F5 42 | ` B < F B +I 7323 2023-11-07 02:02:56 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 0C 00 43 02 00 00 35 17 00 00 | ` C 5 +I 7323 2023-11-07 02:02:56 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 46 03 00 00 01 00 00 00 70 40 00 00 | ` F p@ +I 7323 2023-11-07 02:02:56 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 0B 03 70 40 01 00 00 00 70 00 00 00 | ` p@ p +I 7323 2023-11-07 02:02:56 - [Commands] Received from C-1 (Tali) (version=XB command=62 flag=00) +0000 | 62 00 2C 00 A2 0A 00 00 01 30 70 00 C0 FB CE C0 | b , 0p +0010 | D3 C9 3A 43 0A 00 01 00 01 00 80 3F C0 FF 7F 3F | :C ? ? +0020 | 05 00 00 00 00 00 00 00 01 00 00 00 | +I 7323 2023-11-07 02:02:56 - [Commands] Sending to C-1 (Tali) (version=XB command=62 flag=00) +0000 | 62 00 2C 00 A2 0A 00 00 01 30 70 00 C0 FB CE C0 | b , 0p +0010 | D3 C9 3A 43 0A 00 01 00 01 00 80 3F C0 FF 7F 3F | :C ? ? +0020 | 05 00 00 00 00 00 00 00 01 00 00 00 | +I 7323 2023-11-07 02:02:57 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 1C 00 3E 06 00 00 00 00 34 17 01 00 0A 00 | ` > 4 +0010 | 10 F2 44 C2 82 A9 E5 41 C4 04 F0 42 | D A B +I 7323 2023-11-07 02:02:57 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 8C B4 34 C2 11 CE FD 42 | ` @ 4 B +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:58 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 38 A5 15 C2 08 D8 00 43 | ` @ 8 C +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:58 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 32 19 ED C1 2C 14 02 43 | ` @ 2 , C +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:02:58 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 53 DF BE C1 45 9C 07 43 | ` B S E C +I 7323 2023-11-07 02:02:58 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 BC 10 BA C1 FF E2 0E 43 | ` B C +I 7323 2023-11-07 02:02:59 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 33 D5 B3 C1 B9 3C 16 43 | ` B 3 < C +I 7323 2023-11-07 02:02:59 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 B3 B9 B6 C1 A3 B9 1D 43 | ` B C +I 7323 2023-11-07 02:02:59 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 03 8F BF C1 6C 23 25 43 | ` B l#%C +I 7323 2023-11-07 02:02:59 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 5D B6 CE C1 96 63 2C 43 | ` B ] c,C +I 7323 2023-11-07 02:02:59 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 49 48 E4 C1 55 61 33 43 | ` B IH Ua3C +I 7323 2023-11-07 02:03:00 - [Commands] Received from C-1 (Tali) (version=XB command=62 flag=00) +0000 | 62 00 10 00 5A 03 00 00 72 01 01 06 01 00 00 00 | b Z r +I 7323 2023-11-07 02:03:00 - [Commands] Sending to C-1 (Tali) (version=XB command=62 flag=00) +0000 | 62 00 10 00 5A 03 00 00 72 01 01 06 01 00 00 00 | b Z r +I 7323 2023-11-07 02:03:00 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 5F 15 00 C2 35 03 3A 43 | ` B _ 5 :C +I 7323 2023-11-07 02:03:00 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 18 38 F2 C1 AA 78 41 43 | ` B 8 xAC +I 7323 2023-11-07 02:03:00 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 59 03 00 00 00 00 01 00 72 01 01 06 | ` Y r +I 7323 2023-11-07 02:03:00 - [Lobby:15] Player 0 picked up 06010172 (Frame +1DEF) +[PlayerInventory] Meseta: 0 +[PlayerInventory] 4 items +[PlayerInventory] 0: 02000500 F4010000 00000000 (00010000) 12000009 (Mag LV5 5/0/0/0 18% 0IQ (orange)) +[PlayerInventory] 1: 01010000 00000000 00000000 (00010001) 00000000 (Frame) +[PlayerInventory] 2: 00060000 00000000 00000000 (00010002) 00000000 (Handgun) +[PlayerInventory] 3: 01010000 00000100 00000000 (06010172) 00000000 (Frame +1DEF) +I 7323 2023-11-07 02:03:00 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 1C 00 3E 06 00 00 00 00 6C 06 01 00 0A 00 | ` > l +0010 | 46 7E F6 C1 01 F0 0E 42 6D FA 40 43 | F~ Bm @C +I 7323 2023-11-07 02:03:01 - [Commands] Received from C-1 (Tali) (version=XB command=62 flag=00) +0000 | 62 00 10 00 5A 03 00 00 71 01 01 06 01 00 00 00 | b Z q +I 7323 2023-11-07 02:03:01 - [Commands] Sending to C-1 (Tali) (version=XB command=62 flag=00) +0000 | 62 00 10 00 5A 03 00 00 71 01 01 06 01 00 00 00 | b Z q +I 7323 2023-11-07 02:03:01 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 59 03 00 00 00 00 01 00 71 01 01 06 | ` Y q +I 7323 2023-11-07 02:03:01 - [Lobby:15] Player 0 picked up 06010171 (4 Meseta) +[PlayerInventory] Meseta: 4 +[PlayerInventory] 4 items +[PlayerInventory] 0: 02000500 F4010000 00000000 (00010000) 12000009 (Mag LV5 5/0/0/0 18% 0IQ (orange)) +[PlayerInventory] 1: 01010000 00000000 00000000 (00010001) 00000000 (Frame) +[PlayerInventory] 2: 00060000 00000000 00000000 (00010002) 00000000 (Handgun) +[PlayerInventory] 3: 01010000 00000100 00000000 (06010172) 00000000 (Frame +1DEF) +I 7323 2023-11-07 02:03:24 - [Commands] Received from C-1 (Tali) (version=XB command=06 flag=00) +0000 | 06 00 18 00 00 00 00 00 00 00 00 00 09 45 24 63 | E$c +0010 | 68 65 61 74 00 00 00 00 | heat +I 7323 2023-11-07 02:03:24 - [Commands] Sending to C-1 (Tali) (version=XB command=62 flag=00) +0000 | B0 00 20 00 00 00 00 00 00 00 00 00 43 68 65 61 | Chea +0010 | 74 20 6D 6F 64 65 20 65 6E 61 62 6C 65 64 00 00 | t mode enabled +I 7323 2023-11-07 02:03:24 - [Commands] Received from C-1 (Tali) (version=XB command=06 flag=00) +0000 | 06 00 18 00 00 00 00 00 00 00 00 00 09 45 24 77 | E$w +0010 | 61 72 70 20 30 00 00 00 | arp 0 +I 7323 2023-11-07 02:03:24 - [Commands] Sending to C-1 (Tali) (version=XB command=62 flag=00) +0000 | 62 00 0C 00 94 02 00 00 00 00 00 00 | b +I 7323 2023-11-07 02:03:25 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 0C 00 21 02 00 00 00 00 00 00 | ` ! +I 7323 2023-11-07 02:03:25 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 08 00 22 01 00 00 | ` " +I 7323 2023-11-07 02:03:30 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 1C 00 3F 06 00 00 00 00 00 C0 00 00 00 00 | ` ? +0010 | B0 E7 8E 43 00 00 00 00 40 9F B3 41 | C @ A +I 7323 2023-11-07 02:03:30 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 0C 00 1F 02 00 00 00 00 00 00 | ` +I 7323 2023-11-07 02:03:30 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 08 00 3B 01 00 00 | ` ; +I 7323 2023-11-07 02:03:30 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 08 00 23 01 00 00 | ` # +I 7323 2023-11-07 02:03:31 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 B0 E7 8A 43 40 9F B3 41 | ` @ C@ A +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:03:31 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 B0 E7 86 43 40 9F B3 41 | ` @ C@ A +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:03:32 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 76 16 84 43 EF 0D E1 41 | ` @ v C A +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:03:33 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 28 96 81 43 2F D9 08 42 | ` B ( C/ B +I 7323 2023-11-07 02:03:33 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 C5 B2 7B 43 15 A0 0E 42 | ` B {C B +I 7323 2023-11-07 02:03:33 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 EC B6 74 43 C3 23 19 42 | ` B tC # B +I 7323 2023-11-07 02:03:34 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 C1 87 6D 43 D8 BF 21 42 | ` B mC !B +I 7323 2023-11-07 02:03:34 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 A6 44 6A 43 CA 74 3D 42 | ` B DjC t=B +I 7323 2023-11-07 02:03:34 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 7E D2 66 43 79 82 57 42 | ` B ~ fCy WB +I 7323 2023-11-07 02:03:35 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 EE D4 5F 43 A3 02 64 42 | ` B _C dB +I 7323 2023-11-07 02:03:35 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 97 8C 5E 43 EC C3 81 42 | ` B ^C B +I 7323 2023-11-07 02:03:36 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 1E CC 5C 43 D8 0A 90 42 | ` B \C B +I 7323 2023-11-07 02:03:36 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 F7 64 5C 43 7A 01 9F 42 | ` B d\Cz B +I 7323 2023-11-07 02:03:37 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 74 E1 5C 43 15 F5 AD 42 | ` B t \C B +I 7323 2023-11-07 02:03:37 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 A4 43 5E 43 CB AE BC 42 | ` B C^C B +I 7323 2023-11-07 02:03:37 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 51 66 5A 43 47 EA C9 42 | ` B QfZCG B +I 7323 2023-11-07 02:03:38 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 F5 DA 57 43 6D F3 D7 42 | ` B WCm B +I 7323 2023-11-07 02:03:38 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 38 D4 54 43 C1 AC E5 42 | ` B 8 TC B +I 7323 2023-11-07 02:03:38 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 27 D4 51 43 1F 6C F3 42 | ` B ' QC l B +I 7323 2023-11-07 02:03:39 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 62 D4 4E 43 DD 95 00 43 | ` B b NC C +I 7323 2023-11-07 02:03:39 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 F3 D4 4B 43 D4 75 07 43 | ` B KC u C +I 7323 2023-11-07 02:03:39 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 B0 D5 48 43 D9 55 0E 43 | ` B HC U C +I 7323 2023-11-07 02:03:40 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 95 D6 45 43 F2 35 15 43 | ` B EC 5 C +I 7323 2023-11-07 02:03:40 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 79 D7 42 43 0B 16 1C 43 | ` B y BC C +I 7323 2023-11-07 02:03:40 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 8B D8 3F 43 38 F6 22 43 | ` B ?C8 "C +I 7323 2023-11-07 02:03:41 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 93 D9 3C 43 61 D6 29 43 | ` B G +0010 | E2 7B 96 43 00 00 AC B4 1D 8C 52 43 | { C RC +I 7323 2023-11-07 02:03:49 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 08 00 22 01 00 00 | ` " +I 7323 2023-11-07 02:03:49 - [Commands] Received from C-1 (Tali) (version=XB command=98 flag=03) +0000 | 98 03 80 06 04 00 00 01 02 00 00 00 4C 00 00 00 | L +0010 | 02 00 05 00 F4 01 00 00 00 00 00 00 00 00 01 00 | +0020 | 12 00 00 09 02 00 00 00 4C 00 00 00 01 01 00 00 | L +0030 | 00 00 00 00 00 00 00 00 01 00 01 00 00 00 00 00 | +0040 | 02 00 00 00 4C 00 00 00 00 06 00 00 00 00 00 00 | L +0050 | 00 00 00 00 02 00 01 00 00 00 00 00 01 00 00 00 | +0060 | 44 00 00 00 01 01 00 00 00 00 01 00 00 00 00 00 | D +0070 | 72 01 01 06 00 00 00 00 00 00 00 00 00 00 00 00 | r +0080 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0090 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00A0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00B0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00C0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00D0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00E0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0100 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0110 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0120 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0130 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0140 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0150 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0160 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0170 | 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 | +0180 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0190 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01A0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01B0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01C0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01D0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01E0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0200 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0210 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0220 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0230 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0240 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0250 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0260 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0270 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0280 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0290 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02A0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02B0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02C0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02D0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02E0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0300 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0310 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0320 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0330 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0340 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0350 | 14 00 00 00 1F 00 11 00 17 00 2D 00 0A 00 28 00 | - ( +0360 | 00 00 98 41 00 00 20 41 00 00 00 00 00 00 00 00 | A A +0370 | 04 00 00 00 54 61 6C 69 00 00 00 00 00 00 00 00 | Tali +0380 | 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF | +0390 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +03A0 | 00 00 00 00 04 05 00 02 52 00 00 00 00 00 09 00 | R +03B0 | 00 00 03 00 00 00 00 00 00 00 00 00 AA 5F AC 3E | _ > +03C0 | 00 00 00 00 00 00 00 00 01 06 00 00 02 00 01 00 | +03D0 | 02 01 01 00 04 00 01 00 01 06 01 00 00 00 01 00 | +03E0 | 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 00 | +03F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0400 | 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF | +0410 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | +0420 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0430 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0440 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0450 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0460 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0470 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0480 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0490 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +04A0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +04B0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +04C0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +04D0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +04E0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +04F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0500 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0510 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0520 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0530 | 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 | +0540 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0550 | 00 00 00 00 09 45 77 6F 6F 20 24 43 32 78 62 6F | Ewoo $C2xbo +0560 | 78 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | x +0570 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0580 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0590 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +05A0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +05B0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +05C0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +05D0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +05E0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +05F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0600 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0610 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0620 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0630 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0640 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0650 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0660 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0670 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +I 7323 2023-11-07 02:03:49 - [Lobby:15] Deleted lobby +I 7323 2023-11-07 02:03:52 - [Commands] Received from C-1 (Tali) (version=XB command=84 flag=00) +0000 | 84 00 0C 00 33 00 00 33 01 00 00 00 | 3 3 +I 7323 2023-11-07 02:03:52 - [Commands] Sending to C-1 (Tali) (version=XB command=C5 flag=01) +0000 | C5 01 20 01 00 00 00 00 00 00 00 00 00 00 00 00 | +0010 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0020 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0030 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0040 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0050 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0060 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0070 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0080 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0090 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00A0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00B0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00C0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00D0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00E0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +00F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0100 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0110 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +I 7323 2023-11-07 02:03:52 - [Commands] Sending to C-1 (Tali) (version=XB command=67 flag=01) +0000 | 67 01 90 04 00 00 01 00 01 00 00 00 00 00 00 00 | g +0010 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0020 | 00 00 00 00 00 00 00 00 00 00 01 00 E2 D4 45 39 | E9 +0030 | 0A 00 02 0F 17 7E B2 19 FE E5 00 50 F2 AF A8 DC | ~ P +0040 | 31 0D 39 65 00 0D 0E 89 24 48 A9 24 00 00 09 00 | 1 9e $H $ +0050 | 00 00 00 00 87 AA 3F BE 5B B1 47 B3 5A 2F 1A B0 | ? [ G Z/ +0060 | 00 00 00 00 54 61 6C 69 00 00 00 00 00 00 00 00 | Tali +0070 | 00 00 00 00 04 00 00 01 02 00 00 00 4C 00 00 00 | L +0080 | 02 00 05 00 F4 01 00 00 00 00 00 00 00 00 01 00 | +0090 | 12 00 00 09 02 00 00 00 4C 00 00 00 01 01 00 00 | L +00A0 | 00 00 00 00 00 00 00 00 01 00 01 00 00 00 00 00 | +00B0 | 02 00 00 00 4C 00 00 00 00 06 00 00 00 00 00 00 | L +00C0 | 00 00 00 00 02 00 01 00 00 00 00 00 01 00 00 00 | +00D0 | 44 00 00 00 01 01 00 00 00 00 01 00 00 00 00 00 | D +00E0 | 72 01 01 06 00 00 00 00 00 00 00 00 00 00 00 00 | r +00F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0100 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0110 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0120 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0130 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0140 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0150 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0160 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0170 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0180 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0190 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01A0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01B0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01C0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01D0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +01E0 | 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 | +01F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0200 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0210 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0220 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0230 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0240 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0250 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0260 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0270 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0280 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0290 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02A0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02B0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02C0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02D0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02E0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +02F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0300 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0310 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0320 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0330 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0340 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0350 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0360 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0370 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0380 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0390 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +03A0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +03B0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +03C0 | 14 00 00 00 1F 00 11 00 17 00 2D 00 0A 00 28 00 | - ( +03D0 | 00 00 98 41 00 00 20 41 00 00 00 00 00 00 00 00 | A A +03E0 | 04 00 00 00 54 61 6C 69 00 00 00 00 00 00 00 00 | Tali +03F0 | 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF | +0400 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0410 | E9 F2 96 0D 04 05 00 02 52 00 00 00 00 00 09 00 | R +0420 | 00 00 03 00 00 00 00 00 00 00 00 00 AA 5F AC 3E | _ > +0430 | 00 00 00 00 00 00 00 00 01 06 00 00 02 00 01 00 | +0440 | 02 01 01 00 04 00 01 00 01 06 01 00 00 00 01 00 | +0450 | 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 00 | +0460 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | +0470 | 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF | +0480 | FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF | +I 7323 2023-11-07 02:03:53 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 1C 00 3F 06 00 00 00 00 00 80 0F 00 FF FF | ` ? +0010 | 00 00 00 00 00 00 A0 41 00 00 07 43 | A C +I 7323 2023-11-07 02:03:53 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 0C 00 1F 02 00 00 0F 00 00 00 | ` +I 7323 2023-11-07 02:03:53 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 08 00 23 01 00 00 | ` # +I 7323 2023-11-07 02:03:53 - [Commands] Sending to C-1 (Tali) (version=XB command=88 flag=01) +0000 | 88 01 10 00 00 00 01 00 E2 D4 45 39 00 00 00 00 | E9 +I 7323 2023-11-07 02:03:56 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 00 00 00 00 00 00 FE 42 | ` @ B +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:03:57 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 00 00 00 00 00 00 EE 42 | ` @ B +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:03:58 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 14 00 40 04 00 00 00 00 00 00 00 00 DE 42 | ` @ B +0010 | 00 00 00 00 | +I 7323 2023-11-07 02:03:59 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 00 00 00 00 00 00 CE 42 | ` B B +I 7323 2023-11-07 02:03:59 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 00 00 00 00 00 00 BF 42 | ` B B +I 7323 2023-11-07 02:04:00 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 00 00 00 00 00 00 B0 42 | ` B B +I 7323 2023-11-07 02:04:00 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 00 00 00 00 00 00 A1 42 | ` B B +I 7323 2023-11-07 02:04:01 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 00 00 00 00 00 00 92 42 | ` B B +I 7323 2023-11-07 02:04:01 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 00 00 00 00 00 00 83 42 | ` B B +I 7323 2023-11-07 02:04:02 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 10 00 42 03 00 00 00 00 00 00 00 00 68 42 | ` B hB +I 7323 2023-11-07 02:04:02 - [Commands] Received from C-1 (Tali) (version=XB command=60 flag=00) +0000 | 60 00 1C 00 3E 06 00 00 00 00 00 80 0F 00 01 00 | ` > +0010 | 00 00 00 00 00 00 AC B4 00 00 6A 42 | jB +I 7323 2023-11-07 02:04:09 - [Commands] Received from C-1 (Tali) (version=XB command=05 flag=00) +0000 | 05 00 04 00 | +I 7323 2023-11-07 02:04:09 - [Server] Client disconnected: C-1 on fd 41 +I 7323 2023-11-07 02:04:09 - [C-1] Deleted