fix some basic things on BB proxy server
This commit is contained in:
@@ -130,7 +130,7 @@ struct C_Login_Patch_04 {
|
||||
parray<le_uint32_t, 3> unused;
|
||||
ptext<char, 0x10> username;
|
||||
ptext<char, 0x10> password;
|
||||
ptext<char, 0x40> email; // Note: this field is not present on BB
|
||||
ptext<char, 0x40> email; // Note: this field is blank on BB
|
||||
};
|
||||
|
||||
// 05: Disconnect
|
||||
@@ -684,7 +684,11 @@ struct C_Login_BB_93 {
|
||||
// will be something like "Ver. 1.24.3". Note also that some old versions
|
||||
// (before 1.23.8?) omit the unknown field before the client config, so the
|
||||
// client config starts 8 bytes earlier on those versions.
|
||||
ClientConfigBB client_config;
|
||||
union ClientConfigFields {
|
||||
ClientConfigBB cfg;
|
||||
ptext<char, 0x28> version_string;
|
||||
ClientConfigFields() : version_string() { }
|
||||
} client_config;
|
||||
};
|
||||
|
||||
// 94: Invalid command
|
||||
|
||||
+55
-31
@@ -31,29 +31,31 @@ bool use_terminal_colors = false;
|
||||
|
||||
|
||||
static const vector<PortConfiguration> default_port_to_behavior({
|
||||
{"gc-jp10", 9000, GameVersion::GC, ServerBehavior::LOGIN_SERVER},
|
||||
{"gc-jp11", 9001, GameVersion::GC, ServerBehavior::LOGIN_SERVER},
|
||||
{"gc-jp3", 9003, GameVersion::GC, ServerBehavior::LOGIN_SERVER},
|
||||
{"gc-us10", 9100, GameVersion::PC, ServerBehavior::SPLIT_RECONNECT},
|
||||
{"gc-us3", 9103, GameVersion::GC, ServerBehavior::LOGIN_SERVER},
|
||||
{"gc-eu10", 9200, GameVersion::GC, ServerBehavior::LOGIN_SERVER},
|
||||
{"gc-eu11", 9201, GameVersion::GC, ServerBehavior::LOGIN_SERVER},
|
||||
{"gc-eu3", 9203, GameVersion::GC, ServerBehavior::LOGIN_SERVER},
|
||||
{"pc-login", 9300, GameVersion::PC, ServerBehavior::LOGIN_SERVER},
|
||||
{"pc-patch", 10000, GameVersion::PATCH, ServerBehavior::PATCH_SERVER},
|
||||
{"bb-patch", 11000, GameVersion::PATCH, ServerBehavior::PATCH_SERVER},
|
||||
{"bb-data", 12000, GameVersion::BB, ServerBehavior::DATA_SERVER_BB},
|
||||
{"gc-jp10", 9000, GameVersion::GC, ServerBehavior::LOGIN_SERVER},
|
||||
{"gc-jp11", 9001, GameVersion::GC, ServerBehavior::LOGIN_SERVER},
|
||||
{"gc-jp3", 9003, GameVersion::GC, ServerBehavior::LOGIN_SERVER},
|
||||
{"gc-us10", 9100, GameVersion::PC, ServerBehavior::SPLIT_RECONNECT},
|
||||
{"gc-us3", 9103, GameVersion::GC, ServerBehavior::LOGIN_SERVER},
|
||||
{"gc-eu10", 9200, GameVersion::GC, ServerBehavior::LOGIN_SERVER},
|
||||
{"gc-eu11", 9201, GameVersion::GC, ServerBehavior::LOGIN_SERVER},
|
||||
{"gc-eu3", 9203, GameVersion::GC, ServerBehavior::LOGIN_SERVER},
|
||||
{"pc-login", 9300, GameVersion::PC, ServerBehavior::LOGIN_SERVER},
|
||||
{"pc-patch", 10000, GameVersion::PATCH, ServerBehavior::PATCH_SERVER},
|
||||
{"bb-patch", 11000, GameVersion::PATCH, ServerBehavior::PATCH_SERVER},
|
||||
{"bb-init", 12000, GameVersion::BB, ServerBehavior::DATA_SERVER_BB},
|
||||
{"bb-patch2", 13000, GameVersion::PATCH, ServerBehavior::PATCH_SERVER},
|
||||
{"bb-init2", 14000, GameVersion::BB, ServerBehavior::DATA_SERVER_BB},
|
||||
|
||||
// these aren't hardcoded in any games; user can override them
|
||||
{"bb-data1", 12004, GameVersion::BB, ServerBehavior::DATA_SERVER_BB},
|
||||
{"bb-data2", 12005, GameVersion::BB, ServerBehavior::DATA_SERVER_BB},
|
||||
{"bb-login", 12008, GameVersion::BB, ServerBehavior::LOGIN_SERVER},
|
||||
{"pc-lobby", 9420, GameVersion::PC, ServerBehavior::LOBBY_SERVER},
|
||||
{"gc-lobby", 9421, GameVersion::GC, ServerBehavior::LOBBY_SERVER},
|
||||
{"bb-lobby", 9422, GameVersion::BB, ServerBehavior::LOBBY_SERVER},
|
||||
{"pc-proxy", 9520, GameVersion::PC, ServerBehavior::PROXY_SERVER},
|
||||
{"gc-proxy", 9521, GameVersion::GC, ServerBehavior::PROXY_SERVER},
|
||||
{"bb-proxy", 9522, GameVersion::BB, ServerBehavior::PROXY_SERVER},
|
||||
// These aren't hardcoded in clients; user should be allowed to override them
|
||||
{"bb-data1", 12004, GameVersion::BB, ServerBehavior::DATA_SERVER_BB},
|
||||
{"bb-data2", 12005, GameVersion::BB, ServerBehavior::DATA_SERVER_BB},
|
||||
{"bb-login", 12008, GameVersion::BB, ServerBehavior::LOGIN_SERVER},
|
||||
{"pc-lobby", 9420, GameVersion::PC, ServerBehavior::LOBBY_SERVER},
|
||||
{"gc-lobby", 9421, GameVersion::GC, ServerBehavior::LOBBY_SERVER},
|
||||
{"bb-lobby", 9422, GameVersion::BB, ServerBehavior::LOBBY_SERVER},
|
||||
{"pc-proxy", 9520, GameVersion::PC, ServerBehavior::PROXY_SERVER},
|
||||
{"gc-proxy", 9521, GameVersion::GC, ServerBehavior::PROXY_SERVER},
|
||||
{"bb-proxy", 9522, GameVersion::BB, ServerBehavior::PROXY_SERVER},
|
||||
});
|
||||
|
||||
|
||||
@@ -157,6 +159,19 @@ void populate_state_from_config(shared_ptr<ServerState> s,
|
||||
s->proxy_destination_patch.first = "";
|
||||
s->proxy_destination_patch.second = 0;
|
||||
}
|
||||
try {
|
||||
const string& netloc_str = d.at("ProxyDestination-BB")->as_string();
|
||||
s->proxy_destination_bb = parse_netloc(netloc_str);
|
||||
log(INFO, "BB proxy is enabled with destination %s", netloc_str.c_str());
|
||||
for (auto& it : s->name_to_port_config) {
|
||||
if (it.second->version == GameVersion::BB) {
|
||||
it.second->behavior = ServerBehavior::PROXY_SERVER;
|
||||
}
|
||||
}
|
||||
} catch (const out_of_range&) {
|
||||
s->proxy_destination_bb.first = "";
|
||||
s->proxy_destination_bb.second = 0;
|
||||
}
|
||||
|
||||
s->main_menu.emplace_back(MAIN_MENU_GO_TO_LOBBY, u"Go to lobby",
|
||||
u"Join the lobby", 0);
|
||||
@@ -322,30 +337,39 @@ int main(int, char**) {
|
||||
}
|
||||
|
||||
shared_ptr<Server> game_server;
|
||||
if (!state->proxy_destinations_pc.empty() ||
|
||||
!state->proxy_destinations_gc.empty() ||
|
||||
(state->proxy_destination_patch.second != 0)) {
|
||||
log(INFO, "Starting proxy server");
|
||||
state->proxy_server.reset(new ProxyServer(base, state));
|
||||
}
|
||||
|
||||
log(INFO, "Starting game server");
|
||||
game_server.reset(new Server(base, state));
|
||||
|
||||
log(INFO, "Opening sockets");
|
||||
for (const auto& it : state->name_to_port_config) {
|
||||
if (it.second->behavior == ServerBehavior::PROXY_SERVER) {
|
||||
if (!state->proxy_server.get()) {
|
||||
log(INFO, "Starting proxy server");
|
||||
state->proxy_server.reset(new ProxyServer(base, state));
|
||||
}
|
||||
if (state->proxy_server.get()) {
|
||||
// For PC and GC, proxy sessions are dynamically created when a client
|
||||
// picks a destination from the menu. For patch and BB clients, there's
|
||||
// no way to ask the client which destination they want, so only one
|
||||
// destination is supported, and we have to manually specify the
|
||||
// destination netloc here.
|
||||
if (it.second->version == GameVersion::PATCH) {
|
||||
struct sockaddr_storage ss = make_sockaddr_storage(
|
||||
state->proxy_destination_patch.first,
|
||||
state->proxy_destination_patch.second).first;
|
||||
state->proxy_server->listen(it.second->port, it.second->version, &ss);
|
||||
} if (it.second->version == GameVersion::BB) {
|
||||
struct sockaddr_storage ss = make_sockaddr_storage(
|
||||
state->proxy_destination_bb.first,
|
||||
state->proxy_destination_bb.second).first;
|
||||
state->proxy_server->listen(it.second->port, it.second->version, &ss);
|
||||
} else {
|
||||
state->proxy_server->listen(it.second->port, it.second->version);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!game_server.get()) {
|
||||
log(INFO, "Starting game server");
|
||||
game_server.reset(new Server(base, state));
|
||||
}
|
||||
game_server->listen("", it.second->port, it.second->version, it.second->behavior);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-5
@@ -155,7 +155,7 @@ void for_each_received_command(
|
||||
// BB pads commands to 8-byte boundaries, and this is not reflected in the
|
||||
// size field
|
||||
size_t command_physical_size = (version == GameVersion::BB)
|
||||
? (command_logical_size + header_size - 1) & ~(header_size - 1)
|
||||
? ((command_logical_size + header_size - 1) & ~(header_size - 1))
|
||||
: command_logical_size;
|
||||
if (evbuffer_get_length(buf) < command_physical_size) {
|
||||
break;
|
||||
@@ -165,19 +165,17 @@ void for_each_received_command(
|
||||
|
||||
evbuffer_drain(buf, header_size);
|
||||
|
||||
string command_data(command_logical_size - header_size, '\0');
|
||||
string command_data(command_physical_size - header_size, '\0');
|
||||
if (evbuffer_remove(buf, command_data.data(), command_data.size())
|
||||
< static_cast<ssize_t>(command_data.size())) {
|
||||
throw logic_error("enough bytes available, but could not remove them");
|
||||
}
|
||||
if (command_logical_size != command_physical_size) {
|
||||
evbuffer_drain(buf, command_physical_size - command_logical_size);
|
||||
}
|
||||
|
||||
if (crypt) {
|
||||
crypt->skip(header_size);
|
||||
crypt->decrypt(command_data.data(), command_data.size());
|
||||
}
|
||||
command_data.resize(command_logical_size - header_size);
|
||||
|
||||
fn(header.command(version), header.flag(version), command_data);
|
||||
}
|
||||
|
||||
+38
-7
@@ -115,8 +115,7 @@ static bool process_server_pc_gc_patch_02_17(shared_ptr<ServerState> s,
|
||||
// Most servers don't include after_message or have a shorter
|
||||
// after_message than newserv does, so don't require it
|
||||
const auto& cmd = check_size_t<S_ServerInit_DC_PC_GC_02_17>(data,
|
||||
offsetof(S_ServerInit_DC_PC_GC_02_17, after_message),
|
||||
sizeof(S_ServerInit_DC_PC_GC_02_17));
|
||||
offsetof(S_ServerInit_DC_PC_GC_02_17, after_message), 0xFFFF);
|
||||
|
||||
if (!session.license) {
|
||||
session.log(INFO, "No license in linked session");
|
||||
@@ -202,6 +201,38 @@ static bool process_server_pc_gc_patch_02_17(shared_ptr<ServerState> s,
|
||||
}
|
||||
}
|
||||
|
||||
static bool process_server_bb_03(shared_ptr<ServerState> s,
|
||||
ProxyServer::LinkedSession& session, uint16_t command, uint32_t flag, string& data) {
|
||||
// Most servers don't include after_message or have a shorter
|
||||
// after_message than newserv does, so don't require it
|
||||
const auto& cmd = check_size_t<S_ServerInit_BB_03>(data,
|
||||
offsetof(S_ServerInit_BB_03, after_message), 0xFFFF);
|
||||
|
||||
// Unlike on PC/GC, BB linked sessions never have licenses.
|
||||
// TODO: Is there any way we can support this in the future? Probably not, due
|
||||
// to BB's login and character select flow, right?
|
||||
if (session.license) {
|
||||
throw runtime_error("BB linked session has license");
|
||||
}
|
||||
|
||||
session.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.
|
||||
forward_command(session, false, command, flag, data);
|
||||
|
||||
// BB encryption is stateless after it's initialized, unlike previous
|
||||
// versions, so we can get away with only two instances instead of four here.
|
||||
session.server_input_crypt.reset(new PSOBBEncryption(
|
||||
s->default_key_file, cmd.server_key.data(), sizeof(cmd.server_key)));
|
||||
session.server_output_crypt.reset(new PSOBBEncryption(
|
||||
s->default_key_file, cmd.client_key.data(), sizeof(cmd.client_key)));
|
||||
session.client_input_crypt = session.server_output_crypt;
|
||||
session.client_output_crypt = session.server_input_crypt;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool process_server_dc_pc_gc_04(shared_ptr<ServerState>,
|
||||
ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) {
|
||||
// Some servers send a short 04 command if they don't use all of the 0x20
|
||||
@@ -401,7 +432,7 @@ static bool process_server_gc_1A_D5(shared_ptr<ServerState>,
|
||||
// If the client has the no-close-confirmation flag set in its
|
||||
// newserv client config, send a fake confirmation to the remote
|
||||
// server immediately.
|
||||
if (session.newserv_client_config.flags & Client::Flag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION) {
|
||||
if (session.newserv_client_config.cfg.flags & Client::Flag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION) {
|
||||
session.send_to_end(true, 0xD6, 0x00, "", 0);
|
||||
}
|
||||
return true;
|
||||
@@ -514,8 +545,8 @@ static bool process_server_65_67_68(shared_ptr<ServerState>,
|
||||
// behavior in the client config, so if it happens during a proxy session,
|
||||
// update the client config that we'll restore if the client uses the change
|
||||
// ship or change block command.
|
||||
if (session.newserv_client_config.flags & Client::Flag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION_AFTER_LOBBY_JOIN) {
|
||||
session.newserv_client_config.flags |= Client::Flag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION;
|
||||
if (session.newserv_client_config.cfg.flags & Client::Flag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION_AFTER_LOBBY_JOIN) {
|
||||
session.newserv_client_config.cfg.flags |= Client::Flag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -714,7 +745,7 @@ static bool process_client_dc_pc_gc_A0_A1(shared_ptr<ServerState> s,
|
||||
S_UpdateClientConfig_DC_PC_GC_04 update_client_config_cmd = {
|
||||
0x00010000,
|
||||
session.license->serial_number,
|
||||
session.newserv_client_config,
|
||||
session.newserv_client_config.cfg,
|
||||
};
|
||||
session.send_to_end(false, 0x04, 0x00, &update_client_config_cmd, sizeof(update_client_config_cmd));
|
||||
|
||||
@@ -824,7 +855,7 @@ static process_command_t gc_server_handlers[0x100] = {
|
||||
/* F0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh,
|
||||
};
|
||||
static process_command_t bb_server_handlers[0x100] = {
|
||||
/* 00 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh,
|
||||
/* 00 */ defh, defh, defh, process_server_bb_03, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh,
|
||||
/* 10 */ defh, defh, defh, process_server_13_A7, defh, defh, defh, defh, defh, process_server_19, defh, defh, defh, defh, defh, defh,
|
||||
/* 20 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh,
|
||||
/* 30 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh,
|
||||
|
||||
+7
-7
@@ -240,7 +240,7 @@ void ProxyServer::UnlinkedSession::on_client_input() {
|
||||
shared_ptr<const License> license;
|
||||
uint32_t sub_version = 0;
|
||||
string character_name;
|
||||
ClientConfig client_config;
|
||||
ClientConfigBB client_config;
|
||||
|
||||
try {
|
||||
for_each_received_command(this->bev.get(), this->version, this->crypt_in.get(),
|
||||
@@ -271,7 +271,7 @@ void ProxyServer::UnlinkedSession::on_client_input() {
|
||||
stoul(cmd.serial_number, nullptr, 16), cmd.access_key);
|
||||
sub_version = cmd.sub_version;
|
||||
character_name = cmd.name;
|
||||
client_config = cmd.client_config.cfg;
|
||||
client_config.cfg = cmd.client_config.cfg;
|
||||
|
||||
} else {
|
||||
throw logic_error("unsupported unlinked session version");
|
||||
@@ -302,7 +302,7 @@ void ProxyServer::UnlinkedSession::on_client_input() {
|
||||
// If there's no open session for this license, then there must be a valid
|
||||
// destination in the client config. If there is, open a new linked
|
||||
// session and set its initial destination
|
||||
if (client_config.magic != CLIENT_CONFIG_MAGIC) {
|
||||
if (client_config.cfg.magic != CLIENT_CONFIG_MAGIC) {
|
||||
this->log(ERROR, "Client configuration is invalid; cannot open session");
|
||||
} else {
|
||||
session.reset(new LinkedSession(
|
||||
@@ -388,15 +388,15 @@ ProxyServer::LinkedSession::LinkedSession(
|
||||
uint16_t local_port,
|
||||
GameVersion version,
|
||||
std::shared_ptr<const License> license,
|
||||
const ClientConfig& newserv_client_config)
|
||||
const ClientConfigBB& newserv_client_config)
|
||||
: LinkedSession(server, license->serial_number, local_port, version) {
|
||||
this->license = license;
|
||||
this->newserv_client_config = newserv_client_config;
|
||||
memset(&this->next_destination, 0, sizeof(this->next_destination));
|
||||
struct sockaddr_in* dest_sin = reinterpret_cast<struct sockaddr_in*>(&this->next_destination);
|
||||
dest_sin->sin_family = AF_INET;
|
||||
dest_sin->sin_port = htons(this->newserv_client_config.proxy_destination_port);
|
||||
dest_sin->sin_addr.s_addr = htonl(this->newserv_client_config.proxy_destination_address);
|
||||
dest_sin->sin_port = htons(this->newserv_client_config.cfg.proxy_destination_port);
|
||||
dest_sin->sin_addr.s_addr = htonl(this->newserv_client_config.cfg.proxy_destination_address);
|
||||
}
|
||||
|
||||
ProxyServer::LinkedSession::LinkedSession(
|
||||
@@ -668,7 +668,7 @@ shared_ptr<ProxyServer::LinkedSession> ProxyServer::get_session() {
|
||||
|
||||
std::shared_ptr<ProxyServer::LinkedSession> ProxyServer::create_licensed_session(
|
||||
std::shared_ptr<const License> l, uint16_t local_port, GameVersion version,
|
||||
const ClientConfig& newserv_client_config) {
|
||||
const ClientConfigBB& newserv_client_config) {
|
||||
shared_ptr<LinkedSession> session(new LinkedSession(
|
||||
this, local_port, version, l, newserv_client_config));
|
||||
auto emplace_ret = this->id_to_session.emplace(session->id, session);
|
||||
|
||||
+3
-3
@@ -53,7 +53,7 @@ public:
|
||||
|
||||
uint32_t remote_guild_card_number;
|
||||
parray<uint8_t, 0x20> remote_client_config_data;
|
||||
ClientConfig newserv_client_config;
|
||||
ClientConfigBB newserv_client_config;
|
||||
bool suppress_newserv_commands;
|
||||
bool enable_chat_filter;
|
||||
bool enable_switch_assist;
|
||||
@@ -101,7 +101,7 @@ public:
|
||||
uint16_t local_port,
|
||||
GameVersion version,
|
||||
std::shared_ptr<const License> license,
|
||||
const ClientConfig& newserv_client_config);
|
||||
const ClientConfigBB& newserv_client_config);
|
||||
LinkedSession(
|
||||
ProxyServer* server,
|
||||
uint64_t id,
|
||||
@@ -148,7 +148,7 @@ public:
|
||||
std::shared_ptr<const License> l,
|
||||
uint16_t local_port,
|
||||
GameVersion version,
|
||||
const ClientConfig& newserv_client_config);
|
||||
const ClientConfigBB& newserv_client_config);
|
||||
void delete_session(uint64_t id);
|
||||
|
||||
private:
|
||||
|
||||
@@ -367,7 +367,7 @@ void process_login_bb(shared_ptr<ServerState> s, shared_ptr<Client> c,
|
||||
}
|
||||
|
||||
try {
|
||||
c->import_config(cmd.client_config.cfg);
|
||||
c->import_config(cmd.client_config.cfg.cfg);
|
||||
c->bb_game_state++;
|
||||
} catch (const invalid_argument&) {
|
||||
c->bb_game_state = 0;
|
||||
@@ -749,7 +749,7 @@ void process_menu_selection(shared_ptr<ServerState> s, shared_ptr<Client> c,
|
||||
|
||||
s->proxy_server->delete_session(c->license->serial_number);
|
||||
s->proxy_server->create_licensed_session(
|
||||
c->license, local_port, c->version, c->export_config());
|
||||
c->license, local_port, c->version, c->export_config_bb());
|
||||
|
||||
send_reconnect(c, s->connect_address_for_client(c), local_port);
|
||||
}
|
||||
@@ -1751,13 +1751,10 @@ void process_encryption_ok_patch(shared_ptr<ServerState>, shared_ptr<Client> c,
|
||||
|
||||
void process_login_patch(shared_ptr<ServerState> s, shared_ptr<Client> c,
|
||||
uint16_t, uint32_t, const string& data) {
|
||||
const auto& cmd = check_size_t<C_Login_Patch_04>(data,
|
||||
offsetof(C_Login_Patch_04, email), sizeof(C_Login_Patch_04));
|
||||
const auto& cmd = check_size_t<C_Login_Patch_04>(data);
|
||||
|
||||
if (data.size() == offsetof(C_Login_Patch_04, email)) {
|
||||
if (cmd.email.len() == 0) {
|
||||
c->flags |= Client::Flag::BB_PATCH;
|
||||
} else if (data.size() != sizeof(C_Login_Patch_04)) {
|
||||
throw runtime_error("unknown patch server login format");
|
||||
}
|
||||
|
||||
// On BB we can use colors and newlines should be \n; on PC we can't use
|
||||
|
||||
+4
-4
@@ -66,7 +66,7 @@ Server commands:\n\
|
||||
license is deleted by reloading, they will not be disconnected immediately.\n\
|
||||
add-license <parameters>\n\
|
||||
Add a license to the server. <parameters> is some subset of the following:\n\
|
||||
username=<username> (BB username)\n\
|
||||
bb-username=<username> (BB username)\n\
|
||||
bb-password=<password> (BB password)\n\
|
||||
gc-password=<password> (GC password)\n\
|
||||
access-key=<access-key> (GC/PC access key)\n\
|
||||
@@ -179,11 +179,11 @@ Proxy commands (these will only work when exactly one client is connected):\n\
|
||||
shared_ptr<License> l(new License());
|
||||
|
||||
for (const string& token : split(command_args, ' ')) {
|
||||
if (starts_with(token, "username=")) {
|
||||
if (token.size() >= 29) {
|
||||
if (starts_with(token, "bb-username=")) {
|
||||
if (token.size() >= 32) {
|
||||
throw invalid_argument("username too long");
|
||||
}
|
||||
l->username = token.substr(9);
|
||||
l->username = token.substr(12);
|
||||
|
||||
} else if (starts_with(token, "bb-password=")) {
|
||||
if (token.size() >= 32) {
|
||||
|
||||
@@ -61,6 +61,7 @@ struct ServerState {
|
||||
std::vector<std::pair<std::string, uint16_t>> proxy_destinations_pc;
|
||||
std::vector<std::pair<std::string, uint16_t>> proxy_destinations_gc;
|
||||
std::pair<std::string, uint16_t> proxy_destination_patch;
|
||||
std::pair<std::string, uint16_t> proxy_destination_bb;
|
||||
std::u16string welcome_message;
|
||||
|
||||
std::map<int64_t, std::shared_ptr<Lobby>> id_to_lobby;
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
// patch server (for PC and BB) is bypassed, and any client that connects to
|
||||
// the patch server is instead proxied to this destination.
|
||||
// "ProxyDestination-Patch": "",
|
||||
// Proxy destination for BB clients. If this is given, all BB clients that
|
||||
// connect to newserv will be proxied to this destination.
|
||||
// "ProxyDestination-BB": "",
|
||||
|
||||
// By default, the interactive shell runs if stdin is a terminal, and doesn't
|
||||
// run if it's not. This option, if present, overrides that behavior.
|
||||
|
||||
Reference in New Issue
Block a user