implement patch serving
This commit is contained in:
@@ -65,6 +65,7 @@ add_executable(newserv
|
|||||||
src/Map.cc
|
src/Map.cc
|
||||||
src/Menu.cc
|
src/Menu.cc
|
||||||
src/NetworkAddresses.cc
|
src/NetworkAddresses.cc
|
||||||
|
src/PatchFileIndex.cc
|
||||||
src/Player.cc
|
src/Player.cc
|
||||||
src/ProxyCommands.cc
|
src/ProxyCommands.cc
|
||||||
src/ProxyServer.cc
|
src/ProxyServer.cc
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "CommandFormats.hh"
|
#include "CommandFormats.hh"
|
||||||
#include "FunctionCompiler.hh"
|
#include "FunctionCompiler.hh"
|
||||||
#include "License.hh"
|
#include "License.hh"
|
||||||
|
#include "PatchFileIndex.hh"
|
||||||
#include "Player.hh"
|
#include "Player.hh"
|
||||||
#include "PSOEncryption.hh"
|
#include "PSOEncryption.hh"
|
||||||
#include "PSOProtocol.hh"
|
#include "PSOProtocol.hh"
|
||||||
@@ -74,6 +75,9 @@ struct Client {
|
|||||||
uint32_t proxy_destination_address;
|
uint32_t proxy_destination_address;
|
||||||
uint16_t proxy_destination_port;
|
uint16_t proxy_destination_port;
|
||||||
|
|
||||||
|
// Patch server
|
||||||
|
std::vector<PatchFileChecksumRequest> patch_file_checksum_requests;
|
||||||
|
|
||||||
// Lobby/positioning
|
// Lobby/positioning
|
||||||
float x;
|
float x;
|
||||||
float z;
|
float z;
|
||||||
|
|||||||
@@ -88,8 +88,8 @@ struct ClientConfigBB {
|
|||||||
|
|
||||||
// Patch server commands
|
// Patch server commands
|
||||||
|
|
||||||
// The patch protocol is nearly identical between PSO PC and PSO BB (the only
|
// The patch protocol is identical between PSO PC and PSO BB (the only versions
|
||||||
// versions on which it is used). Only the client's 04 command differs.
|
// on which it is used).
|
||||||
|
|
||||||
// A patch server session generally goes like this:
|
// A patch server session generally goes like this:
|
||||||
// Server: 02 (unencrypted)
|
// Server: 02 (unencrypted)
|
||||||
@@ -157,12 +157,14 @@ struct S_ServerInit_Patch_02 {
|
|||||||
// Client will respond with an 04 command.
|
// Client will respond with an 04 command.
|
||||||
|
|
||||||
// 04 (C->S): Log in (patch)
|
// 04 (C->S): Log in (patch)
|
||||||
|
// The email field is always blank on BB. It may be blank on PC too, so this
|
||||||
|
// cannot be used to determine the game version used by a patch client.
|
||||||
|
|
||||||
struct C_Login_Patch_04 {
|
struct C_Login_Patch_04 {
|
||||||
parray<le_uint32_t, 3> unused;
|
parray<le_uint32_t, 3> unused;
|
||||||
ptext<char, 0x10> username;
|
ptext<char, 0x10> username;
|
||||||
ptext<char, 0x10> password;
|
ptext<char, 0x10> password;
|
||||||
ptext<char, 0x40> email; // Note: this field is blank on BB
|
ptext<char, 0x40> email;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 05 (S->C): Unknown
|
// 05 (S->C): Unknown
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ PrefixedLogger function_compiler_log ("[FunctionCompiler] ", LogLevel::USE_DEFAU
|
|||||||
PrefixedLogger ip_stack_simulator_log("[IPStackSimulator] ", LogLevel::USE_DEFAULT);
|
PrefixedLogger ip_stack_simulator_log("[IPStackSimulator] ", LogLevel::USE_DEFAULT);
|
||||||
PrefixedLogger license_log ("[LicenseManager] " , LogLevel::USE_DEFAULT);
|
PrefixedLogger license_log ("[LicenseManager] " , LogLevel::USE_DEFAULT);
|
||||||
PrefixedLogger lobby_log ("" , LogLevel::USE_DEFAULT);
|
PrefixedLogger lobby_log ("" , LogLevel::USE_DEFAULT);
|
||||||
|
PrefixedLogger patch_index_log ("[PatchFileIndex] " , LogLevel::USE_DEFAULT);
|
||||||
PrefixedLogger player_data_log ("" , LogLevel::USE_DEFAULT);
|
PrefixedLogger player_data_log ("" , LogLevel::USE_DEFAULT);
|
||||||
PrefixedLogger proxy_server_log ("[ProxyServer] " , LogLevel::USE_DEFAULT);
|
PrefixedLogger proxy_server_log ("[ProxyServer] " , LogLevel::USE_DEFAULT);
|
||||||
PrefixedLogger replay_log ("[ReplaySession] " , LogLevel::USE_DEFAULT);
|
PrefixedLogger replay_log ("[ReplaySession] " , LogLevel::USE_DEFAULT);
|
||||||
@@ -51,6 +52,7 @@ void set_log_levels_from_json(shared_ptr<JSONObject> json) {
|
|||||||
set_log_level_from_json(ip_stack_simulator_log, json, "IPStackSimulator");
|
set_log_level_from_json(ip_stack_simulator_log, json, "IPStackSimulator");
|
||||||
set_log_level_from_json(license_log , json, "LicenseManager");
|
set_log_level_from_json(license_log , json, "LicenseManager");
|
||||||
set_log_level_from_json(lobby_log , json, "Lobbies");
|
set_log_level_from_json(lobby_log , json, "Lobbies");
|
||||||
|
set_log_level_from_json(patch_index_log , json, "PatchFileIndex");
|
||||||
set_log_level_from_json(player_data_log , json, "PlayerData");
|
set_log_level_from_json(player_data_log , json, "PlayerData");
|
||||||
set_log_level_from_json(proxy_server_log , json, "ProxyServer");
|
set_log_level_from_json(proxy_server_log , json, "ProxyServer");
|
||||||
set_log_level_from_json(replay_log , json, "Replay");
|
set_log_level_from_json(replay_log , json, "Replay");
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ extern PrefixedLogger function_compiler_log;
|
|||||||
extern PrefixedLogger ip_stack_simulator_log;
|
extern PrefixedLogger ip_stack_simulator_log;
|
||||||
extern PrefixedLogger license_log;
|
extern PrefixedLogger license_log;
|
||||||
extern PrefixedLogger lobby_log;
|
extern PrefixedLogger lobby_log;
|
||||||
|
extern PrefixedLogger patch_index_log;
|
||||||
extern PrefixedLogger player_data_log;
|
extern PrefixedLogger player_data_log;
|
||||||
extern PrefixedLogger proxy_server_log;
|
extern PrefixedLogger proxy_server_log;
|
||||||
extern PrefixedLogger replay_log;
|
extern PrefixedLogger replay_log;
|
||||||
|
|||||||
+13
@@ -496,6 +496,19 @@ int main(int argc, char** argv) {
|
|||||||
state->dol_file_index.reset(new DOLFileIndex());
|
state->dol_file_index.reset(new DOLFileIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isdir("system/patch-pc")) {
|
||||||
|
config_log.info("Indexing PSO PC patch files");
|
||||||
|
state->pc_patch_file_index.reset(new PatchFileIndex("system/patch-pc"));
|
||||||
|
} else {
|
||||||
|
config_log.info("PSO PC patch files not present");
|
||||||
|
}
|
||||||
|
if (isdir("system/patch-bb")) {
|
||||||
|
config_log.info("Indexing PSO BB patch files");
|
||||||
|
state->bb_patch_file_index.reset(new PatchFileIndex("system/patch-bb"));
|
||||||
|
} else {
|
||||||
|
config_log.info("PSO BB patch files not present");
|
||||||
|
}
|
||||||
|
|
||||||
config_log.info("Creating menus");
|
config_log.info("Creating menus");
|
||||||
state->create_menus(config_json);
|
state->create_menus(config_json);
|
||||||
|
|
||||||
|
|||||||
+107
-18
@@ -83,8 +83,10 @@ void process_connect(std::shared_ptr<ServerState> s, std::shared_ptr<Client> c)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ServerBehavior::PATCH_SERVER_BB:
|
||||||
|
c->flags |= Client::Flag::BB_PATCH;
|
||||||
|
case ServerBehavior::PATCH_SERVER_PC:
|
||||||
case ServerBehavior::DATA_SERVER_BB:
|
case ServerBehavior::DATA_SERVER_BB:
|
||||||
case ServerBehavior::PATCH_SERVER:
|
|
||||||
case ServerBehavior::LOBBY_SERVER:
|
case ServerBehavior::LOBBY_SERVER:
|
||||||
send_server_init(s, c, false, false);
|
send_server_init(s, c, false, false);
|
||||||
break;
|
break;
|
||||||
@@ -2349,13 +2351,40 @@ void process_encryption_ok_patch(shared_ptr<ServerState>, shared_ptr<Client> c,
|
|||||||
send_command(c, 0x04, 0x00); // This requests the user's login information
|
send_command(c, 0x04, 0x00); // This requests the user's login information
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void change_to_directory_patch(
|
||||||
|
shared_ptr<Client> c,
|
||||||
|
vector<string>& client_path_directories,
|
||||||
|
const vector<string>& file_path_directories) {
|
||||||
|
// First, exit all leaf directories that don't match the desired path
|
||||||
|
while (!client_path_directories.empty() &&
|
||||||
|
((client_path_directories.size() > file_path_directories.size()) ||
|
||||||
|
(client_path_directories.back() != file_path_directories[client_path_directories.size() - 1]))) {
|
||||||
|
send_command(c, 0x0A, 0x00);
|
||||||
|
client_path_directories.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point, client_path_directories should be a prefix of
|
||||||
|
// file_path_directories (or should match exactly)
|
||||||
|
if (client_path_directories.size() > file_path_directories.size()) {
|
||||||
|
throw logic_error("did not exit all necessary directories");
|
||||||
|
}
|
||||||
|
for (size_t x = 0; x < client_path_directories.size(); x++) {
|
||||||
|
if (client_path_directories[x] != file_path_directories[x]) {
|
||||||
|
throw logic_error("intermediate path is not a prefix of final path");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second, enter all necessary leaf directories
|
||||||
|
while (client_path_directories.size() < file_path_directories.size()) {
|
||||||
|
const string& dir = file_path_directories[client_path_directories.size()];
|
||||||
|
send_enter_directory_patch(c, dir);
|
||||||
|
client_path_directories.emplace_back(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void process_login_patch(shared_ptr<ServerState> s, shared_ptr<Client> c,
|
void process_login_patch(shared_ptr<ServerState> s, shared_ptr<Client> c,
|
||||||
uint16_t, uint32_t, const string& data) {
|
uint16_t, uint32_t, const string& data) {
|
||||||
const auto& cmd = check_size_t<C_Login_Patch_04>(data);
|
check_size_v(data.size(), sizeof(C_Login_Patch_04));
|
||||||
|
|
||||||
if (cmd.email.len() == 0) {
|
|
||||||
c->flags |= Client::Flag::BB_PATCH;
|
|
||||||
}
|
|
||||||
|
|
||||||
// On BB we can use colors and newlines should be \n; on PC we can't use
|
// On BB we can use colors and newlines should be \n; on PC we can't use
|
||||||
// colors, the text is auto-word-wrapped, and newlines should be \r\n.
|
// colors, the text is auto-word-wrapped, and newlines should be \r\n.
|
||||||
@@ -2365,16 +2394,72 @@ void process_login_patch(shared_ptr<ServerState> s, shared_ptr<Client> c,
|
|||||||
send_message_box(c, message.c_str());
|
send_message_box(c, message.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement patch serving for realz.
|
auto index = (c->flags & Client::Flag::BB_PATCH) ?
|
||||||
send_enter_directory_patch(c, ".");
|
s->bb_patch_file_index : s->pc_patch_file_index;
|
||||||
send_enter_directory_patch(c, "data");
|
if (index.get()) {
|
||||||
send_enter_directory_patch(c, "scene");
|
send_command(c, 0x0B, 0x00); // Start patch session; go to root directory
|
||||||
send_command(c, 0x0A, 0x00);
|
|
||||||
send_command(c, 0x0A, 0x00);
|
vector<string> path_directories;
|
||||||
send_command(c, 0x0A, 0x00);
|
for (const auto& file : index->files) {
|
||||||
|
change_to_directory_patch(c, path_directories, file->path_directories);
|
||||||
|
|
||||||
|
S_FileChecksumRequest_Patch_0C req = {
|
||||||
|
c->patch_file_checksum_requests.size(), file->name};
|
||||||
|
send_command_t(c, 0x0C, 0x00, req);
|
||||||
|
c->patch_file_checksum_requests.emplace_back(file);
|
||||||
|
}
|
||||||
|
change_to_directory_patch(c, path_directories, {});
|
||||||
|
|
||||||
|
send_command(c, 0x0D, 0x00); // End of checksum requests
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// No patch index present: just do something that will satisfy the client
|
||||||
|
// without actually checking or downloading any files
|
||||||
|
send_enter_directory_patch(c, ".");
|
||||||
|
send_enter_directory_patch(c, "data");
|
||||||
|
send_enter_directory_patch(c, "scene");
|
||||||
|
send_command(c, 0x0A, 0x00);
|
||||||
|
send_command(c, 0x0A, 0x00);
|
||||||
|
send_command(c, 0x0A, 0x00);
|
||||||
|
send_command(c, 0x12, 0x00);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void process_file_checksum_result_patch(shared_ptr<ServerState>,
|
||||||
|
shared_ptr<Client> c, uint16_t, uint32_t, const string& data) { // 0F
|
||||||
|
auto& cmd = check_size_t<C_FileInformation_Patch_0F>(data);
|
||||||
|
auto& req = c->patch_file_checksum_requests.at(cmd.request_id);
|
||||||
|
req.crc32 = cmd.checksum;
|
||||||
|
req.size = cmd.size;
|
||||||
|
req.response_received = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void process_file_checksum_results_done_patch(shared_ptr<ServerState>,
|
||||||
|
shared_ptr<Client> c, uint16_t, uint32_t, const string&) { // 10
|
||||||
|
|
||||||
|
S_StartFileDownloads_Patch_11 start_cmd = {0, 0};
|
||||||
|
for (const auto& req : c->patch_file_checksum_requests) {
|
||||||
|
if (!req.response_received) {
|
||||||
|
throw runtime_error("client did not respond to checksum request");
|
||||||
|
}
|
||||||
|
if (req.needs_update()) {
|
||||||
|
start_cmd.total_bytes += req.file->size;
|
||||||
|
start_cmd.num_files++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start_cmd.num_files) {
|
||||||
|
send_command_t(c, 0x11, 0x00, start_cmd);
|
||||||
|
vector<string> path_directories;
|
||||||
|
for (const auto& req : c->patch_file_checksum_requests) {
|
||||||
|
if (req.needs_update()) {
|
||||||
|
change_to_directory_patch(c, path_directories, req.file->path_directories);
|
||||||
|
send_patch_file(c, req.file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
change_to_directory_patch(c, path_directories, {});
|
||||||
|
}
|
||||||
|
|
||||||
// This command terminates the patch connection successfully. PSOBB complains
|
|
||||||
// if we don't check the above directories before sending this though
|
|
||||||
send_command(c, 0x12, 0x00);
|
send_command(c, 0x12, 0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2832,11 +2917,15 @@ static process_command_t patch_handlers[0x100] = {
|
|||||||
// 00
|
// 00
|
||||||
nullptr, nullptr, process_encryption_ok_patch, nullptr,
|
nullptr, nullptr, process_encryption_ok_patch, nullptr,
|
||||||
process_login_patch, nullptr, nullptr, nullptr,
|
process_login_patch, nullptr, nullptr, nullptr,
|
||||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
nullptr, nullptr, nullptr, nullptr,
|
||||||
|
nullptr, nullptr, nullptr, process_file_checksum_result_patch,
|
||||||
|
|
||||||
// 10
|
// 10
|
||||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
process_file_checksum_results_done_patch, nullptr, nullptr, nullptr,
|
||||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
nullptr, nullptr, nullptr, nullptr,
|
||||||
|
nullptr, nullptr, nullptr, nullptr,
|
||||||
|
nullptr, nullptr, nullptr, nullptr,
|
||||||
|
|
||||||
// 20
|
// 20
|
||||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||||
|
|||||||
@@ -445,6 +445,28 @@ void send_enter_directory_patch(shared_ptr<Client> c, const string& dir) {
|
|||||||
send_command_t(c, 0x09, 0x00, cmd);
|
send_command_t(c, 0x09, 0x00, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void send_patch_file(shared_ptr<Client> c, shared_ptr<const PatchFileIndex::File> f) {
|
||||||
|
S_OpenFile_Patch_06 open_cmd = {0, f->size, f->name};
|
||||||
|
send_command_t(c, 0x06, 0x00, open_cmd);
|
||||||
|
|
||||||
|
for (size_t x = 0; x < f->chunks.size(); x++) {
|
||||||
|
const auto& chunk = f->chunks[x];
|
||||||
|
|
||||||
|
// TODO: The use of StringWriter here is... unfortunate. Write a version of
|
||||||
|
// Channel::send that takes iovecs or something to avoid these dumb massive
|
||||||
|
// string copies.
|
||||||
|
StringWriter w;
|
||||||
|
S_WriteFileHeader_Patch_07 write_cmd_header = {
|
||||||
|
x, chunk.crc32, chunk.data.size()};
|
||||||
|
w.put(write_cmd_header);
|
||||||
|
w.write(chunk.data);
|
||||||
|
send_command(c, 0x07, 0x00, w.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
S_CloseCurrentFile_Patch_08 close_cmd = {0};
|
||||||
|
send_command_t(c, 0x08, 0x00, close_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ void send_approve_player_choice_bb(std::shared_ptr<Client> c);
|
|||||||
void send_complete_player_bb(std::shared_ptr<Client> c);
|
void send_complete_player_bb(std::shared_ptr<Client> c);
|
||||||
|
|
||||||
void send_enter_directory_patch(std::shared_ptr<Client> c, const std::string& dir);
|
void send_enter_directory_patch(std::shared_ptr<Client> c, const std::string& dir);
|
||||||
|
void send_patch_file(std::shared_ptr<Client> c, std::shared_ptr<const PatchFileIndex::File> f);
|
||||||
|
|
||||||
void send_message_box(std::shared_ptr<Client> c, const std::u16string& text);
|
void send_message_box(std::shared_ptr<Client> c, const std::u16string& text);
|
||||||
void send_lobby_name(std::shared_ptr<Client> c, const std::u16string& text);
|
void send_lobby_name(std::shared_ptr<Client> c, const std::u16string& text);
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ struct ServerState {
|
|||||||
RunShellBehavior run_shell_behavior;
|
RunShellBehavior run_shell_behavior;
|
||||||
std::vector<std::shared_ptr<const PSOBBEncryption::KeyFile>> bb_private_keys;
|
std::vector<std::shared_ptr<const PSOBBEncryption::KeyFile>> bb_private_keys;
|
||||||
std::shared_ptr<const FunctionCodeIndex> function_code_index;
|
std::shared_ptr<const FunctionCodeIndex> function_code_index;
|
||||||
|
std::shared_ptr<const PatchFileIndex> pc_patch_file_index;
|
||||||
|
std::shared_ptr<const PatchFileIndex> bb_patch_file_index;
|
||||||
std::shared_ptr<const DOLFileIndex> dol_file_index;
|
std::shared_ptr<const DOLFileIndex> dol_file_index;
|
||||||
std::shared_ptr<const Ep3DataIndex> ep3_data_index;
|
std::shared_ptr<const Ep3DataIndex> ep3_data_index;
|
||||||
std::shared_ptr<const QuestIndex> quest_index;
|
std::shared_ptr<const QuestIndex> quest_index;
|
||||||
|
|||||||
+8
-4
@@ -113,8 +113,10 @@ const char* name_for_server_behavior(ServerBehavior behavior) {
|
|||||||
return "lobby_server";
|
return "lobby_server";
|
||||||
case ServerBehavior::DATA_SERVER_BB:
|
case ServerBehavior::DATA_SERVER_BB:
|
||||||
return "data_server_bb";
|
return "data_server_bb";
|
||||||
case ServerBehavior::PATCH_SERVER:
|
case ServerBehavior::PATCH_SERVER_PC:
|
||||||
return "patch_server";
|
return "patch_server_pc";
|
||||||
|
case ServerBehavior::PATCH_SERVER_BB:
|
||||||
|
return "patch_server_bb";
|
||||||
case ServerBehavior::PROXY_SERVER:
|
case ServerBehavior::PROXY_SERVER:
|
||||||
return "proxy_server";
|
return "proxy_server";
|
||||||
default:
|
default:
|
||||||
@@ -131,8 +133,10 @@ ServerBehavior server_behavior_for_name(const char* name) {
|
|||||||
return ServerBehavior::LOBBY_SERVER;
|
return ServerBehavior::LOBBY_SERVER;
|
||||||
} else if (!strcasecmp(name, "data_server_bb") || !strcasecmp(name, "data_server") || !strcasecmp(name, "data")) {
|
} else if (!strcasecmp(name, "data_server_bb") || !strcasecmp(name, "data_server") || !strcasecmp(name, "data")) {
|
||||||
return ServerBehavior::DATA_SERVER_BB;
|
return ServerBehavior::DATA_SERVER_BB;
|
||||||
} else if (!strcasecmp(name, "patch_server") || !strcasecmp(name, "patch")) {
|
} else if (!strcasecmp(name, "patch_server_pc") || !strcasecmp(name, "patch_pc")) {
|
||||||
return ServerBehavior::PATCH_SERVER;
|
return ServerBehavior::PATCH_SERVER_PC;
|
||||||
|
} else if (!strcasecmp(name, "patch_server_bb") || !strcasecmp(name, "patch_bb")) {
|
||||||
|
return ServerBehavior::PATCH_SERVER_BB;
|
||||||
} else if (!strcasecmp(name, "proxy_server") || !strcasecmp(name, "proxy")) {
|
} else if (!strcasecmp(name, "proxy_server") || !strcasecmp(name, "proxy")) {
|
||||||
return ServerBehavior::PROXY_SERVER;
|
return ServerBehavior::PROXY_SERVER;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+2
-1
@@ -18,7 +18,8 @@ enum class ServerBehavior {
|
|||||||
LOGIN_SERVER,
|
LOGIN_SERVER,
|
||||||
LOBBY_SERVER,
|
LOBBY_SERVER,
|
||||||
DATA_SERVER_BB,
|
DATA_SERVER_BB,
|
||||||
PATCH_SERVER,
|
PATCH_SERVER_PC,
|
||||||
|
PATCH_SERVER_BB,
|
||||||
PROXY_SERVER,
|
PROXY_SERVER,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,8 @@
|
|||||||
"gc-eu11": [9201, "gc", "login_server"],
|
"gc-eu11": [9201, "gc", "login_server"],
|
||||||
"gc-eu3": [9203, "gc", "login_server"],
|
"gc-eu3": [9203, "gc", "login_server"],
|
||||||
"pc-login": [9300, "pc", "login_server"],
|
"pc-login": [9300, "pc", "login_server"],
|
||||||
"pc-patch": [10000, "patch", "patch_server"],
|
"pc-patch": [10000, "patch", "patch_server_pc"],
|
||||||
"bb-patch": [11000, "patch", "patch_server"],
|
"bb-patch": [11000, "patch", "patch_server_bb"],
|
||||||
"bb-init": [12000, "bb", "data_server_bb"],
|
"bb-init": [12000, "bb", "data_server_bb"],
|
||||||
|
|
||||||
// TODO: If Xbox support ever gets built, add this port to the above config.
|
// TODO: If Xbox support ever gets built, add this port to the above config.
|
||||||
@@ -132,6 +132,9 @@
|
|||||||
// Lobby messages describe creation and deletion of lobbies and games, as
|
// Lobby messages describe creation and deletion of lobbies and games, as
|
||||||
// well as item tracking events within games.
|
// well as item tracking events within games.
|
||||||
"Lobbies": "info",
|
"Lobbies": "info",
|
||||||
|
// Patch file index messages describe finding and preloading the patch files
|
||||||
|
// available for download to BB and PC clients.
|
||||||
|
"PatchFileIndex": "info",
|
||||||
// Player data messages describe the loading and saving of player and
|
// Player data messages describe the loading and saving of player and
|
||||||
// account data files.
|
// account data files.
|
||||||
"PlayerData": "info",
|
"PlayerData": "info",
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
0x09 0x0009 # TAB
|
0x09 0x0009 # TAB
|
||||||
0x0A 0x000A # NEWLINE
|
0x0A 0x000A # NEWLINE
|
||||||
|
0x0D 0x000D # CARRIAGE RETURN
|
||||||
0x20 0x0020 # SPACE
|
0x20 0x0020 # SPACE
|
||||||
0x21 0x0021 # EXCLAMATION MARK
|
0x21 0x0021 # EXCLAMATION MARK
|
||||||
0x22 0x0022 # QUOTATION MARK
|
0x22 0x0022 # QUOTATION MARK
|
||||||
|
|||||||
+23
-23
@@ -18,29 +18,29 @@ I 80820 2022-07-07 23:33:27 - [Commands] Received from C-1 (version=Patch comman
|
|||||||
0000000000000050 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
0000000000000050 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
||||||
0000000000000060 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
0000000000000060 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
||||||
I 80820 2022-07-07 23:33:27 - [Commands] Sending to C-1 (version=Patch command=13 flag=00)
|
I 80820 2022-07-07 23:33:27 - [Commands] Sending to C-1 (version=Patch command=13 flag=00)
|
||||||
0000000000000000 | 70 01 13 00 09 00 43 00 37 00 6E 00 65 00 77 00 | p C 7 n e w
|
0000000000000000 | 6C 01 13 00 6E 00 65 00 77 00 73 00 65 00 72 00 | l n e w s e r
|
||||||
0000000000000010 | 73 00 65 00 72 00 76 00 20 00 70 00 61 00 74 00 | s e r v p a t
|
0000000000000010 | 76 00 20 00 70 00 61 00 74 00 63 00 68 00 20 00 | v p a t c h
|
||||||
0000000000000020 | 63 00 68 00 20 00 73 00 65 00 72 00 76 00 65 00 | c h s e r v e
|
0000000000000020 | 73 00 65 00 72 00 76 00 65 00 72 00 0D 00 0A 00 | s e r v e r
|
||||||
0000000000000030 | 72 00 0A 00 0A 00 54 00 68 00 69 00 73 00 20 00 | r T h i s
|
0000000000000030 | 0D 00 0A 00 54 00 68 00 69 00 73 00 20 00 73 00 | T h i s s
|
||||||
0000000000000040 | 73 00 65 00 72 00 76 00 65 00 72 00 20 00 69 00 | s e r v e r i
|
0000000000000040 | 65 00 72 00 76 00 65 00 72 00 20 00 69 00 73 00 | e r v e r i s
|
||||||
0000000000000050 | 73 00 20 00 6E 00 6F 00 74 00 20 00 61 00 66 00 | s n o t a f
|
0000000000000050 | 20 00 6E 00 6F 00 74 00 20 00 61 00 66 00 66 00 | n o t a f f
|
||||||
0000000000000060 | 66 00 69 00 6C 00 69 00 61 00 74 00 65 00 64 00 | f i l i a t e d
|
0000000000000060 | 69 00 6C 00 69 00 61 00 74 00 65 00 64 00 20 00 | i l i a t e d
|
||||||
0000000000000070 | 20 00 77 00 69 00 74 00 68 00 2C 00 20 00 73 00 | w i t h , s
|
0000000000000070 | 77 00 69 00 74 00 68 00 2C 00 20 00 73 00 70 00 | w i t h , s p
|
||||||
0000000000000080 | 70 00 6F 00 6E 00 73 00 6F 00 72 00 65 00 64 00 | p o n s o r e d
|
0000000000000080 | 6F 00 6E 00 73 00 6F 00 72 00 65 00 64 00 20 00 | o n s o r e d
|
||||||
0000000000000090 | 20 00 62 00 79 00 2C 00 20 00 6F 00 72 00 20 00 | b y , o r
|
0000000000000090 | 62 00 79 00 2C 00 20 00 6F 00 72 00 20 00 69 00 | b y , o r i
|
||||||
00000000000000A0 | 69 00 6E 00 20 00 61 00 6E 00 79 00 0A 00 6F 00 | i n a n y o
|
00000000000000A0 | 6E 00 20 00 61 00 6E 00 79 00 20 00 6F 00 74 00 | n a n y o t
|
||||||
00000000000000B0 | 74 00 68 00 65 00 72 00 20 00 77 00 61 00 79 00 | t h e r w a y
|
00000000000000B0 | 68 00 65 00 72 00 20 00 77 00 61 00 79 00 20 00 | h e r w a y
|
||||||
00000000000000C0 | 20 00 63 00 6F 00 6E 00 6E 00 65 00 63 00 74 00 | c o n n e c t
|
00000000000000C0 | 63 00 6F 00 6E 00 6E 00 65 00 63 00 74 00 65 00 | c o n n e c t e
|
||||||
00000000000000D0 | 65 00 64 00 20 00 74 00 6F 00 20 00 53 00 45 00 | e d t o S E
|
00000000000000D0 | 64 00 20 00 74 00 6F 00 20 00 53 00 45 00 47 00 | d t o S E G
|
||||||
00000000000000E0 | 47 00 41 00 20 00 6F 00 72 00 20 00 53 00 6F 00 | G A o r S o
|
00000000000000E0 | 41 00 20 00 6F 00 72 00 20 00 53 00 6F 00 6E 00 | A o r S o n
|
||||||
00000000000000F0 | 6E 00 69 00 63 00 20 00 54 00 65 00 61 00 6D 00 | n i c T e a m
|
00000000000000F0 | 69 00 63 00 20 00 54 00 65 00 61 00 6D 00 2C 00 | i c T e a m ,
|
||||||
0000000000000100 | 2C 00 20 00 61 00 6E 00 64 00 20 00 69 00 73 00 | , a n d i s
|
0000000000000100 | 20 00 61 00 6E 00 64 00 20 00 69 00 73 00 20 00 | a n d i s
|
||||||
0000000000000110 | 20 00 6F 00 77 00 6E 00 65 00 64 00 0A 00 61 00 | o w n e d a
|
0000000000000110 | 6F 00 77 00 6E 00 65 00 64 00 20 00 61 00 6E 00 | o w n e d a n
|
||||||
0000000000000120 | 6E 00 64 00 20 00 6F 00 70 00 65 00 72 00 61 00 | n d o p e r a
|
0000000000000120 | 64 00 20 00 6F 00 70 00 65 00 72 00 61 00 74 00 | d o p e r a t
|
||||||
0000000000000130 | 74 00 65 00 64 00 20 00 63 00 6F 00 6D 00 70 00 | t e d c o m p
|
0000000000000130 | 65 00 64 00 20 00 63 00 6F 00 6D 00 70 00 6C 00 | e d c o m p l
|
||||||
0000000000000140 | 6C 00 65 00 74 00 65 00 6C 00 79 00 20 00 69 00 | l e t e l y i
|
0000000000000140 | 65 00 74 00 65 00 6C 00 79 00 20 00 69 00 6E 00 | e t e l y i n
|
||||||
0000000000000150 | 6E 00 64 00 65 00 70 00 65 00 6E 00 64 00 65 00 | n d e p e n d e
|
0000000000000150 | 64 00 65 00 70 00 65 00 6E 00 64 00 65 00 6E 00 | d e p e n d e n
|
||||||
0000000000000160 | 6E 00 74 00 6C 00 79 00 2E 00 00 00 00 00 00 00 | n t l y .
|
0000000000000160 | 74 00 6C 00 79 00 2E 00 00 00 00 00 | t l y .
|
||||||
I 80820 2022-07-07 23:33:27 - [Commands] Sending to C-1 (version=Patch command=09 flag=00)
|
I 80820 2022-07-07 23:33:27 - [Commands] Sending to C-1 (version=Patch command=09 flag=00)
|
||||||
0000000000000000 | 44 00 09 00 2E 00 00 00 00 00 00 00 00 00 00 00 | D .
|
0000000000000000 | 44 00 09 00 2E 00 00 00 00 00 00 00 00 00 00 00 | D .
|
||||||
0000000000000010 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
0000000000000010 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
||||||
|
|||||||
+3
-3
@@ -26,10 +26,10 @@
|
|||||||
"gc-eu11": [9201, "gc", "login_server"],
|
"gc-eu11": [9201, "gc", "login_server"],
|
||||||
"gc-eu3": [9203, "gc", "login_server"],
|
"gc-eu3": [9203, "gc", "login_server"],
|
||||||
"pc-login": [9300, "pc", "login_server"],
|
"pc-login": [9300, "pc", "login_server"],
|
||||||
"pc-patch": [10000, "patch", "patch_server"],
|
"pc-patch": [10000, "patch", "patch_server_pc"],
|
||||||
"bb-patch": [11000, "patch", "patch_server"],
|
"bb-patch": [11000, "patch", "patch_server_bb"],
|
||||||
"bb-init": [12000, "bb", "data_server_bb"],
|
"bb-init": [12000, "bb", "data_server_bb"],
|
||||||
"bb-patch2": [10500, "patch", "patch_server"],
|
"bb-patch2": [10500, "patch", "patch_server_bb"],
|
||||||
"bb-init2": [13000, "bb", "data_server_bb"],
|
"bb-init2": [13000, "bb", "data_server_bb"],
|
||||||
"bb-proxy2": [9932, "bb", "proxy_server"],
|
"bb-proxy2": [9932, "bb", "proxy_server"],
|
||||||
"bb-data1": [12004, "bb", "data_server_bb"],
|
"bb-data1": [12004, "bb", "data_server_bb"],
|
||||||
|
|||||||
Reference in New Issue
Block a user