mirror of
https://github.com/dashr9230/SA-MP.git
synced 2024-12-23 06:57:31 +08:00
618 lines
16 KiB
C++
618 lines
16 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 "RakClient.h"
|
|
#include "PacketEnumerations.h"
|
|
#include "GetTime.h"
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning( push )
|
|
#endif
|
|
|
|
// Constructor
|
|
RakClient::RakClient()
|
|
{
|
|
unsigned i;
|
|
|
|
for ( i = 0; i < 32; i++ )
|
|
otherClients[ i ].isActive = false;
|
|
|
|
nextSeedUpdate = 0;
|
|
}
|
|
|
|
// Destructor
|
|
RakClient::~RakClient()
|
|
{}
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning( disable : 4100 ) // warning C4100: 'depreciated' : unreferenced formal parameter
|
|
#endif
|
|
bool RakClient::Connect( const char* host, unsigned short serverPort, unsigned short clientPort, unsigned int depreciated, int threadSleepTimer )
|
|
{
|
|
RakPeer::Disconnect( 100 );
|
|
|
|
RakPeer::Initialize( 1, clientPort, threadSleepTimer );
|
|
|
|
if ( host[ 0 ] < '0' || host[ 0 ] > '2' )
|
|
{
|
|
#if !defined(_COMPATIBILITY_1)
|
|
host = ( char* ) SocketLayer::Instance()->DomainNameToIP( host );
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
unsigned i;
|
|
|
|
for ( i = 0; i < 32; i++ )
|
|
{
|
|
otherClients[ i ].isActive = false;
|
|
otherClients[ i ].playerId = UNASSIGNED_PLAYER_ID;
|
|
otherClients[ i ].staticData.Reset();
|
|
}
|
|
|
|
// ignore depreciated. A pointless variable
|
|
return RakPeer::Connect( host, serverPort, ( char* ) password.GetData(), password.GetNumberOfBytesUsed() );
|
|
}
|
|
|
|
void RakClient::Disconnect( unsigned int blockDuration, unsigned char orderingChannel )
|
|
{
|
|
RakPeer::Disconnect( blockDuration, orderingChannel );
|
|
}
|
|
|
|
void RakClient::InitializeSecurity( const char *privKeyP, const char *privKeyQ )
|
|
{
|
|
RakPeer::InitializeSecurity( privKeyP, privKeyQ, 0, 0 );
|
|
}
|
|
|
|
void RakClient::SetPassword( const char *_password )
|
|
{
|
|
if ( _password == 0 || _password[ 0 ] == 0 )
|
|
password.Reset();
|
|
else
|
|
{
|
|
password.Reset();
|
|
password.Write( _password, ( int ) strlen( _password ) + 1 );
|
|
}
|
|
}
|
|
|
|
bool RakClient::HasPassword( void ) const
|
|
{
|
|
return password.GetNumberOfBytesUsed() > 0;
|
|
}
|
|
|
|
bool RakClient::Send( const char *data, const int length, PacketPriority priority, PacketReliability reliability, char orderingChannel )
|
|
{
|
|
if ( remoteSystemList == 0 )
|
|
return false;
|
|
|
|
return RakPeer::Send( data, length, priority, reliability, orderingChannel, remoteSystemList[ 0 ].playerId, false );
|
|
}
|
|
|
|
bool RakClient::Send( RakNet::BitStream * bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel )
|
|
{
|
|
if ( remoteSystemList == 0 )
|
|
return false;
|
|
|
|
return RakPeer::Send( bitStream, priority, reliability, orderingChannel, remoteSystemList[ 0 ].playerId, false );
|
|
}
|
|
|
|
Packet* RakClient::Receive( void )
|
|
{
|
|
Packet * packet = RakPeer::Receive();
|
|
|
|
// Intercept specific client / server feature packets
|
|
|
|
if ( packet )
|
|
{
|
|
RakNet::BitStream bitStream( packet->data, packet->length, false );
|
|
int i;
|
|
|
|
if ( packet->data[ 0 ] == ID_CONNECTION_REQUEST_ACCEPTED )
|
|
{
|
|
// ConnectionAcceptStruct cas;
|
|
// cas.Deserialize(bitStream);
|
|
// unsigned short remotePort;
|
|
// PlayerID externalID;
|
|
PlayerIndex playerIndex;
|
|
|
|
RakNet::BitStream inBitStream(packet->data, packet->length, false);
|
|
inBitStream.IgnoreBits(8); // ID_CONNECTION_REQUEST_ACCEPTED
|
|
inBitStream.IgnoreBits(8 * sizeof(unsigned short)); //inBitStream.Read(remotePort);
|
|
inBitStream.IgnoreBits(8 * sizeof(unsigned int)); //inBitStream.Read(externalID.binaryAddress);
|
|
inBitStream.IgnoreBits(8 * sizeof(unsigned short)); //inBitStream.Read(externalID.port);
|
|
inBitStream.Read(playerIndex);
|
|
|
|
localPlayerIndex = playerIndex;
|
|
packet->playerIndex = playerIndex;
|
|
}
|
|
else if (
|
|
packet->data[ 0 ] == ID_REMOTE_NEW_INCOMING_CONNECTION ||
|
|
packet->data[ 0 ] == ID_REMOTE_EXISTING_CONNECTION ||
|
|
packet->data[ 0 ] == ID_REMOTE_DISCONNECTION_NOTIFICATION ||
|
|
packet->data[ 0 ] == ID_REMOTE_CONNECTION_LOST )
|
|
{
|
|
bitStream.IgnoreBits( 8 ); // Ignore identifier
|
|
bitStream.Read( packet->playerId.binaryAddress );
|
|
bitStream.Read( packet->playerId.port );
|
|
|
|
if ( bitStream.Read( ( unsigned short& ) packet->playerIndex ) == false )
|
|
{
|
|
DeallocatePacket( packet );
|
|
return 0;
|
|
}
|
|
|
|
|
|
if ( packet->data[ 0 ] == ID_REMOTE_DISCONNECTION_NOTIFICATION ||
|
|
packet->data[ 0 ] == ID_REMOTE_CONNECTION_LOST )
|
|
{
|
|
i = GetOtherClientIndexByPlayerID( packet->playerId );
|
|
|
|
if ( i >= 0 )
|
|
otherClients[ i ].isActive = false;
|
|
}
|
|
}
|
|
else if ( packet->data[ 0 ] == ID_REMOTE_STATIC_DATA )
|
|
{
|
|
bitStream.IgnoreBits( 8 ); // Ignore identifier
|
|
bitStream.Read( packet->playerId.binaryAddress );
|
|
bitStream.Read( packet->playerId.port );
|
|
bitStream.Read( packet->playerIndex ); // ADDED BY KURI
|
|
|
|
i = GetOtherClientIndexByPlayerID( packet->playerId );
|
|
|
|
if ( i < 0 )
|
|
i = GetFreeOtherClientIndex();
|
|
|
|
if ( i >= 0 )
|
|
{
|
|
otherClients[ i ].playerId = packet->playerId;
|
|
otherClients[ i ].isActive = true;
|
|
otherClients[ i ].staticData.Reset();
|
|
// The static data is what is left over in the stream
|
|
otherClients[ i ].staticData.Write( ( char* ) bitStream.GetData() + BITS_TO_BYTES( bitStream.GetReadOffset() ), bitStream.GetNumberOfBytesUsed() - BITS_TO_BYTES( bitStream.GetReadOffset() ) );
|
|
}
|
|
}
|
|
else if ( packet->data[ 0 ] == ID_BROADCAST_PINGS )
|
|
{
|
|
PlayerID playerId;
|
|
int index;
|
|
|
|
bitStream.IgnoreBits( 8 ); // Ignore identifier
|
|
|
|
for ( i = 0; i < 32; i++ )
|
|
{
|
|
if ( bitStream.Read( playerId.binaryAddress ) == false )
|
|
break; // No remaining data!
|
|
|
|
bitStream.Read( playerId.port );
|
|
|
|
index = GetOtherClientIndexByPlayerID( playerId );
|
|
|
|
if ( index >= 0 )
|
|
bitStream.Read( otherClients[ index ].ping );
|
|
else
|
|
{
|
|
index = GetFreeOtherClientIndex();
|
|
|
|
if ( index >= 0 )
|
|
{
|
|
otherClients[ index ].isActive = true;
|
|
bitStream.Read( otherClients[ index ].ping );
|
|
otherClients[ index ].playerId = playerId;
|
|
otherClients[ index ].staticData.Reset();
|
|
}
|
|
|
|
else
|
|
bitStream.IgnoreBits( sizeof( short ) * 8 );
|
|
}
|
|
}
|
|
|
|
DeallocatePacket( packet );
|
|
return 0;
|
|
}
|
|
else
|
|
if ( packet->data[ 0 ] == ID_TIMESTAMP &&
|
|
packet->length == sizeof(unsigned char)+sizeof(unsigned int)+sizeof(unsigned char)+sizeof(unsigned int)+sizeof(unsigned int) )
|
|
{
|
|
|
|
|
|
RakNet::BitStream inBitStream(packet->data, packet->length, false);
|
|
|
|
RakNetTime timeStamp;
|
|
unsigned char typeId;
|
|
unsigned int in_seed;
|
|
unsigned int in_nextSeed;
|
|
inBitStream.IgnoreBits(8); // ID_TIMESTAMP
|
|
inBitStream.Read(timeStamp);
|
|
inBitStream.Read(typeId); // ID_SET_RANDOM_NUMBER_SEED ?
|
|
|
|
// Check to see if this is a user TIMESTAMP message which
|
|
// accidentally has length SetRandomNumberSeedStruct_Size
|
|
if ( typeId != ID_SET_RANDOM_NUMBER_SEED )
|
|
return packet;
|
|
|
|
inBitStream.Read(in_seed);
|
|
inBitStream.Read(in_nextSeed);
|
|
|
|
seed = in_seed;
|
|
nextSeed = in_nextSeed;
|
|
nextSeedUpdate = timeStamp + 9000; // Seeds are updated every 9 seconds
|
|
|
|
DeallocatePacket( packet );
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return packet;
|
|
}
|
|
|
|
void RakClient::DeallocatePacket( Packet *packet )
|
|
{
|
|
RakPeer::DeallocatePacket( packet );
|
|
}
|
|
|
|
void RakClient::PingServer( void )
|
|
{
|
|
if ( remoteSystemList == 0 )
|
|
return ;
|
|
|
|
RakPeer::Ping( remoteSystemList[ 0 ].playerId );
|
|
}
|
|
|
|
void RakClient::PingServer( const char* host, unsigned short serverPort, unsigned short clientPort, bool onlyReplyOnAcceptingConnections )
|
|
{
|
|
RakPeer::Initialize( 1, clientPort, 0 );
|
|
RakPeer::Ping( host, serverPort, onlyReplyOnAcceptingConnections );
|
|
}
|
|
|
|
int RakClient::GetAveragePing( void )
|
|
{
|
|
if ( remoteSystemList == 0 )
|
|
return -1;
|
|
|
|
return RakPeer::GetAveragePing( remoteSystemList[ 0 ].playerId );
|
|
}
|
|
|
|
int RakClient::GetLastPing( void ) const
|
|
{
|
|
if ( remoteSystemList == 0 )
|
|
return -1;
|
|
|
|
return RakPeer::GetLastPing( remoteSystemList[ 0 ].playerId );
|
|
}
|
|
|
|
int RakClient::GetLowestPing( void ) const
|
|
{
|
|
if ( remoteSystemList == 0 )
|
|
return -1;
|
|
|
|
return RakPeer::GetLowestPing( remoteSystemList[ 0 ].playerId );
|
|
}
|
|
|
|
int RakClient::GetPlayerPing( const PlayerID playerId )
|
|
{
|
|
int i;
|
|
|
|
for ( i = 0; i < 32; i++ )
|
|
if ( otherClients[ i ].playerId == playerId )
|
|
return otherClients[ i ].ping;
|
|
|
|
return -1;
|
|
}
|
|
|
|
void RakClient::StartOccasionalPing( void )
|
|
{
|
|
RakPeer::SetOccasionalPing( true );
|
|
}
|
|
|
|
void RakClient::StopOccasionalPing( void )
|
|
{
|
|
RakPeer::SetOccasionalPing( false );
|
|
}
|
|
|
|
bool RakClient::IsConnected( void ) const
|
|
{
|
|
unsigned short numberOfSystems;
|
|
|
|
RakPeer::GetConnectionList( 0, &numberOfSystems );
|
|
return numberOfSystems == 1;
|
|
}
|
|
|
|
unsigned int RakClient::GetSynchronizedRandomInteger( void ) const
|
|
{
|
|
if ( RakNet::GetTime() > nextSeedUpdate )
|
|
return nextSeed;
|
|
else
|
|
return seed;
|
|
}
|
|
|
|
bool RakClient::GenerateCompressionLayer( unsigned int inputFrequencyTable[ 256 ], bool inputLayer )
|
|
{
|
|
return RakPeer::GenerateCompressionLayer( inputFrequencyTable, inputLayer );
|
|
}
|
|
|
|
bool RakClient::DeleteCompressionLayer( bool inputLayer )
|
|
{
|
|
return RakPeer::DeleteCompressionLayer( inputLayer );
|
|
}
|
|
|
|
void RakClient::RegisterAsRemoteProcedureCall( char* uniqueID, void ( *functionPointer ) ( RPCParameters *rpcParms ) )
|
|
{
|
|
RakPeer::RegisterAsRemoteProcedureCall( uniqueID, functionPointer );
|
|
}
|
|
|
|
void RakClient::RegisterClassMemberRPC( char* uniqueID, void *functionPointer )
|
|
{
|
|
RakPeer::RegisterClassMemberRPC( uniqueID, functionPointer );
|
|
}
|
|
|
|
void RakClient::UnregisterAsRemoteProcedureCall( char* uniqueID )
|
|
{
|
|
RakPeer::UnregisterAsRemoteProcedureCall( uniqueID );
|
|
}
|
|
|
|
bool RakClient::RPC( char* uniqueID, const char *data, unsigned int bitLength, PacketPriority priority, PacketReliability reliability, char orderingChannel, bool shiftTimestamp, NetworkID networkID, RakNet::BitStream *replyFromTarget )
|
|
{
|
|
if ( remoteSystemList == 0 )
|
|
return false;
|
|
|
|
return RakPeer::RPC( uniqueID, data, bitLength, priority, reliability, orderingChannel, remoteSystemList[ 0 ].playerId, false, shiftTimestamp, networkID, replyFromTarget );
|
|
}
|
|
|
|
bool RakClient::RPC( char* uniqueID, RakNet::BitStream *parameters, PacketPriority priority, PacketReliability reliability, char orderingChannel, bool shiftTimestamp, NetworkID networkID, RakNet::BitStream *replyFromTarget )
|
|
{
|
|
if ( remoteSystemList == 0 )
|
|
return false;
|
|
|
|
return RakPeer::RPC( uniqueID, parameters, priority, reliability, orderingChannel, remoteSystemList[ 0 ].playerId, false, shiftTimestamp, networkID, replyFromTarget );
|
|
}
|
|
|
|
// SAMPSRV (adding this just as a tag for next RakNet upgrade)
|
|
bool RakClient::RPC( char* uniqueID, RakNet::BitStream *parameters, PacketPriority priority, PacketReliability reliability, char orderingChannel, bool shiftTimestamp )
|
|
{
|
|
if ( remoteSystemList == 0 )
|
|
return false;
|
|
|
|
return RakPeer::RPC( uniqueID, parameters, priority, reliability, orderingChannel, remoteSystemList[ 0 ].playerId, false, shiftTimestamp, UNASSIGNED_NETWORK_ID, 0 );
|
|
}
|
|
// SAMPSRV end
|
|
|
|
void RakClient::SetTrackFrequencyTable( bool b )
|
|
{
|
|
RakPeer::SetCompileFrequencyTable( b );
|
|
}
|
|
|
|
bool RakClient::GetSendFrequencyTable( unsigned int outputFrequencyTable[ 256 ] )
|
|
{
|
|
return RakPeer::GetOutgoingFrequencyTable( outputFrequencyTable );
|
|
}
|
|
|
|
float RakClient::GetCompressionRatio( void ) const
|
|
{
|
|
return RakPeer::GetCompressionRatio();
|
|
}
|
|
|
|
float RakClient::GetDecompressionRatio( void ) const
|
|
{
|
|
return RakPeer::GetDecompressionRatio();
|
|
}
|
|
|
|
void RakClient::AttachPlugin( PluginInterface *messageHandler )
|
|
{
|
|
RakPeer::AttachPlugin(messageHandler);
|
|
}
|
|
|
|
void RakClient::DetachPlugin( PluginInterface *messageHandler )
|
|
{
|
|
RakPeer::DetachPlugin(messageHandler);
|
|
}
|
|
|
|
RakNet::BitStream * RakClient::GetStaticServerData( void )
|
|
{
|
|
if ( remoteSystemList == 0 )
|
|
return 0;
|
|
|
|
return RakPeer::GetRemoteStaticData( remoteSystemList[ 0 ].playerId );
|
|
}
|
|
|
|
void RakClient::SetStaticServerData( const char *data, const int length )
|
|
{
|
|
if ( remoteSystemList == 0 )
|
|
return ;
|
|
|
|
RakPeer::SetRemoteStaticData( remoteSystemList[ 0 ].playerId, data, length );
|
|
}
|
|
|
|
RakNet::BitStream * RakClient::GetStaticClientData( const PlayerID playerId )
|
|
{
|
|
int i;
|
|
|
|
if ( playerId == UNASSIGNED_PLAYER_ID )
|
|
{
|
|
return & localStaticData;
|
|
}
|
|
|
|
else
|
|
{
|
|
i = GetOtherClientIndexByPlayerID( playerId );
|
|
|
|
if ( i >= 0 )
|
|
{
|
|
return & ( otherClients[ i ].staticData );
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void RakClient::SetStaticClientData( const PlayerID playerId, const char *data, const int length )
|
|
{
|
|
int i;
|
|
|
|
if ( playerId == UNASSIGNED_PLAYER_ID )
|
|
{
|
|
localStaticData.Reset();
|
|
localStaticData.Write( data, length );
|
|
}
|
|
|
|
else
|
|
{
|
|
i = GetOtherClientIndexByPlayerID( playerId );
|
|
|
|
if ( i >= 0 )
|
|
{
|
|
otherClients[ i ].staticData.Reset();
|
|
otherClients[ i ].staticData.Write( data, length );
|
|
}
|
|
|
|
else
|
|
RakPeer::SetRemoteStaticData( playerId, data, length );
|
|
}
|
|
|
|
}
|
|
|
|
void RakClient::SendStaticClientDataToServer( void )
|
|
{
|
|
if ( remoteSystemList == 0 )
|
|
return ;
|
|
|
|
RakPeer::SendStaticData( remoteSystemList[ 0 ].playerId );
|
|
}
|
|
|
|
PlayerID RakClient::GetServerID( void ) const
|
|
{
|
|
if ( remoteSystemList == 0 )
|
|
return UNASSIGNED_PLAYER_ID;
|
|
|
|
return remoteSystemList[ 0 ].playerId;
|
|
}
|
|
|
|
PlayerID RakClient::GetPlayerID( void ) const
|
|
{
|
|
if ( remoteSystemList == 0 )
|
|
return UNASSIGNED_PLAYER_ID;
|
|
|
|
// GetExternalID is more accurate because it reflects our external IP and port to the server.
|
|
// GetInternalID only matches the parameters we passed
|
|
PlayerID myID = RakPeer::GetExternalID( remoteSystemList[ 0 ].playerId );
|
|
|
|
if ( myID == UNASSIGNED_PLAYER_ID )
|
|
return RakPeer::GetInternalID();
|
|
else
|
|
return myID;
|
|
}
|
|
|
|
PlayerID RakClient::GetInternalID( void ) const
|
|
{
|
|
return RakPeer::GetInternalID();
|
|
}
|
|
|
|
const char* RakClient::PlayerIDToDottedIP( const PlayerID playerId ) const
|
|
{
|
|
return RakPeer::PlayerIDToDottedIP( playerId );
|
|
}
|
|
|
|
void RakClient::PushBackPacket( Packet *packet, bool pushAtHead )
|
|
{
|
|
RakPeer::PushBackPacket(packet, pushAtHead);
|
|
}
|
|
|
|
void RakClient::SetRouterInterface( RouterInterface *routerInterface )
|
|
{
|
|
RakPeer::SetRouterInterface(routerInterface);
|
|
}
|
|
void RakClient::RemoveRouterInterface( RouterInterface *routerInterface )
|
|
{
|
|
RakPeer::RemoveRouterInterface(routerInterface);
|
|
}
|
|
|
|
void RakClient::SetTimeoutTime( RakNetTime timeMS )
|
|
{
|
|
RakPeer::SetTimeoutTime( timeMS, GetServerID() );
|
|
}
|
|
|
|
bool RakClient::SetMTUSize( int size )
|
|
{
|
|
return RakPeer::SetMTUSize( size );
|
|
}
|
|
|
|
int RakClient::GetMTUSize( void ) const
|
|
{
|
|
return RakPeer::GetMTUSize();
|
|
}
|
|
|
|
void RakClient::AllowConnectionResponseIPMigration( bool allow )
|
|
{
|
|
RakPeer::AllowConnectionResponseIPMigration( allow );
|
|
}
|
|
|
|
void RakClient::AdvertiseSystem( const char *host, unsigned short remotePort, const char *data, int dataLength )
|
|
{
|
|
RakPeer::AdvertiseSystem( host, remotePort, data, dataLength );
|
|
}
|
|
|
|
RakNetStatisticsStruct* const RakClient::GetStatistics( void )
|
|
{
|
|
return RakPeer::GetStatistics( remoteSystemList[ 0 ].playerId );
|
|
}
|
|
|
|
void RakClient::ApplyNetworkSimulator( double maxSendBPS, unsigned short minExtraPing, unsigned short extraPingVariance)
|
|
{
|
|
RakPeer::ApplyNetworkSimulator( maxSendBPS, minExtraPing, extraPingVariance );
|
|
}
|
|
|
|
bool RakClient::IsNetworkSimulatorActive( void )
|
|
{
|
|
return RakPeer::IsNetworkSimulatorActive();
|
|
}
|
|
|
|
int RakClient::GetOtherClientIndexByPlayerID( const PlayerID playerId )
|
|
{
|
|
unsigned i;
|
|
|
|
for ( i = 0; i < 32; i++ )
|
|
{
|
|
if ( otherClients[ i ].playerId == playerId )
|
|
return i;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int RakClient::GetFreeOtherClientIndex( void )
|
|
{
|
|
unsigned i;
|
|
|
|
for ( i = 0; i < 32; i++ )
|
|
{
|
|
if ( otherClients[ i ].isActive == false )
|
|
return i;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
PlayerIndex RakClient::GetPlayerIndex( void )
|
|
{
|
|
return localPlayerIndex;
|
|
}
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning( pop )
|
|
#endif
|