mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-03 09:10:10 +00:00
Fixed utterly broken RNG due to improper serialization of seeds.
(Issue spotted by isionous.)
This commit is contained in:
parent
742b794302
commit
390713c969
@ -995,7 +995,7 @@ void mouse_handler::attack_enemy_(const map_location& att_loc
|
||||
|
||||
void mouse_handler::perform_attack(
|
||||
map_location attacker_loc, map_location defender_loc,
|
||||
int attacker_weapon, int defender_weapon, rand_rng::seed_t seed)
|
||||
int attacker_weapon, int defender_weapon, int seed)
|
||||
{
|
||||
// this function gets it's arguments by value because the calling function
|
||||
// object might get deleted in the clear callback call below, invalidating
|
||||
|
@ -106,7 +106,7 @@ protected:
|
||||
|
||||
// the perform attack function called after a random seed is obtained
|
||||
void perform_attack(map_location attacker_loc, map_location defender_loc,
|
||||
int attacker_weapon, int defender_weapon, rand_rng::seed_t seed);
|
||||
int attacker_weapon, int defender_weapon, int seed);
|
||||
|
||||
void show_attack_options(const unit_map::const_iterator &u);
|
||||
map_location current_unit_attacks_from(const map_location& loc);
|
||||
|
@ -81,7 +81,7 @@ turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg
|
||||
network::connection from, std::deque<config>& backlog, bool skip_replay)
|
||||
{
|
||||
if (const config &rnd_seed = cfg.child("random_seed")) {
|
||||
rand_rng::set_seed(lexical_cast<rand_rng::seed_t>(rnd_seed["seed"]));
|
||||
rand_rng::set_seed(rnd_seed["seed"]);
|
||||
//may call a callback function, see rand_rng::set_seed_callback
|
||||
}
|
||||
|
||||
|
@ -57,9 +57,9 @@ static lg::log_domain log_random("random");
|
||||
|
||||
namespace {
|
||||
rand_rng::rng *random_generator = NULL ;
|
||||
rand_rng::seed_t last_seed;
|
||||
int last_seed;
|
||||
bool seed_valid = false;
|
||||
boost::function<void (rand_rng::seed_t)> new_seed_callback;
|
||||
boost::function<void (int)> new_seed_callback;
|
||||
}
|
||||
|
||||
|
||||
@ -94,7 +94,7 @@ void set_random_results(const config& cfg)
|
||||
namespace rand_rng
|
||||
{
|
||||
|
||||
void set_seed(seed_t seed)
|
||||
void set_seed(int seed)
|
||||
{
|
||||
LOG_RND << "set_seed with " << seed << "\n";
|
||||
assert(random_generator!=NULL);
|
||||
@ -111,7 +111,7 @@ void invalidate_seed()
|
||||
{
|
||||
LOG_RND << "invalidate_seed\n";
|
||||
assert(random_generator!=NULL);
|
||||
last_seed = rand();
|
||||
last_seed = rand() & 0x7FFFFFFF;
|
||||
if (has_valid_seed()) { //aka SRNG is disabled
|
||||
random_generator->set_seed(last_seed);
|
||||
}
|
||||
@ -124,12 +124,12 @@ bool has_valid_seed()
|
||||
return (network::nconnections() == 0) || seed_valid;
|
||||
}
|
||||
|
||||
seed_t get_last_seed()
|
||||
int get_last_seed()
|
||||
{
|
||||
return last_seed;
|
||||
}
|
||||
|
||||
void set_new_seed_callback(boost::function<void (seed_t)> f)
|
||||
void set_new_seed_callback(boost::function<void (int)> f)
|
||||
{
|
||||
DBG_RND << "set_new_seed_callback\n";
|
||||
new_seed_callback = f;
|
||||
@ -219,7 +219,7 @@ void rng::set_random(config* random)
|
||||
return;
|
||||
}
|
||||
|
||||
void rng::set_seed(seed_t seed)
|
||||
void rng::set_seed(int seed)
|
||||
{
|
||||
LOG_RND << "Set random seed to " << seed << "\n";
|
||||
generator_.seed_random(seed, 0);
|
||||
|
@ -29,8 +29,6 @@ void set_random_results(const config& cfg);
|
||||
namespace rand_rng
|
||||
{
|
||||
|
||||
typedef unsigned int seed_t;
|
||||
|
||||
class rng;
|
||||
|
||||
struct set_random_generator {
|
||||
|
@ -265,10 +265,10 @@ void replay::add_attack(const map_location& a, const map_location& b,
|
||||
add_unit_checksum(b,current_);
|
||||
}
|
||||
|
||||
void replay::add_seed(const char* child_name, rand_rng::seed_t seed)
|
||||
void replay::add_seed(const char* child_name, int seed)
|
||||
{
|
||||
LOG_REPLAY << "Setting seed for child type " << child_name << ": " << seed << "\n";
|
||||
random()->child(child_name)["seed"] = lexical_cast<std::string>(seed);
|
||||
random()->child(child_name)["seed"] = seed;
|
||||
}
|
||||
|
||||
void replay::add_pos(const std::string& type,
|
||||
@ -1087,16 +1087,9 @@ bool do_replay_handle(int side_num, const std::string &do_untill)
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
rand_rng::seed_t seed = lexical_cast<rand_rng::seed_t>(child["seed"]);
|
||||
rand_rng::set_seed(seed);
|
||||
LOG_REPLAY << "Replaying attack with seed " << seed << "\n";
|
||||
} catch (bad_lexical_cast) {
|
||||
std::stringstream errbuf;
|
||||
errbuf << "illegal random seed for the attack " << src << " -> " << dst << '\n';
|
||||
replay::process_error(errbuf.str());
|
||||
continue;
|
||||
}
|
||||
int seed = child["seed"];
|
||||
rand_rng::set_seed(child["seed"]);
|
||||
LOG_REPLAY << "Replaying attack with seed " << seed << "\n";
|
||||
|
||||
DBG_REPLAY << "Attacker XP (before attack): " << u->experience() << "\n";
|
||||
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
int att_weapon, int def_weapon, const std::string& attacker_type_id,
|
||||
const std::string& defender_type_id, int attacker_lvl,
|
||||
int defender_lvl, const size_t turn, const time_of_day &t);
|
||||
void add_seed(const char* child_name, rand_rng::seed_t seed);
|
||||
void add_seed(const char* child_name, int seed);
|
||||
void user_input(const std::string &, const config &);
|
||||
void add_label(const terrain_label*);
|
||||
void clear_labels(const std::string&, bool);
|
||||
|
@ -46,7 +46,7 @@ public:
|
||||
const config* get_random_results();
|
||||
void set_random_results(const config& cfg);
|
||||
|
||||
void set_seed(seed_t seed);
|
||||
void set_seed(int seed);
|
||||
|
||||
protected:
|
||||
int get_random_private(bool check);
|
||||
@ -64,7 +64,7 @@ private:
|
||||
* Set the random seed for the current random number generator, sets the seed
|
||||
* as valid nd calls the new seed callback if set
|
||||
*/
|
||||
void set_seed(seed_t seed);
|
||||
void set_seed(int seed);
|
||||
|
||||
/**
|
||||
* Mark the RNG seed as invalid
|
||||
@ -80,7 +80,7 @@ bool has_valid_seed();
|
||||
/**
|
||||
* Get the last seed the RNG was seeded with in set_seed
|
||||
*/
|
||||
seed_t get_last_seed();
|
||||
int get_last_seed();
|
||||
|
||||
/**
|
||||
* Set the callback for a function that will be called on subsequent set_seed
|
||||
@ -88,7 +88,7 @@ seed_t get_last_seed();
|
||||
* @todo needs a reliable way of clearing the callback when things don't go as
|
||||
* normal (e.g. player quit the game while the callback is set)
|
||||
*/
|
||||
void set_new_seed_callback(boost::function<void (seed_t)> f);
|
||||
void set_new_seed_callback(boost::function<void (int)> f);
|
||||
|
||||
/**
|
||||
* Clear the new seed callback
|
||||
|
@ -830,7 +830,7 @@ bool game::process_turn(simple_wml::document& data, const player_map::const_iter
|
||||
}
|
||||
for (command = commands.begin(); command != commands.end(); ++command) {
|
||||
if (simple_wml::node* attack = (**command).child("attack")) {
|
||||
int seed = rand();
|
||||
int seed = rand() & 0x7FFFFFFF;
|
||||
attack->set_attr_int("seed", seed);
|
||||
simple_wml::document doc;
|
||||
simple_wml::node& rs = doc.root().add_child("random_seed");
|
||||
|
Loading…
x
Reference in New Issue
Block a user