add oos debug mode and mp_debug_checkup class
The game sometimes does some checkup to test whether the calculated results in a replay match the ones calculated during the original game. This data was stored in the replay inside the [command] for that action. The problem is that this doesn't work in networked mp because we often send the [command] before calculating the results. I added an alternative mode that used get_user_choice to compare the results, this also works in networked mp but it causes a little more network traffic.
This commit is contained in:
parent
5067ecf932
commit
dbb75bdd47
6 changed files with 83 additions and 44 deletions
|
@ -44,7 +44,8 @@ game_classification::game_classification():
|
|||
end_text(),
|
||||
end_text_duration(),
|
||||
difficulty(DEFAULT_DIFFICULTY),
|
||||
random_mode("")
|
||||
random_mode(""),
|
||||
oos_debug(false)
|
||||
{}
|
||||
|
||||
game_classification::game_classification(const config& cfg):
|
||||
|
@ -64,7 +65,8 @@ game_classification::game_classification(const config& cfg):
|
|||
end_text(cfg["end_text"]),
|
||||
end_text_duration(cfg["end_text_duration"]),
|
||||
difficulty(cfg["difficulty"].empty() ? DEFAULT_DIFFICULTY : cfg["difficulty"].str()),
|
||||
random_mode(cfg["random_mode"])
|
||||
random_mode(cfg["random_mode"]),
|
||||
oos_debug(cfg["oos_debug"].to_bool(false))
|
||||
{}
|
||||
|
||||
game_classification::game_classification(const game_classification& gc):
|
||||
|
@ -84,7 +86,8 @@ game_classification::game_classification(const game_classification& gc):
|
|||
end_text(gc.end_text),
|
||||
end_text_duration(gc.end_text_duration),
|
||||
difficulty(gc.difficulty),
|
||||
random_mode(gc.random_mode)
|
||||
random_mode(gc.random_mode),
|
||||
oos_debug(gc.oos_debug)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -108,6 +111,6 @@ config game_classification::to_config() const
|
|||
cfg["end_text_duration"] = str_cast<unsigned int>(end_text_duration);
|
||||
cfg["difficulty"] = difficulty;
|
||||
cfg["random_mode"] = random_mode;
|
||||
|
||||
cfg["oos_debug"] = oos_debug;
|
||||
return cfg;
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@ public:
|
|||
unsigned int end_text_duration; /**< for how long the end-of-campaign text is shown */
|
||||
std::string difficulty; /**< The difficulty level the game is being played on. */
|
||||
std::string random_mode;
|
||||
bool oos_debug;
|
||||
};
|
||||
MAKE_ENUM_STREAM_OPS2(game_classification, CAMPAIGN_TYPE)
|
||||
|
||||
|
|
|
@ -11,11 +11,13 @@
|
|||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
#include "global.hpp"
|
||||
#include "synced_checkup.hpp"
|
||||
#include "log.hpp"
|
||||
#include "map_location.hpp"
|
||||
#include "unit_map.hpp"
|
||||
#include "unit.hpp"
|
||||
#include "replay.hpp"
|
||||
#include "resources.hpp"
|
||||
#include "game_display.hpp"
|
||||
static lg::log_domain log_replay("replay");
|
||||
|
@ -52,15 +54,6 @@ bool ignored_checkup::local_checkup(const config& /*expected_data*/, config& rea
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ignored_checkup::networked_checkup(const config& /*expected_data*/, config& real_data)
|
||||
{
|
||||
assert(real_data.empty());
|
||||
|
||||
LOG_REPLAY << "ignored_checkup::networked_checkup called\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
synced_checkup::synced_checkup(config& buffer)
|
||||
: buffer_(buffer), pos_(0)
|
||||
{
|
||||
|
@ -89,9 +82,44 @@ bool synced_checkup::local_checkup(const config& expected_data, config& real_dat
|
|||
}
|
||||
}
|
||||
|
||||
bool synced_checkup::networked_checkup(const config& /*expected_data*/, config& real_data)
|
||||
|
||||
namespace
|
||||
{
|
||||
struct checkup_choice : public mp_sync::user_choice
|
||||
{
|
||||
checkup_choice(const config& cfg) : cfg_(cfg)
|
||||
{
|
||||
}
|
||||
virtual ~checkup_choice()
|
||||
{
|
||||
}
|
||||
virtual config random_choice(int /*side*/) const OVERRIDE
|
||||
{
|
||||
throw "not implemented";
|
||||
}
|
||||
virtual bool is_visible() const OVERRIDE
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual config query_user(int /*side*/) const OVERRIDE
|
||||
{
|
||||
return cfg_;
|
||||
}
|
||||
const config& cfg_;
|
||||
};
|
||||
}
|
||||
|
||||
mp_debug_checkup::mp_debug_checkup()
|
||||
{
|
||||
}
|
||||
|
||||
mp_debug_checkup::~mp_debug_checkup()
|
||||
{
|
||||
}
|
||||
|
||||
bool mp_debug_checkup::local_checkup(const config& expected_data, config& real_data)
|
||||
{
|
||||
assert(real_data.empty());
|
||||
throw "not implemented";
|
||||
//TODO: something with get_user_choice :).
|
||||
real_data = get_user_choice("mp_checkup", checkup_choice(expected_data));
|
||||
return real_data == expected_data;
|
||||
}
|
||||
|
|
|
@ -34,37 +34,24 @@ public:
|
|||
returns whether the two config objects are equal.
|
||||
*/
|
||||
virtual bool local_checkup(const config& expected_data, config& real_data) = 0;
|
||||
/**
|
||||
compares data on all clients in a networked game, the disadvantage is,
|
||||
that the clients have to communicate more which might be not wanted if some persons have laggy inet.
|
||||
returns whether the two config objects are equal.
|
||||
|
||||
This is currently not used.
|
||||
This is currently not implemented.
|
||||
|
||||
TODO: we might want to change the design to have a 'local_checkup' subclass (the normal case)
|
||||
and a 'networked_checkup' subclass (for network OOS debugging) of the checkup class that then replace
|
||||
the synced_checkup class. Instead of having 2 different methods local_checkup,networked_checkup.
|
||||
*/
|
||||
virtual bool networked_checkup(const config& expected_data, config& real_data) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
This checkup compares whether the results calculated during the original game match the ones calculated during replay.
|
||||
Whether this checkup also compares the calculated results of different clients in a a mp game depends on whether
|
||||
there was already data sended about the current synced command.
|
||||
*/
|
||||
class synced_checkup : public checkup
|
||||
{
|
||||
public:
|
||||
synced_checkup(config& buffer);
|
||||
virtual ~synced_checkup();
|
||||
virtual bool local_checkup(const config& expected_data, config& real_data);
|
||||
virtual bool networked_checkup(const config& expected_data, config& real_data);
|
||||
private:
|
||||
config& buffer_;
|
||||
unsigned int pos_;
|
||||
};
|
||||
|
||||
/*
|
||||
the only purpose of these function isto thro OOS erros, because they should never be called.
|
||||
*/
|
||||
|
||||
class ignored_checkup : public checkup
|
||||
{
|
||||
public:
|
||||
|
@ -74,10 +61,16 @@ public:
|
|||
always returns true
|
||||
*/
|
||||
virtual bool local_checkup(const config& expected_data, config& real_data);
|
||||
/**
|
||||
always returns true
|
||||
*/
|
||||
virtual bool networked_checkup(const config& expected_data, config& real_data);
|
||||
};
|
||||
/**
|
||||
This checkup always compares the results in from different clients in a mp game but it also causes more network overhead.
|
||||
*/
|
||||
class mp_debug_checkup : public checkup
|
||||
{
|
||||
public:
|
||||
mp_debug_checkup();
|
||||
virtual ~mp_debug_checkup();
|
||||
virtual bool local_checkup(const config& expected_data, config& real_data);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -339,17 +339,29 @@ config synced_context::ask_server_for_seed()
|
|||
}
|
||||
|
||||
set_scontext_synced::set_scontext_synced()
|
||||
: new_rng_(synced_context::get_rng_for_action()), new_checkup_(recorder.get_last_real_command().child_or_add("checkup")), disabler_()
|
||||
: new_rng_(synced_context::get_rng_for_action()), new_checkup_(generate_checkup("checkup")), disabler_()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
set_scontext_synced::set_scontext_synced(int number)
|
||||
: new_rng_(synced_context::get_rng_for_action()), new_checkup_(recorder.get_last_real_command().child_or_add("checkup" + boost::lexical_cast<std::string>(number))), disabler_()
|
||||
: new_rng_(synced_context::get_rng_for_action()), new_checkup_(generate_checkup("checkup" + boost::lexical_cast<std::string>(number))), disabler_()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
checkup* set_scontext_synced::generate_checkup(const std::string& tagname)
|
||||
{
|
||||
if(resources::classification->oos_debug)
|
||||
{
|
||||
return new mp_debug_checkup();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new synced_checkup(recorder.get_last_real_command().child_or_add(tagname));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
so we dont have to write the same code 3 times.
|
||||
*/
|
||||
|
@ -362,7 +374,7 @@ void set_scontext_synced::init()
|
|||
synced_context::reset_is_simultaneously();
|
||||
|
||||
old_checkup_ = checkup_instance;
|
||||
checkup_instance = & new_checkup_;
|
||||
checkup_instance = &*new_checkup_;
|
||||
old_rng_ = random_new::generator;
|
||||
random_new::generator = new_rng_.get();
|
||||
}
|
||||
|
@ -370,7 +382,7 @@ set_scontext_synced::~set_scontext_synced()
|
|||
{
|
||||
LOG_REPLAY << "set_scontext_synced:: destructor\n";
|
||||
assert(synced_context::get_synced_state() == synced_context::SYNCED);
|
||||
assert(checkup_instance == &new_checkup_);
|
||||
assert(checkup_instance == &*new_checkup_);
|
||||
config co;
|
||||
if(!checkup_instance->local_checkup(config_of("random_calls", new_rng_->get_random_calls()), co))
|
||||
{
|
||||
|
@ -393,7 +405,7 @@ int set_scontext_synced::get_random_calls()
|
|||
|
||||
set_scontext_local_choice::set_scontext_local_choice()
|
||||
{
|
||||
|
||||
//TODO: should we also reset the synced checkup?
|
||||
assert(synced_context::get_synced_state() == synced_context::SYNCED);
|
||||
synced_context::set_synced_state(synced_context::LOCAL_CHOICE);
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "generic_event.hpp"
|
||||
#include "mouse_handler_base.hpp"
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
class config;
|
||||
|
||||
//only static methods.
|
||||
|
@ -145,10 +146,11 @@ public:
|
|||
private:
|
||||
//only called by contructors.
|
||||
void init();
|
||||
static checkup* generate_checkup(const std::string& tagname);
|
||||
random_new::rng* old_rng_;
|
||||
boost::shared_ptr<random_new::rng> new_rng_;
|
||||
checkup* old_checkup_;
|
||||
synced_checkup new_checkup_;
|
||||
boost::scoped_ptr<checkup> new_checkup_;
|
||||
events::command_disabler disabler_;
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue