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);
98 ERR_REPLAY <<
"ignored attempt to invoke a synced command during replay";
104 bool success =
run(commandname,
data, use_undo,
show, error_handler);
137 ERR_REPLAY <<
"trying to execute action while being in a local_choice";
145 error_handler(
"commandname [" + commandname +
"] not found");
148 return it->second(
data,
false,
show, error_handler);
152 assert(
false &&
"found unknown synced_context::synced_state");
159 ERR_REPLAY <<
"Unexpected Error during synced execution" << message;
160 assert(!
"Unexpected Error during synced execution, more info in stderr.");
165 ERR_REPLAY <<
"Error during synced execution: " << message;
170 DBG_REPLAY <<
"Ignored during synced execution: " << message;
190 virtual const char*
name()
const override
192 return "random_seed";
202 return seed_val.
str();
247 if(mode ==
"deterministic" || mode ==
"biased") {
262 "request_choice",
config {
263 "request_id", request_id(),
273 <<
"' choice in a unsynced context, doing the choice locally. This can cause OOS.";
280 bool did_require =
false;
292 if(is_replay_end && !is_mp_game) {
294 DBG_REPLAY <<
"MP synchronization: local server choice";
302 }
else if(is_replay_end && is_mp_game) {
303 DBG_REPLAY <<
"MP synchronization: remote server choice";
321 }
else if(!is_replay_end) {
323 DBG_REPLAY <<
"MP synchronization: replay server choice";
335 + action->
debug() +
"\n");
341 if((*action)[
"from_side"].str() !=
"server" || (*action)[
"side_invalid"].to_bool(
false)) {
349 WRN_REPLAY <<
"Unexpected request_id: " << res[
"request_id"] <<
" expected: " << sch.
request_id();
375 LOG_REPLAY <<
"set_scontext_synced_base::set_scontext_synced_base";
391 LOG_REPLAY <<
"set_scontext_synced_base:: destructor";
399 , new_checkup_(generate_checkup(
"checkup"))
407 , new_checkup_(generate_checkup(
"checkup" + std::to_string(number)))
427 LOG_REPLAY <<
"set_scontext_synced::set_scontext_synced";
436 std::stringstream
msg;
439 "random_calls",
new_rng_->get_random_calls(),
447 if(co[
"random_calls"].empty()) {
448 msg <<
"cannot find random_calls check in replay" << std::endl;
449 }
else if(co[
"random_calls"] != cn[
"random_calls"]) {
450 msg <<
"We called random " <<
new_rng_->get_random_calls() <<
" times, but the original game called random "
451 << co[
"random_calls"].to_int() <<
" times." << std::endl;
455 if(!co[
"next_unit_id"].empty() && co[
"next_unit_id"] != cn[
"next_unit_id"]) {
456 msg <<
"Our next unit id is " << cn[
"next_unit_id"].to_int() <<
" but during the original the next unit id was "
457 << co[
"next_unit_id"].to_int() << std::endl;
460 if(!
msg.str().empty()) {
474 LOG_REPLAY <<
"set_scontext_synced:: destructor";
484 return new_rng_->get_random_calls();
void clear()
Clears the stack of undoable (and redoable) actions.
A class to check whether the results that were calculated in the replay match the results calculated ...
virtual bool local_checkup(const config &expected_data, config &real_data)=0
Compares data to the results calculated during the original game.
Variant for storing WML attributes.
std::string str(const std::string &fallback="") const
A config object defines a single node in a WML file, with access to child nodes.
config & mandatory_child(config_key_type key, int n=0)
Returns the nth child with the given key, or throws an error if there is none.
bool has_child(config_key_type key) const
Determine whether a config has a child or not.
std::string debug() const
virtual void play_slice(bool is_delay_enabled=true)
n_unit::id_manager & unit_id_manager()
bool end_turn_forced() const
A RAII object to temporary leave the synced context like in wesnoth.synchronize_choice.
randomness::rng * old_rng_
This checkup always compares the results in from different clients in a mp game but it also causes mo...
std::size_t get_save_id() const
Used for saving id to savegame.
void maybe_throw_return_to_play_side() const
int get_server_request_number() const
void check_victory()
Checks to see if a side has won.
void increase_server_request_number()
virtual void send_to_wesnothd(const config &, const std::string &="unknown") const
virtual bool is_networked_mp() const
unsigned int get_random_calls() const
Provides the number of random calls to the rng in this context.
static rng & default_instance()
void add_synced_command(const std::string &name, const config &command)
void user_input(const std::string &name, const config &input, int from_side)
adds a user_input to the replay
static void process_error(const std::string &msg)
config * get_next_action()
std::shared_ptr< randomness::rng > new_rng_
~set_scontext_synced_base()
randomness::rng * old_rng_
set_scontext_synced_base()
A RAII object to enter the synced context, cannot be called if we are already in a synced context.
void do_final_checkup(bool dont_throw=false)
static checkup * generate_checkup(const std::string &tagname)
const std::unique_ptr< checkup > new_checkup_
This checkup compares whether the results calculated during the original game match the ones calculat...
static map & registry()
using static function variable instead of static member variable to prevent static initialization fia...
std::function< void(const std::string &)> error_handler_function
virtual config request() const =0
The request which is sent to the mp server.
void send_request() const
virtual const char * name() const =0
virtual config local_choice() const =0
We are in a game with no mp server and need to do this choice locally.
static void set_last_unit_id(int id)
static bool undo_blocked()
static std::shared_ptr< randomness::rng > get_rng_for_action()
static config ask_server_choice(const server_choice &)
If we are in a mp game, ask the server, otherwise generate the answer ourselves.
static void reset_is_simultaneous()
Sets is_simultaneous_ = false, called when entering the synced context.
static void add_undo_commands(const config &commands, const game_events::queued_event &ctx)
static event_list undo_commands_
Actions to be executed when the current action is undone.
static void reset_undo_commands()
static void ignore_error_function(const std::string &message)
A function to be passed to run_in_synced_context to ignore the error.
static std::string generate_random_seed()
Generates a new seed for a synced event, by asking the 'server'.
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)
static int get_unit_id_diff()
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).
static void just_log_error_function(const std::string &message)
A function to be passed to run_in_synced_context to log the error.
static synced_state get_synced_state()
static void pull_remote_user_input()
called from get_user_choice while waiting for a remove user choice.
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 bool is_simultaneous_
As soon as get_user_choice is used with side != current_side (for example in generate_random_seed) ot...
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)
static bool is_unsynced()
static int last_unit_id_
Used to restore the unit id manager when undoing.
static void set_synced_state(synced_state newstate)
Should only be called form set_scontext_synced, set_scontext_local_choice.
static void send_user_choice()
called from get_user_choice to send a recently made choice to the other clients.
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.
static void set_is_simultaneous()
Sets is_simultaneous_ = true, called using a user choice that is not the currently playing side.
static void send_user_choice()
static void pull_remote_choice()
Contains the exception interfaces used to signal completion of a scenario, campaign or turn.
Standard logging facilities (interface).
void show(const std::string &window_id, const t_string &message, const point &mouse, const SDL_Rect &source_rect)
Shows a tip.
rng * generator
This generator is automatically synced during synced context.
actions::undo_list * undo_stack
game_classification * classification
play_controller * controller
std::shared_ptr< wb::manager > whiteboard
std::string next_seed_str()
std::string::const_iterator iterator
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
REPLAY_RETURN do_replay_handle(bool one_move)
checkup * checkup_instance
static lg::log_domain log_replay("replay")
Various functions that implement the undoing (and redoing) of in-game commands.