Use a consistent PRNG on all platforms

This commit is contained in:
heinrich5991 2020-05-25 15:08:24 +02:00
parent 7f14b4b2bb
commit 2692f3c758
11 changed files with 54 additions and 29 deletions

View file

@ -313,8 +313,8 @@ void CCharacterCore::Tick(bool UseInput)
m_HookedPlayer = -1; m_HookedPlayer = -1;
m_NewHook = true; m_NewHook = true;
int Num = (*m_pTeleOuts)[teleNr-1].size(); int RandomOut = m_pWorld->RandomOr0((*m_pTeleOuts)[teleNr-1].size());
m_HookPos = (*m_pTeleOuts)[teleNr-1][(Num==1)?0:rand() % Num]+TargetDirection*PhysSize*1.5f; m_HookPos = (*m_pTeleOuts)[teleNr-1][RandomOut]+TargetDirection*PhysSize*1.5f;
m_HookDir = TargetDirection; m_HookDir = TargetDirection;
m_HookTeleBase = m_HookPos; m_HookTeleBase = m_HookPos;
} }

View file

@ -14,6 +14,7 @@
#include <engine/shared/protocol.h> #include <engine/shared/protocol.h>
#include <game/generated/protocol.h> #include <game/generated/protocol.h>
#include "prng.h"
#include "teamscore.h" #include "teamscore.h"
#include "mapitems.h" #include "mapitems.h"
@ -180,10 +181,21 @@ public:
CWorldCore() CWorldCore()
{ {
mem_zero(m_apCharacters, sizeof(m_apCharacters)); mem_zero(m_apCharacters, sizeof(m_apCharacters));
m_pPrng = 0;
}
int RandomOr0(int BelowThis)
{
if(BelowThis <= 1 || !m_pPrng)
{
return 0;
}
return m_pPrng->RandomInt() % BelowThis;
} }
CTuningParams m_Tuning[2]; CTuningParams m_Tuning[2];
class CCharacterCore *m_apCharacters[MAX_CLIENTS]; class CCharacterCore *m_apCharacters[MAX_CLIENTS];
CPrng *m_pPrng;
}; };
class CCharacterCore class CCharacterCore

View file

