mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-06 23:15:28 +00:00
checksum verification of recruitment provided by Xan
(only enabled when starting with --debug)
This commit is contained in:
parent
24528ae9ff
commit
bd38112c4e
@ -305,6 +305,7 @@ bool ai_interface::recruit(const std::string& unit_name, location loc)
|
||||
" gold=" << data.gold <<
|
||||
((data.net_income < 0) ? "" : "+") <<
|
||||
data.net_income << "\n";
|
||||
recorder.add_checksum_check(loc);
|
||||
return true;
|
||||
} else {
|
||||
const team_data data = calculate_team_data(current_team(),info_.team_num,info_.units);
|
||||
|
@ -203,6 +203,7 @@ game_controller::game_controller(int argc, char** argv)
|
||||
test_mode_ = true;
|
||||
} else if(val == "--debug" || val == "-d") {
|
||||
game_config::debug = true;
|
||||
game_config::mp_debug = true;
|
||||
} else if (val.substr(0, 6) == "--log-") {
|
||||
} else if(val == "--nosound") {
|
||||
preferences::set_sound(false);
|
||||
|
@ -30,7 +30,7 @@ namespace game_config
|
||||
int kill_experience = 8;
|
||||
int leadership_bonus = 25;
|
||||
const std::string version = VERSION;
|
||||
bool debug = false, editor = false, ignore_replay_errors = false;
|
||||
bool debug = false, editor = false, ignore_replay_errors = false, mp_debug = false;
|
||||
|
||||
std::string game_icon = "wesnoth-icon.png", game_title, game_logo, title_music, anonymous_music,
|
||||
victory_music, defeat_music;
|
||||
|
@ -33,7 +33,7 @@ namespace game_config
|
||||
extern int leadership_bonus;
|
||||
extern const std::string version;
|
||||
|
||||
extern bool debug, editor, ignore_replay_errors;
|
||||
extern bool debug, editor, ignore_replay_errors, mp_debug;
|
||||
|
||||
extern std::string path;
|
||||
|
||||
|
@ -644,6 +644,7 @@ namespace events{
|
||||
gui_->recalculate_minimap();
|
||||
gui_->invalidate_game_status();
|
||||
gui_->invalidate_all();
|
||||
recorder.add_checksum_check(loc);
|
||||
} else {
|
||||
recorder.undo();
|
||||
gui::show_dialog(*gui_,NULL,"",msg,gui::OK_ONLY);
|
||||
@ -753,6 +754,7 @@ namespace events{
|
||||
recall_list.erase(recall_list.begin()+res);
|
||||
gui_->invalidate_game_status();
|
||||
gui_->invalidate_all();
|
||||
recorder.add_checksum_check(loc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -895,6 +897,7 @@ namespace events{
|
||||
|
||||
gui_->invalidate(action.recall_loc);
|
||||
gui_->draw();
|
||||
recorder.add_checksum_check(action.recall_loc);
|
||||
} else {
|
||||
recorder.undo();
|
||||
gui::show_dialog(*gui_,NULL,"",msg,gui::OK_ONLY);
|
||||
@ -936,6 +939,7 @@ namespace events{
|
||||
gui_->draw();
|
||||
//gui_.invalidate_game_status();
|
||||
//gui_.invalidate_all();
|
||||
recorder.add_checksum_check(loc);
|
||||
} else {
|
||||
recorder.undo();
|
||||
gui::show_dialog(*gui_,NULL,"",msg,gui::OK_ONLY);
|
||||
|
@ -214,6 +214,21 @@ void replay::save_game(const std::string& label, const config& snapshot,
|
||||
saveInfo_.snapshot = config();
|
||||
}
|
||||
|
||||
void replay::add_unit_checksum(const gamemap::location& loc,config* const cfg)
|
||||
{
|
||||
if(! game_config::mp_debug) {
|
||||
return;
|
||||
}
|
||||
wassert(unit_map_ref);
|
||||
config& cc = cfg->add_child("checksum");
|
||||
loc.write(cc);
|
||||
unit_map::const_iterator u = unit_map_ref->find(loc);
|
||||
wassert(u != unit_map_ref->end());
|
||||
std::string chk_value;
|
||||
u->second.write_checksum(chk_value);
|
||||
cc["value"] = chk_value;
|
||||
}
|
||||
|
||||
void replay::add_start()
|
||||
{
|
||||
config* const cmd = add_command(true);
|
||||
@ -286,6 +301,8 @@ void replay::add_attack(const gamemap::location& a, const gamemap::location& b,
|
||||
char buf[100];
|
||||
snprintf(buf,sizeof(buf),"%d",weapon);
|
||||
current_->child("attack")->values["weapon"] = buf;
|
||||
add_unit_checksum(a,current_);
|
||||
add_unit_checksum(b,current_);
|
||||
}
|
||||
|
||||
void replay::add_pos(const std::string& type,
|
||||
@ -366,6 +383,14 @@ void replay::add_event(const std::string& name)
|
||||
ev["raise"] = name;
|
||||
(*cmd)["undo"] = "no";
|
||||
}
|
||||
void replay::add_checksum_check(const gamemap::location& loc)
|
||||
{
|
||||
if(! game_config::mp_debug) {
|
||||
return;
|
||||
}
|
||||
config* const cmd = add_command();
|
||||
add_unit_checksum(loc,cmd);
|
||||
}
|
||||
void replay::speak(const config& cfg)
|
||||
{
|
||||
config* const cmd = add_command(false);
|
||||
@ -560,6 +585,32 @@ replay& get_replay_source()
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
void check_checksums(display& disp,const unit_map& units,const config& cfg)
|
||||
{
|
||||
if(! game_config::mp_debug) {
|
||||
return;
|
||||
}
|
||||
for(config::child_list::const_iterator ci = cfg.get_children("checksum").begin(); ci != cfg.get_children("checksum").end(); ++ci) {
|
||||
gamemap::location loc(**ci);
|
||||
unit_map::const_iterator u = units.find(loc);
|
||||
if(u == units.end()) {
|
||||
std::stringstream message;
|
||||
message << "non existant unit to checksum at " << loc.x+1 << "," << loc.y+1 << "!";
|
||||
disp.add_chat_message("verification",1,message.str(),display::MESSAGE_PRIVATE);
|
||||
continue;
|
||||
}
|
||||
std::string check;
|
||||
u->second.write_checksum(check);
|
||||
if(check != (**ci)["value"]) {
|
||||
std::stringstream message;
|
||||
message << "checksum mismatch at " << loc.x+1 << "," << loc.y+1 << "!";
|
||||
disp.add_chat_message("verification",1,message.str(),display::MESSAGE_PRIVATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo,
|
||||
unit_map& units,
|
||||
std::vector<team>& teams, int team_num, const gamestatus& state,
|
||||
@ -618,7 +669,8 @@ bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo,
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//if there is nothing more in the records
|
||||
if(cfg == NULL) {
|
||||
//replayer.set_skip(false);
|
||||
@ -728,6 +780,7 @@ bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo,
|
||||
current_team.spend_gold(u_type->second.cost());
|
||||
LOG_NW << "-> " << (current_team.gold()) << "\n";
|
||||
fix_shroud = !replayer.is_skipping();
|
||||
check_checksums(disp,units,*cfg);
|
||||
}
|
||||
|
||||
else if((child = cfg->child("recall")) != NULL) {
|
||||
@ -755,6 +808,7 @@ bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo,
|
||||
if (!game_config::ignore_replay_errors) throw replay::error();
|
||||
}
|
||||
fix_shroud = !replayer.is_skipping();
|
||||
check_checksums(disp,units,*cfg);
|
||||
}
|
||||
|
||||
else if((child = cfg->child("disband")) != NULL) {
|
||||
@ -852,6 +906,7 @@ bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo,
|
||||
up->first = dst;
|
||||
units.add(up);
|
||||
u = units.find(dst);
|
||||
check_checksums(disp,units,*cfg);
|
||||
if(map.is_village(dst)) {
|
||||
const int orig_owner = village_owner(dst,teams) + 1;
|
||||
if(orig_owner != team_num) {
|
||||
@ -883,6 +938,7 @@ bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo,
|
||||
else if((child = cfg->child("attack")) != NULL) {
|
||||
const config* const destination = child->child("destination");
|
||||
const config* const source = child->child("source");
|
||||
check_checksums(disp,units,*cfg);
|
||||
|
||||
if(destination == NULL || source == NULL) {
|
||||
ERR_NW << "no destination/source found in attack\n";
|
||||
@ -938,8 +994,12 @@ bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo,
|
||||
}
|
||||
game_events::fire((*child)["raise"]);
|
||||
} else {
|
||||
ERR_NW << "unrecognized action\n";
|
||||
if (!game_config::ignore_replay_errors) throw replay::error();
|
||||
if(! cfg->child("checksum")) {
|
||||
ERR_NW << "unrecognized action\n";
|
||||
if (!game_config::ignore_replay_errors) throw replay::error();
|
||||
} else {
|
||||
check_checksums(disp,units,*cfg);
|
||||
}
|
||||
}
|
||||
|
||||
//Check if we should refresh the shroud, and redraw the minimap/map tiles.
|
||||
|
@ -58,6 +58,8 @@ public:
|
||||
void add_rename(const std::string& name, const gamemap::location& loc);
|
||||
void end_turn();
|
||||
void add_event(const std::string& name);
|
||||
void add_unit_checksum(const gamemap::location& loc,config* const cfg);
|
||||
void add_checksum_check(const gamemap::location& loc);
|
||||
|
||||
void speak(const config& cfg);
|
||||
std::string build_chat_log(const std::string& team) const;
|
||||
|
11
src/unit.cpp
11
src/unit.cpp
@ -203,7 +203,13 @@ void unit::set_game_context(const game_data* gamedata, unit_map* unitmap, const
|
||||
gamestatus_ = game_status;
|
||||
teams_ = teams;
|
||||
}
|
||||
|
||||
void unit::write_checksum(std::string& str) const
|
||||
{
|
||||
config unit_config;
|
||||
write(unit_config);
|
||||
unit_config["controller"] = "";
|
||||
str = unit_config.hash();
|
||||
}
|
||||
|
||||
std::string unit::generate_description() const
|
||||
{
|
||||
@ -932,7 +938,6 @@ void unit::read(const config& cfg)
|
||||
|
||||
bool type_set = false;
|
||||
id_ = "";
|
||||
traits_description_ = cfg["traits_description"];
|
||||
if(cfg["type"] != "" && cfg["type"] != cfg["id"]) {
|
||||
wassert(gamedata_ != NULL);
|
||||
std::map<std::string,unit_type>::const_iterator i = gamedata_->unit_types.find(cfg["type"]);
|
||||
@ -1159,8 +1164,6 @@ void unit::write(config& cfg) const
|
||||
cfg["user_description"] = custom_unit_description_;
|
||||
cfg["description"] = underlying_description_;
|
||||
|
||||
cfg["traits_description"] = traits_description_;
|
||||
|
||||
if(can_recruit())
|
||||
cfg["canrecruit"] = "1";
|
||||
|
||||
|
@ -59,6 +59,7 @@ class unit
|
||||
virtual ~unit();
|
||||
|
||||
void set_game_context(const game_data* gamedata, unit_map* unitmap, const gamemap* map, const gamestatus* game_status, const std::vector<team>* teams);
|
||||
void write_checksum(std::string& str) const;
|
||||
|
||||
// Advances this unit to another type
|
||||
void advance_to(const unit_type* t);
|
||||
|
@ -954,11 +954,11 @@ const std::string& unit_type::image_profile() const
|
||||
return val;
|
||||
}
|
||||
|
||||
const std::string& unit_type::unit_description() const
|
||||
const t_string& unit_type::unit_description() const
|
||||
{
|
||||
static const std::string default_val("No description available");
|
||||
static const t_string default_val("No description available");
|
||||
|
||||
const std::string& desc = cfg_["unit_description"];
|
||||
const t_string& desc = cfg_["unit_description"];
|
||||
if(desc.empty())
|
||||
return default_val;
|
||||
else
|
||||
|
@ -188,7 +188,7 @@ public:
|
||||
|
||||
const std::string& image() const;
|
||||
const std::string& image_profile() const;
|
||||
const std::string& unit_description() const;
|
||||
const t_string& unit_description() const;
|
||||
|
||||
const std::vector<Uint32>& flag_rgb() const;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user