fix case where map selection is changed during setup
This commit is contained in:
+25
-33
@@ -34,6 +34,9 @@ Server::Server(shared_ptr<Lobby> lobby, Options&& options)
|
||||
last_chosen_map(this->options.tournament ? this->options.tournament->get_map() : nullptr),
|
||||
tournament_match_result_sent(false),
|
||||
override_environment_number(0xFF),
|
||||
def_dice_value_range_override(0xFF),
|
||||
atk_dice_value_range_2v1_override(0xFF),
|
||||
def_dice_value_range_2v1_override(0xFF),
|
||||
battle_finished(false),
|
||||
battle_in_progress(false),
|
||||
round_num(1),
|
||||
@@ -2146,26 +2149,35 @@ void Server::handle_CAx12_end_attack_list(shared_ptr<Client>, const string& data
|
||||
}
|
||||
|
||||
template <typename CmdT>
|
||||
void Server::handle_CAx13_update_map_during_setup_t(shared_ptr<Client>, const string& data) {
|
||||
void Server::handle_CAx13_update_map_during_setup_t(shared_ptr<Client> c, const string& data) {
|
||||
const auto& in_cmd = check_size_t<CmdT>(data);
|
||||
this->send_debug_command_received_message(
|
||||
in_cmd.header.subsubcommand, "UPDATE MAP");
|
||||
this->send_debug_command_received_message(in_cmd.header.subsubcommand, "UPDATE MAP");
|
||||
|
||||
if (!this->battle_in_progress &&
|
||||
(this->setup_phase == SetupPhase::REGISTRATION) &&
|
||||
(this->map_and_rules->num_players == 0) &&
|
||||
(this->registration_phase != RegistrationPhase::REGISTERED) &&
|
||||
(this->registration_phase != RegistrationPhase::BATTLE_STARTED)) {
|
||||
// newserv's extended rules are stored in unused parts of the Rules struct,
|
||||
// and clients will probably overwrite them with zeroes if we allow them to.
|
||||
// So, we preserve the extended rules manually here.
|
||||
uint8_t def_dice_value_range = this->map_and_rules->rules.def_dice_value_range;
|
||||
uint8_t atk_dice_value_range_2v1 = this->map_and_rules->rules.atk_dice_value_range_2v1;
|
||||
uint8_t def_dice_value_range_2v1 = this->map_and_rules->rules.def_dice_value_range_2v1;
|
||||
if (!this->last_chosen_map) {
|
||||
throw runtime_error("CAx13 sent with no map chosen");
|
||||
}
|
||||
|
||||
*this->map_and_rules = in_cmd.map_and_rules_state;
|
||||
this->map_and_rules->rules.def_dice_value_range = def_dice_value_range;
|
||||
this->map_and_rules->rules.atk_dice_value_range_2v1 = atk_dice_value_range_2v1;
|
||||
this->map_and_rules->rules.def_dice_value_range_2v1 = def_dice_value_range_2v1;
|
||||
// The client will likely send incorrect values for the extended rules (or
|
||||
// in the case of NTE, no values at all, since the Rules structure is
|
||||
// smaller). So, use the values from the last chosen map if applicable, or
|
||||
// the values from the $dicerange command if available.
|
||||
const auto& map_rules = this->last_chosen_map->version(c->language())->map->default_rules;
|
||||
auto& server_rules = this->map_and_rules->rules;
|
||||
server_rules.def_dice_value_range = (map_rules.def_dice_value_range == 0xFF)
|
||||
? ((this->def_dice_value_range_override == 0xFF) ? 0 : this->def_dice_value_range_override)
|
||||
: map_rules.def_dice_value_range;
|
||||
server_rules.atk_dice_value_range_2v1 = (map_rules.atk_dice_value_range_2v1 == 0xFF)
|
||||
? ((this->atk_dice_value_range_2v1_override == 0xFF) ? 0 : this->atk_dice_value_range_2v1_override)
|
||||
: map_rules.atk_dice_value_range_2v1;
|
||||
server_rules.def_dice_value_range_2v1 = (map_rules.def_dice_value_range_2v1 == 0xFF)
|
||||
? ((this->def_dice_value_range_2v1_override == 0xFF) ? 0 : this->def_dice_value_range_2v1_override)
|
||||
: map_rules.def_dice_value_range_2v1;
|
||||
|
||||
// If this match is part of a tournament, ignore the rules sent by the
|
||||
// client and use the tournament rules instead.
|
||||
@@ -2603,30 +2615,10 @@ void Server::send_6xB6x41_to_all_clients() const {
|
||||
}
|
||||
}
|
||||
|
||||
void Server::handle_CAx41_map_request(shared_ptr<Client> c, const string& data) {
|
||||
void Server::handle_CAx41_map_request(shared_ptr<Client>, const string& data) {
|
||||
const auto& cmd = check_size_t<G_MapDataRequest_Ep3_CAx41>(data);
|
||||
this->send_debug_command_received_message(cmd.header.subsubcommand, "MAP DATA");
|
||||
|
||||
this->last_chosen_map = this->options.map_index->for_number(cmd.map_number);
|
||||
|
||||
// We don't trust the extended rules fields from the client, and the client
|
||||
// can't modify it anyway, so we always apply the map's extended rules here.
|
||||
// This allows map creators to use newserv's extended rules in quests.
|
||||
if (this->setup_phase == SetupPhase::REGISTRATION) {
|
||||
auto mv = this->last_chosen_map->version(c->language());
|
||||
const auto& map_rules = mv->map->default_rules;
|
||||
auto& server_rules = this->map_and_rules->rules;
|
||||
if (map_rules.def_dice_value_range != 0xFF) {
|
||||
server_rules.def_dice_value_range = map_rules.def_dice_value_range;
|
||||
}
|
||||
if (map_rules.atk_dice_value_range_2v1 != 0xFF) {
|
||||
server_rules.atk_dice_value_range_2v1 = map_rules.atk_dice_value_range_2v1;
|
||||
}
|
||||
if (map_rules.def_dice_value_range_2v1 != 0xFF) {
|
||||
server_rules.def_dice_value_range_2v1 = map_rules.def_dice_value_range_2v1;
|
||||
}
|
||||
}
|
||||
|
||||
this->send_6xB6x41_to_all_clients();
|
||||
}
|
||||
|
||||
|
||||
@@ -278,6 +278,9 @@ public:
|
||||
std::shared_ptr<const MapIndex::Map> last_chosen_map;
|
||||
bool tournament_match_result_sent;
|
||||
uint8_t override_environment_number;
|
||||
uint8_t def_dice_value_range_override;
|
||||
uint8_t atk_dice_value_range_2v1_override;
|
||||
uint8_t def_dice_value_range_2v1_override;
|
||||
mutable std::deque<StackLogger*> logger_stack;
|
||||
|
||||
// These fields were originally contained in the TCardServerBase object
|
||||
|
||||
Reference in New Issue
Block a user