10 #include "../stdafx.h"
16 #include "../network/network.h"
17 #include "../network/network_server.h"
18 #include "../network/network_internal.h"
19 #include "../company_func.h"
20 #include "../fileio_func.h"
21 #include "../timer/timer_game_calendar.h"
27 #elif defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__)
29 #elif defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 25)))
30 # include <sys/random.h>
31 #elif defined(__EMSCRIPTEN__)
32 # include <emscripten.h>
35 #include "../safeguards.h"
45 const uint32_t s = this->
state[0];
46 const uint32_t t = this->
state[1];
48 this->
state[0] = s + std::rotr(t ^ 0x1234567F, 7) + 1;
49 return this->
state[1] = std::rotr(s, 3) - 1;
60 return ((uint64_t)this->
Next() * (uint64_t)limit) >> 32;
69 this->
state[0] = seed;
70 this->
state[1] = seed;
84 uint32_t DoRandom(
int line,
const char *file)
86 if (
_networking && (!
_network_server || (NetworkClientSocket::IsValidID(0) && NetworkClientSocket::Get(0)->status != NetworkClientSocket::STATUS_INACTIVE))) {
93 uint32_t DoRandomRange(uint32_t limit,
int line,
const char *file)
95 return ((uint64_t)DoRandom(line, file) * (uint64_t)limit) >> 32;
114 auto res = BCryptGenRandom(
nullptr,
static_cast<PUCHAR
>(buf.data()),
static_cast<ULONG
>(buf.size()), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
115 if (res >= 0)
return;
116 #elif defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__)
117 arc4random_buf(buf.data(), buf.size());
119 #elif defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 25)))
120 auto res = getrandom(buf.data(), buf.size(), 0);
121 if (res > 0 &&
static_cast<size_t>(res) == buf.size())
return;
122 #elif defined(__EMSCRIPTEN__)
123 auto res = EM_ASM_INT({
127 var crypto = window.crypto;
128 if (crypto === undefined || crypto.getRandomValues === undefined) {
132 crypto.getRandomValues(Module.HEAPU8.subarray(buf, buf + bytes));
134 }, buf.data(), buf.size());
137 # warning "No cryptographically-strong random generator available; using a fallback instead"
140 static bool warned_once =
false;
141 Debug(misc, warned_once ? 1 : 0,
"Cryptographically-strong random generator unavailable; using fallback");
144 for (uint i = 0; i < buf.size(); i++) {
145 buf[i] =
static_cast<uint8_t
>(InteractiveRandom());