enum StreamType
{
// Acknowledgement that a stream was received.
ACK = 500,
// Check for speedhacks from the samples collected and reset state to 0th sample.
VALIDATE = 501,
// Sample packet to check for speed hacks
SPEEDCHECK = 503,
// Confirm that speed hack was detected
CONFIRM = 502
}
// Frequency at which packets are sent to players.(in mili seconds)
FREQUENCY <- 2000;
// Number of samples the script takes before making a decision.
const SAMPLES = 10;
// Percentage of speed increase to be forgiven
const SLACK = 5.0;
// Array to store samples of time stamps when packets are received.
timeStamp <- ::array( SAMPLES, null );
function CheckSpeedData( int )
{
// Read what kind of data the server sent.
switch( int )
{
case StreamType.VALIDATE:
{
::ValidateSpeed();
// Reset the samples
::timeStamp = ::array( SAMPLES, null );
}
default:
{
if ( int < 503 )
return false;
// Log the time stamp when the server sent the data.(5 samples)
local index = int - 503;
::timeStamp[index] = Script.GetTicks();
// Acknowledge to server that the packet was received.
// local stream = Stream();
// stream.WriteByte(StreamType.ACK);
// Server.SendData(stream);
break;
}
}
}
function ValidateSpeed()
{
local duration = array( SAMPLES - 1, null );
local speedCount = 0;
local increase = 0, maxIncrease = 0;
for( local i = 0; i < SAMPLES - 1; i++ )
{
if( !timeStamp[i+1] || !timeStamp )
return false;
duration = timeStamp[i+1] - timeStamp;
increase = ( ( duration - FREQUENCY ).tofloat()/FREQUENCY) * 100.0;
maxIncrease = ( increase > maxIncrease ? increase : maxIncrease );
if( maxIncrease > SLACK ) speedCount++;
}
if( speedCount > 0 )
{
local stream = Stream();
stream.WriteInt(StreamType.CONFIRM);
stream.WriteString(World.FindLocalPlayer().ID + "-" + speedCount + "-" + maxIncrease);
Server.SendData(stream);
}
}