@ -258,14 +258,15 @@ void CGameContext::ConToTeleporter(IConsole::IResult *pResult, void *pUserData)
{ {
CGameContext *pSelf = (CGameContext *) pUserData; CGameContext *pSelf = (CGameContext *) pUserData;
unsigned int TeleTo = pResult->GetInteger(0); unsigned int TeleTo = pResult->GetInteger(0);
CGameControllerDDRace *pGameControllerDDRace = (CGameControllerDDRace *)pSelf->m_pController;
if (((CGameControllerDDRace*)pSelf->m_pController)->m_TeleOuts[TeleTo-1].size()) if(pGameControllerDDRace->m_TeleOuts[TeleTo-1].size())
{ {
int Num = ((CGameControllerDDRace*)pSelf->m_pController)->m_TeleOuts[TeleTo-1].size();
vec2 TelePos = ((CGameControllerDDRace*)pSelf->m_pController)->m_TeleOuts[TeleTo-1][(!Num)?Num:rand() % Num];
CCharacter *pChr = pSelf->GetPlayerChar(pResult->m_ClientID); CCharacter *pChr = pSelf->GetPlayerChar(pResult->m_ClientID);
if(pChr) if(pChr)
{ {
int TeleOut = pSelf->m_World.m_Core.RandomOr0(pGameControllerDDRace->m_TeleOuts[TeleTo-1].size());
vec2 TelePos = pGameControllerDDRace->m_TeleOuts[TeleTo-1][TeleOut];
pChr->Core()->m_Pos = TelePos; pChr->Core()->m_Pos = TelePos;
pChr->m_Pos = TelePos; pChr->m_Pos = TelePos;
pChr->m_PrevPos = TelePos; pChr->m_PrevPos = TelePos;
@ -278,14 +279,15 @@ void CGameContext::ConToCheckTeleporter(IConsole::IResult *pResult, void *pUserD
{ {
CGameContext *pSelf = (CGameContext *) pUserData; CGameContext *pSelf = (CGameContext *) pUserData;
unsigned int TeleTo = pResult->GetInteger(0); unsigned int TeleTo = pResult->GetInteger(0);
CGameControllerDDRace *pGameControllerDDRace = (CGameControllerDDRace *)pSelf->m_pController;
if (((CGameControllerDDRace*)pSelf->m_pController)->m_TeleCheckOuts[TeleTo-1].size()) if(pGameControllerDDRace->m_TeleCheckOuts[TeleTo-1].size())
{ {
int Num = ((CGameControllerDDRace*)pSelf->m_pController)->m_TeleCheckOuts[TeleTo-1].size();
vec2 TelePos = ((CGameControllerDDRace*)pSelf->m_pController)->m_TeleCheckOuts[TeleTo-1][(!Num)?Num:rand() % Num];
CCharacter *pChr = pSelf->GetPlayerChar(pResult->m_ClientID); CCharacter *pChr = pSelf->GetPlayerChar(pResult->m_ClientID);
if(pChr) if(pChr)
{ {
int TeleOut = pSelf->m_World.m_Core.RandomOr0(pGameControllerDDRace->m_TeleCheckOuts[TeleTo-1].size());
vec2 TelePos = pGameControllerDDRace->m_TeleCheckOuts[TeleTo-1][TeleOut];
pChr->Core()->m_Pos = TelePos; pChr->Core()->m_Pos = TelePos;
pChr->m_Pos = TelePos; pChr->m_Pos = TelePos;
pChr->m_PrevPos = TelePos; pChr->m_PrevPos = TelePos;

View file

@ -1927,8 +1927,8 @@ void CCharacter::HandleTiles(int Index)
{ {
if (m_Super) if (m_Super)
return; return;
int Num = Controller->m_TeleOuts[z-1].size(); int TeleOut = m_Core.m_pWorld->RandomOr0(Controller->m_TeleOuts[z-1].size());
m_Core.m_Pos = Controller->m_TeleOuts[z-1][(!Num)?Num:rand() % Num]; m_Core.m_Pos = Controller->m_TeleOuts[z-1][TeleOut];
if(!g_Config.m_SvTeleportHoldHook) if(!g_Config.m_SvTeleportHoldHook)
{ {
m_Core.m_HookedPlayer = -1; m_Core.m_HookedPlayer = -1;
@ -1948,8 +1948,8 @@ void CCharacter::HandleTiles(int Index)
{ {
if (m_Super) if (m_Super)
return; return;
int Num = Controller->m_TeleOuts[evilz-1].size(); int TeleOut = m_Core.m_pWorld->RandomOr0(Controller->m_TeleOuts[evilz-1].size());
m_Core.m_Pos = Controller->m_TeleOuts[evilz-1][(!Num)?Num:rand() % Num]; m_Core.m_Pos = Controller->m_TeleOuts[evilz-1][TeleOut];
if (!g_Config.m_SvOldTeleportHook && !g_Config.m_SvOldTeleportWeapons) if (!g_Config.m_SvOldTeleportHook && !g_Config.m_SvOldTeleportWeapons)
{ {
m_Core.m_Vel = vec2(0,0); m_Core.m_Vel = vec2(0,0);
@ -1979,8 +1979,8 @@ void CCharacter::HandleTiles(int Index)
{ {
if(Controller->m_TeleCheckOuts[k].size()) if(Controller->m_TeleCheckOuts[k].size())
{ {
int Num = Controller->m_TeleCheckOuts[k].size(); int TeleOut = m_Core.m_pWorld->RandomOr0(Controller->m_TeleCheckOuts[k].size());
m_Core.m_Pos = Controller->m_TeleCheckOuts[k][(!Num)?Num:rand() % Num]; m_Core.m_Pos = Controller->m_TeleCheckOuts[k][TeleOut];
m_Core.m_Vel = vec2(0,0); m_Core.m_Vel = vec2(0,0);
if(!g_Config.m_SvTeleportHoldHook) if(!g_Config.m_SvTeleportHoldHook)
@ -2022,8 +2022,8 @@ void CCharacter::HandleTiles(int Index)
{ {
if(Controller->m_TeleCheckOuts[k].size()) if(Controller->m_TeleCheckOuts[k].size())
{ {
int Num = Controller->m_TeleCheckOuts[k].size(); int TeleOut = m_Core.m_pWorld->RandomOr0(Controller->m_TeleCheckOuts[k].size());
m_Core.m_Pos = Controller->m_TeleCheckOuts[k][(!Num)?Num:rand() % Num]; m_Core.m_Pos = Controller->m_TeleCheckOuts[k][TeleOut];
if(!g_Config.m_SvTeleportHoldHook) if(!g_Config.m_SvTeleportHoldHook)
{ {

View file

@ -127,10 +127,11 @@ void CLaser::DoBounce()
else else
m_Energy -= distance(m_From, m_Pos) + GameServer()->TuningList()[m_TuneZone].m_LaserBounceCost; m_Energy -= distance(m_From, m_Pos) + GameServer()->TuningList()[m_TuneZone].m_LaserBounceCost;
if (Res == TILE_TELEINWEAPON && ((CGameControllerDDRace*)GameServer()->m_pController)->m_TeleOuts[z-1].size()) CGameControllerDDRace *pControllerDDRace = (CGameControllerDDRace *)GameServer()->m_pController;
if(Res == TILE_TELEINWEAPON && pControllerDDRace->m_TeleOuts[z-1].size())
{ {
int Num = ((CGameControllerDDRace*)GameServer()->m_pController)->m_TeleOuts[z-1].size(); int TeleOut = GameServer()->m_World.m_Core.RandomOr0(pControllerDDRace->m_TeleOuts[z-1].size());
m_TelePos = ((CGameControllerDDRace*)GameServer()->m_pController)->m_TeleOuts[z-1][(!Num)?Num:rand() % Num]; m_TelePos = pControllerDDRace->m_TeleOuts[z-1][TeleOut];
m_WasTele = true; m_WasTele = true;
} }
else else

View file

@ -275,10 +275,11 @@ void CProjectile::Tick()
z = GameServer()->Collision()->IsTeleport(x); z = GameServer()->Collision()->IsTeleport(x);
else else
z = GameServer()->Collision()->IsTeleportWeapon(x); z = GameServer()->Collision()->IsTeleportWeapon(x);
if (z && ((CGameControllerDDRace*)GameServer()->m_pController)->m_TeleOuts[z-1].size()) CGameControllerDDRace *pControllerDDRace = (CGameControllerDDRace *)GameServer()->m_pController;
if (z && pControllerDDRace->m_TeleOuts[z-1].size())
{ {
int Num = ((CGameControllerDDRace*)GameServer()->m_pController)->m_TeleOuts[z-1].size(); int TeleOut = GameServer()->m_World.m_Core.RandomOr0(pControllerDDRace->m_TeleOuts[z-1].size());
m_Pos = ((CGameControllerDDRace*)GameServer()->m_pController)->m_TeleOuts[z-1][(!Num)?Num:rand() % Num]; m_Pos = pControllerDDRace->m_TeleOuts[z-1][TeleOut];
m_StartTick = Server()->Tick(); m_StartTick = Server()->Tick();
} }
} }

View file

@ -2625,6 +2625,9 @@ void CGameContext::OnInit(/*class IKernel *pKernel*/)
m_GameUuid = RandomUuid(); m_GameUuid = RandomUuid();
Console()->SetTeeHistorianCommandCallback(CommandCallback, this); Console()->SetTeeHistorianCommandCallback(CommandCallback, this);
m_Prng.Seed(1);
m_World.m_Core.m_pPrng = &m_Prng;
DeleteTempfile(); DeleteTempfile();
//if(!data) // only load once //if(!data) // only load once
@ -2739,6 +2742,7 @@ void CGameContext::OnInit(/*class IKernel *pKernel*/)
GameInfo.m_GameUuid = m_GameUuid; GameInfo.m_GameUuid = m_GameUuid;
GameInfo.m_pServerVersion = aVersion; GameInfo.m_pServerVersion = aVersion;
GameInfo.m_StartTime = time(0); GameInfo.m_StartTime = time(0);
GameInfo.m_pPrngDescription = m_Prng.Description();
GameInfo.m_pServerName = g_Config.m_SvName; GameInfo.m_pServerName = g_Config.m_SvName;
GameInfo.m_ServerPort = g_Config.m_SvPort; GameInfo.m_ServerPort = g_Config.m_SvPort;

View file

@ -79,6 +79,7 @@ class CGameContext : public IGameServer
ASYNCIO *m_pTeeHistorianFile; ASYNCIO *m_pTeeHistorianFile;
CUuid m_GameUuid; CUuid m_GameUuid;
CMapBugs m_MapBugs; CMapBugs m_MapBugs;
CPrng m_Prng;
std::shared_ptr<CRandomMapResult> m_pRandomMapResult; std::shared_ptr<CRandomMapResult> m_pRandomMapResult;
std::shared_ptr<CMapVoteResult> m_pMapVoteResult; std::shared_ptr<CMapVoteResult> m_pMapVoteResult;

View file

@ -80,12 +80,13 @@ void CTeeHistorian::WriteHeader(const CGameInfo *pGameInfo)
char aGameTypeBuffer[128]; char aGameTypeBuffer[128];
char aMapNameBuffer[128]; char aMapNameBuffer[128];
char aMapSha256Buffer[256]; char aMapSha256Buffer[256];
char aPrngDescription[128];
char aJson[2048]; char aJson[2048];
#define E(buf, str) EscapeJson(buf, sizeof(buf), str) #define E(buf, str) EscapeJson(buf, sizeof(buf), str)
str_format(aJson, sizeof(aJson), "{\"comment\":\"%s\",\"version\":\"%s\",\"game_uuid\":\"%s\",\"server_version\":\"%s\",\"start_time\":\"%s\",\"server_name\":\"%s\",\"server_port\":\"%d\",\"game_type\":\"%s\",\"map_name\":\"%s\",\"map_size\":\"%d\",\"map_sha256\":\"%s\",\"map_crc\":\"%08x\",\"config\":{", str_format(aJson, sizeof(aJson), "{\"comment\":\"%s\",\"version\":\"%s\",\"game_uuid\":\"%s\",\"server_version\":\"%s\",\"start_time\":\"%s\",\"server_name\":\"%s\",\"server_port\":\"%d\",\"game_type\":\"%s\",\"map_name\":\"%s\",\"map_size\":\"%d\",\"map_sha256\":\"%s\",\"map_crc\":\"%08x\",\"prng_description\":\"%s\",\"config\":{",
E(aCommentBuffer, TEEHISTORIAN_NAME), E(aCommentBuffer, TEEHISTORIAN_NAME),
TEEHISTORIAN_VERSION, TEEHISTORIAN_VERSION,
aGameUuid, aGameUuid,
@ -97,7 +98,8 @@ void CTeeHistorian::WriteHeader(const CGameInfo *pGameInfo)
E(aMapNameBuffer, pGameInfo->m_pMapName), E(aMapNameBuffer, pGameInfo->m_pMapName),
pGameInfo->m_MapSize, pGameInfo->m_MapSize,
E(aMapSha256Buffer, aMapSha256), E(aMapSha256Buffer, aMapSha256),
pGameInfo->m_MapCrc); pGameInfo->m_MapCrc,
E(aPrngDescription, pGameInfo->m_pPrngDescription));
Write(aJson, str_length(aJson)); Write(aJson, str_length(aJson));
char aBuffer1[1024]; char aBuffer1[1024];

View file

@ -23,6 +23,7 @@ public:
CUuid m_GameUuid; CUuid m_GameUuid;
const char *m_pServerVersion; const char *m_pServerVersion;
time_t m_StartTime; time_t m_StartTime;
const char *m_pPrngDescription;
const char *m_pServerName; const char *m_pServerName;
int m_ServerPort; int m_ServerPort;

View file

@ -57,6 +57,7 @@ protected:
m_GameInfo.m_GameUuid = CalculateUuid("test@ddnet.tw"); m_GameInfo.m_GameUuid = CalculateUuid("test@ddnet.tw");
m_GameInfo.m_pServerVersion = "DDNet test"; m_GameInfo.m_pServerVersion = "DDNet test";
m_GameInfo.m_StartTime = time(0); m_GameInfo.m_StartTime = time(0);
m_GameInfo.m_pPrngDescription = "test-prng:02468ace";
m_GameInfo.m_pServerName = "server name"; m_GameInfo.m_pServerName = "server name";
m_GameInfo.m_ServerPort = 8303; m_GameInfo.m_ServerPort = 8303;
@ -91,7 +92,7 @@ protected:
{ {
static CUuid TEEHISTORIAN_UUID = CalculateUuid("teehistorian@ddnet.tw"); static CUuid TEEHISTORIAN_UUID = CalculateUuid("teehistorian@ddnet.tw");
static const char PREFIX1[] = "{\"comment\":\"teehistorian@ddnet.tw\",\"version\":\"2\",\"game_uuid\":\"a1eb7182-796e-3b3e-941d-38ca71b2a4a8\",\"server_version\":\"DDNet test\",\"start_time\":\""; static const char PREFIX1[] = "{\"comment\":\"teehistorian@ddnet.tw\",\"version\":\"2\",\"game_uuid\":\"a1eb7182-796e-3b3e-941d-38ca71b2a4a8\",\"server_version\":\"DDNet test\",\"start_time\":\"";
static const char PREFIX2[] = "\",\"server_name\":\"server name\",\"server_port\":\"8303\",\"game_type\":\"game type\",\"map_name\":\"Kobra 3 Solo\",\"map_size\":\"903514\",\"map_sha256\":\"0123456789012345678901234567890123456789012345678901234567890123\",\"map_crc\":\"eceaf25c\",\"config\":{},\"tuning\":{},\"uuids\":["; static const char PREFIX2[] = "\",\"server_name\":\"server name\",\"server_port\":\"8303\",\"game_type\":\"game type\",\"map_name\":\"Kobra 3 Solo\",\"map_size\":\"903514\",\"map_sha256\":\"0123456789012345678901234567890123456789012345678901234567890123\",\"map_crc\":\"eceaf25c\",\"prng_description\":\"test-prng:02468ace\",\"config\":{},\"tuning\":{},\"uuids\":[";
static const char PREFIX3[] = "]}"; static const char PREFIX3[] = "]}";
char aTimeBuf[64]; char aTimeBuf[64];