implement switch assist on proxy server

This commit is contained in:
Martin Michelsen
2022-04-02 00:53:04 -07:00
parent 76fd9c22bf
commit 5afe3fb8d2
3 changed files with 64 additions and 55 deletions
+37 -14
View File
@@ -580,17 +580,13 @@ void ProxyServer::LinkedSession::disconnect() {
static void check_implemented_subcommand(
uint64_t id, uint16_t command, const string& data) {
if (command == 0x60 || command == 0x6C || command == 0xC9 ||
command == 0x62 || command == 0x6D || command == 0xCB) {
if (data.size() < 4) {
log(WARNING, "[ProxyServer/%08" PRIX64 "] Received broadcast/target command with no contents", id);
} else {
if (!subcommand_is_implemented(data[0])) {
log(WARNING, "[ProxyServer/%08" PRIX64 "] Received subcommand %02hhX which is not implemented on the server",
id, data[0]);
}
static void check_implemented_subcommand(uint64_t id, const string& data) {
if (data.size() < 4) {
log(WARNING, "[ProxyServer/%08" PRIX64 "] Received broadcast/target command with no contents", id);
} else {
if (!subcommand_is_implemented(data[0])) {
log(WARNING, "[ProxyServer/%08" PRIX64 "] Received subcommand %02hhX which is not implemented on the server",
id, data[0]);
}
}
}
@@ -601,7 +597,6 @@ void ProxyServer::LinkedSession::on_client_input() {
[&](uint16_t command, uint32_t flag, string& data) {
print_received_command(command, flag, data.data(), data.size(),
this->version, name.c_str());
check_implemented_subcommand(this->id, command, data);
bool should_forward = true;
switch (command) {
@@ -624,6 +619,26 @@ void ProxyServer::LinkedSession::on_client_input() {
}
break;
case 0x60:
case 0x62:
case 0x6C:
case 0x6D:
case 0xC9:
case 0xCB:
check_implemented_subcommand(this->id, data);
if (!data.empty() && (data[0] == 0x05) && (data[data.size() - 1] == 0x01) && this->enable_switch_assist) {
if (!this->last_switch_enabled_subcommand.empty()) {
log(WARNING, "[ProxyServer/%08" PRIX64 "] Switch assist: replaying previous enable subcommand",
this->id);
send_command(this->client_bev.get(), this->version,
this->client_output_crypt.get(), 0x60, 0x00,
this->last_switch_enabled_subcommand.data(),
this->last_switch_enabled_subcommand.size(), name.c_str());
}
this->last_switch_enabled_subcommand = data;
}
break;
case 0xA0: // Change ship
case 0xA1: { // Change block
if ((this->version == GameVersion::PATCH) || (this->version == GameVersion::BB)) {
@@ -724,7 +739,6 @@ void ProxyServer::LinkedSession::on_server_input() {
[&](uint16_t command, uint32_t flag, string& data) {
print_received_command(command, flag, data.data(), data.size(),
this->version, name.c_str());
check_implemented_subcommand(this->id, command, data);
// In the case of server init commands, the client output crypt cannot
// be set until after we forwarwd the command to the client, hence this
@@ -991,6 +1005,15 @@ void ProxyServer::LinkedSession::on_server_input() {
break;
}
case 0x60:
case 0x62:
case 0x6C:
case 0x6D:
case 0xC9:
case 0xCB:
check_implemented_subcommand(this->id, data);
break;
case 0x44:
case 0xA6: {
if (this->version != GameVersion::GC) {
@@ -1163,7 +1186,7 @@ void ProxyServer::LinkedSession::on_server_input() {
if (this->override_lobby_event >= 0) {
cmd->event = this->override_lobby_event;
}
if (this->override_lobby_event >= 0) {
if (this->override_lobby_number >= 0) {
cmd->lobby_number = this->override_lobby_number;
}
}
+2
View File
@@ -53,6 +53,8 @@ public:
ClientConfig newserv_client_config;
bool suppress_newserv_commands;
bool enable_chat_filter;
bool enable_switch_assist;
std::string last_switch_enabled_subcommand;
int16_t override_section_id;
int16_t override_lobby_event;
int16_t override_lobby_number;
+25 -41
View File
@@ -31,6 +31,16 @@ shared_ptr<ProxyServer::LinkedSession> ServerShell::get_proxy_session() {
return this->state->proxy_server->get_session();
}
static void set_boolean(bool* target, const string& args) {
if (args == "on") {
*target = true;
} else if (args == "off") {
*target = false;
} else {
throw invalid_argument("argument must be \"on\" or \"off\"");
}
}
void ServerShell::execute_command(const string& command) {
// find the entry in the command table and run the command
size_t command_end = skip_non_whitespace(command, 0);
@@ -93,19 +103,17 @@ Proxy commands (these will only work when exactly one client is connected):\n\
Set your info board contents with arbitrary data.\n\
marker <color-id>\n\
Send a lobby marker message to the server.\n\
event <event-id>\n\
Send a lobby event update to yourself.\n\
warp <area-id>\n\
Send yourself to a specific area.\n\
set-section-id [section-id]\n\
set-override-section-id [section-id]\n\
Override the section ID for games you create or join. This affects the\n\
active drop chart if you are the leader of the game and the server doesn't\n\
override drops entirely. If no argument is given, clears the override.\n\
set-event [event]\n\
set-override-event [event]\n\
Override the lobby event for all lobbies and games you join. This applies\n\
only to you; other players do not see this override. If no argument is\n\
given, clears the override.\n\
set-lobby-number [number]\n\
set-override-lobby-number [number]\n\
Override the lobby type for all lobbies you join. This applies only to you;\n\
other players do not see this override. If no argument is given, clears the\n\
override.\n\
@@ -298,14 +306,6 @@ Proxy commands (these will only work when exactly one client is connected):\n\
session->send_to_end(data, true);
} else if (command_name == "event") {
auto session = this->get_proxy_session();
string data("\xDA\x00\x04\x00", 4);
data[1] = stod(command_args);
session->send_to_end(data, false);
} else if (command_name == "warp") {
auto session = this->get_proxy_session();
@@ -335,7 +335,7 @@ Proxy commands (these will only work when exactly one client is connected):\n\
session->send_to_end(data, true);
} else if (command_name == "set-section-id") {
} else if (command_name == "set-override-section-id") {
auto session = this->get_proxy_session();
if (command_args.empty()) {
session->override_section_id = -1;
@@ -343,15 +343,18 @@ Proxy commands (these will only work when exactly one client is connected):\n\
session->override_section_id = section_id_for_name(command_args);
}
} else if (command_name == "set-event") {
} else if (command_name == "set-override-event") {
auto session = this->get_proxy_session();
if (command_args.empty()) {
session->override_lobby_event = -1;
} else {
session->override_lobby_event = event_for_name(command_args);
string data("\xDA\x00\x04\x00", 4);
data[1] = session->override_lobby_event;
session->send_to_end(data, false);
}
} else if (command_name == "set-lobby-number") {
} else if (command_name == "set-override-lobby-number") {
auto session = this->get_proxy_session();
if (command_args.empty()) {
session->override_lobby_number = -1;
@@ -361,42 +364,23 @@ Proxy commands (these will only work when exactly one client is connected):\n\
} else if (command_name == "set-chat-filter") {
auto session = this->get_proxy_session();
if (command_args == "on") {
session->enable_chat_filter = true;
} else if (command_args == "off") {
session->enable_chat_filter = false;
} else {
throw invalid_argument("argument must be \"on\" or \"off\"");
}
set_boolean(&session->enable_chat_filter, command_args);
} else if (command_name == "set-chat-safety") {
auto session = this->get_proxy_session();
set_boolean(&session->suppress_newserv_commands, command_args);
if (command_args == "on") {
session->suppress_newserv_commands = true;
} else if (command_args == "off") {
session->suppress_newserv_commands = false;
} else {
throw invalid_argument("argument must be \"on\" or \"off\"");
}
} else if (command_name == "set-switch-assist") {
auto session = this->get_proxy_session();
set_boolean(&session->enable_switch_assist, command_args);
} else if (command_name == "set-save-files") {
if (this->state->proxy_server.get()) {
if (command_args == "on") {
this->state->proxy_server->save_files = true;
} else if (command_args == "off") {
this->state->proxy_server->save_files = false;
} else {
throw invalid_argument("argument must be \"on\" or \"off\"");
}
set_boolean(&this->state->proxy_server->save_files, command_args);
} else {
throw invalid_argument("proxy server is not available");
}
} else {
throw invalid_argument("unknown command; try \'help\'");
}