implement switch assist on proxy server
This commit is contained in:
+37
-14
@@ -580,17 +580,13 @@ void ProxyServer::LinkedSession::disconnect() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void check_implemented_subcommand(
|
static void check_implemented_subcommand(uint64_t id, const string& data) {
|
||||||
uint64_t id, uint16_t command, const string& data) {
|
if (data.size() < 4) {
|
||||||
if (command == 0x60 || command == 0x6C || command == 0xC9 ||
|
log(WARNING, "[ProxyServer/%08" PRIX64 "] Received broadcast/target command with no contents", id);
|
||||||
command == 0x62 || command == 0x6D || command == 0xCB) {
|
} else {
|
||||||
if (data.size() < 4) {
|
if (!subcommand_is_implemented(data[0])) {
|
||||||
log(WARNING, "[ProxyServer/%08" PRIX64 "] Received broadcast/target command with no contents", id);
|
log(WARNING, "[ProxyServer/%08" PRIX64 "] Received subcommand %02hhX which is not implemented on the server",
|
||||||
} else {
|
id, data[0]);
|
||||||
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) {
|
[&](uint16_t command, uint32_t flag, string& data) {
|
||||||
print_received_command(command, flag, data.data(), data.size(),
|
print_received_command(command, flag, data.data(), data.size(),
|
||||||
this->version, name.c_str());
|
this->version, name.c_str());
|
||||||
check_implemented_subcommand(this->id, command, data);
|
|
||||||
|
|
||||||
bool should_forward = true;
|
bool should_forward = true;
|
||||||
switch (command) {
|
switch (command) {
|
||||||
@@ -624,6 +619,26 @@ void ProxyServer::LinkedSession::on_client_input() {
|
|||||||
}
|
}
|
||||||
break;
|
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 0xA0: // Change ship
|
||||||
case 0xA1: { // Change block
|
case 0xA1: { // Change block
|
||||||
if ((this->version == GameVersion::PATCH) || (this->version == GameVersion::BB)) {
|
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) {
|
[&](uint16_t command, uint32_t flag, string& data) {
|
||||||
print_received_command(command, flag, data.data(), data.size(),
|
print_received_command(command, flag, data.data(), data.size(),
|
||||||
this->version, name.c_str());
|
this->version, name.c_str());
|
||||||
check_implemented_subcommand(this->id, command, data);
|
|
||||||
|
|
||||||
// In the case of server init commands, the client output crypt cannot
|
// 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
|
// be set until after we forwarwd the command to the client, hence this
|
||||||
@@ -991,6 +1005,15 @@ void ProxyServer::LinkedSession::on_server_input() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 0x60:
|
||||||
|
case 0x62:
|
||||||
|
case 0x6C:
|
||||||
|
case 0x6D:
|
||||||
|
case 0xC9:
|
||||||
|
case 0xCB:
|
||||||
|
check_implemented_subcommand(this->id, data);
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x44:
|
case 0x44:
|
||||||
case 0xA6: {
|
case 0xA6: {
|
||||||
if (this->version != GameVersion::GC) {
|
if (this->version != GameVersion::GC) {
|
||||||
@@ -1163,7 +1186,7 @@ void ProxyServer::LinkedSession::on_server_input() {
|
|||||||
if (this->override_lobby_event >= 0) {
|
if (this->override_lobby_event >= 0) {
|
||||||
cmd->event = this->override_lobby_event;
|
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;
|
cmd->lobby_number = this->override_lobby_number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ public:
|
|||||||
ClientConfig newserv_client_config;
|
ClientConfig newserv_client_config;
|
||||||
bool suppress_newserv_commands;
|
bool suppress_newserv_commands;
|
||||||
bool enable_chat_filter;
|
bool enable_chat_filter;
|
||||||
|
bool enable_switch_assist;
|
||||||
|
std::string last_switch_enabled_subcommand;
|
||||||
int16_t override_section_id;
|
int16_t override_section_id;
|
||||||
int16_t override_lobby_event;
|
int16_t override_lobby_event;
|
||||||
int16_t override_lobby_number;
|
int16_t override_lobby_number;
|
||||||
|
|||||||
+25
-41
@@ -31,6 +31,16 @@ shared_ptr<ProxyServer::LinkedSession> ServerShell::get_proxy_session() {
|
|||||||
return this->state->proxy_server->get_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) {
|
void ServerShell::execute_command(const string& command) {
|
||||||
// find the entry in the command table and run the command
|
// find the entry in the command table and run the command
|
||||||
size_t command_end = skip_non_whitespace(command, 0);
|
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\
|
Set your info board contents with arbitrary data.\n\
|
||||||
marker <color-id>\n\
|
marker <color-id>\n\
|
||||||
Send a lobby marker message to the server.\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\
|
warp <area-id>\n\
|
||||||
Send yourself to a specific area.\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\
|
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\
|
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\
|
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\
|
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\
|
only to you; other players do not see this override. If no argument is\n\
|
||||||
given, clears the override.\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\
|
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\
|
other players do not see this override. If no argument is given, clears the\n\
|
||||||
override.\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);
|
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") {
|
} else if (command_name == "warp") {
|
||||||
auto session = this->get_proxy_session();
|
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);
|
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();
|
auto session = this->get_proxy_session();
|
||||||
if (command_args.empty()) {
|
if (command_args.empty()) {
|
||||||
session->override_section_id = -1;
|
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);
|
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();
|
auto session = this->get_proxy_session();
|
||||||
if (command_args.empty()) {
|
if (command_args.empty()) {
|
||||||
session->override_lobby_event = -1;
|
session->override_lobby_event = -1;
|
||||||
} else {
|
} else {
|
||||||
session->override_lobby_event = event_for_name(command_args);
|
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();
|
auto session = this->get_proxy_session();
|
||||||
if (command_args.empty()) {
|
if (command_args.empty()) {
|
||||||
session->override_lobby_number = -1;
|
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") {
|
} else if (command_name == "set-chat-filter") {
|
||||||
auto session = this->get_proxy_session();
|
auto session = this->get_proxy_session();
|
||||||
|
set_boolean(&session->enable_chat_filter, command_args);
|
||||||
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\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (command_name == "set-chat-safety") {
|
} else if (command_name == "set-chat-safety") {
|
||||||
auto session = this->get_proxy_session();
|
auto session = this->get_proxy_session();
|
||||||
|
set_boolean(&session->suppress_newserv_commands, command_args);
|
||||||
|
|
||||||
if (command_args == "on") {
|
} else if (command_name == "set-switch-assist") {
|
||||||
session->suppress_newserv_commands = true;
|
auto session = this->get_proxy_session();
|
||||||
} else if (command_args == "off") {
|
set_boolean(&session->enable_switch_assist, command_args);
|
||||||
session->suppress_newserv_commands = false;
|
|
||||||
} else {
|
|
||||||
throw invalid_argument("argument must be \"on\" or \"off\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (command_name == "set-save-files") {
|
} else if (command_name == "set-save-files") {
|
||||||
if (this->state->proxy_server.get()) {
|
if (this->state->proxy_server.get()) {
|
||||||
if (command_args == "on") {
|
set_boolean(&this->state->proxy_server->save_files, command_args);
|
||||||
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\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw invalid_argument("proxy server is not available");
|
throw invalid_argument("proxy server is not available");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw invalid_argument("unknown command; try \'help\'");
|
throw invalid_argument("unknown command; try \'help\'");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user