45 #define DBG_REPLAY LOG_STREAM(debug, log_replay) 46 #define LOG_REPLAY LOG_STREAM(info, log_replay) 47 #define WRN_REPLAY LOG_STREAM(warn, log_replay) 48 #define ERR_REPLAY LOG_STREAM(err, log_replay) 56 DBG_REPLAY <<
"run_in_synced_context:" << commandname;
66 error_handler(
"commandname [" + commandname +
"] not found");
68 bool success = it->second(data, use_undo, show, error_handler);
90 ERR_REPLAY <<
"ignored attempt to invoke a synced command during replay";
96 bool success =
run(commandname, data, use_undo, show, error_handler);
110 bool success =
run_and_store(commandname, data, use_undo, show, error_handler);
126 return run_and_throw(commandname, data, use_undo, show, error_handler);
129 ERR_REPLAY <<
"trying to execute action while being in a local_choice";
137 error_handler(
"commandname [" + commandname +
"] not found");
140 return it->second(data,
false, show, error_handler);
144 assert(
false &&
"found unknown synced_context::synced_state");
151 ERR_REPLAY <<
"Unexpected Error during synced execution" << message;
152 assert(!
"Unexpected Error during synced execution, more info in stderr.");
157 ERR_REPLAY <<
"Error during synced execution: " << message;
162 DBG_REPLAY <<
"Ignored during synced execution: " << message;
171 virtual config local_choice()
const override 177 virtual config request()
const override 182 virtual const char* name()
const override 184 return "random_seed";
194 return seed_val.
str();
232 if(mode ==
"deterministic" || mode ==
"biased") {
242 "request_choice",
config {
253 <<
"' choice in a unsynced context, doing the choice locally. This can cause OOS.";
260 bool did_require =
false;
272 if(is_replay_end && !is_mp_game) {
274 DBG_REPLAY <<
"MP synchronization: local server choice";
282 }
else if(is_replay_end && is_mp_game) {
283 DBG_REPLAY <<
"MP synchronization: remote server choice";
301 }
else if(!is_replay_end) {
303 DBG_REPLAY <<
"MP synchronization: replay server choice";
315 + action->
debug() +
"\n");
321 if((*action)[
"from_side"].str() !=
"server" || (*action)[
"side_invalid"].to_bool(
false)) {
341 LOG_REPLAY <<
"set_scontext_synced_base::set_scontext_synced_base";
357 LOG_REPLAY <<
"set_scontext_synced_base:: destructor";
365 , new_checkup_(generate_checkup(
"checkup"))
393 LOG_REPLAY <<
"set_scontext_synced::set_scontext_synced";
402 std::stringstream
msg;
405 "random_calls",
new_rng_->get_random_calls(),
413 if(co[
"random_calls"].empty()) {
414 msg <<
"cannot find random_calls check in replay" << std::endl;
415 }
else if(co[
"random_calls"] != cn[
"random_calls"]) {
416 msg <<
"We called random " <<
new_rng_->get_random_calls() <<
" times, but the original game called random " 417 << co[
"random_calls"].to_int() <<
" times." << std::endl;
421 if(!co[
"next_unit_id"].empty() && co[
"next_unit_id"] != cn[
"next_unit_id"]) {
422 msg <<
"Our next unit id is " << cn[
"next_unit_id"].to_int() <<
" but during the original the next unit id was " 423 << co[
"next_unit_id"].to_int() << std::endl;
426 if(!msg.str().empty()) {
427 msg << co.
debug() << std::endl;
440 LOG_REPLAY <<
"set_scontext_synced:: destructor";
450 return new_rng_->get_random_calls();
static lg::log_domain log_replay("replay")
void clear()
Clears the stack of undoable (and redoable) actions.
play_controller * controller
static void add_undo_commands(const config &commands, const game_events::queued_event &ctx)
static synced_state get_synced_state()
config & child(config_key_type key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
static bool run_and_store(const std::string &commandname, const config &data, bool use_undo=true, bool show=true, synced_command::error_handler_function error_handler=default_error_function)
std::size_t get_save_id() const
Used for saving id to savegame.
game_classification * classification
void do_final_checkup(bool dont_throw=false)
Variant for storing WML attributes.
static bool run(const std::string &commandname, const config &data, bool use_undo=true, bool show=true, synced_command::error_handler_function error_handler=default_error_function)
Sets the context to 'synced', initialises random context, and calls the given function.
static void set_synced_state(synced_state newstate)
Should only be called form set_scontext_synced, set_scontext_local_choice.
static map & registry()
using static function variable instead of static member variable to prevent static initialization fia...
bool has_child(config_key_type key) const
Determine whether a config has a child or not.
const randomness::mt_rng & rng() const
static std::string generate_random_seed()
Generates a new seed for a synced event, by asking the 'server'.
static void set_is_simultaneous()
Sets is_simultaneous_ = true, called using a user choice that is not the currently playing side...
static event_list undo_commands_
Actions wml to be executed when the current action is undone.
static bool is_simultaneous_
As soon as get_user_choice is used with side != current_side (for example in generate_random_seed) ot...
virtual config local_choice() const =0
We are in a game with no mp server and need to do this choice locally.
A RAII object to enter the synced context, cannot be called if we are already in a synced context...
randomness::rng * old_rng_
virtual void play_slice(bool is_delay_enabled=true)
static void pull_remote_choice()
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
void check_victory()
Checks to see if a side has won.
Contains the exception interfaces used to signal completion of a scenario, campaign or turn...
Definitions for the interface to Wesnoth Markup Language (WML).
void add_synced_command(const std::string &name, const config &command)
int get_server_request_number() const
static void just_log_error_function(const std::string &message)
A function to be passed to run_in_synced_context to log the error.
std::shared_ptr< randomness::rng > new_rng_
unsigned int get_random_calls() const
Provides the number of random calls to the rng in this context.
virtual const char * name() const =0
static void reset_undo_commands()
void user_input(const std::string &name, const config &input, int from_side)
adds a user_input to the replay
std::string next_seed_str()
checkup * checkup_instance
events::command_disabler disabler_
This checkup compares whether the results calculated during the original game match the ones calculat...
std::function< void(const std::string &)> error_handler_function
static void send_user_choice()
called from get_user_choice to send a recently made choice to the other clients.
static void pull_remote_user_input()
called from get_user_choice while waiting for a remove user choice.
static int last_unit_id_
Used to restore the unit id manager when undoing.
std::shared_ptr< wb::manager > whiteboard
static void process_error(const std::string &msg)
static checkup * generate_checkup(const std::string &tagname)
A class to check whether the results that were calculated in the replay match the results calculated ...
virtual bool is_networked_mp() const
static int get_unit_id_diff()
randomness::rng * old_rng_
static void send_user_choice()
static void set_last_unit_id(int id)
void send_request() const
static void ignore_error_function(const std::string &message)
A function to be passed to run_in_synced_context to ignore the error.
rng * generator
This generator is automatically synced during synced context.
static void default_error_function(const std::string &message)
A function to be passed to run_in_synced_context to assert false on error (the default).
set_scontext_synced_base()
const std::unique_ptr< checkup > new_checkup_
static bool run_and_throw(const std::string &commandname, const config &data, bool use_undo=true, bool show=true, synced_command::error_handler_function error_handler=default_error_function)
n_unit::id_manager & unit_id_manager()
static void reset_is_simultaneous()
Sets is_simultaneous_ = false, called when entering the synced context.
static bool run_in_synced_context_if_not_already(const std::string &commandname, const config &data, bool use_undo=true, bool show=true, synced_command::error_handler_function error_handler=default_error_function)
Checks whether we are currently running in a synced context, and if not we enters it...
void maybe_throw_return_to_play_side() const
Various functions that implement the undoing (and redoing) of in-game commands.
Standard logging facilities (interface).
config * get_next_action()
static std::shared_ptr< randomness::rng > get_rng_for_action()
A RAII object to temporary leave the synced context like in wesnoth.synchronize_choice.
~set_scontext_synced_base()
actions::undo_list * undo_stack
virtual bool local_checkup(const config &expected_data, config &real_data)=0
Compares data to the results calculated during the original game.
A config object defines a single node in a WML file, with access to child nodes.
REPLAY_RETURN do_replay_handle(bool one_move)
static rng & default_instance()
std::string::const_iterator iterator
This checkup always compares the results in from different clients in a mp game but it also causes mo...
virtual void send_to_wesnothd(const config &, const std::string &="unknown") const
std::string debug() const
static config ask_server_choice(const server_choice &)
If we are in a mp game, ask the server, otherwise generate the answer ourselves.
std::string str(const std::string &fallback="") const
void show(const std::string &window_id, const t_string &message, const point &mouse, const SDL_Rect &source_rect)
Shows a tip.
void increase_server_request_number()