rewrite proxy server to support multiple clients and integration with game server
This commit is contained in:
+129
-3
@@ -14,14 +14,23 @@ using namespace std;
|
||||
|
||||
|
||||
|
||||
ServerShell::ServerShell(std::shared_ptr<struct event_base> base,
|
||||
std::shared_ptr<ServerState> state) : Shell(base, state) { }
|
||||
ServerShell::ServerShell(
|
||||
shared_ptr<struct event_base> base,
|
||||
shared_ptr<ServerState> state)
|
||||
: Shell(base, state) { }
|
||||
|
||||
void ServerShell::print_prompt() {
|
||||
fwrite("newserv> ", 9, 1, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
shared_ptr<ProxyServer::LinkedSession> ServerShell::get_proxy_session() {
|
||||
if (!this->state->proxy_server.get()) {
|
||||
throw runtime_error("the proxy server is disabled");
|
||||
}
|
||||
return this->state->proxy_server->get_session();
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -34,9 +43,11 @@ void ServerShell::execute_command(const string& command) {
|
||||
|
||||
} else if (command_name == "help") {
|
||||
fprintf(stderr, "\
|
||||
Commands:\n\
|
||||
General commands:\n\
|
||||
help\n\
|
||||
You\'re reading it now.\n\
|
||||
\n\
|
||||
Server commands:\n\
|
||||
exit (or ctrl+d)\n\
|
||||
Shut down the server.\n\
|
||||
reload <item> ...\n\
|
||||
@@ -66,8 +77,32 @@ Commands:\n\
|
||||
Song IDs are 0 through 51; the default song is -1.\n\
|
||||
announce <message>\n\
|
||||
Send an announcement message to all players.\n\
|
||||
\n\
|
||||
Proxy commands (these will only work when exactly one client is connected):\n\
|
||||
sc <data>\n\
|
||||
Send a command to the client.\n\
|
||||
ss <data>\n\
|
||||
Send a command to the server.\n\
|
||||
chat <text>\n\
|
||||
Send a chat message to the server.\n\
|
||||
dchat <data>\n\
|
||||
Send a chat message to the server with arbitrary data in it.\n\
|
||||
info-board <text>\n\
|
||||
Set your info board contents.\n\
|
||||
info-board-data <data>\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\
|
||||
ship\n\
|
||||
Request the ship select menu from the server.\n\
|
||||
");
|
||||
|
||||
|
||||
|
||||
// SERVER COMMANDS
|
||||
|
||||
} else if (command_name == "reload") {
|
||||
auto types = split(command_args, ' ');
|
||||
if (types.empty()) {
|
||||
@@ -189,6 +224,97 @@ Commands:\n\
|
||||
u16string message16 = decode_sjis(command_args);
|
||||
send_text_message(this->state, message16.c_str());
|
||||
|
||||
|
||||
|
||||
// PROXY COMMANDS
|
||||
|
||||
} else if ((command_name == "sc") || (command_name == "ss")) {
|
||||
auto session = this->get_proxy_session();
|
||||
|
||||
bool to_server = (command_name[1] == 's');
|
||||
string data = parse_data_string(command_args);
|
||||
if (data.size() & 3) {
|
||||
throw invalid_argument("data size is not a multiple of 4");
|
||||
}
|
||||
if (data.size() == 0) {
|
||||
throw invalid_argument("no data given");
|
||||
}
|
||||
uint16_t* size_field = reinterpret_cast<uint16_t*>(data.data() + 2);
|
||||
*size_field = data.size();
|
||||
|
||||
session->send_to_end(data, to_server);
|
||||
|
||||
} else if ((command_name == "chat") || (command_name == "dchat")) {
|
||||
auto session = this->get_proxy_session();
|
||||
|
||||
string data(12, '\0');
|
||||
data[0] = 0x06;
|
||||
data.push_back('\x09');
|
||||
data.push_back('E');
|
||||
if (command_name == "dchat") {
|
||||
data += parse_data_string(command_args);
|
||||
} else {
|
||||
data += command_args;
|
||||
}
|
||||
data.push_back('\0');
|
||||
data.resize((data.size() + 3) & (~3));
|
||||
uint16_t* size_field = reinterpret_cast<uint16_t*>(data.data() + 2);
|
||||
*size_field = data.size();
|
||||
|
||||
session->send_to_end(data, true);
|
||||
|
||||
} else if (command_name == "marker") {
|
||||
auto session = this->get_proxy_session();
|
||||
|
||||
string data("\x89\x00\x04\x00", 4);
|
||||
data[1] = stod(command_args);
|
||||
|
||||
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 == "ship") {
|
||||
auto session = this->get_proxy_session();
|
||||
|
||||
static const string data("\xA0\x00\x04\x00", 4);
|
||||
session->send_to_end(data, true);
|
||||
|
||||
} else if ((command_name == "info-board") || (command_name == "info-board-data")) {
|
||||
auto session = this->get_proxy_session();
|
||||
|
||||
string data(4, '\0');
|
||||
data[0] = 0xD9;
|
||||
if (command_name == "info-board-data") {
|
||||
data += parse_data_string(command_args);
|
||||
} else {
|
||||
data += command_args;
|
||||
}
|
||||
data.push_back('\0');
|
||||
data.resize((data.size() + 3) & (~3));
|
||||
uint16_t* size_field = reinterpret_cast<uint16_t*>(data.data() + 2);
|
||||
*size_field = data.size();
|
||||
|
||||
session->send_to_end(data, true);
|
||||
|
||||
} else if (command_name == "set-save-quests") {
|
||||
auto session = this->get_proxy_session();
|
||||
|
||||
if (command_args == "on") {
|
||||
session->save_quests = true;
|
||||
} else if (command_args == "off") {
|
||||
session->save_quests = false;
|
||||
} else {
|
||||
throw invalid_argument("argument must be \"on\" or \"off\"");
|
||||
}
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
throw invalid_argument("unknown command; try \'help\'");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user