enable $patch on proxy server
This commit is contained in:
+15
-1
@@ -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
@@ -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,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
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user