enable $patch on proxy server

This commit is contained in:
Martin Michelsen
2022-11-03 15:28:03 -07:00
parent 247904f019
commit a0a802f42f
5 changed files with 60 additions and 6 deletions
+15 -1
View File
@@ -216,6 +216,20 @@ static void server_command_patch(shared_ptr<ServerState> s, shared_ptr<Lobby>,
}
}
static void proxy_command_patch(shared_ptr<ServerState> s,
ProxyServer::LinkedSession& session, const std::u16string& args) {
std::shared_ptr<CompiledFunctionCode> fn;
try {
fn = s->function_code_index->name_to_function.at(encode_sjis(args));
send_function_call(
session.client_channel, session.newserv_client_config.cfg.flags, fn);
// Don't forward the patch response to the server
session.should_forward_function_call_return_queue.emplace_back(false);
} catch (const out_of_range&) {
send_text_message(session.client_channel, u"Invalid patch name");
}
}
static void server_command_persist(shared_ptr<ServerState>, shared_ptr<Lobby> l,
shared_ptr<Client> c, const std::u16string&) {
check_privileges(c, Privilege::DEBUG);
@@ -980,7 +994,7 @@ static const unordered_map<u16string, ChatCommandDefinition> chat_commands({
{u"$minlevel", {server_command_min_level, nullptr, u"Usage:\nmin_level <level>"}},
{u"$next", {server_command_next, proxy_command_next, u"Usage:\nnext"}},
{u"$password", {server_command_password, nullptr, u"Usage:\nlock [password]\nomit password to\nunlock game"}},
{u"$patch", {server_command_patch, nullptr, u"Usage:\npatch <name>"}},
{u"$patch", {server_command_patch, proxy_command_patch, u"Usage:\npatch <name>"}},
{u"$persist", {server_command_persist, nullptr, u"Usage:\npersist"}},
{u"$rand", {server_command_rand, proxy_command_rand, u"Usage:\nrand [hex seed]\nomit seed to revert\nto default"}},
{u"$secid", {server_command_secid, proxy_command_secid, u"Usage:\nsecid [section ID]\nomit section ID to\nrevert to normal"}},
+13 -1
View File
@@ -687,10 +687,22 @@ static HandlerResult S_B2(shared_ptr<ServerState>,
session.server_channel.send(0xB3, flag, &cmd, sizeof(cmd));
return HandlerResult::Type::SUPPRESS;
} else {
session.should_forward_function_call_return_queue.emplace_back(true);
return HandlerResult::Type::FORWARD;
}
}
static HandlerResult C_B3(shared_ptr<ServerState>,
ProxyServer::LinkedSession& session, uint16_t, uint32_t, string&) {
if (session.should_forward_function_call_return_queue.empty()) {
session.log.warning("Received function call result with empty result queue");
return HandlerResult::Type::FORWARD;
}
bool should_forward = session.should_forward_function_call_return_queue.front();
session.should_forward_function_call_return_queue.pop_front();
return should_forward ? HandlerResult::Type::FORWARD : HandlerResult::Type::SUPPRESS;
}
static HandlerResult S_B_E7(shared_ptr<ServerState>,
ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) {
if (session.save_files) {
@@ -1554,7 +1566,7 @@ static on_command_t handlers[0x100][6][2] = {
/* B0 */ {{S_invalid, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}},
/* B1 */ {{S_invalid, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}},
/* B2 */ {{S_invalid, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}, {S_B2, nullptr}, {S_B2, nullptr}, {S_B2, nullptr}},
/* B3 */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}},
/* B3 */ {{S_invalid, C_B3}, {S_invalid, C_B3}, {S_invalid, C_B3}, {S_invalid, C_B3}, {S_invalid, C_B3}, {S_invalid, C_B3}},
/* B4 */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}},
/* B5 */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}},
/* B6 */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}},
+2
View File
@@ -2,6 +2,7 @@
#include <event2/event.h>
#include <deque>
#include <map>
#include <unordered_map>
#include <unordered_set>
@@ -67,6 +68,7 @@ public:
bool infinite_tp;
bool save_files;
bool suppress_remote_login;
std::deque<bool> should_forward_function_call_return_queue;
int64_t function_call_return_value; // -1 = don't block function calls
G_SwitchStateChanged_6x05 last_switch_enabled_command;
PlayerInventoryItem next_drop_item;
+22 -4
View File
@@ -318,10 +318,28 @@ void send_function_call(
const std::string& suffix,
uint32_t checksum_addr,
uint32_t checksum_size) {
if (c->flags & Client::Flag::NO_SEND_FUNCTION_CALL) {
return send_function_call(
c->channel,
c->flags,
code,
label_writes,
suffix,
checksum_addr,
checksum_size);
}
void send_function_call(
Channel& ch,
uint64_t client_flags,
shared_ptr<CompiledFunctionCode> code,
const std::unordered_map<std::string, uint32_t>& label_writes,
const std::string& suffix,
uint32_t checksum_addr,
uint32_t checksum_size) {
if (client_flags & Client::Flag::NO_SEND_FUNCTION_CALL) {
throw logic_error("client does not support function calls");
}
if (code.get() && (c->flags & Client::Flag::SEND_FUNCTION_CALL_CHECKSUM_ONLY)) {
if (code.get() && (client_flags & Client::Flag::SEND_FUNCTION_CALL_CHECKSUM_ONLY)) {
throw logic_error("client only supports checksums in send_function_call");
}
@@ -331,7 +349,7 @@ void send_function_call(
data = code->generate_client_command(label_writes, suffix);
index = code->index;
if (c->flags & Client::Flag::ENCRYPTED_SEND_FUNCTION_CALL) {
if (client_flags & Client::Flag::ENCRYPTED_SEND_FUNCTION_CALL) {
uint32_t key = random_object<uint32_t>();
// This format was probably never used on any little-endian system, but we
@@ -364,7 +382,7 @@ void send_function_call(
w.put(header);
w.write(data);
send_command(c, 0xB2, index, w.str());
ch.send(0xB2, index, w.str());
}
+8
View File
@@ -124,6 +124,14 @@ void send_update_client_config(std::shared_ptr<Client> c);
void send_quest_buffer_overflow(
std::shared_ptr<ServerState> s, std::shared_ptr<Client> c);
void send_function_call(
Channel& ch,
uint64_t client_flags,
std::shared_ptr<CompiledFunctionCode> code,
const std::unordered_map<std::string, uint32_t>& label_writes = {},
const std::string& suffix = "",
uint32_t checksum_addr = 0,
uint32_t checksum_size = 0);
void send_function_call(
std::shared_ptr<Client> c,
std::shared_ptr<CompiledFunctionCode> code,