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_NewHook = true;
int Num = (*m_pTeleOuts)[teleNr-1].size();
m_HookPos = (*m_pTeleOuts)[teleNr-1][(Num==1)?0:rand() % Num]+TargetDirection*PhysSize*1.5f;
int RandomOut = m_pWorld->RandomOr0((*m_pTeleOuts)[teleNr-1].size());
m_HookPos = (*m_pTeleOuts)[teleNr-1][RandomOut]+TargetDirection*PhysSize*1.5f;
m_HookDir = TargetDirection;
m_HookTeleBase = m_HookPos;
}

View file

@ -14,6 +14,7 @@
#include <engine/shared/protocol.h>
#include <game/generated/protocol.h>
#include "prng.h"
#include "teamscore.h"
#include "mapitems.h"
@ -180,10 +181,21 @@ public:
CWorldCore()
{
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];
class CCharacterCore *m_apCharacters[MAX_CLIENTS];
CPrng *m_pPrng;
};
class CCharacterCore

View file

@ -258,14 +258,15 @@ void CGameContext::ConToTeleporter(IConsole::IResult *pResult, void *pUserData)
{
CGameContext *pSelf = (CGameContext *) pUserData;
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);
if (pChr)
CCharacter *pChr = pSelf->GetPlayerChar(pResult->m_ClientID);
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->m_Pos = TelePos;
pChr->m_PrevPos = TelePos;
@ -278,14 +279,15 @@ void CGameContext::ConToCheckTeleporter(IConsole::IResult *pResult, void *pUserD
{
CGameContext *pSelf = (CGameContext *) pUserData;
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);
if (pChr)
CCharacter *pChr = pSelf->GetPlayerChar(pResult->m_ClientID);
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->m_Pos = TelePos;
pChr->m_PrevPos = TelePos;

View file

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

View file

@ -127,10 +127,11 @@ void CLaser::DoBounce()
else
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();
m_TelePos = ((CGameControllerDDRace*)GameServer()->m_pController)->m_TeleOuts[z-1][(!Num)?Num:rand() % Num];
int TeleOut = GameServer()->m_World.m_Core.RandomOr0(pControllerDDRace->m_TeleOuts[z-1].size());
m_TelePos = pControllerDDRace->m_TeleOuts[z-1][TeleOut];
m_WasTele = true;
}
else

View file

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

View file

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

View file

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

View file

@ -80,12 +80,13 @@ void CTeeHistorian::WriteHeader(const CGameInfo *pGameInfo)
char aGameTypeBuffer[128];
char aMapNameBuffer[128];
char aMapSha256Buffer[256];
char aPrngDescription[128];
char aJson[2048];
#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),
TEEHISTORIAN_VERSION,
aGameUuid,
@ -97,7 +98,8 @@ void CTeeHistorian::WriteHeader(const CGameInfo *pGameInfo)
E(aMapNameBuffer, pGameInfo->m_pMapName),
pGameInfo->m_MapSize,
E(aMapSha256Buffer, aMapSha256),
pGameInfo->m_MapCrc);
pGameInfo->m_MapCrc,
E(aPrngDescription, pGameInfo->m_pPrngDescription));
Write(aJson, str_length(aJson));
char aBuffer1[1024];

View file

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

View file

@ -57,6 +57,7 @@ protected:
m_GameInfo.m_GameUuid = CalculateUuid("test@ddnet.tw");
m_GameInfo.m_pServerVersion = "DDNet test";
m_GameInfo.m_StartTime = time(0);
m_GameInfo.m_pPrngDescription = "test-prng:02468ace";
m_GameInfo.m_pServerName = "server name";
m_GameInfo.m_ServerPort = 8303;
@ -91,7 +92,7 @@ protected:
{
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 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[] = "]}";
char aTimeBuf[64];