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),
|
last_chosen_map(this->options.tournament ? this->options.tournament->get_map() : nullptr),
|
||||||
tournament_match_result_sent(false),
|
tournament_match_result_sent(false),
|
||||||
override_environment_number(0xFF),
|
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_finished(false),
|
||||||
battle_in_progress(false),
|
battle_in_progress(false),
|
||||||
round_num(1),
|
round_num(1),
|
||||||
@@ -2146,26 +2149,35 @@ void Server::handle_CAx12_end_attack_list(shared_ptr<Client>, const string& data
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename CmdT>
|
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);
|
const auto& in_cmd = check_size_t<CmdT>(data);
|
||||||
this->send_debug_command_received_message(
|
this->send_debug_command_received_message(in_cmd.header.subsubcommand, "UPDATE MAP");
|
||||||
in_cmd.header.subsubcommand, "UPDATE MAP");
|
|
||||||
|
|
||||||
if (!this->battle_in_progress &&
|
if (!this->battle_in_progress &&
|
||||||
(this->setup_phase == SetupPhase::REGISTRATION) &&
|
(this->setup_phase == SetupPhase::REGISTRATION) &&
|
||||||
(this->map_and_rules->num_players == 0) &&
|
(this->map_and_rules->num_players == 0) &&
|
||||||
(this->registration_phase != RegistrationPhase::REGISTERED) &&
|
(this->registration_phase != RegistrationPhase::REGISTERED) &&
|
||||||
(this->registration_phase != RegistrationPhase::BATTLE_STARTED)) {
|
(this->registration_phase != RegistrationPhase::BATTLE_STARTED)) {
|
||||||
// newserv's extended rules are stored in unused parts of the Rules struct,
|
if (!this->last_chosen_map) {
|
||||||
// and clients will probably overwrite them with zeroes if we allow them to.
|
throw runtime_error("CAx13 sent with no map chosen");
|
||||||
// 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;
|
|
||||||
*this->map_and_rules = in_cmd.map_and_rules_state;
|
*this->map_and_rules = in_cmd.map_and_rules_state;
|
||||||
this->map_and_rules->rules.def_dice_value_range = def_dice_value_range;
|
// The client will likely send incorrect values for the extended rules (or
|
||||||
this->map_and_rules->rules.atk_dice_value_range_2v1 = atk_dice_value_range_2v1;
|
// in the case of NTE, no values at all, since the Rules structure is
|
||||||
this->map_and_rules->rules.def_dice_value_range_2v1 = def_dice_value_range_2v1;
|
// 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
|
// If this match is part of a tournament, ignore the rules sent by the
|
||||||
// client and use the tournament rules instead.
|
// 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);
|
const auto& cmd = check_size_t<G_MapDataRequest_Ep3_CAx41>(data);
|
||||||
this->send_debug_command_received_message(cmd.header.subsubcommand, "MAP 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);
|
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();
|
this->send_6xB6x41_to_all_clients();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -278,6 +278,9 @@ public:
|
|||||||
std::shared_ptr<const MapIndex::Map> last_chosen_map;
|
std::shared_ptr<const MapIndex::Map> last_chosen_map;
|
||||||
bool tournament_match_result_sent;
|
bool tournament_match_result_sent;
|
||||||
uint8_t override_environment_number;
|
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;
|
mutable std::deque<StackLogger*> logger_stack;
|
||||||
|
|
||||||
// These fields were originally contained in the TCardServerBase object
|
// These fields were originally contained in the TCardServerBase object
|
||||||
|
|||||||
Reference in New Issue
Block a user