add infinite ep3 meseta and ability to save media updates
This commit is contained in:
@@ -38,6 +38,7 @@ ClientOptions::ClientOptions()
|
|||||||
enable_chat_filter(true),
|
enable_chat_filter(true),
|
||||||
suppress_remote_login(false),
|
suppress_remote_login(false),
|
||||||
zero_remote_guild_card(false),
|
zero_remote_guild_card(false),
|
||||||
|
ep3_infinite_meseta(false),
|
||||||
function_call_return_value(-1) { }
|
function_call_return_value(-1) { }
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ struct ClientOptions {
|
|||||||
bool enable_chat_filter;
|
bool enable_chat_filter;
|
||||||
bool suppress_remote_login;
|
bool suppress_remote_login;
|
||||||
bool zero_remote_guild_card;
|
bool zero_remote_guild_card;
|
||||||
|
bool ep3_infinite_meseta;
|
||||||
int64_t function_call_return_value; // -1 = don't block function calls
|
int64_t function_call_return_value; // -1 = don't block function calls
|
||||||
|
|
||||||
ClientOptions();
|
ClientOptions();
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ namespace ProxyOptionsMenuItemID {
|
|||||||
constexpr uint32_t SAVE_FILES = 0xAA6666AA;
|
constexpr uint32_t SAVE_FILES = 0xAA6666AA;
|
||||||
constexpr uint32_t SUPPRESS_LOGIN = 0xAA7777AA;
|
constexpr uint32_t SUPPRESS_LOGIN = 0xAA7777AA;
|
||||||
constexpr uint32_t SKIP_CARD = 0xAA8888AA;
|
constexpr uint32_t SKIP_CARD = 0xAA8888AA;
|
||||||
|
constexpr uint32_t EP3_INFINITE_MESETA = 0xAA9999AA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+58
-3
@@ -1101,8 +1101,15 @@ static HandlerResult S_13_A7(shared_ptr<ServerState>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static HandlerResult S_G_B7(shared_ptr<ServerState>,
|
static HandlerResult S_G_B7(shared_ptr<ServerState>,
|
||||||
ProxyServer::LinkedSession& session, uint16_t, uint32_t, string&) {
|
ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) {
|
||||||
if (session.newserv_client_config.cfg.flags & Client::Flag::IS_EPISODE_3) {
|
if (session.newserv_client_config.cfg.flags & Client::Flag::IS_EPISODE_3) {
|
||||||
|
if (session.options.ep3_infinite_meseta) {
|
||||||
|
auto& cmd = check_size_t<S_RankUpdate_GC_Ep3_B7>(data);
|
||||||
|
if (cmd.meseta != 1000000) {
|
||||||
|
cmd.meseta = 1000000;
|
||||||
|
return HandlerResult::Type::MODIFIED;
|
||||||
|
}
|
||||||
|
}
|
||||||
return HandlerResult::Type::FORWARD;
|
return HandlerResult::Type::FORWARD;
|
||||||
} else {
|
} else {
|
||||||
session.server_channel.send(0xB7, 0x00);
|
session.server_channel.send(0xB7, 0x00);
|
||||||
@@ -1139,6 +1146,54 @@ static HandlerResult S_G_B8(shared_ptr<ServerState>,
|
|||||||
: HandlerResult::Type::SUPPRESS;
|
: HandlerResult::Type::SUPPRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HandlerResult S_G_B9(shared_ptr<ServerState>,
|
||||||
|
ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) {
|
||||||
|
|
||||||
|
if (session.options.save_files) {
|
||||||
|
try {
|
||||||
|
const auto& header = check_size_t<S_UpdateMediaHeader_GC_Ep3_B9>(data,
|
||||||
|
sizeof(S_UpdateMediaHeader_GC_Ep3_B9), 0xFFFF);
|
||||||
|
|
||||||
|
if (data.size() - sizeof(header) < header.size) {
|
||||||
|
throw runtime_error("Media data size extends beyond end of command; not saving file");
|
||||||
|
}
|
||||||
|
|
||||||
|
string decompressed_data = prs_decompress(
|
||||||
|
data.data() + sizeof(header), data.size() - sizeof(header));
|
||||||
|
|
||||||
|
string output_filename = string_printf("media-update.%" PRIu64, now());
|
||||||
|
if (header.type == 1) {
|
||||||
|
output_filename += ".gvm";
|
||||||
|
} else if (header.type == 2 || header.type == 3) {
|
||||||
|
output_filename += ".bml";
|
||||||
|
} else {
|
||||||
|
output_filename += ".bin";
|
||||||
|
}
|
||||||
|
save_file(output_filename, decompressed_data);
|
||||||
|
session.log.info("Wrote %zu bytes to %s",
|
||||||
|
decompressed_data.size(), output_filename.c_str());
|
||||||
|
} catch (const exception& e) {
|
||||||
|
session.log.warning("Failed to save file: %s", e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (session.newserv_client_config.cfg.flags & Client::Flag::IS_EPISODE_3)
|
||||||
|
? HandlerResult::Type::FORWARD
|
||||||
|
: HandlerResult::Type::SUPPRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HandlerResult S_G_BA(shared_ptr<ServerState>,
|
||||||
|
ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) {
|
||||||
|
if (session.options.ep3_infinite_meseta) {
|
||||||
|
auto& cmd = check_size_t<S_Meseta_GC_Ep3_BA>(data);
|
||||||
|
if (cmd.remaining_meseta != 1000000) {
|
||||||
|
cmd.remaining_meseta = 1000000;
|
||||||
|
return HandlerResult::Type::MODIFIED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return HandlerResult::Type::FORWARD;
|
||||||
|
}
|
||||||
|
|
||||||
static void update_leader_id(ProxyServer::LinkedSession& session, uint8_t leader_id) {
|
static void update_leader_id(ProxyServer::LinkedSession& session, uint8_t leader_id) {
|
||||||
if (session.leader_client_id != leader_id) {
|
if (session.leader_client_id != leader_id) {
|
||||||
session.leader_client_id = leader_id;
|
session.leader_client_id = leader_id;
|
||||||
@@ -1654,8 +1709,8 @@ static on_command_t handlers[0x100][6][2] = {
|
|||||||
/* B6 */ {{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}},
|
||||||
/* B7 */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_G_B7, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}},
|
/* B7 */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_G_B7, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}},
|
||||||
/* B8 */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_G_B8, nullptr}, {S_invalid, nullptr}, {nullptr, nullptr}},
|
/* B8 */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_G_B8, nullptr}, {S_invalid, nullptr}, {nullptr, nullptr}},
|
||||||
/* B9 */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {nullptr, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}},
|
/* B9 */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_G_B9, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}},
|
||||||
/* BA */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {nullptr, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}},
|
/* BA */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_G_BA, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}},
|
||||||
/* BB */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {nullptr, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}},
|
/* BB */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {nullptr, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}},
|
||||||
/* BC */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}},
|
/* BC */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}},
|
||||||
/* BD */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}},
|
/* BD */ {{S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}, {S_invalid, nullptr}},
|
||||||
|
|||||||
+24
-18
@@ -76,6 +76,7 @@ static const unordered_map<uint32_t, const char16_t*> proxy_options_menu_descrip
|
|||||||
{ProxyOptionsMenuItemID::INFINITE_HP, u"Enable automatic HP\nrestoration when\nyou are hit by an\nenemy or trap\n\nCannot revive you\nfrom one-hit kills"},
|
{ProxyOptionsMenuItemID::INFINITE_HP, u"Enable automatic HP\nrestoration when\nyou are hit by an\nenemy or trap\n\nCannot revive you\nfrom one-hit kills"},
|
||||||
{ProxyOptionsMenuItemID::INFINITE_TP, u"Enable automatic TP\nrestoration when\nyou cast any\ntechnique"},
|
{ProxyOptionsMenuItemID::INFINITE_TP, u"Enable automatic TP\nrestoration when\nyou cast any\ntechnique"},
|
||||||
{ProxyOptionsMenuItemID::SWITCH_ASSIST, u"Automatically try\nto unlock 2-player\ndoors when you step\non both switches\nsequentially"},
|
{ProxyOptionsMenuItemID::SWITCH_ASSIST, u"Automatically try\nto unlock 2-player\ndoors when you step\non both switches\nsequentially"},
|
||||||
|
{ProxyOptionsMenuItemID::EP3_INFINITE_MESETA, u"Fix Meseta value\nat 1,000,000"},
|
||||||
{ProxyOptionsMenuItemID::BLOCK_EVENTS, u"Disable seasonal\nevents in the lobby\nand in games"},
|
{ProxyOptionsMenuItemID::BLOCK_EVENTS, u"Disable seasonal\nevents in the lobby\nand in games"},
|
||||||
{ProxyOptionsMenuItemID::BLOCK_PATCHES, u"Disable patches sent\nby the remote server"},
|
{ProxyOptionsMenuItemID::BLOCK_PATCHES, u"Disable patches sent\nby the remote server"},
|
||||||
{ProxyOptionsMenuItemID::SAVE_FILES, u"Save local copies of\nfiles from the remote\nserver (quests, etc.)"},
|
{ProxyOptionsMenuItemID::SAVE_FILES, u"Save local copies of\nfiles from the remote\nserver (quests, etc.)"},
|
||||||
@@ -91,30 +92,32 @@ static vector<MenuItem> proxy_options_menu_for_client(
|
|||||||
// way in which the menu abstraction is currently insufficient (there is a
|
// way in which the menu abstraction is currently insufficient (there is a
|
||||||
// TODO about this in README.md).
|
// TODO about this in README.md).
|
||||||
ret.emplace_back(ProxyOptionsMenuItemID::GO_BACK, u"Go back", u"", 0);
|
ret.emplace_back(ProxyOptionsMenuItemID::GO_BACK, u"Go back", u"", 0);
|
||||||
ret.emplace_back(ProxyOptionsMenuItemID::CHAT_FILTER,
|
|
||||||
c->options.enable_chat_filter ? u"Chat filter ON" : u"Chat filter OFF", u"", 0);
|
auto add_option = [&](uint32_t item_id, bool is_enabled, const char16_t* text) -> void {
|
||||||
|
u16string option = is_enabled ? u"* " : u"- ";
|
||||||
|
option += text;
|
||||||
|
ret.emplace_back(item_id, option, u"", 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
add_option(ProxyOptionsMenuItemID::CHAT_FILTER, c->options.enable_chat_filter, u"Chat filter");
|
||||||
if (!(c->flags & Client::Flag::IS_EPISODE_3)) {
|
if (!(c->flags & Client::Flag::IS_EPISODE_3)) {
|
||||||
ret.emplace_back(ProxyOptionsMenuItemID::INFINITE_HP,
|
add_option(ProxyOptionsMenuItemID::INFINITE_HP, c->options.infinite_hp, u"Infinite HP");
|
||||||
c->options.infinite_hp ? u"Infinite HP ON" : u"Infinite HP OFF", u"", 0);
|
add_option(ProxyOptionsMenuItemID::INFINITE_TP, c->options.infinite_tp, u"Infinite TP");
|
||||||
ret.emplace_back(ProxyOptionsMenuItemID::INFINITE_TP,
|
add_option(ProxyOptionsMenuItemID::SWITCH_ASSIST, c->options.switch_assist, u"Switch assist");
|
||||||
c->options.infinite_tp ? u"Infinite TP ON" : u"Infinite TP OFF", u"", 0);
|
} else {
|
||||||
ret.emplace_back(ProxyOptionsMenuItemID::SWITCH_ASSIST,
|
// Note: Thie option's text is the maximum possible length for any menu item
|
||||||
c->options.switch_assist ? u"Switch assist ON" : u"Switch assist OFF", u"", 0);
|
add_option(ProxyOptionsMenuItemID::EP3_INFINITE_MESETA, c->options.ep3_infinite_meseta, u"Infinite Meseta");
|
||||||
}
|
}
|
||||||
ret.emplace_back(ProxyOptionsMenuItemID::BLOCK_EVENTS,
|
add_option(ProxyOptionsMenuItemID::BLOCK_EVENTS, (c->options.override_lobby_event >= 0), u"Block events");
|
||||||
(c->options.override_lobby_event >= 0) ? u"Block events ON" : u"Block events OFF", u"", 0);
|
add_option(ProxyOptionsMenuItemID::BLOCK_PATCHES, (c->options.function_call_return_value >= 0), u"Block patches");
|
||||||
ret.emplace_back(ProxyOptionsMenuItemID::BLOCK_PATCHES,
|
|
||||||
(c->options.function_call_return_value >= 0) ? u"Block patches ON" : u"Block patches OFF", u"", 0);
|
|
||||||
if (s->proxy_allow_save_files) {
|
if (s->proxy_allow_save_files) {
|
||||||
ret.emplace_back(ProxyOptionsMenuItemID::SAVE_FILES,
|
add_option(ProxyOptionsMenuItemID::SAVE_FILES, c->options.save_files, u"Save files");
|
||||||
c->options.save_files ? u"Save files ON" : u"Save files OFF", u"", 0);
|
|
||||||
}
|
}
|
||||||
if (s->proxy_enable_login_options) {
|
if (s->proxy_enable_login_options) {
|
||||||
ret.emplace_back(ProxyOptionsMenuItemID::SUPPRESS_LOGIN,
|
add_option(ProxyOptionsMenuItemID::SUPPRESS_LOGIN, c->options.suppress_remote_login, u"Skip login");
|
||||||
c->options.suppress_remote_login ? u"Skip login ON" : u"Skip login OFF", u"", 0);
|
add_option(ProxyOptionsMenuItemID::SKIP_CARD, c->options.zero_remote_guild_card, u"Skip card");
|
||||||
ret.emplace_back(ProxyOptionsMenuItemID::SKIP_CARD,
|
|
||||||
c->options.zero_remote_guild_card ? u"Skip card ON" : u"Skip card OFF", u"", 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1801,6 +1804,9 @@ static void on_10(shared_ptr<ServerState> s, shared_ptr<Client> c,
|
|||||||
case ProxyOptionsMenuItemID::SWITCH_ASSIST:
|
case ProxyOptionsMenuItemID::SWITCH_ASSIST:
|
||||||
c->options.switch_assist = !c->options.switch_assist;
|
c->options.switch_assist = !c->options.switch_assist;
|
||||||
goto resend_proxy_options_menu;
|
goto resend_proxy_options_menu;
|
||||||
|
case ProxyOptionsMenuItemID::EP3_INFINITE_MESETA:
|
||||||
|
c->options.ep3_infinite_meseta = !c->options.ep3_infinite_meseta;
|
||||||
|
goto resend_proxy_options_menu;
|
||||||
case ProxyOptionsMenuItemID::BLOCK_EVENTS:
|
case ProxyOptionsMenuItemID::BLOCK_EVENTS:
|
||||||
if (c->options.override_lobby_event >= 0) {
|
if (c->options.override_lobby_event >= 0) {
|
||||||
c->options.override_lobby_event = -1;
|
c->options.override_lobby_event = -1;
|
||||||
|
|||||||
Reference in New Issue
Block a user