add $qgread and $qgwrite commands

This commit is contained in:
Martin Michelsen
2024-01-31 18:02:25 -08:00
parent 4830f5a41e
commit b6817e278a
8 changed files with 71 additions and 21 deletions
+47
View File
@@ -375,6 +375,51 @@ static void proxy_command_qclear(shared_ptr<ProxyServer::LinkedSession> ses, con
return proxy_command_qset_qclear(ses, args, false);
}
static void server_command_qgread(shared_ptr<Client> c, const std::string& args) {
uint8_t flag_num = stoul(args, nullptr, 0);
const auto& flags = c->character()->quest_counters;
if (flag_num >= flags.size()) {
send_text_message_printf(c, "$C7Flag number must be\nless than %zu", flags.size());
} else {
send_text_message_printf(c, "$C7Quest counter %hhu\nhas value %" PRIu32,
flag_num, flags[flag_num].load());
}
}
static void server_command_qgwrite(shared_ptr<Client> c, const std::string& args) {
if (c->version() != Version::BB_V4) {
send_text_message(c, "$C6This command can\nonly be used on BB");
return;
}
if (!c->config.check_flag(Client::Flag::DEBUG_ENABLED)) {
send_text_message(c, "$C6This command can only\nbe run in debug mode\n(run %sdebug first)");
return;
}
auto l = c->require_lobby();
if (!l->is_game()) {
send_text_message(c, "$C6This command cannot\nbe used in the lobby");
return;
}
auto tokens = split(args, ' ');
if (tokens.size() != 2) {
send_text_message(c, "$C6Incorrect number\nof arguments");
return;
}
uint8_t flag_num = stoul(tokens[0], nullptr, 0);
uint32_t value = stoul(tokens[1], nullptr, 0);
auto& flags = c->character()->quest_counters;
if (flag_num >= flags.size()) {
send_text_message_printf(c, "$C7Flag number must be\nless than %zu", flags.size());
} else {
c->character()->quest_counters[flag_num] = value;
G_SetQuestCounter_BB_6xD2 cmd = {{0xD2, sizeof(G_SetQuestCounter_BB_6xD2) / 4, c->lobby_client_id}, flag_num, value};
send_command_t(c, 0x60, 0x00, cmd);
send_text_message_printf(c, "$C7Quest counter %hhu\nset to %" PRIu32, flag_num, value);
}
}
static void server_command_qsync_qsyncall(shared_ptr<Client> c, const std::string& args, bool send_to_lobby) {
if (!c->config.check_flag(Client::Flag::DEBUG_ENABLED)) {
send_text_message(c, "$C6This command can only\nbe run in debug mode\n(run %sdebug first)");
@@ -2021,6 +2066,8 @@ static const unordered_map<string, ChatCommandDefinition> chat_commands({
{"$qcall", {server_command_qcall, proxy_command_qcall}},
{"$qcheck", {server_command_qcheck, nullptr}},
{"$qclear", {server_command_qclear, proxy_command_qclear}},
{"$qgread", {server_command_qgread, nullptr}},
{"$qgwrite", {server_command_qgwrite, nullptr}},
{"$qset", {server_command_qset, proxy_command_qset}},
{"$qsync", {server_command_qsync, proxy_command_qsync}},
{"$qsyncall", {server_command_qsyncall, proxy_command_qsyncall}},
+1 -1
View File
@@ -811,7 +811,7 @@ void Client::load_all_files() {
this->character_data->battle_records = nsc_data.battle_records;
this->character_data->challenge_records = nsc_data.challenge_records;
this->character_data->tech_menu_config = nsc_data.tech_menu_config;
this->character_data->quest_global_flags = nsc_data.quest_global_flags;
this->character_data->quest_counters = nsc_data.quest_counters;
if (nsa_data) {
this->character_data->option_flags = nsa_data->option_flags;
this->character_data->symbol_chats = nsa_data->symbol_chats;
+2 -2
View File
@@ -5881,10 +5881,10 @@ struct G_ChallengeModeGraveRecoveryItemRequest_BB_6xD1 {
le_uint32_t item_type = 0; // Should be < 6
} __packed__;
// 6xD2: Set quest global flag (BB)
// 6xD2: Set quest counter (BB)
// Writes 4 bytes to the 32-bit field specified by index.
struct G_SetQuestGlobalFlag_BB_6xD2 {
struct G_SetQuestCounter_BB_6xD2 {
G_ClientIDHeader header;
le_uint32_t index = 0; // There are 0x10 of them (0x00-0x0F)
le_uint32_t value = 0;
+1 -1
View File
@@ -827,7 +827,7 @@ struct PlayerConfig {
/* 000C:---- */ parray<uint8_t, 0x1C> unknown_a1;
/* 0028:---- */ parray<be_uint16_t, 20> tech_menu_shortcut_entries;
/* 0050:---- */ parray<be_uint32_t, 10> choice_search_config;
// This field maps to quest_global_flags on Episodes 1 & 2
// This field maps to quest_counters on Episodes 1 & 2
/* 0078:---- */ parray<be_uint32_t, 0x30> scenario_progress;
// place_counts[0] and [1] from this field are added to the player's win and
// loss count respectively when they're shown in the status menu. However,
+7 -7
View File
@@ -279,11 +279,11 @@ static const QuestScriptOpcodeDefinition opcode_defs[] = {
{0x0010, "set", {REG}, F_V0_V4}, // Sets a register to 1
{0x0011, "clear", {REG}, F_V0_V4}, // Sets a register to 0
{0x0012, "rev", {REG}, F_V0_V4}, // Sets a register to 0 if it's nonzero and vice versa
{0x0013, "gset", {INT16}, F_V0_V4}, // Sets a global flag
{0x0014, "gclear", {INT16}, F_V0_V4}, // Clears a global flag
{0x0015, "grev", {INT16}, F_V0_V4}, // Flips a global flag
{0x0016, "glet", {INT16, REG}, F_V0_V4}, // Sets a global flag to a specific value
{0x0017, "gget", {INT16, REG}, F_V0_V4}, // Gets a global flag
{0x0013, "gset", {INT16}, F_V0_V4}, // Sets a quest flag
{0x0014, "gclear", {INT16}, F_V0_V4}, // Clears a quest flag
{0x0015, "grev", {INT16}, F_V0_V4}, // Flips a quest flag
{0x0016, "glet", {INT16, REG}, F_V0_V4}, // Sets a quest flag to a specific value
{0x0017, "gget", {INT16, REG}, F_V0_V4}, // Gets a quest flag
{0x0018, "add", {REG, REG}, F_V0_V4}, // regA += regB
{0x0019, "addi", {REG, INT32}, F_V0_V4}, // regA += imm
{0x001A, "sub", {REG, REG}, F_V0_V4}, // regA -= regB
@@ -779,8 +779,8 @@ static const QuestScriptOpcodeDefinition opcode_defs[] = {
{0xF922, "get_player_hp", {CLIENT_ID, {REG_SET_FIXED, 4}}, F_V3_V4 | F_ARGS},
{0xF923, "get_floor_number", {CLIENT_ID, {REG_SET_FIXED, 2}}, F_V3_V4 | F_ARGS},
{0xF924, "get_coord_player_detect", {{REG_SET_FIXED, 3}, {REG_SET_FIXED, 4}}, F_V3_V4},
{0xF925, "read_global_flag", {INT32, REG}, F_V3_V4 | F_ARGS},
{0xF926, "write_global_flag", {INT32, INT32}, F_V3_V4 | F_ARGS},
{0xF925, "read_counter", {INT32, REG}, F_V3_V4 | F_ARGS},
{0xF926, "write_counter", {INT32, INT32}, F_V3_V4 | F_ARGS},
{0xF927, "item_detect_bank2", {{REG_SET_FIXED, 4}, REG}, F_V3_V4},
{0xF928, "floor_player_detect", {{REG_SET_FIXED, 4}}, F_V3_V4},
{0xF929, "prepare_gba_rom_from_disk", {CSTRING}, F_V3 | F_ARGS}, // Prepares to load a GBA ROM from a local GSL file
+4 -4
View File
@@ -3567,9 +3567,9 @@ static void on_upgrade_weapon_attribute_bb(shared_ptr<Client> c, uint8_t, uint8_
}
}
static void on_write_quest_global_flag_bb(shared_ptr<Client> c, uint8_t, uint8_t, void* data, size_t size) {
const auto& cmd = check_size_t<G_SetQuestGlobalFlag_BB_6xD2>(data, size);
c->character()->quest_global_flags[cmd.index] = cmd.value;
static void on_write_quest_counter_bb(shared_ptr<Client> c, uint8_t, uint8_t, void* data, size_t size) {
const auto& cmd = check_size_t<G_SetQuestCounter_BB_6xD2>(data, size);
c->character()->quest_counters[cmd.index] = cmd.value;
}
////////////////////////////////////////////////////////////////////////////////
@@ -3785,7 +3785,7 @@ const SubcommandDefinition subcommand_definitions[0x100] = {
/* 6xCF */ {0x00, 0x00, 0xCF, on_battle_restart_bb},
/* 6xD0 */ {0x00, 0x00, 0xD0, on_battle_level_up_bb},
/* 6xD1 */ {0x00, 0x00, 0xD1, on_request_challenge_grave_recovery_item_bb},
/* 6xD2 */ {0x00, 0x00, 0xD2, on_write_quest_global_flag_bb},
/* 6xD2 */ {0x00, 0x00, 0xD2, on_write_quest_counter_bb},
/* 6xD3 */ {0x00, 0x00, 0xD3, on_invalid},
/* 6xD4 */ {0x00, 0x00, 0xD4, on_forward_check_game},
/* 6xD5 */ {0x00, 0x00, 0xD5, on_quest_exchange_item_bb},
+3 -3
View File
@@ -210,7 +210,7 @@ struct PSOBBCharacterFile {
/* 2DF8 */ parray<le_uint16_t, 0x0014> tech_menu_config;
/* 2E20 */ ChoiceSearchConfig choice_search_config;
/* 2E38 */ parray<uint8_t, 0x0010> unknown_a6;
/* 2E48 */ parray<le_uint32_t, 0x0010> quest_global_flags;
/* 2E48 */ parray<le_uint32_t, 0x0010> quest_counters;
/* 2E88 */ parray<uint8_t, 0x1C> unknown_a7;
/* 2EA4 */
@@ -360,7 +360,7 @@ struct PSOGCCharacterFile {
/* 25E0:21C4 */ PlayerRecordsV3_Challenge<true> challenge_records;
/* 26E0:22C4 */ parray<be_uint16_t, 20> tech_menu_shortcut_entries;
/* 2708:22EC */ parray<uint8_t, 0x28> unknown_a6;
/* 2730:2314 */ parray<be_uint32_t, 0x10> quest_global_flags;
/* 2730:2314 */ parray<be_uint32_t, 0x10> quest_counters;
/* 2770:2354 */ PlayerRecords_Battle<true> offline_battle_records;
/* 2788:236C */ parray<uint8_t, 4> unknown_f5;
/* 278C:2370 */ be_uint32_t unknown_f6;
@@ -766,7 +766,7 @@ struct LegacySavedPlayerDataBB { // .nsc file format
/* 1D00 */ parray<uint8_t, 4> unknown_a2;
/* 1D04 */ QuestFlags quest_flags;
/* 1F04 */ le_uint32_t death_count;
/* 1F08 */ parray<le_uint32_t, 0x0016> quest_global_flags;
/* 1F08 */ parray<le_uint32_t, 0x0016> quest_counters;
/* 1F60 */ parray<le_uint16_t, 0x0014> tech_menu_config;
/* 1F88 */
} __attribute__((packed));