Files
mcpe/thirdparty/raknet/RandSync.cpp
iProgramInCpp 9642818a88 * Initial commit.
:)
2023-07-30 22:22:02 +03:00

167 lines
4.3 KiB
C++

/*
* Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#include "RandSync.h"
#include "BitStream.h"
#include <limits>
#include <limits.h>
namespace RakNet
{
RakNetRandomSync::RakNetRandomSync()
{
seed = (uint32_t) -1;
callCount = 0;
usedValueBufferCount = 0;
}
RakNetRandomSync::~RakNetRandomSync()
{
}
void RakNetRandomSync::SeedMT( uint32_t _seed )
{
seed = _seed;
rnr.SeedMT( seed );
callCount = 0;
usedValueBufferCount = 0;
}
void RakNetRandomSync::SeedMT( uint32_t _seed, uint32_t skipValues )
{
SeedMT(_seed);
Skip(skipValues);
}
float RakNetRandomSync::FrandomMT( void )
{
return ( float ) ( ( double ) RandomMT() / (double) UINT_MAX );
}
unsigned int RakNetRandomSync::RandomMT( void )
{
if (usedValueBufferCount > 0)
{
--usedValueBufferCount;
if (usedValueBufferCount < usedValues.Size())
{
// The remote system had less calls than the current system, so return values from the past
return usedValues[usedValues.Size()-usedValueBufferCount-1];
}
else
{
// Unknown past value, too far back
// Return true random
return rnr.RandomMT();
}
}
else
{
// Get random number and store what it is
usedValues.Push(rnr.RandomMT(), _FILE_AND_LINE_);
++callCount;
while (usedValues.Size()>64)
usedValues.Pop();
return usedValues[usedValues.Size()-1];
}
}
uint32_t RakNetRandomSync::GetSeed( void ) const
{
return seed;
}
uint32_t RakNetRandomSync::GetCallCount( void ) const
{
return callCount;
}
void RakNetRandomSync::SetCallCount( uint32_t i )
{
callCount = i;
}
void RakNetRandomSync::SerializeConstruction(RakNet::BitStream *constructionBitstream)
{
constructionBitstream->Write(seed);
constructionBitstream->Write(callCount);
}
bool RakNetRandomSync::DeserializeConstruction(RakNet::BitStream *constructionBitstream)
{
uint32_t _seed;
uint32_t _skipValues;
constructionBitstream->Read(_seed);
bool success = constructionBitstream->Read(_skipValues);
if (success)
SeedMT(_seed, _skipValues);
return success;
}
void RakNetRandomSync::Serialize(RakNet::BitStream *outputBitstream)
{
outputBitstream->Write(callCount);
}
void RakNetRandomSync::Deserialize(RakNet::BitStream *outputBitstream)
{
uint32_t _callCount;
outputBitstream->Read(_callCount);
if (_callCount < callCount )
{
// We locally read more values than the remote system
// The next n calls should come from buffered values
usedValueBufferCount = callCount - _callCount;
}
else if (_callCount > callCount )
{
// Remote system read more values than us
uint32_t diff = _callCount - callCount;
if (diff <= usedValueBufferCount)
usedValueBufferCount -= diff;
if (diff > 0)
Skip(diff);
}
}
void RakNetRandomSync::Skip( uint32_t count )
{
for (uint32_t i = 0; i < count; i++)
rnr.RandomMT();
callCount+=count;
}
} // namespace RakNet
/*
RakNetRandomSync r1, r2;
BitStream bsTest;
r1.SeedMT(0);
r1.SerializeConstruction(&bsTest);
bsTest.SetReadOffset(0);
r2.DeserializeConstruction(&bsTest);
printf("1. (r1) %f\n", r1.FrandomMT());
printf("1. (r2) %f\n", r2.FrandomMT());
printf("2. (r1) %f\n", r1.FrandomMT());
printf("2. (r2) %f\n", r2.FrandomMT());
printf("3. (r1) %f\n", r1.FrandomMT());
printf("3. (r2) %f\n", r2.FrandomMT());
printf("4. (r1) %f\n", r1.FrandomMT());
printf("4. (r2) %f\n", r2.FrandomMT());
printf("5. (r2) %f\n", r2.FrandomMT());
printf("6. (r2) %f\n", r2.FrandomMT());
printf("7. (r2) %f\n", r2.FrandomMT());
bsTest.Reset();
r1.Serialize(&bsTest);
bsTest.SetReadOffset(0);
r2.Deserialize(&bsTest);
printf("Synched r2 to match r1\n");
printf("5. (r1) %f\n", r1.FrandomMT());
printf("5. (r2) %f --Should continue sequence from 5-\n", r2.FrandomMT());
printf("6. (r1) %f\n", r1.FrandomMT());
printf("6. (r2) %f\n", r2.FrandomMT());
printf("7. (r1) %f -- Extra call to r1, no r2 equivalent --\n", r1.FrandomMT());
printf("8. (r1) %f -- Extra call to r1, no r2 equivalent --\n", r1.FrandomMT());
bsTest.Reset();
r1.Serialize(&bsTest);
bsTest.SetReadOffset(0);
r2.Deserialize(&bsTest);
printf("Synched r2 to match r1\n");
printf("9. (r1) %f\n", r1.FrandomMT());
printf("9. (r2) %f --SKIPPED 7,8, SHOULD MATCH 9-\n", r2.FrandomMT());
*/