SA-MP/raknet/RakServer.cpp
RD42 bcdbedc0be Revert RakNet source files back to the original v2.518 state
* Add RakNet source files to the VS project
2024-08-16 23:33:48 +08:00

590 lines
17 KiB
C++

/// \file
///
/// This file is part of RakNet Copyright 2003 Kevin Jenkins.
///
/// Usage of RakNet is subject to the appropriate license agreement.
/// Creative Commons Licensees are subject to the
/// license found at
/// http://creativecommons.org/licenses/by-nc/2.5/
/// Single application licensees are subject to the license found at
/// http://www.rakkarsoft.com/SingleApplicationLicense.html
/// Custom license users are subject to the terms therein.
/// GPL license users are subject to the GNU General Public
/// License as published by the Free
/// Software Foundation; either version 2 of the License, or (at your
/// option) any later version.
#include "RakServer.h"
#include "PacketEnumerations.h"
#include "GetTime.h"
#include "Rand.h"
#ifdef _MSC_VER
#pragma warning( push )
#endif
RakServer::RakServer()
{
nextSeedUpdate = 0;
synchronizedRandomInteger = false;
relayStaticClientData = false;
broadcastPingsTime = 0;
}
RakServer::~RakServer()
{}
void RakServer::InitializeSecurity( const char *pubKeyE, const char *pubKeyN )
{
RakPeer::InitializeSecurity( 0, 0, pubKeyE, pubKeyN );
}
void RakServer::DisableSecurity( void )
{
RakPeer::DisableSecurity();
}
#ifdef _MSC_VER
#pragma warning( disable : 4100 ) // warning C4100: 'depreciated' : unreferenced formal parameter
#endif
bool RakServer::Start( unsigned short AllowedPlayers, unsigned int depreciated, int threadSleepTimer, unsigned short port, const char *forceHostAddress )
{
bool init;
RakPeer::Disconnect( 30 );
init = RakPeer::Initialize( AllowedPlayers, port, threadSleepTimer, forceHostAddress );
RakPeer::SetMaximumIncomingConnections( AllowedPlayers );
// Random number seed
RakNetTime time = RakNet::GetTime();
seedMT( (unsigned int) time );
seed = randomMT();
if ( seed % 2 == 0 ) // Even
seed--; // make odd
nextSeed = randomMT();
if ( nextSeed % 2 == 0 ) // Even
nextSeed--; // make odd
return init;
}
void RakServer::SetPassword( const char *_password )
{
if ( _password )
{
RakPeer::SetIncomingPassword( _password, ( int ) strlen( _password ) + 1 );
}
else
{
RakPeer::SetIncomingPassword( 0, 0 );
}
}
bool RakServer::HasPassword( void )
{
int passwordLength;
GetIncomingPassword(0, &passwordLength);
return passwordLength > 0;
}
void RakServer::Disconnect( unsigned int blockDuration, unsigned char orderingChannel )
{
RakPeer::Disconnect( blockDuration, orderingChannel );
}
bool RakServer::Send( const char *data, const int length, PacketPriority priority, PacketReliability reliability, char orderingChannel, PlayerID playerId, bool broadcast )
{
return RakPeer::Send( data, length, priority, reliability, orderingChannel, playerId, broadcast );
}
bool RakServer::Send( RakNet::BitStream *bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel, PlayerID playerId, bool broadcast )
{
return RakPeer::Send( bitStream, priority, reliability, orderingChannel, playerId, broadcast );
}
Packet* RakServer::Receive( void )
{
Packet * packet = RakPeer::Receive();
// This is just a regular time based update. Nowhere else good to put it
if ( RakPeer::IsActive() && occasionalPing )
{
RakNetTime time = RakNet::GetTime();
if ( time > broadcastPingsTime || ( packet && packet->data[ 0 ] == ID_RECEIVED_STATIC_DATA ) )
{
if ( time > broadcastPingsTime )
broadcastPingsTime = time + 30000; // Broadcast pings every 30 seconds
unsigned i, count;
RemoteSystemStruct *remoteSystem;
RakNet::BitStream bitStream( ( PlayerID_Size + sizeof( short ) ) * 32 + sizeof(unsigned char) );
unsigned char typeId = ID_BROADCAST_PINGS;
bitStream.Write( typeId );
//for ( i = 0, count = 0; count < 32 && i < remoteSystemListSize; i++ )
for ( i = 0, count = 0; count < 32 && i < maximumNumberOfPeers; i++ )
{
remoteSystem = remoteSystemList + i;
if ( remoteSystem->playerId != UNASSIGNED_PLAYER_ID && remoteSystem->isActive)
{
bitStream.Write( remoteSystem->playerId.binaryAddress );
bitStream.Write( remoteSystem->playerId.port );
bitStream.Write( remoteSystem->pingAndClockDifferential[ remoteSystem->pingAndClockDifferentialWriteIndex ].pingTime );
count++;
}
}
if ( count > 0 ) // If we wrote anything
{
if ( packet && packet->data[ 0 ] == ID_NEW_INCOMING_CONNECTION ) // If this was a new connection
Send( &bitStream, SYSTEM_PRIORITY, RELIABLE, 0, packet->playerId, false ); // Send to the new connection
else
Send( &bitStream, SYSTEM_PRIORITY, RELIABLE, 0, UNASSIGNED_PLAYER_ID, true ); // Send to everyone
}
}
}
// This is just a regular time based update. Nowhere else good to put it
if ( RakPeer::IsActive() && synchronizedRandomInteger )
{
RakNetTime time = RakNet::GetTime();
if ( time > nextSeedUpdate || ( packet && packet->data[ 0 ] == ID_NEW_INCOMING_CONNECTION ) )
{
if ( time > nextSeedUpdate )
nextSeedUpdate = time + 9000; // Seeds are updated every 9 seconds
seed = nextSeed;
nextSeed = randomMT();
if ( nextSeed % 2 == 0 ) // Even
nextSeed--; // make odd
/* SetRandomNumberSeedStruct s;
s.ts = ID_TIMESTAMP;
s.timeStamp = RakNet::GetTime();
s.typeId = ID_SET_RANDOM_NUMBER_SEED;
s.seed = seed;
s.nextSeed = nextSeed;
RakNet::BitStream s_BitS( SetRandomNumberSeedStruct_Size );
s.Serialize( s_BitS );
*/
RakNet::BitStream outBitStream(sizeof(unsigned char)+sizeof(unsigned int)+sizeof(unsigned char)+sizeof(unsigned int)+sizeof(unsigned int));
outBitStream.Write((unsigned char) ID_TIMESTAMP);
outBitStream.Write((unsigned int) RakNet::GetTime());
outBitStream.Write((unsigned char) ID_SET_RANDOM_NUMBER_SEED);
outBitStream.Write(seed);
outBitStream.Write(nextSeed);
if ( packet && packet->data[ 0 ] == ID_NEW_INCOMING_CONNECTION )
Send( &outBitStream, SYSTEM_PRIORITY, RELIABLE, 0, packet->playerId, false );
else
Send( &outBitStream, SYSTEM_PRIORITY, RELIABLE, 0, UNASSIGNED_PLAYER_ID, true );
}
}
if ( packet )
{
// Intercept specific client / server feature packets. This will do an extra send and still pass on the data to the user
if ( packet->data[ 0 ] == ID_RECEIVED_STATIC_DATA )
{
if ( relayStaticClientData )
{
// Relay static data to the other systems but the sender
RakNet::BitStream bitStream( packet->length + PlayerID_Size );
unsigned char typeId = ID_REMOTE_STATIC_DATA;
bitStream.Write( typeId );
bitStream.Write( packet->playerId.binaryAddress );
bitStream.Write( packet->playerId.port );
bitStream.Write( packet->playerIndex );
bitStream.Write( ( char* ) packet->data + sizeof(unsigned char), packet->length - sizeof(unsigned char) );
Send( &bitStream, SYSTEM_PRIORITY, RELIABLE, 0, packet->playerId, true );
}
}
else
if ( packet->data[ 0 ] == ID_DISCONNECTION_NOTIFICATION || packet->data[ 0 ] == ID_CONNECTION_LOST || packet->data[ 0 ] == ID_NEW_INCOMING_CONNECTION )
{
// Relay the disconnection
RakNet::BitStream bitStream( packet->length + PlayerID_Size );
unsigned char typeId;
if ( packet->data[ 0 ] == ID_DISCONNECTION_NOTIFICATION )
typeId = ID_REMOTE_DISCONNECTION_NOTIFICATION;
else
if ( packet->data[ 0 ] == ID_CONNECTION_LOST )
typeId = ID_REMOTE_CONNECTION_LOST;
else
typeId = ID_REMOTE_NEW_INCOMING_CONNECTION;
bitStream.Write( typeId );
bitStream.Write( packet->playerId.binaryAddress );
bitStream.Write( packet->playerId.port );
bitStream.Write( ( unsigned short& ) packet->playerIndex );
Send( &bitStream, SYSTEM_PRIORITY, RELIABLE, 0, packet->playerId, true );
if ( packet->data[ 0 ] == ID_NEW_INCOMING_CONNECTION )
{
unsigned i;
//for ( i = 0; i < remoteSystemListSize; i++ )
for ( i = 0; i < maximumNumberOfPeers; i++ )
{
if ( remoteSystemList[ i ].isActive && remoteSystemList[ i ].playerId != UNASSIGNED_PLAYER_ID && packet->playerId != remoteSystemList[ i ].playerId )
{
bitStream.Reset();
typeId = ID_REMOTE_EXISTING_CONNECTION;
bitStream.Write( typeId );
bitStream.Write( remoteSystemList[ i ].playerId.binaryAddress );
bitStream.Write( remoteSystemList[ i ].playerId.port );
bitStream.Write( ( unsigned short ) i );
// One send to tell them of the connection
Send( &bitStream, SYSTEM_PRIORITY, RELIABLE, 0, packet->playerId, false );
if ( relayStaticClientData )
{
bitStream.Reset();
typeId = ID_REMOTE_STATIC_DATA;
bitStream.Write( typeId );
bitStream.Write( remoteSystemList[ i ].playerId.binaryAddress );
bitStream.Write( remoteSystemList[ i ].playerId.port );
bitStream.Write( (unsigned short) i );
bitStream.Write( ( char* ) remoteSystemList[ i ].staticData.GetData(), remoteSystemList[ i ].staticData.GetNumberOfBytesUsed() );
// Another send to tell them of the static data
Send( &bitStream, SYSTEM_PRIORITY, RELIABLE, 0, packet->playerId, false );
}
}
}
}
}
}
return packet;
}
void RakServer::Kick( const PlayerID playerId )
{
RakPeer::CloseConnection(playerId, true, 0);
}
void RakServer::DeallocatePacket( Packet *packet )
{
RakPeer::DeallocatePacket( packet );
}
void RakServer::SetAllowedPlayers( unsigned short AllowedPlayers )
{
RakPeer::SetMaximumIncomingConnections( AllowedPlayers );
}
unsigned short RakServer::GetAllowedPlayers( void ) const
{
return RakPeer::GetMaximumIncomingConnections();
}
unsigned short RakServer::GetConnectedPlayers( void )
{
unsigned short numberOfSystems;
RakPeer::GetConnectionList( 0, &numberOfSystems );
return numberOfSystems;
}
void RakServer::GetPlayerIPFromID( const PlayerID playerId, char returnValue[ 22 ], unsigned short *port )
{
*port = playerId.port;
strcpy( returnValue, RakPeer::PlayerIDToDottedIP( playerId ) );
}
void RakServer::PingPlayer( const PlayerID playerId )
{
RakPeer::Ping( playerId );
}
int RakServer::GetAveragePing( const PlayerID playerId )
{
return RakPeer::GetAveragePing( playerId );
}
int RakServer::GetLastPing( const PlayerID playerId )
{
return RakPeer::GetLastPing( playerId );
}
int RakServer::GetLowestPing( const PlayerID playerId )
{
return RakPeer::GetLowestPing( playerId );
}
void RakServer::StartOccasionalPing( void )
{
RakPeer::SetOccasionalPing( true );
}
void RakServer::StopOccasionalPing( void )
{
RakPeer::SetOccasionalPing( false );
}
bool RakServer::IsActive( void ) const
{
return RakPeer::IsActive();
}
unsigned int RakServer::GetSynchronizedRandomInteger( void ) const
{
return seed;
}
void RakServer::StartSynchronizedRandomInteger( void )
{
synchronizedRandomInteger = true;
}
void RakServer::StopSynchronizedRandomInteger( void )
{
synchronizedRandomInteger = false;
}
bool RakServer::GenerateCompressionLayer( unsigned int inputFrequencyTable[ 256 ], bool inputLayer )
{
return RakPeer::GenerateCompressionLayer( inputFrequencyTable, inputLayer );
}
bool RakServer::DeleteCompressionLayer( bool inputLayer )
{
return RakPeer::DeleteCompressionLayer( inputLayer );
}
void RakServer::RegisterAsRemoteProcedureCall( char* uniqueID, void ( *functionPointer ) ( RPCParameters *rpcParms ) )
{
RakPeer::RegisterAsRemoteProcedureCall( uniqueID, functionPointer );
}
void RakServer::RegisterClassMemberRPC( char* uniqueID, void *functionPointer )
{
RakPeer::RegisterClassMemberRPC( uniqueID, functionPointer );
}
void RakServer::UnregisterAsRemoteProcedureCall( char* uniqueID )
{
RakPeer::UnregisterAsRemoteProcedureCall( uniqueID );
}
bool RakServer::RPC( char* uniqueID, const char *data, unsigned int bitLength, PacketPriority priority, PacketReliability reliability, char orderingChannel, PlayerID playerId, bool broadcast, bool shiftTimestamp, NetworkID networkID, RakNet::BitStream *replyFromTarget )
{
return RakPeer::RPC( uniqueID, data, bitLength, priority, reliability, orderingChannel, playerId, broadcast, shiftTimestamp, networkID, replyFromTarget );
}
bool RakServer::RPC( char* uniqueID, RakNet::BitStream *parameters, PacketPriority priority, PacketReliability reliability, char orderingChannel, PlayerID playerId, bool broadcast, bool shiftTimestamp, NetworkID networkID, RakNet::BitStream *replyFromTarget )
{
return RakPeer::RPC( uniqueID, parameters, priority, reliability, orderingChannel, playerId, broadcast, shiftTimestamp, networkID, replyFromTarget );
}
void RakServer::SetTrackFrequencyTable( bool b )
{
RakPeer::SetCompileFrequencyTable( b );
}
bool RakServer::GetSendFrequencyTable( unsigned int outputFrequencyTable[ 256 ] )
{
return RakPeer::GetOutgoingFrequencyTable( outputFrequencyTable );
}
float RakServer::GetCompressionRatio( void ) const
{
return RakPeer::GetCompressionRatio();
}
float RakServer::GetDecompressionRatio( void ) const
{
return RakPeer::GetDecompressionRatio();
}
void RakServer::AttachPlugin( PluginInterface *messageHandler )
{
RakPeer::AttachPlugin(messageHandler);
}
void RakServer::DetachPlugin( PluginInterface *messageHandler )
{
RakPeer::DetachPlugin(messageHandler);
}
RakNet::BitStream * RakServer::GetStaticServerData( void )
{
return RakPeer::GetRemoteStaticData( myPlayerId );
}
void RakServer::SetStaticServerData( const char *data, const int length )
{
RakPeer::SetRemoteStaticData( myPlayerId, data, length );
}
void RakServer::SetRelayStaticClientData( bool b )
{
relayStaticClientData = b;
}
void RakServer::SendStaticServerDataToClient( const PlayerID playerId )
{
RakPeer::SendStaticData( playerId );
}
void RakServer::SetOfflinePingResponse( const char *data, const unsigned int length )
{
RakPeer::SetOfflinePingResponse( data, length );
}
RakNet::BitStream * RakServer::GetStaticClientData( const PlayerID playerId )
{
return RakPeer::GetRemoteStaticData( playerId );
}
void RakServer::SetStaticClientData( const PlayerID playerId, const char *data, const int length )
{
RakPeer::SetRemoteStaticData( playerId, data, length );
}
// This will read the data from playerChangedId and send it to playerToSendToId
void RakServer::ChangeStaticClientData( const PlayerID playerChangedId, PlayerID playerToSendToId )
{
RemoteSystemStruct * remoteSystem = GetRemoteSystemFromPlayerID( playerChangedId, false, true );
if ( remoteSystem == 0 )
return ; // No such playerChangedId
// Relay static data to the other systems but the sender
RakNet::BitStream bitStream;
unsigned char typeId = ID_REMOTE_STATIC_DATA;
bitStream.Write( typeId );
bitStream.Write( playerChangedId.binaryAddress );
bitStream.Write( playerChangedId.port );
bitStream.Write( ( char* ) remoteSystem->staticData.GetData(), remoteSystem->staticData.GetNumberOfBytesUsed() );
Send( &bitStream, SYSTEM_PRIORITY, RELIABLE, 0, playerToSendToId, true );
}
unsigned int RakServer::GetNumberOfAddresses( void )
{
return RakPeer::GetNumberOfAddresses();
}
PlayerID RakServer::GetInternalID( void ) const
{
return RakPeer::GetInternalID();
}
void RakServer::PushBackPacket( Packet *packet, bool pushAtHead )
{
RakPeer::PushBackPacket(packet, pushAtHead);
}
void RakServer::SetRouterInterface( RouterInterface *routerInterface )
{
RakPeer::SetRouterInterface(routerInterface);
}
void RakServer::RemoveRouterInterface( RouterInterface *routerInterface )
{
RakPeer::RemoveRouterInterface(routerInterface);
}
const char* RakServer::GetLocalIP( unsigned int index )
{
return RakPeer::GetLocalIP( index );
}
int RakServer::GetIndexFromPlayerID( const PlayerID playerId )
{
return RakPeer::GetIndexFromPlayerID( playerId );
}
PlayerID RakServer::GetPlayerIDFromIndex( int index )
{
return RakPeer::GetPlayerIDFromIndex( index );
}
void RakServer::AddToBanList( const char *IP )
{
RakPeer::AddToBanList( IP );
}
void RakServer::RemoveFromBanList( const char *IP )
{
RakPeer::RemoveFromBanList( IP );
}
void RakServer::ClearBanList( void )
{
RakPeer::ClearBanList();
}
bool RakServer::IsBanned( const char *IP )
{
return RakPeer::IsBanned( IP );
}
bool RakServer::IsActivePlayerID( const PlayerID playerId )
{
return RakPeer::GetRemoteSystemFromPlayerID( playerId, false, true ) != 0;
}
void RakServer::SetTimeoutTime( RakNetTime timeMS, const PlayerID target )
{
RakPeer::SetTimeoutTime(timeMS, target);
}
bool RakServer::SetMTUSize( int size )
{
return RakPeer::SetMTUSize( size );
}
int RakServer::GetMTUSize( void ) const
{
return RakPeer::GetMTUSize();
}
void RakServer::AdvertiseSystem( const char *host, unsigned short remotePort, const char *data, int dataLength )
{
RakPeer::AdvertiseSystem( host, remotePort, data, dataLength );
}
RakNetStatisticsStruct * const RakServer::GetStatistics( const PlayerID playerId )
{
return RakPeer::GetStatistics( playerId );
}
void RakServer::ApplyNetworkSimulator( double maxSendBPS, unsigned short minExtraPing, unsigned short extraPingVariance)
{
RakPeer::ApplyNetworkSimulator( maxSendBPS, minExtraPing, extraPingVariance );
}
bool RakServer::IsNetworkSimulatorActive( void )
{
return RakPeer::IsNetworkSimulatorActive();
}
#ifdef _MSC_VER
#pragma warning( pop )
#endif