enforce min level limits when cheat mode is disabled

This commit is contained in:
Martin Michelsen
2024-01-04 17:31:41 -08:00
parent e50d7a4e65
commit b7257a793f
4 changed files with 47 additions and 26 deletions
+21 -1
View File
@@ -698,6 +698,14 @@ static void server_command_cheat(shared_ptr<Client> c, const std::string&) {
} else {
l->toggle_flag(Lobby::Flag::CHEATS_ENABLED);
send_text_message_printf(l, "Cheat mode %s", l->check_flag(Lobby::Flag::CHEATS_ENABLED) ? "enabled" : "disabled");
if (!(c->license->flags & License::Flag::CHEAT_ANYWHERE)) {
size_t default_min_level = s->default_min_level_for_game(l->base_version, l->episode, l->difficulty);
if (l->min_level < default_min_level) {
l->min_level = default_min_level;
send_text_message_printf(l, "$C6Minimum level set\nto %" PRIu32, l->min_level + 1);
}
}
}
}
@@ -985,7 +993,19 @@ static void server_command_min_level(shared_ptr<Client> c, const std::string& ar
check_is_game(l, true);
check_is_leader(l, c);
l->min_level = stoull(args) - 1;
size_t new_min_level = stoull(args) - 1;
auto s = c->require_server_state();
bool cheats_allowed = (l->check_flag(Lobby::Flag::CHEATS_ENABLED) || (c->license->flags & License::Flag::CHEAT_ANYWHERE));
if (!cheats_allowed) {
size_t default_min_level = s->default_min_level_for_game(l->base_version, l->episode, l->difficulty);
if (new_min_level < default_min_level) {
send_text_message_printf(c, "$C6Cannot set minimum\nlevel below %zu", default_min_level + 1);
return;
}
}
l->min_level = new_min_level;
send_text_message_printf(l, "$C6Minimum level set\nto %" PRIu32, l->min_level + 1);
}
+1 -25
View File
@@ -3966,31 +3966,7 @@ shared_ptr<Lobby> create_game_generic(
auto current_lobby = c->require_lobby();
size_t min_level;
// A player's actual level is their displayed level - 1, so the minimums for
// Episode 1 (for example) are actually 1, 20, 40, 80.
switch (episode) {
case Episode::EP1: {
const auto& min_levels = (c->version() == Version::BB_V4) ? s->min_levels_v4[0] : DEFAULT_MIN_LEVELS_V3;
min_level = min_levels[difficulty];
break;
}
case Episode::EP2: {
const auto& min_levels = (c->version() == Version::BB_V4) ? s->min_levels_v4[1] : DEFAULT_MIN_LEVELS_V3;
min_level = min_levels[difficulty];
break;
}
case Episode::EP3:
min_level = 0;
break;
case Episode::EP4: {
const auto& min_levels = (c->version() == Version::BB_V4) ? s->min_levels_v4[2] : DEFAULT_MIN_LEVELS_V3;
min_level = min_levels[difficulty];
break;
}
default:
throw runtime_error("invalid episode");
}
size_t min_level = s->default_min_level_for_game(c->version(), episode, difficulty);
auto p = c->character();
if (!(c->license->flags & License::Flag::FREE_JOIN_GAMES) &&
+23
View File
@@ -342,6 +342,29 @@ shared_ptr<const QuestIndex> ServerState::quest_index(Version version) const {
return is_ep3(version) ? this->ep3_download_quest_index : this->default_quest_index;
}
size_t ServerState::default_min_level_for_game(Version version, Episode episode, uint8_t difficulty) const {
// A player's actual level is their displayed level - 1, so the minimums for
// Episode 1 (for example) are actually 1, 20, 40, 80.
switch (episode) {
case Episode::EP1: {
const auto& min_levels = (version == Version::BB_V4) ? this->min_levels_v4[0] : DEFAULT_MIN_LEVELS_V3;
return min_levels.at(difficulty);
}
case Episode::EP2: {
const auto& min_levels = (version == Version::BB_V4) ? this->min_levels_v4[1] : DEFAULT_MIN_LEVELS_V3;
return min_levels.at(difficulty);
}
case Episode::EP3:
return 0;
case Episode::EP4: {
const auto& min_levels = (version == Version::BB_V4) ? this->min_levels_v4[2] : DEFAULT_MIN_LEVELS_V3;
return min_levels.at(difficulty);
}
default:
throw runtime_error("invalid episode");
}
}
void ServerState::dispatch_destroy_lobbies(evutil_socket_t, short, void* ctx) {
reinterpret_cast<ServerState*>(ctx)->lobbies_to_destroy.clear();
}
+2
View File
@@ -282,6 +282,8 @@ struct ServerState : public std::enable_shared_from_this<ServerState> {
std::shared_ptr<const std::vector<std::string>> information_contents_for_client(std::shared_ptr<const Client> c) const;
std::shared_ptr<const QuestIndex> quest_index(Version version) const;
size_t default_min_level_for_game(Version version, Episode episode, uint8_t difficulty) const;
void set_port_configuration(const std::vector<PortConfiguration>& port_configs);
std::shared_ptr<const std::string> load_bb_file(