diff --git a/src/ChatCommands.cc b/src/ChatCommands.cc index 998ebdbe..be4eb084 100644 --- a/src/ChatCommands.cc +++ b/src/ChatCommands.cc @@ -1463,15 +1463,23 @@ static void server_command_infinite_hp(shared_ptr c, const std::string&) check_cheats_enabled(l, c); c->config.toggle_flag(Client::Flag::INFINITE_HP_ENABLED); - send_text_message_printf(c, "$C6Infinite HP %s", c->config.check_flag(Client::Flag::INFINITE_HP_ENABLED) ? "enabled" : "disabled"); + bool enabled = c->config.check_flag(Client::Flag::INFINITE_HP_ENABLED); + send_text_message_printf(c, "$C6Infinite HP %s", enabled ? "enabled" : "disabled"); + if (enabled && l->is_game()) { + send_remove_conditions(c); + } } static void proxy_command_infinite_hp(shared_ptr ses, const std::string&) { auto s = ses->require_server_state(); check_cheats_allowed(s, ses); ses->config.toggle_flag(Client::Flag::INFINITE_HP_ENABLED); - send_text_message_printf(ses->client_channel, "$C6Infinite HP %s", - ses->config.check_flag(Client::Flag::INFINITE_HP_ENABLED) ? "enabled" : "disabled"); + bool enabled = ses->config.check_flag(Client::Flag::INFINITE_HP_ENABLED); + send_text_message_printf(ses->client_channel, "$C6Infinite HP %s", enabled ? "enabled" : "disabled"); + if (enabled && ses->is_in_game) { + send_remove_conditions(ses->client_channel, ses->lobby_client_id); + send_remove_conditions(ses->server_channel, ses->lobby_client_id); + } } static void server_command_infinite_tp(shared_ptr c, const std::string&) { diff --git a/src/ProxyCommands.cc b/src/ProxyCommands.cc index a2a52c83..458aba8c 100644 --- a/src/ProxyCommands.cc +++ b/src/ProxyCommands.cc @@ -1711,6 +1711,11 @@ static HandlerResult C_6x(shared_ptr ses, uint16_t c const auto& cmd = check_size_t(data); ses->floor = cmd.floor; + } else if (data[0] == 0x0C) { + if (ses->config.check_flag(Client::Flag::INFINITE_HP_ENABLED)) { + send_remove_conditions(ses->client_channel, ses->lobby_client_id); + send_remove_conditions(ses->server_channel, ses->lobby_client_id); + } } else if (data[0] == 0x2F || data[0] == 0x4B || data[0] == 0x4C) { if (ses->config.check_flag(Client::Flag::INFINITE_HP_ENABLED)) { send_player_stats_change(ses->client_channel, diff --git a/src/ReceiveSubcommands.cc b/src/ReceiveSubcommands.cc index c2c8c421..60e99236 100644 --- a/src/ReceiveSubcommands.cc +++ b/src/ReceiveSubcommands.cc @@ -950,7 +950,21 @@ static void on_player_died(shared_ptr c, uint8_t command, uint8_t flag, forward_subcommand(c, command, flag, data, size); } -// When a player is hit by an enemy, heal them if infinite HP is enabled +static void on_received_condition(shared_ptr c, uint8_t command, uint8_t flag, void* data, size_t size) { + const auto& cmd = check_size_t(data, size, 0xFFFF); + + auto l = c->require_lobby(); + if (l->is_game()) { + forward_subcommand(c, command, flag, data, size); + if (cmd.client_id == c->lobby_client_id) { + bool player_cheats_enabled = l->check_flag(Lobby::Flag::CHEATS_ENABLED) || (c->license->flags & License::Flag::CHEAT_ANYWHERE); + if (player_cheats_enabled && c->config.check_flag(Client::Flag::INFINITE_HP_ENABLED)) { + send_remove_conditions(c); + } + } + } +} + static void on_hit_by_enemy(shared_ptr c, uint8_t command, uint8_t flag, void* data, size_t size) { const auto& cmd = check_size_t(data, size, 0xFFFF); @@ -965,7 +979,6 @@ static void on_hit_by_enemy(shared_ptr c, uint8_t command, uint8_t flag, } } -// When a player casts a tech, restore TP if infinite TP is enabled static void on_cast_technique_finished(shared_ptr c, uint8_t command, uint8_t flag, void* data, size_t size) { const auto& cmd = check_size_t(data, size); @@ -3080,7 +3093,7 @@ const SubcommandDefinition subcommand_definitions[0x100] = { /* 6x09 */ {0x09, 0x09, 0x09, nullptr}, /* 6x0A */ {0x0A, 0x0A, 0x0A, on_enemy_hit}, /* 6x0B */ {0x0B, 0x0B, 0x0B, on_forward_check_game}, - /* 6x0C */ {0x0C, 0x0C, 0x0C, on_forward_check_game}, + /* 6x0C */ {0x0C, 0x0C, 0x0C, on_received_condition}, /* 6x0D */ {0x00, 0x00, 0x0D, on_forward_check_game}, /* 6x0E */ {0x00, 0x00, 0x0E, nullptr}, /* 6x0F */ {0x00, 0x00, 0x0F, on_invalid}, diff --git a/src/SendCommands.cc b/src/SendCommands.cc index 528ad979..b9483963 100644 --- a/src/SendCommands.cc +++ b/src/SendCommands.cc @@ -2310,6 +2310,26 @@ void send_player_stats_change(Channel& ch, uint16_t client_id, PlayerStatsChange send_command_vt(ch, (subs.size() > 0x400 / sizeof(G_UpdatePlayerStat_6x9A)) ? 0x6C : 0x60, 0x00, subs); } +void send_remove_conditions(shared_ptr c) { + auto l = c->require_lobby(); + for (auto& lc : l->clients) { + if (lc) { + send_remove_conditions(lc->channel, c->lobby_client_id); + } + } +} + +void send_remove_conditions(Channel& ch, uint16_t client_id) { + parray cmds; + for (size_t z = 0; z < 4; z++) { + auto& cmd = cmds[z]; + cmd.header = {0x0D, sizeof(G_AddOrRemoveCondition_6x0C_6x0D) >> 2, client_id}; + cmd.unknown_a1 = z; + cmd.unknown_a2 = 0; + } + ch.send(0x60, 0x00, &cmds, sizeof(cmds)); +} + void send_warp(Channel& ch, uint8_t client_id, uint32_t floor, bool is_private) { G_InterLevelWarp_6x94 cmd = {{0x94, 0x02, 0}, floor, {}}; ch.send(is_private ? 0x62 : 0x60, client_id, &cmd, sizeof(cmd)); diff --git a/src/SendCommands.hh b/src/SendCommands.hh index 54f0e396..c36e3fe3 100644 --- a/src/SendCommands.hh +++ b/src/SendCommands.hh @@ -288,8 +288,9 @@ enum PlayerStatsChange { }; void send_player_stats_change(std::shared_ptr c, PlayerStatsChange stat, uint32_t amount); -void send_player_stats_change( - Channel& ch, uint16_t client_id, PlayerStatsChange stat, uint32_t amount); +void send_player_stats_change(Channel& ch, uint16_t client_id, PlayerStatsChange stat, uint32_t amount); +void send_remove_conditions(std::shared_ptr c); +void send_remove_conditions(Channel& ch, uint16_t client_id); void send_warp(Channel& ch, uint8_t client_id, uint32_t floor, bool is_private); void send_warp(std::shared_ptr c, uint32_t floor, bool is_private); void send_warp(std::shared_ptr l, uint32_t floor, bool is_private); diff --git a/tests/GC-ForestGame.test.txt b/tests/GC-ForestGame.test.txt index 67438ef4..d0a3b8aa 100644 --- a/tests/GC-ForestGame.test.txt +++ b/tests/GC-ForestGame.test.txt @@ -1218,6 +1218,11 @@ I 49108 2023-05-26 16:19:14 - [Commands] Sending to C-2 (Jess) (version=GC comma 0000 | B0 00 24 00 00 00 00 00 00 00 00 00 09 43 36 49 | $ C6I 0010 | 6E 66 69 6E 69 74 65 20 48 50 20 65 6E 61 62 6C | nfinite HP enabl 0020 | 65 64 00 00 | ed +I 49108 2023-05-26 16:19:14 - [Commands] Sending to C-2 (Jess) (version=GC command=B0 flag=00) +0000 | 60 00 34 00 0D 03 00 00 00 00 00 00 00 00 00 00 | ` 4 +0010 | 0D 03 00 00 01 00 00 00 00 00 00 00 0D 03 00 00 | +0020 | 02 00 00 00 00 00 00 00 0D 03 00 00 03 00 00 00 | +0030 | 00 00 00 00 | I 49108 2023-05-26 16:19:16 - [Commands] Received from C-2 (Jess) (version=GC command=06 flag=00) 0000 | 06 00 18 00 00 00 00 00 00 00 00 00 09 45 24 69 | E$i 0010 | 6E 66 74 70 00 00 00 00 | nftp