void sendPickUp(int iPickupID) { RakNet::BitStream bsSend; bsSend.Write(iPickupID); pRakClient->RPC(&RPC_PickedUpPickup, &bsSend, HIGH_PRIORITY, RELIABLE_ORDERED, 0, FALSE, UNASSIGNED_NETWORK_ID, NULL); }
void CChat::ProcessInput( void ) { // Are we not connected? if( !pCore->GetNetworkModule() || !pCore->GetNetworkModule()->IsConnected() ) return; // Was anything entered? if( m_strInput.GetLength() > 0 ) { // Is the input a command? bool bIsCommand = (m_strInput.GetChar( 0 ) == CHAT_CMD_CHAR); // Internal cmds bool bHasUsedCmd = false; // Process internal commands if( bIsCommand ) { // std::string sInput = m_strInput.Get(); // Get the end of the command size_t sCommandEnd = sInput.find( " " ); // If we don't have a valid end use the end of the string if ( sCommandEnd == std::string::npos ) sCommandEnd = sInput.length(); // Get the command name std::string strCommand = sInput.substr( 1, (sCommandEnd - 1) ); // Get the command parameters std::string strParams; // Do we have any parameters? if( sCommandEnd < sInput.length() ) strParams = sInput.substr( (sCommandEnd + 1), sInput.length() ); if( strCommand == "q" || strCommand == "quit" || strCommand == "exit" ) { // Shutdown pCore->Shutdown(); return; } else if( strCommand == "disconnect" ) { // Are we connected? if( pCore->GetNetworkModule() && pCore->GetNetworkModule()->IsConnected() ) { // Disconnect from the network pCore->GetNetworkModule()->Disconnect(); // Stop multiplayer pCore->StopMultiplayer(); // Go back to main menu pCore->GetGUI()->GetMainMenu()->SetVisible( true ); } bHasUsedCmd = true; } else if( strCommand == "savepos" ) { bHasUsedCmd = true; // Are we spawned? if( pCore->GetPlayerManager()->GetLocalPlayer()->IsSpawned() ) { // CVector3 vecPosition; CVector3 vecRotation; bool bOnFoot = true; // Is the player on-foot? if( pCore->GetPlayerManager()->GetLocalPlayer()->GetState() == ePlayerState::PLAYERSTATE_ONFOOT ) { // Get the localplayer position pCore->GetPlayerManager()->GetLocalPlayer()->GetPosition( &vecPosition ); // Get the localplayer rotation pCore->GetPlayerManager()->GetLocalPlayer()->GetRotation( &vecRotation ); } else if( pCore->GetPlayerManager()->GetLocalPlayer()->GetState() == ePlayerState::PLAYERSTATE_DRIVER || pCore->GetPlayerManager()->GetLocalPlayer()->GetState() == ePlayerState::PLAYERSTATE_PASSENGER ) { // Get the vehicle position pCore->GetPlayerManager()->GetLocalPlayer()->GetVehicle()->GetPosition( &vecPosition ); // Get the vehicle rotation pCore->GetPlayerManager()->GetLocalPlayer()->GetVehicle()->GetRotation( &vecRotation ); // bOnFoot = false; } // Open the saved positions file FILE * pFile = fopen( SharedUtility::GetAbsolutePath( "data\\savedpositions.txt" ).Get(), "a" ); // Did the file open? if( pFile ) { // Get the localplayer pointer CLocalPlayer * pLocalPlayer = pCore->GetPlayerManager()->GetLocalPlayer(); // Save the player position fprintf( pFile, "%d, %f, %f, %f, %f, %f, %f // %s\n", (bOnFoot ? pLocalPlayer->GetModel () : pLocalPlayer->GetVehicle()->GetModel ()), vecPosition.fX, vecPosition.fY, vecPosition.fZ, vecRotation.fX, vecRotation.fY, vecRotation.fZ, strParams.c_str() ); // Close the saved positions file fclose( pFile ); // AddInfoMessage( (bOnFoot ? " -> Onfoot position saved!" : " -> Invehicle position saved!") ); } else { // AddInfoMessage( CColor( 255, 0, 0, 255 ), "Failed to open savedpositions.txt" ); } } } #ifdef DEBUG else if( strCommand == "lua" ) { bHasUsedCmd = true; if( CLua::Execute( strParams.c_str() ) ) AddInfoMessage( CColor( 50, 177, 94, 255 ), strParams.c_str() ); else AddInfoMessage( CColor( 178, 40, 86, 255 ), strParams.c_str() ); } #endif } // Have we used a command? if( bHasUsedCmd ) { // Add this command to the history AddToHistory(); // This is an internal command, don't pass it to the server! return; } // Is the network module instance valid? if( pCore->GetNetworkModule() ) { // Are we connected? if( pCore->GetNetworkModule()->IsConnected() ) { RakNet::BitStream bitStream; RakNet::RakString strInput; // Is this a command? if( bIsCommand ) { // Write 1 bitStream.Write1(); // Set the input minus the command character strInput = (GetInputText() + 1); } else { // Write 0 bitStream.Write0(); // Set the input strInput = GetInputText(); } // Write the input bitStream.Write( strInput ); // Call the client event CSquirrelArguments pArguments; pArguments.push( strInput.C_String () ); // Should we send this message? if ( pCore->GetClientScriptingManager()->GetEvents()->Call( "onClientChat", &pArguments ).GetInteger() == 1 ) { // Send it to the server pCore->GetNetworkModule()->Call( RPC_PLAYER_CHAT, &bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, true ); // Add this message to the history AddToHistory(); // Add the chat message for the localplayer if it's not a command if ( !bIsCommand ) AddChatMessage( pCore->GetPlayerManager()->GetLocalPlayer(), GetInputText() ); } } } } }
void AutoRPC::OnAutoRPCCall(SystemAddress systemAddress, unsigned char *data, unsigned int lengthInBytes) { RakNet::BitStream bs(data,lengthInBytes,false); bool hasParameterCount=false; char parameterCount; char inputStack[ARPC_MAX_STACK_SIZE]; NetworkIDObject *networkIdObject; NetworkID networkId; bool hasNetworkId=false; bool hasFunctionIndex=false; unsigned int functionIndex; unsigned int bytesOnStack; char strIdentifier[512]; int numberOfBitsUsed; incomingExtraData.Reset(); bs.Read(hasParameterCount); if (hasParameterCount) bs.Read(parameterCount); else parameterCount=-1; bs.ReadCompressed(numberOfBitsUsed); if (numberOfBitsUsed > (int) incomingExtraData.GetNumberOfBitsAllocated()) incomingExtraData.AddBitsAndReallocate(numberOfBitsUsed-(int) incomingExtraData.GetNumberOfBitsAllocated()); bs.ReadBits(incomingExtraData.GetData(), numberOfBitsUsed, false); incomingExtraData.SetWriteOffset(numberOfBitsUsed); // const unsigned int outputStackSize = ARPC_MAX_STACK_SIZE+128*4; // Enough padding to round up to 4 for each parameter, max 128 parameters // char outputStack[outputStackSize]; bs.Read(hasNetworkId); if (hasNetworkId) { bs.Read(networkId); if (networkIdManager==0 && (networkIdManager=rakPeerInterface->GetNetworkIDManager())==0) { // Failed - Tried to call object member, however, networkIDManager system was never registered SendError(systemAddress, RPC_ERROR_NETWORK_ID_MANAGER_UNAVAILABLE, ""); return; } networkIdObject = networkIdManager->GET_OBJECT_FROM_ID<NetworkIDObject*>(networkId); if (networkIdObject==0) { // Failed - Tried to call object member, object does not exist (deleted?) SendError(systemAddress, RPC_ERROR_OBJECT_DOES_NOT_EXIST, ""); return; } } else { networkIdObject=0; } bs.AlignReadToByteBoundary(); bs.Read(hasFunctionIndex); if (hasFunctionIndex) bs.ReadCompressed(functionIndex); else stringCompressor->DecodeString(strIdentifier,512,&bs,0); bs.ReadCompressed(bytesOnStack); bs.ReadAlignedBytes((unsigned char *) inputStack,bytesOnStack); if (hasFunctionIndex) { if (functionIndex>localFunctions.Size()) { // Failed - other system specified a totally invalid index // Possible causes: Bugs, attempts to crash the system, requested function not registered SendError(systemAddress, RPC_ERROR_FUNCTION_INDEX_OUT_OF_RANGE, ""); return; } // it was actually a mistake to implement ID_AUTO_RPC_UNKNOWN_REMOTE_INDEX. This hides the more relevant return code RPC_ERROR_FUNCTION_NO_LONGER_REGISTERED and more importantly can result in the calls being out of order since it takes extra communication steps. /* if (localFunctions[functionIndex].functionPtr==0) { // Failed - Function index lookup failure. Try passing back what was sent to us, and requesting the string RakNet::BitStream out; if (incomingTimeStamp!=0) { out.Write((MessageID)ID_TIMESTAMP); out.Write(incomingTimeStamp); } out.Write((MessageID)ID_AUTO_RPC_UNKNOWN_REMOTE_INDEX); if (parameterCount>=0) { out.Write(true); out.Write(parameterCount); } else { out.Write(false); } out.WriteCompressed(functionIndex); out.WriteCompressed(numberOfBitsUsed); out.Write(&incomingExtraData); out.Write(hasNetworkId); if (hasNetworkId) out.Write(networkId); out.WriteCompressed(bytesOnStack); out.WriteAlignedBytes((const unsigned char*) inputStack, bytesOnStack); SendUnified(&out, HIGH_PRIORITY, RELIABLE_ORDERED, 0, systemAddress, false); return; } */ } else { // Find the registered function with this str for (functionIndex=0; functionIndex < localFunctions.Size(); functionIndex++) { if (localFunctions[functionIndex].identifier.isObjectMember == (networkIdObject!=0) && strcmp(localFunctions[functionIndex].identifier.uniqueIdentifier, strIdentifier)==0) { // SEND RPC MAPPING RakNet::BitStream outgoingBitstream; outgoingBitstream.Write((MessageID)ID_AUTO_RPC_REMOTE_INDEX); outgoingBitstream.Write(hasNetworkId); outgoingBitstream.WriteCompressed(functionIndex); stringCompressor->EncodeString(strIdentifier,512,&outgoingBitstream,0); SendUnified(&outgoingBitstream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, systemAddress, false); break; } } if (functionIndex==localFunctions.Size()) { for (functionIndex=0; functionIndex < localFunctions.Size(); functionIndex++) { if (strcmp(localFunctions[functionIndex].identifier.uniqueIdentifier, strIdentifier)==0) { if (localFunctions[functionIndex].identifier.isObjectMember==true && networkIdObject==0) { // Failed - Calling C++ function as C function SendError(systemAddress, RPC_ERROR_CALLING_CPP_AS_C, strIdentifier); return; } if (localFunctions[functionIndex].identifier.isObjectMember==false && networkIdObject!=0) { // Failed - Calling C++ function as C function SendError(systemAddress, RPC_ERROR_CALLING_C_AS_CPP, strIdentifier); return; } } } SendError(systemAddress, RPC_ERROR_FUNCTION_NOT_REGISTERED, strIdentifier); return; } } if (localFunctions[functionIndex].functionPtr==0) { // Failed - Function was previously registered, but isn't registered any longer SendError(systemAddress, RPC_ERROR_FUNCTION_NO_LONGER_REGISTERED, localFunctions[functionIndex].identifier.uniqueIdentifier); return; } if (bytesOnStack > ARPC_MAX_STACK_SIZE) { // Failed - Not enough bytes on predetermined stack. Shouldn't hit this since the sender also uses this value SendError(systemAddress, RPC_ERROR_STACK_TOO_SMALL, localFunctions[functionIndex].identifier.uniqueIdentifier); return; } if (localFunctions[functionIndex].parameterCount>=0 && parameterCount>=0 && parameterCount!=localFunctions[functionIndex].parameterCount) { // Failed - The number of parameters that this function has was explicitly specified, and does not match up. SendError(systemAddress, RPC_ERROR_INCORRECT_NUMBER_OF_PARAMETERS, localFunctions[functionIndex].identifier.uniqueIdentifier); return; } // unsigned int bytesWritten; // unsigned char numParameters; // unsigned int parameterLengths[64]; // 64 is arbitrary, just needs to be more than whatever might be serialized GenRPC::CallParams call; if (DeserializeParametersAndBuildCall(call, inputStack, bytesOnStack, this, networkIdObject)==false) { // Failed - Couldn't deserialize SendError(systemAddress, RPC_ERROR_STACK_DESERIALIZATION_FAILED, localFunctions[functionIndex].identifier.uniqueIdentifier); return; } strncpy(currentExecution, localFunctions[functionIndex].identifier.uniqueIdentifier, sizeof(currentExecution)-1); if (!CallWithStack( call, localFunctions[functionIndex].functionPtr)){ // Failed - Couldn't deserialize SendError(systemAddress, RPC_ERROR_STACK_DESERIALIZATION_FAILED, currentExecution); return; } currentExecution[0]=0; }
void InitialData(RakNet::BitStream * pBitStream, RakNet::Packet * pPacket) { // Get the playerid EntityId playerId = (EntityId) pPacket->guid.systemIndex; // Read the player version DWORD dwVersion; pBitStream->Read(dwVersion); // Read the player name RakNet::RakString _strName; pBitStream->Read(_strName); CString strName(_strName.C_String()); // Read the player serial RakNet::RakString _strSerial; pBitStream->Read(_strSerial); CString strSerial(_strSerial.C_String()); // Is the network version invalid? if (dwVersion != (DWORD)/*NETWORK_VERSION*/0x0) { // TODO } // Is the nickname already in use? // TODO: check is nick in use // Is the player banned? // TODO: check is banned // Add the player to the manager // TODO: add to player manager CPlayerEntity * pPlayer = new CPlayerEntity(); pPlayer->SetName(strName); // Do we need the id; maybe internal for easier sync but definetly not public to the scripting engine pPlayer->SetId(CServer::GetInstance()->GetPlayerManager()->Add(pPlayer)); playerId = pPlayer->GetId(); srand(time(NULL)); pPlayer->SetColor(CColor(rand() % 256, rand() % 256, rand() % 256).dwHexColor); //generate random color CLogFile::Printf("[join] %s (%i) has connected to the server. (%s)", strName.Get(), playerId, strSerial.Get()); CScriptArguments args; CScriptPlayer * pScriptPlayer = new CScriptPlayer(); pScriptPlayer->SetEntity(pPlayer); pPlayer->SetScriptPlayer(pScriptPlayer); args.push(pScriptPlayer); CEvents::GetInstance()->Call("playerJoin", &args, CEventHandler::eEventType::NATIVE_EVENT, 0); // Construct a new bitstream RakNet::BitStream bitStream; // Write the player id bitStream.Write(playerId); // Write the player colour bitStream.Write(pPlayer->GetColor()); // Write the server name bitStream.Write(RakNet::RakString("IV:Network DEV Server")); // Write the max player count bitStream.Write(CVAR_GET_INTEGER("maxplayers")); // Write the port bitStream.Write(CVAR_GET_INTEGER("port")); // Send it back to the player CServer::GetInstance()->GetNetworkModule()->Call(GET_RPC_CODEX(RPC_INITIAL_DATA), &bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, playerId, false); for (EntityId i = 0; i < CServer::GetInstance()->GetPlayerManager()->GetMax(); ++i) { if (CServer::GetInstance()->GetPlayerManager()->DoesExists(i) && i != playerId) { bitStream.Reset(); bitStream.Write(i); bitStream.Write(CServer::GetInstance()->GetPlayerManager()->GetAt(i)->GetName().Get()); bitStream.Write(CServer::GetInstance()->GetPlayerManager()->GetAt(i)->GetColor()); CServer::GetInstance()->GetNetworkModule()->Call(GET_RPC_CODEX(RPC_NEW_PLAYER), &bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, playerId, false); } } for (EntityId i = 0; i < CServer::GetInstance()->GetPlayerManager()->GetMax(); ++i) { if (CServer::GetInstance()->GetPlayerManager()->DoesExists(i) && i != playerId) { bitStream.Reset(); bitStream.Write(playerId); bitStream.Write(pPlayer->GetName().Get()); bitStream.Write(pPlayer->GetColor()); CServer::GetInstance()->GetNetworkModule()->Call(GET_RPC_CODEX(RPC_NEW_PLAYER), &bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, i, false); } } for (EntityId i = 0; i < CServer::GetInstance()->GetVehicleManager()->GetMax(); ++i) { if (CServer::GetInstance()->GetVehicleManager()->DoesExists(i)) { bitStream.Reset(); CVehicleEntity * pVehicle = CServer::GetInstance()->GetVehicleManager()->GetAt(i); bitStream.Write(pVehicle->GetId()); bitStream.Write(pVehicle->GetModelId()); CVector3 vecPosition; pVehicle->GetPosition(vecPosition); bitStream.Write(vecPosition); CVector3 vecRotation; pVehicle->GetRotation(vecRotation); bitStream.Write(vecRotation.fX); bitStream.Write(pVehicle->GetColor(1)); bitStream.Write(pVehicle->GetColor(2)); bitStream.Write(pVehicle->GetColor(3)); bitStream.Write(pVehicle->GetColor(4)); bitStream.Write(pVehicle->GetColor(5)); CServer::GetInstance()->GetNetworkModule()->Call(GET_RPC_CODEX(RPC_CREATE_VEHICLE), &bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, playerId, false); } } bitStream.Reset(); bitStream.Write(playerId); bitStream.Write(7); bitStream.Write(3); bitStream.Write(3); bitStream.Write(1); }
void NatTypeDetectionServer::Update(void) { int i=0; RakNet::TimeMS time = RakNet::GetTimeMS(); RakNet::BitStream bs; SystemAddress boundAddress; RNS2RecvStruct *recvStruct; bufferedPacketsMutex.Lock(); if (bufferedPackets.Size()>0) recvStruct=bufferedPackets.Pop(); else recvStruct=0; bufferedPacketsMutex.Unlock(); while (recvStruct) { SystemAddress senderAddr = recvStruct->systemAddress; char *data = recvStruct->data; if (data[0]==NAT_TYPE_PORT_RESTRICTED && recvStruct->socket==s3p4) { RakNet::BitStream bsIn((unsigned char*) data,recvStruct->bytesRead,false); RakNetGUID senderGuid; bsIn.IgnoreBytes(sizeof(MessageID)); bool readSuccess = bsIn.Read(senderGuid); RakAssert(readSuccess); if (readSuccess) { unsigned int i = GetDetectionAttemptIndex(senderGuid); if (i!=(unsigned int)-1) { bs.Reset(); bs.Write((unsigned char) ID_NAT_TYPE_DETECTION_RESULT); // If different, then symmetric if (senderAddr!=natDetectionAttempts[i].systemAddress) { #ifdef NTDS_VERBOSE printf("Determined client is symmetric\n"); #endif bs.Write((unsigned char) NAT_TYPE_SYMMETRIC); } else { // else port restricted #ifdef NTDS_VERBOSE printf("Determined client is port restricted\n"); #endif bs.Write((unsigned char) NAT_TYPE_PORT_RESTRICTED); } rakPeerInterface->Send(&bs,HIGH_PRIORITY,RELIABLE,0,natDetectionAttempts[i].systemAddress,false); // Done natDetectionAttempts.RemoveAtIndexFast(i); } else { // RakAssert("i==0 in Update when looking up GUID in NatTypeDetectionServer.cpp. Either a bug or a late resend" && 0); } } else { // RakAssert("Didn't read GUID in Update in NatTypeDetectionServer.cpp. Message format error" && 0); } } DeallocRNS2RecvStruct(recvStruct, _FILE_AND_LINE_); bufferedPacketsMutex.Lock(); if (bufferedPackets.Size()>0) recvStruct=bufferedPackets.Pop(); else recvStruct=0; bufferedPacketsMutex.Unlock(); } /* // Only socket that receives messages is s3p4, to see if the external address is different than that of the connection to rakPeerInterface char data[ MAXIMUM_MTU_SIZE ]; int len; SystemAddress senderAddr; len=NatTypeRecvFrom(data, s3p4, senderAddr); // Client is asking us if this is port restricted. Only client requests of this type come in on s3p4 while (len>0 && data[0]==NAT_TYPE_PORT_RESTRICTED) { RakNet::BitStream bsIn((unsigned char*) data,len,false); RakNetGUID senderGuid; bsIn.IgnoreBytes(sizeof(MessageID)); bool readSuccess = bsIn.Read(senderGuid); RakAssert(readSuccess); if (readSuccess) { unsigned int i = GetDetectionAttemptIndex(senderGuid); if (i!=(unsigned int)-1) { bs.Reset(); bs.Write((unsigned char) ID_NAT_TYPE_DETECTION_RESULT); // If different, then symmetric if (senderAddr!=natDetectionAttempts[i].systemAddress) { #ifdef NTDS_VERBOSE printf("Determined client is symmetric\n"); #endif bs.Write((unsigned char) NAT_TYPE_SYMMETRIC); } else { // else port restricted #ifdef NTDS_VERBOSE printf("Determined client is port restricted\n"); #endif bs.Write((unsigned char) NAT_TYPE_PORT_RESTRICTED); } rakPeerInterface->Send(&bs,HIGH_PRIORITY,RELIABLE,0,natDetectionAttempts[i].systemAddress,false); // Done natDetectionAttempts.RemoveAtIndexFast(i); } else { // RakAssert("i==0 in Update when looking up GUID in NatTypeDetectionServer.cpp. Either a bug or a late resend" && 0); } } else { // RakAssert("Didn't read GUID in Update in NatTypeDetectionServer.cpp. Message format error" && 0); } len=NatTypeRecvFrom(data, s3p4, senderAddr); } */ while (i < (int) natDetectionAttempts.Size()) { if (time > natDetectionAttempts[i].nextStateTime) { RNS2_SendParameters bsp; natDetectionAttempts[i].detectionState=(NATDetectionState)((int)natDetectionAttempts[i].detectionState+1); natDetectionAttempts[i].nextStateTime=time+natDetectionAttempts[i].timeBetweenAttempts; SystemAddress saOut; unsigned char c; bs.Reset(); switch (natDetectionAttempts[i].detectionState) { case STATE_TESTING_NONE_1: case STATE_TESTING_NONE_2: c = NAT_TYPE_NONE; #ifdef NTDS_VERBOSE printf("Testing NAT_TYPE_NONE\n"); #endif // S4P5 sends to C2. If arrived, no NAT. Done. (Else S4P5 potentially banned, do not use again). saOut=natDetectionAttempts[i].systemAddress; saOut.SetPortHostOrder(natDetectionAttempts[i].c2Port); // SocketLayer::SendTo_PC( s4p5, (const char*) &c, 1, saOut, __FILE__, __LINE__ ); bsp.data = (char*) &c; bsp.length = 1; bsp.systemAddress = saOut; s4p5->Send(&bsp, _FILE_AND_LINE_); break; case STATE_TESTING_FULL_CONE_1: case STATE_TESTING_FULL_CONE_2: #ifdef NTDS_VERBOSE printf("Testing NAT_TYPE_FULL_CONE\n"); #endif rakPeerInterface->WriteOutOfBandHeader(&bs); bs.Write((unsigned char) ID_NAT_TYPE_DETECT); bs.Write((unsigned char) NAT_TYPE_FULL_CONE); // S2P3 sends to C1 (Different address, different port, to previously used port on client). If received, Full-cone nat. Done. (Else S2P3 potentially banned, do not use again). saOut=natDetectionAttempts[i].systemAddress; saOut.SetPortHostOrder(natDetectionAttempts[i].systemAddress.GetPort()); // SocketLayer::SendTo_PC( s2p3, (const char*) bs.GetData(), bs.GetNumberOfBytesUsed(), saOut, __FILE__, __LINE__ ); bsp.data = (char*) bs.GetData(); bsp.length = bs.GetNumberOfBytesUsed(); bsp.systemAddress = saOut; s2p3->Send(&bsp, _FILE_AND_LINE_); break; case STATE_TESTING_ADDRESS_RESTRICTED_1: case STATE_TESTING_ADDRESS_RESTRICTED_2: #ifdef NTDS_VERBOSE printf("Testing NAT_TYPE_ADDRESS_RESTRICTED\n"); #endif rakPeerInterface->WriteOutOfBandHeader(&bs); bs.Write((unsigned char) ID_NAT_TYPE_DETECT); bs.Write((unsigned char) NAT_TYPE_ADDRESS_RESTRICTED); // S1P2 sends to C1 (Same address, different port, to previously used port on client). If received, address-restricted cone nat. Done. saOut=natDetectionAttempts[i].systemAddress; saOut.SetPortHostOrder(natDetectionAttempts[i].systemAddress.GetPort()); //SocketLayer::SendTo_PC( s1p2, (const char*) bs.GetData(), bs.GetNumberOfBytesUsed(), saOut, __FILE__, __LINE__ ); bsp.data = (char*) bs.GetData(); bsp.length = bs.GetNumberOfBytesUsed(); bsp.systemAddress = saOut; s1p2->Send(&bsp, _FILE_AND_LINE_); break; case STATE_TESTING_PORT_RESTRICTED_1: case STATE_TESTING_PORT_RESTRICTED_2: // C1 sends to S3P4. If address of C1 as seen by S3P4 is the same as the address of C1 as seen by S1P1, then port-restricted cone nat. Done #ifdef NTDS_VERBOSE printf("Testing NAT_TYPE_PORT_RESTRICTED\n"); #endif bs.Write((unsigned char) ID_NAT_TYPE_DETECTION_REQUEST); bs.Write(RakString::NonVariadic(s3p4Address)); bs.Write(s3p4->GetBoundAddress().GetPort()); rakPeerInterface->Send(&bs,HIGH_PRIORITY,RELIABLE,0,natDetectionAttempts[i].systemAddress,false); break; default: #ifdef NTDS_VERBOSE printf("Warning, exceeded final check STATE_TESTING_PORT_RESTRICTED_2.\nExpected that client would have sent NAT_TYPE_PORT_RESTRICTED on s3p4.\nDefaulting to Symmetric\n"); #endif bs.Write((unsigned char) ID_NAT_TYPE_DETECTION_RESULT); bs.Write((unsigned char) NAT_TYPE_SYMMETRIC); rakPeerInterface->Send(&bs,HIGH_PRIORITY,RELIABLE,0,natDetectionAttempts[i].systemAddress,false); natDetectionAttempts.RemoveAtIndexFast(i); i--; break; } } i++; } }
void RPC4::CallLoopback( const char* uniqueID, RakNet::BitStream * bitStream ) { Packet *p=0; DataStructures::HashIndex skhi = registeredNonblockingFunctions.GetIndexOf(uniqueID); if (skhi.IsInvalid()==true) { if (rakPeerInterface) p=AllocatePacketUnified(sizeof(MessageID)+sizeof(unsigned char)+(unsigned int) strlen(uniqueID)+1); #if _RAKNET_SUPPORT_PacketizedTCP==1 && _RAKNET_SUPPORT_TCPInterface==1 else p=tcpInterface->AllocatePacket(sizeof(MessageID)+sizeof(unsigned char)+(unsigned int) strlen(uniqueID)+1); #endif if (rakPeerInterface) p->guid=rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS); #if _RAKNET_SUPPORT_PacketizedTCP==1 && _RAKNET_SUPPORT_TCPInterface==1 else p->guid=UNASSIGNED_RAKNET_GUID; #endif p->systemAddress=UNASSIGNED_SYSTEM_ADDRESS; p->systemAddress.systemIndex=(SystemIndex)-1; p->data[0]=ID_RPC_REMOTE_ERROR; p->data[1]=RPC_ERROR_FUNCTION_NOT_REGISTERED; strcpy((char*) p->data+2, uniqueID); PushBackPacketUnified(p,false); return; } RakNet::BitStream out; out.Write((MessageID) ID_RPC_PLUGIN); out.Write((MessageID) ID_RPC4_CALL); out.WriteCompressed(uniqueID); out.Write(false); // nonblocking if (bitStream) { bitStream->ResetReadPointer(); out.AlignWriteToByteBoundary(); out.Write(bitStream); } if (rakPeerInterface) p=AllocatePacketUnified(out.GetNumberOfBytesUsed()); #if _RAKNET_SUPPORT_PacketizedTCP==1 && _RAKNET_SUPPORT_TCPInterface==1 else p=tcpInterface->AllocatePacket(out.GetNumberOfBytesUsed()); #endif if (rakPeerInterface) p->guid=rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS); #if _RAKNET_SUPPORT_PacketizedTCP==1 && _RAKNET_SUPPORT_TCPInterface==1 else p->guid=UNASSIGNED_RAKNET_GUID; #endif p->systemAddress=UNASSIGNED_SYSTEM_ADDRESS; p->systemAddress.systemIndex=(SystemIndex)-1; memcpy(p->data,out.GetData(),out.GetNumberOfBytesUsed()); PushBackPacketUnified(p,false); return; }
PluginReceiveResult RPC4::OnReceive(Packet *packet) { if (packet->data[0]==ID_RPC_PLUGIN) { RakNet::BitStream bsIn(packet->data,packet->length,false); bsIn.IgnoreBytes(2); if (packet->data[1]==ID_RPC4_CALL) { RakNet::RakString functionName; bsIn.ReadCompressed(functionName); bool isBlocking=false; bsIn.Read(isBlocking); if (isBlocking==false) { DataStructures::HashIndex skhi = registeredNonblockingFunctions.GetIndexOf(functionName.C_String()); if (skhi.IsInvalid()) { RakNet::BitStream bsOut; bsOut.Write((unsigned char) ID_RPC_REMOTE_ERROR); bsOut.Write((unsigned char) RPC_ERROR_FUNCTION_NOT_REGISTERED); bsOut.Write(functionName.C_String(),(unsigned int) functionName.GetLength()+1); SendUnified(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false); return RR_STOP_PROCESSING_AND_DEALLOCATE; } void ( *fp ) ( RakNet::BitStream *, Packet * ); fp = registeredNonblockingFunctions.ItemAtIndex(skhi); bsIn.AlignReadToByteBoundary(); fp(&bsIn,packet); } else { DataStructures::HashIndex skhi = registeredBlockingFunctions.GetIndexOf(functionName.C_String()); if (skhi.IsInvalid()) { RakNet::BitStream bsOut; bsOut.Write((unsigned char) ID_RPC_REMOTE_ERROR); bsOut.Write((unsigned char) RPC_ERROR_FUNCTION_NOT_REGISTERED); bsOut.Write(functionName.C_String(),(unsigned int) functionName.GetLength()+1); SendUnified(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false); return RR_STOP_PROCESSING_AND_DEALLOCATE; } void ( *fp ) ( RakNet::BitStream *, RakNet::BitStream *, Packet * ); fp = registeredBlockingFunctions.ItemAtIndex(skhi); RakNet::BitStream returnData; bsIn.AlignReadToByteBoundary(); fp(&bsIn, &returnData, packet); RakNet::BitStream out; out.Write((MessageID) ID_RPC_PLUGIN); out.Write((MessageID) ID_RPC4_RETURN); returnData.ResetReadPointer(); out.AlignWriteToByteBoundary(); out.Write(returnData); SendUnified(&out,IMMEDIATE_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false); } } else if (packet->data[1]==ID_RPC4_SIGNAL) { RakNet::RakString sharedIdentifier; bsIn.ReadCompressed(sharedIdentifier); DataStructures::HashIndex functionIndex; functionIndex = localSlots.GetIndexOf(sharedIdentifier); RakNet::BitStream serializedParameters; bsIn.AlignReadToByteBoundary(); bsIn.Read(&serializedParameters); InvokeSignal(functionIndex, &serializedParameters, packet); } else { RakAssert(packet->data[1]==ID_RPC4_RETURN); blockingReturnValue.Reset(); blockingReturnValue.Write(bsIn); gotBlockingReturnValue=true; } return RR_STOP_PROCESSING_AND_DEALLOCATE; } bool objectExists; unsigned int index, index2; index = localCallbacks.GetIndexFromKey(packet->data[0],&objectExists); if (objectExists) { LocalCallback *lc; lc = localCallbacks[index]; for (index2=0; index2 < lc->functions.Size(); index2++) { RakNet::BitStream bsIn(packet->data, packet->length, false); DataStructures::HashIndex skhi = registeredNonblockingFunctions.GetIndexOf(lc->functions[index2].C_String()); if (skhi.IsInvalid()==false) { void ( *fp ) ( RakNet::BitStream *, Packet * ); fp = registeredNonblockingFunctions.ItemAtIndex(skhi); bsIn.AlignReadToByteBoundary(); fp(&bsIn,packet); } } } return RR_CONTINUE_PROCESSING; }
PluginReceiveResult SQLite3ServerPlugin::OnReceive(Packet *packet) { switch (packet->data[0]) { case ID_SQLite3_EXEC: { unsigned int queryId; RakNet::RakString dbIdentifier; RakNet::RakString inputStatement; RakNet::BitStream bsIn(packet->data, packet->length, false); bsIn.IgnoreBytes(sizeof(MessageID)); bsIn.Read(queryId); bsIn.Read(dbIdentifier); bsIn.Read(inputStatement); bool isRequest; bsIn.Read(isRequest); if (isRequest) { // Server code unsigned int idx = dbHandles.GetIndexOf(dbIdentifier); if (idx==-1) { RakNet::BitStream bsOut; bsOut.Write((MessageID)ID_SQLite3_UNKNOWN_DB); bsOut.Write(queryId); bsOut.Write(dbIdentifier); bsOut.Write(inputStatement); SendUnified(&bsOut, MEDIUM_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false); } else { #ifdef SQLite3_STATEMENT_EXECUTE_THREADED // Push to the thread SQLExecThreadInput input; input.data=(char*) rakMalloc_Ex(packet->length, _FILE_AND_LINE_); memcpy(input.data,packet->data,packet->length); input.dbHandle=dbHandles[idx].dbHandle; input.length=packet->length; input.sender=packet->systemAddress; sqlThreadPool.AddInput(ExecStatementThread, input); #else char *errorMsg; RakNet::RakString errorMsgStr; SQLite3Table outputTable; sqlite3_exec(dbHandles[idx].dbHandle, inputStatement.C_String(), PerRowCallback, &outputTable, &errorMsg); if (errorMsg) { errorMsgStr=errorMsg; sqlite3_free(errorMsg); } RakNet::BitStream bsOut; bsOut.Write((MessageID)ID_SQLite3_EXEC); bsOut.Write(queryId); bsOut.Write(dbIdentifier); bsOut.Write(inputStatement); bsOut.Write(false); bsOut.Write(errorMsgStr); outputTable.Serialize(&bsOut); SendUnified(&bsOut, MEDIUM_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false); #endif } } return RR_STOP_PROCESSING_AND_DEALLOCATE; } break; } return RR_CONTINUE_PROCESSING; }
// native SendLastSyncData(playerid, toplayerid, animation = 0) static cell AMX_NATIVE_CALL Natives::SendLastSyncData( AMX* amx, cell* params ) { if (!serverVersion) return 0; CHECK_PARAMS(3, "SendLastSyncData"); int playerid = (int)params[1]; int toplayerid = (int)params[2]; int animation = (int)params[3]; BYTE ps = ID_PLAYER_SYNC; CSyncData* d = &lastSyncData[playerid]; RakNet::BitStream bs; bs.Write((BYTE)ID_PLAYER_SYNC); bs.Write((WORD)playerid); if (d->wUDAnalog) { bs.Write(true); bs.Write((WORD)d->wUDAnalog); } else { bs.Write(false); } if (d->wLRAnalog) { bs.Write(true); bs.Write((WORD)d->wLRAnalog); } else { bs.Write(false); } bs.Write((WORD)d->wKeys); bs.Write(d->vecPosition.fX); bs.Write(d->vecPosition.fY); bs.Write(d->vecPosition.fZ); if (fakeQuat[playerid] != NULL) { bs.Write((bool)(fakeQuat[playerid]->w<0.0f)); bs.Write((bool)(fakeQuat[playerid]->x<0.0f)); bs.Write((bool)(fakeQuat[playerid]->y<0.0f)); bs.Write((bool)(fakeQuat[playerid]->z<0.0f)); bs.Write((unsigned short)(fabs(fakeQuat[playerid]->x)*65535.0)); bs.Write((unsigned short)(fabs(fakeQuat[playerid]->y)*65535.0)); bs.Write((unsigned short)(fabs(fakeQuat[playerid]->z)*65535.0)); } else { bs.Write((bool)(d->fQuaternionAngle<0.0f)); bs.Write((bool)(d->vecQuaternion.fX<0.0f)); bs.Write((bool)(d->vecQuaternion.fY<0.0f)); bs.Write((bool)(d->vecQuaternion.fZ<0.0f)); bs.Write((unsigned short)(fabs(d->vecQuaternion.fX)*65535.0)); bs.Write((unsigned short)(fabs(d->vecQuaternion.fY)*65535.0)); bs.Write((unsigned short)(fabs(d->vecQuaternion.fZ)*65535.0)); } BYTE health, armour; if (fakeHealth[playerid] != 255) { health = fakeHealth[playerid]; } else { health = d->byteHealth; } if (fakeArmour[playerid] != 255) { armour = fakeArmour[playerid]; } else { armour = d->byteArmour; } if (health >= 100) { health = 0xF; } else { health /= 7; } if (armour >= 100) { armour = 0xF; } else { armour /= 7; } bs.Write((BYTE)((health << 4) | (armour))); bs.Write(d->byteWeapon); bs.Write(d->byteSpecialAction); // Make them appear standing still if paused if (GetTickCount() - lastUpdateTick[playerid] > 2000) { bs.WriteVector(0.0f, 0.0f, 0.0f); } else { bs.WriteVector(d->vecVelocity.fX, d->vecVelocity.fY, d->vecVelocity.fZ); } if (d->wSurfingInfo) { bs.Write(true); bs.Write(d->wSurfingInfo); bs.Write(d->vecSurfing.fX); bs.Write(d->vecSurfing.fY); bs.Write(d->vecSurfing.fZ); } else { bs.Write(false); } // Animations are only sent when they are changed if (animation) { bs.Write(true); bs.Write(animation); } else { bs.Write(false); } pRakServer->Send(&bs, HIGH_PRIORITY, RELIABLE_SEQUENCED, 0, pRakServer->GetPlayerIDFromIndex(toplayerid), false); return 1; }
PluginReceiveResult FullyConnectedMesh2::OnVerifiedJoinStart(Packet *packet) { RakNet::BitStream bsIn(packet->data,packet->length,false); bsIn.IgnoreBytes(sizeof(MessageID)); unsigned short listSize; bsIn.Read(listSize); unsigned int curIndex = GetJoinsInProgressIndex(packet->guid); if (curIndex!=(unsigned int) -1) { // Got update to existing list VerifiedJoinInProgress *vjip = joinsInProgress[curIndex]; // if (vjip->sentResults==false) // { // // Got ID_FCM2_VERIFIED_JOIN_START twice before sending ID_FCM2_VERIFIED_JOIN_CAPABLE // RakAssert(vjip->sentResults!=false); // return RR_STOP_PROCESSING_AND_DEALLOCATE; // } for (unsigned int i=0; i < vjip->members.Size(); i++) { vjip->members[i].workingFlag=false; } // Server has updated list of participants for (unsigned short i=0; i < listSize; i++) { VerifiedJoinInProgressMember vjipm; ReadVerifiedJoinInProgressMember(&bsIn, &vjipm); unsigned int j; if (vjipm.guid!=UNASSIGNED_RAKNET_GUID) j = GetVerifiedJoinInProgressMemberIndex(vjipm.guid, vjip); else j = GetVerifiedJoinInProgressMemberIndex(vjipm.systemAddress, vjip); if (j==(unsigned int)-1) { // New vjipm.workingFlag=true; vjipm.joinInProgressState=JIPS_PROCESSING; vjip->members.Push(vjipm, _FILE_AND_LINE_); // Allow resend of ID_FCM2_VERIFIED_JOIN_CAPABLE //vjip->sentResults=false; } else { vjip->members[j].workingFlag=true; } } for (unsigned int i=0; i < vjip->members.Size(); i++) { if (vjip->members[i].workingFlag==false) vjip->members[i].joinInProgressState=JIPS_UNNECESSARY; } if (ProcessVerifiedJoinInProgressIfCompleted(vjip)) { // Completed return RR_STOP_PROCESSING_AND_DEALLOCATE; } // Else tell user about new list return RR_CONTINUE_PROCESSING; } VerifiedJoinInProgress *vjip = RakNet::OP_NEW<VerifiedJoinInProgress>(_FILE_AND_LINE_); vjip->requester=packet->guid; if (listSize==0) { //vjip->sentResults=true; // Send back result RakNet::BitStream bsOut; bsOut.Write((MessageID)ID_FCM2_VERIFIED_JOIN_CAPABLE); bsOut.WriteCasted<unsigned short>(0); SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false); //vjip->sentResults=true; joinsInProgress.Push(vjip, _FILE_AND_LINE_); return RR_STOP_PROCESSING_AND_DEALLOCATE; } //vjip->sentResults=false; for (unsigned short i=0; i < listSize; i++) { VerifiedJoinInProgressMember vjipm; ReadVerifiedJoinInProgressMember(&bsIn, &vjipm); vjip->members.Push(vjipm, _FILE_AND_LINE_); } joinsInProgress.Push(vjip, _FILE_AND_LINE_); return RR_CONTINUE_PROCESSING; }
SQLite3ServerPlugin::SQLExecThreadOutput ExecStatementThread(SQLite3ServerPlugin::SQLExecThreadInput threadInput, bool *returnOutput, void* perThreadData) { unsigned int queryId; RakNet::RakString dbIdentifier; RakNet::RakString inputStatement; RakNet::BitStream bsIn((unsigned char*) threadInput.data, threadInput.length, false); bsIn.IgnoreBytes(sizeof(MessageID)); bsIn.Read(queryId); bsIn.Read(dbIdentifier); bsIn.Read(inputStatement); // bool isRequest; // bsIn.Read(isRequest); bsIn.IgnoreBits(1); char *errorMsg; RakNet::RakString errorMsgStr; SQLite3Table outputTable; sqlite3_exec(threadInput.dbHandle, inputStatement.C_String(), PerRowCallback, &outputTable, &errorMsg); if (errorMsg) { errorMsgStr=errorMsg; sqlite3_free(errorMsg); } RakNet::BitStream bsOut; bsOut.Write((MessageID)ID_SQLite3_EXEC); bsOut.Write(queryId); bsOut.Write(dbIdentifier); bsOut.Write(inputStatement); bsOut.Write(false); bsOut.Write(errorMsgStr); outputTable.Serialize(&bsOut); // Free input data rakFree_Ex(threadInput.data,_FILE_AND_LINE_); // Copy to output data SQLite3ServerPlugin::SQLExecThreadOutput threadOutput; threadOutput.data=(char*) rakMalloc_Ex(bsOut.GetNumberOfBytesUsed(),_FILE_AND_LINE_); memcpy(threadOutput.data,bsOut.GetData(),bsOut.GetNumberOfBytesUsed()); threadOutput.length=bsOut.GetNumberOfBytesUsed(); threadOutput.sender=threadInput.sender; // SendUnified(&bsOut, MEDIUM_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false); *returnOutput=true; return threadOutput; }
void FullyConnectedMesh2::RespondOnVerifiedJoinCapable(Packet *packet, bool accept, BitStream *additionalData) { VerifiedJoinInProgress vjip; DecomposeJoinCapable(packet, &vjip); DataStructures::List<RakNetGUID> participatingMembersOnClientSucceeded; DataStructures::List<RakNetGUID> participatingMembersOnClientFailed; DataStructures::List<RakNetGUID> participatingMembersNotOnClient; DataStructures::List<RakNetGUID> clientMembersNotParticipatingSucceeded; DataStructures::List<RakNetGUID> clientMembersNotParticipatingFailed; CategorizeVJIP(&vjip, participatingMembersOnClientSucceeded, participatingMembersOnClientFailed, participatingMembersNotOnClient, clientMembersNotParticipatingSucceeded, clientMembersNotParticipatingFailed); if (participatingMembersNotOnClient.Size()>0) { BitStream bsOut; bsOut.Write((MessageID) ID_FCM2_VERIFIED_JOIN_START); bsOut.WriteCasted<unsigned short>(participatingMembersNotOnClient.Size()); unsigned int i; for (i=0; i < participatingMembersNotOnClient.Size(); i++) { bsOut.Write(participatingMembersNotOnClient[i]); bsOut.Write(rakPeerInterface->GetSystemAddressFromGuid(participatingMembersNotOnClient[i])); } SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false); return; } RakAssert(participatingMembersOnClientFailed.Size()==0); RakAssert(participatingMembersNotOnClient.Size()==0); RakNet::BitStream bsOut; if (accept) { bsOut.Write((MessageID)ID_FCM2_VERIFIED_JOIN_ACCEPTED); bsOut.Write(packet->guid); // Tell client to disconnect from clientMembersNotParticipatingSucceeded bsOut.WriteCasted<unsigned short>(clientMembersNotParticipatingSucceeded.Size()); for (unsigned int i=0; i < clientMembersNotParticipatingSucceeded.Size(); i++) bsOut.Write(clientMembersNotParticipatingSucceeded[i]); // Tell client to call AddParticipant() for participatingMembersOnClientSucceeded bsOut.WriteCasted<unsigned short>(participatingMembersOnClientSucceeded.Size()); for (unsigned int i=0; i < participatingMembersOnClientSucceeded.Size(); i++) bsOut.Write(participatingMembersOnClientSucceeded[i]); if (additionalData) bsOut.Write(additionalData); for (unsigned int i=0; i < fcm2ParticipantList.Size(); i++) SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, fcm2ParticipantList[i].rakNetGuid, false); // Process immediately // This is so if another ID_FCM2_VERIFIED_JOIN_CAPABLE is buffered, it responds with ID_FCM2_VERIFIED_JOIN_START AddParticipant(packet->guid); Packet *p = AllocatePacketUnified(bsOut.GetNumberOfBytesUsed()); memcpy(p->data, bsOut.GetData(), bsOut.GetNumberOfBytesUsed()); p->systemAddress=packet->systemAddress; p->systemAddress.systemIndex=(SystemIndex)-1; p->guid=packet->guid; p->wasGeneratedLocally=true; rakPeerInterface->PushBackPacket(p, true); } else { // Tell client rejected, otherwise process the same as ID_FCM2_VERIFIED_JOIN_FAILED bsOut.Write((MessageID)ID_FCM2_VERIFIED_JOIN_REJECTED); bsOut.Write(additionalData); } SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false); }
void RequestClass(PCHAR Data, int iBitLength, PlayerID sender) { RakNet::BitStream bsData(Data,iBitLength/8,FALSE); BYTE byteRequestedClass; BYTE byteRequestOutcome = 0; BYTE bytePlayerID = pRak->GetIndexFromPlayerID(sender); bsData.Read(byteRequestedClass); if(!pNetGame->GetPlayerPool()->GetSlotState(bytePlayerID)) return; if(pNetGame->GetGameLogic()->HandleSpawnClassRequest(bytePlayerID,byteRequestedClass)) { byteRequestOutcome = 1; } RakNet::BitStream bsSpawnRequestReply; CPlayer *pPlayer=pNetGame->GetPlayerPool()->GetAt(bytePlayerID); PLAYER_SPAWN_INFO *SpawnInfo = pPlayer->GetSpawnInfo(); bsSpawnRequestReply.Write(byteRequestOutcome); bsSpawnRequestReply.Write(SpawnInfo->byteTeam); bsSpawnRequestReply.Write(SpawnInfo->byteSkin); bsSpawnRequestReply.Write((float)SpawnInfo->vecPos.X); bsSpawnRequestReply.Write((float)SpawnInfo->vecPos.Y); bsSpawnRequestReply.Write((float)SpawnInfo->vecPos.Z); bsSpawnRequestReply.Write((float)SpawnInfo->fRotation); bsSpawnRequestReply.Write(SpawnInfo->iSpawnWeapons[0]); bsSpawnRequestReply.Write(SpawnInfo->iSpawnWeaponsAmmo[0]); bsSpawnRequestReply.Write(SpawnInfo->iSpawnWeapons[1]); bsSpawnRequestReply.Write(SpawnInfo->iSpawnWeaponsAmmo[1]); bsSpawnRequestReply.Write(SpawnInfo->iSpawnWeapons[2]); bsSpawnRequestReply.Write(SpawnInfo->iSpawnWeaponsAmmo[2]); pRak->RPC("RequestClass",&bsSpawnRequestReply,HIGH_PRIORITY,RELIABLE,0,sender,FALSE,FALSE); }
void selectTextDraw(int iTextDrawID) { RakNet::BitStream bsSend; bsSend.Write(iTextDrawID); pRakClient->RPC(&RPC_ClickTextDraw, &bsSend, HIGH_PRIORITY, RELIABLE_ORDERED, 0, FALSE, UNASSIGNED_NETWORK_ID, NULL); }
void NatPunchthroughServer::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason ) { (void) lostConnectionReason; (void) systemAddress; unsigned int i=0; bool objectExists; i = users.GetIndexFromKey(rakNetGUID, &objectExists); if (objectExists) { RakNet::BitStream outgoingBs; DataStructures::List<User *> freedUpInProgressUsers; User *user = users[i]; User *otherUser; unsigned int connectionAttemptIndex; ConnectionAttempt *connectionAttempt; for (connectionAttemptIndex=0; connectionAttemptIndex < user->connectionAttempts.Size(); connectionAttemptIndex++) { connectionAttempt=user->connectionAttempts[connectionAttemptIndex]; outgoingBs.Reset(); if (connectionAttempt->recipient==user) { otherUser=connectionAttempt->sender; } else { otherUser=connectionAttempt->recipient; } // 05/28/09 Previously only told sender about ID_NAT_CONNECTION_TO_TARGET_LOST // However, recipient may be expecting it due to external code // In that case, recipient would never get any response if the sender dropped outgoingBs.Write((MessageID)ID_NAT_CONNECTION_TO_TARGET_LOST); outgoingBs.Write(rakNetGUID); outgoingBs.Write(connectionAttempt->sessionId); rakPeerInterface->Send(&outgoingBs,HIGH_PRIORITY,RELIABLE_ORDERED,0,otherUser->systemAddress,false); // 4/22/09 - Bug: was checking inProgress, legacy variable not used elsewhere if (connectionAttempt->attemptPhase==ConnectionAttempt::NAT_ATTEMPT_PHASE_GETTING_RECENT_PORTS) { otherUser->isReady=true; freedUpInProgressUsers.Insert(otherUser, _FILE_AND_LINE_ ); } otherUser->DeleteConnectionAttempt(connectionAttempt); } RakNet::OP_DELETE(users[i], _FILE_AND_LINE_); users.RemoveAtIndex(i); for (i=0; i < freedUpInProgressUsers.Size(); i++) { StartPunchthroughForUser(freedUpInProgressUsers[i]); } } // Also remove from groupPunchthroughRequests for (i=0; i < users.Size(); i++) { bool objectExists; unsigned int gprIndex; gprIndex = users[i]->groupPunchthroughRequests.GetIndexFromKey(rakNetGUID, &objectExists); if (objectExists) { // printf("DEBUG %i\n", __LINE__); RakNet::BitStream outgoingBs; outgoingBs.Write((MessageID)ID_NAT_TARGET_NOT_CONNECTED); outgoingBs.Write(rakNetGUID); rakPeerInterface->Send(&outgoingBs,HIGH_PRIORITY,RELIABLE_ORDERED,0,users[i]->systemAddress,false); users[i]->groupPunchthroughRequests.RemoveAtIndex(gprIndex); } } }
void CGangZonePool::HideForAll(WORD wZone) { RakNet::BitStream bsParams; bsParams.Write(wZone); pNetGame->GetRakServer()->RPC(RPC_ScrRemoveGangZone, &bsParams, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_PLAYER_ID, true, false); }
void NatPunchthroughServer::OnGetMostRecentPort(Packet *packet) { RakNet::BitStream bsIn(packet->data, packet->length, false); bsIn.IgnoreBytes(sizeof(MessageID)); uint16_t sessionId; unsigned short mostRecentPort; bsIn.Read(sessionId); bsIn.Read(mostRecentPort); unsigned int i,j; User *user; ConnectionAttempt *connectionAttempt; bool objectExists; i = users.GetIndexFromKey(packet->guid, &objectExists); if (natPunchthroughServerDebugInterface) { RakNet::RakString log; char addr1[128], addr2[128]; packet->systemAddress.ToString(true,addr1); packet->guid.ToString(addr2); log=RakNet::RakString("Got ID_NAT_GET_MOST_RECENT_PORT from systemAddress %s guid %s. port=%i. sessionId=%i. userFound=%i.", addr1, addr2, mostRecentPort, sessionId, objectExists); natPunchthroughServerDebugInterface->OnServerMessage(log.C_String()); } if (objectExists) { user=users[i]; user->mostRecentPort=mostRecentPort; RakNet::Time time = RakNet::GetTime(); for (j=0; j < user->connectionAttempts.Size(); j++) { connectionAttempt=user->connectionAttempts[j]; if (connectionAttempt->attemptPhase==ConnectionAttempt::NAT_ATTEMPT_PHASE_GETTING_RECENT_PORTS && connectionAttempt->sender->mostRecentPort!=0 && connectionAttempt->recipient->mostRecentPort!=0 && // 04/29/08 add sessionId to prevent processing for other systems connectionAttempt->sessionId==sessionId) { SystemAddress senderSystemAddress = connectionAttempt->sender->systemAddress; SystemAddress recipientSystemAddress = connectionAttempt->recipient->systemAddress; SystemAddress recipientTargetAddress = recipientSystemAddress; SystemAddress senderTargetAddress = senderSystemAddress; recipientTargetAddress.SetPort(connectionAttempt->recipient->mostRecentPort); senderTargetAddress.SetPort(connectionAttempt->sender->mostRecentPort); // Pick a time far enough in the future that both systems will have gotten the message int targetPing = rakPeerInterface->GetAveragePing(recipientTargetAddress); int senderPing = rakPeerInterface->GetAveragePing(senderSystemAddress); RakNet::Time simultaneousAttemptTime; if (targetPing==-1 || senderPing==-1) simultaneousAttemptTime = time + 1500; else { int largerPing = targetPing > senderPing ? targetPing : senderPing; if (largerPing * 4 < 100) simultaneousAttemptTime = time + 100; else simultaneousAttemptTime = time + (largerPing * 4); } if (natPunchthroughServerDebugInterface) { RakNet::RakString log; char addr1[128], addr2[128]; recipientSystemAddress.ToString(true,addr1); connectionAttempt->recipient->guid.ToString(addr2); log=RakNet::RakString("Sending ID_NAT_CONNECT_AT_TIME to recipient systemAddress %s guid %s", addr1, addr2); natPunchthroughServerDebugInterface->OnServerMessage(log.C_String()); } // Send to recipient timestamped message to connect at time RakNet::BitStream bsOut; bsOut.Write((MessageID)ID_TIMESTAMP); bsOut.Write(simultaneousAttemptTime); bsOut.Write((MessageID)ID_NAT_CONNECT_AT_TIME); bsOut.Write(connectionAttempt->sessionId); bsOut.Write(senderTargetAddress); // Public IP, using most recent port for (j=0; j < MAXIMUM_NUMBER_OF_INTERNAL_IDS; j++) // Internal IP bsOut.Write(rakPeerInterface->GetInternalID(senderSystemAddress,j)); bsOut.Write(connectionAttempt->sender->guid); bsOut.Write(false); rakPeerInterface->Send(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,recipientSystemAddress,false); if (natPunchthroughServerDebugInterface) { RakNet::RakString log; char addr1[128], addr2[128]; senderSystemAddress.ToString(true,addr1); connectionAttempt->sender->guid.ToString(addr2); log=RakNet::RakString("Sending ID_NAT_CONNECT_AT_TIME to sender systemAddress %s guid %s", addr1, addr2); natPunchthroughServerDebugInterface->OnServerMessage(log.C_String()); } // Same for sender bsOut.Reset(); bsOut.Write((MessageID)ID_TIMESTAMP); bsOut.Write(simultaneousAttemptTime); bsOut.Write((MessageID)ID_NAT_CONNECT_AT_TIME); bsOut.Write(connectionAttempt->sessionId); bsOut.Write(recipientTargetAddress); // Public IP, using most recent port for (j=0; j < MAXIMUM_NUMBER_OF_INTERNAL_IDS; j++) // Internal IP bsOut.Write(rakPeerInterface->GetInternalID(recipientSystemAddress,j)); bsOut.Write(connectionAttempt->recipient->guid); bsOut.Write(true); rakPeerInterface->Send(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,senderSystemAddress,false); connectionAttempt->recipient->DerefConnectionAttempt(connectionAttempt); connectionAttempt->sender->DeleteConnectionAttempt(connectionAttempt); // 04/29/08 missing return return; } } } else { if (natPunchthroughServerDebugInterface) { RakNet::RakString log; char addr1[128], addr2[128]; packet->systemAddress.ToString(true,addr1); packet->guid.ToString(addr2); log=RakNet::RakString("Ignoring ID_NAT_GET_MOST_RECENT_PORT from systemAddress %s guid %s", addr1, addr2); natPunchthroughServerDebugInterface->OnServerMessage(log.C_String()); } } }
void CLocalPlayer::SendInVehicleSync( void ) { // Are we not connected to the network? if( !pCore->GetNetworkModule()->IsConnected() ) return; // Are we dead? if( IsDead() ) return; // Get the vehicle instance CNetworkVehicle * pVehicle = pCore->GetVehicleManager()->GetFromGameGUID( GetPlayerPed()->GetCurrentVehicle()->m_dwGUID ); // Did we fail to find the vehicle? if( !pVehicle ) return; // Construct a new bitstream RakNet::BitStream pBitStream; // Write the vehicle id pBitStream.WriteCompressed( pVehicle->GetId() ); // Construct a new in vehicle sync data structure InVehicleSync inVehicleSync; // Get the vehicle position pVehicle->GetPosition( &inVehicleSync.m_vecPosition ); // Get the vehicle rotation pVehicle->GetRotation( &inVehicleSync.m_vecRotation ); // Get the vehicle dirt level inVehicleSync.m_fDirtLevel = pVehicle->GetVehicle()->GetDirtLevel(); // Get the vehicle tuning table inVehicleSync.m_iTuningTable = pVehicle->GetVehicle()->GetTuningTable(); // Get the vehicle horn state inVehicleSync.m_bHornState = pVehicle->GetVehicle()->IsHornOn(); // Get the vehicle siren state inVehicleSync.m_bSirenState = pVehicle->GetVehicle()->IsSirenOn(); // Get the vehicle fuel inVehicleSync.m_fFuel = pVehicle->GetVehicle()->GetFuel(); // Get the vehicle speed pVehicle->GetSpeedVec( &inVehicleSync.m_vecVelocity ); // Get the turn speed inVehicleSync.m_fTurnSpeed = pVehicle->GetSteer(); // Get the engine damage inVehicleSync.m_fEngineDamage = pVehicle->GetVehicle()->GetEngineDamage(); // Get the vehicle plate text strcpy( inVehicleSync.m_szPlateText, pVehicle->GetPlateText() ); inVehicleSync.m_szPlateText[ 6 ] = '\0'; // Get the vehicle colour pVehicle->GetColour( &inVehicleSync.m_primaryColour, &inVehicleSync.m_secondaryColour ); // Get the power state inVehicleSync.m_bPower = pVehicle->GetVehicle()->GetPower(); // Get the brake state inVehicleSync.m_bBrake = pVehicle->GetVehicle()->GetBrake(); // Get the vehicle wheel models (DISABLED FOR TESTING) for ( int i = 0; i < 3; i++ ) inVehicleSync.m_bWheelModels[ i ] = 0xFF; //Game::GetIdFromVehicleWheelModel ( pVehicle->GetVehicle()->GetWheelTexture ( i ) ); // Get the handbrake state inVehicleSync.m_bHandbrake = pVehicle->GetVehicle()->IsHandbrakeOn (); // Get the light state inVehicleSync.m_bLightState = pVehicle->GetVehicle()->GetLightState (); // Write the sync structure into the bitstream pBitStream.Write( (char *)&inVehicleSync, sizeof(InVehicleSync) ); // Send the bitstream to the server pCore->GetNetworkModule()->Call( RPC_VEHICLE_SYNC, &pBitStream, LOW_PRIORITY, UNRELIABLE_SEQUENCED, true ); }
bool RPC4::CallBlocking( const char* uniqueID, RakNet::BitStream * bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel, const AddressOrGUID systemIdentifier, RakNet::BitStream *returnData ) { RakNet::BitStream out; out.Write((MessageID) ID_RPC_PLUGIN); out.Write((MessageID) ID_RPC4_CALL); out.WriteCompressed(uniqueID); out.Write(true); // Blocking if (bitStream) { bitStream->ResetReadPointer(); out.AlignWriteToByteBoundary(); out.Write(bitStream); } RakAssert(returnData); RakAssert(rakPeerInterface); ConnectionState cs; cs = rakPeerInterface->GetConnectionState(systemIdentifier); if (cs!=IS_CONNECTED) return false; SendUnified(&out,priority,reliability,orderingChannel,systemIdentifier,false); returnData->Reset(); blockingReturnValue.Reset(); gotBlockingReturnValue=false; Packet *packet; DataStructures::Queue<Packet*> packetQueue; while (gotBlockingReturnValue==false) { // TODO - block, filter until gotBlockingReturnValue==true or ID_CONNECTION_LOST or ID_DISCONNECTION_NOTIFICXATION or ID_RPC_REMOTE_ERROR/RPC_ERROR_FUNCTION_NOT_REGISTERED RakSleep(30); packet=rakPeerInterface->Receive(); if (packet) { if ( (packet->data[0]==ID_CONNECTION_LOST || packet->data[0]==ID_DISCONNECTION_NOTIFICATION) && ((systemIdentifier.rakNetGuid!=UNASSIGNED_RAKNET_GUID && packet->guid==systemIdentifier.rakNetGuid) || (systemIdentifier.systemAddress!=UNASSIGNED_SYSTEM_ADDRESS && packet->systemAddress==systemIdentifier.systemAddress)) ) { // Push back to head in reverse order rakPeerInterface->PushBackPacket(packet,true); while (packetQueue.Size()) rakPeerInterface->PushBackPacket(packetQueue.Pop(),true); return false; } else if (packet->data[0]==ID_RPC_REMOTE_ERROR && packet->data[1]==RPC_ERROR_FUNCTION_NOT_REGISTERED) { RakNet::RakString functionName; RakNet::BitStream bsIn(packet->data,packet->length,false); bsIn.IgnoreBytes(2); bsIn.Read(functionName); if (functionName==uniqueID) { // Push back to head in reverse order rakPeerInterface->PushBackPacket(packet,true); while (packetQueue.Size()) rakPeerInterface->PushBackPacket(packetQueue.Pop(),true); return false; } else { packetQueue.PushAtHead(packet,0,_FILE_AND_LINE_); } } else { packetQueue.PushAtHead(packet,0,_FILE_AND_LINE_); } } } returnData->Write(blockingReturnValue); returnData->ResetReadPointer(); return true; }
void CLocalPlayer::OnEnterVehicle( void ) { // Get the vehicle instance from the vehicle guid CNetworkVehicle * pNetworkVehicle = pCore->GetVehicleManager()->GetFromGameGUID( GetPlayerPed()->GetCurrentVehicle()->m_dwGUID ); // Is the vehicle instance valid? if( pNetworkVehicle ) { #ifdef _DEBUG M2Vehicle * pVehicle = pNetworkVehicle->GetVehicle()->GetVehicle(); DWORD dwVehicleData = (DWORD)(pVehicle) + 0xA8; pCore->GetChat()->AddDebugMessage ( "Vehicle: 0x%p, VehicleData: 0x%p", pVehicle, dwVehicleData ); #endif // Set the initial seat as the driver EntityId seat = 0; // Is the player in the passenger seat? //if( GetState() == PLAYERSTATE_PASSENGER ) // seat = pNetworkVehicle->GetVehicle()->GetPedOccupiedSeat( GetPlayerPed()->GetPed() ); // Does the vehicle already have a driver? if ( pNetworkVehicle->GetDriver () ) seat = pNetworkVehicle->GetVehicle()->GetPedOccupiedSeat( GetPlayerPed()->GetPed() ); // Are we getting in as the driver? if( seat == 0 ) SetState( PLAYERSTATE_DRIVER ); else SetState( PLAYERSTATE_PASSENGER ); #ifdef _DEBUG pCore->GetChat()->AddDebugMessage( "Seat: %d, Driver: 0x%p, State: %d", seat, pNetworkVehicle->GetDriver (), GetState () ); #endif // Construct a new bitstream RakNet::BitStream pBitStream; // Write the vehicle id pBitStream.WriteCompressed( pNetworkVehicle->GetId() ); // Write the seat pBitStream.WriteCompressed( seat ); // Send to the server pCore->GetNetworkModule()->Call( RPC_ENTER_VEHICLE, &pBitStream, HIGH_PRIORITY, RELIABLE_ORDERED, true ); #ifdef _DEBUG pCore->GetChat()->AddDebugMessage( "CLocalPlayer::OnEnterVehicle( %d, %d )", pNetworkVehicle->GetId(), seat ); #endif // Handle this enter with the network vehicle pNetworkVehicle->HandlePlayerEnter( this, seat ); // Set the vehicle SetVehicle( pNetworkVehicle ); // Set the seat SetSeat( seat ); // Set the target data SetEnteringVehicle( pNetworkVehicle, seat ); } }
PluginReceiveResult Router::OnReceive(Packet *packet) { if (packet->data[0]==ID_ROUTE_AND_MULTICAST || (packet->length>5 && packet->data[0]==ID_TIMESTAMP && packet->data[5]==ID_ROUTE_AND_MULTICAST)) { #ifdef _DO_PRINTF RAKNET_DEBUG_PRINTF("%i got routed message from %i\n", peer->GetExternalID(packet->systemAddress).port, packet->systemAddress.port); #endif RakNetTime timestamp; PacketPriority priority; PacketReliability reliability; unsigned char orderingChannel; SystemAddress originalSender; RakNet::BitStream out; BitSize_t outStartingOffset; unsigned int payloadBitLength; unsigned payloadWriteByteOffset; RakNet::BitStream incomingBitstream(packet->data, packet->length, false); incomingBitstream.IgnoreBits(8); if (packet->data[0]==ID_TIMESTAMP) { incomingBitstream.Read(timestamp); out.Write((MessageID)ID_TIMESTAMP); out.Write(timestamp); incomingBitstream.IgnoreBits(8); } // Read the send parameters unsigned char c; incomingBitstream.ReadCompressed(c); priority=(PacketPriority)c; incomingBitstream.ReadCompressed(c); reliability=(PacketReliability)c; incomingBitstream.ReadCompressed(orderingChannel); incomingBitstream.Read(payloadBitLength); out.Write((MessageID)ID_ROUTE_AND_MULTICAST); out.WriteCompressed((unsigned char)priority); out.WriteCompressed((unsigned char)reliability); out.WriteCompressed((unsigned char)orderingChannel); out.Write(payloadBitLength); out.AlignWriteToByteBoundary(); incomingBitstream.AlignReadToByteBoundary(); payloadWriteByteOffset=(unsigned int) BITS_TO_BYTES(out.GetWriteOffset()); out.Write(&incomingBitstream, payloadBitLength); // This write also does a read on incomingBitStream if (restrictByType) { RakNet::BitStream t(out.GetData()+payloadWriteByteOffset, sizeof(unsigned char), false); MessageID messageID; t.Read(messageID); if (allowedTypes.HasData(messageID)==false) return RR_STOP_PROCESSING_AND_DEALLOCATE; // Don't route restricted types } incomingBitstream.Read(originalSender); out.Write(originalSender); outStartingOffset=out.GetWriteOffset(); // Deserialize the root bool hasData=false; SystemAddress recipient; unsigned short numberOfChildren; incomingBitstream.Read(hasData); incomingBitstream.Read(recipient); // This should be our own address if (incomingBitstream.ReadCompressed(numberOfChildren)==false) { #ifdef _DEBUG RakAssert(0); #endif return RR_STOP_PROCESSING_AND_DEALLOCATE; } unsigned childIndex; bool childHasData=false; SystemAddress childRecipient; unsigned short childNumberOfChildren; SystemAddress immediateRecipient; immediateRecipient=UNASSIGNED_SYSTEM_ADDRESS; int pendingNodeCount=0; for (childIndex=0; childIndex < numberOfChildren; childIndex++) { while (pendingNodeCount!=-1) { // Copy out the serialized subtree for this child incomingBitstream.Read(childHasData); incomingBitstream.Read(childRecipient); if (!incomingBitstream.ReadCompressed(childNumberOfChildren)) return RR_STOP_PROCESSING_AND_DEALLOCATE; if (immediateRecipient==UNASSIGNED_SYSTEM_ADDRESS) { immediateRecipient=childRecipient; } pendingNodeCount+=childNumberOfChildren-1; out.Write(childHasData); out.Write(childRecipient); out.WriteCompressed(childNumberOfChildren); } #ifdef _DO_PRINTF RAKNET_DEBUG_PRINTF("%i routing to %i\n", peer->GetExternalID(packet->systemAddress).port, immediateRecipient.port); #endif // Send what we got so far SendUnified(&out, priority, reliability, orderingChannel, immediateRecipient, false); // Restart writing the per recipient data out.SetWriteOffset(outStartingOffset); // Reread the top level node immediateRecipient=UNASSIGNED_SYSTEM_ADDRESS; pendingNodeCount=0; } // Write the user payload to the packet struct if this is a destination and change the sender and return true if (hasData) { #ifdef _DO_PRINTF RAKNET_DEBUG_PRINTF("%i returning payload to user\n", peer->GetExternalID(packet->systemAddress).port); #endif if (packet->data[0]==ID_TIMESTAMP ) { memcpy( packet->data + sizeof(RakNetTime)+sizeof(unsigned char), out.GetData()+payloadWriteByteOffset, BITS_TO_BYTES(payloadBitLength) ); packet->bitSize=BYTES_TO_BITS(sizeof(RakNetTime)+sizeof(unsigned char))+payloadBitLength; } else { memcpy( packet->data, out.GetData()+payloadWriteByteOffset, BITS_TO_BYTES(payloadBitLength) ); packet->bitSize=payloadBitLength; } packet->length=(unsigned int) BITS_TO_BYTES(packet->bitSize); packet->systemAddress.systemIndex=(SystemIndex)-1; packet->systemAddress=originalSender; return RR_CONTINUE_PROCESSING; } // Absorb return RR_STOP_PROCESSING_AND_DEALLOCATE; } return RR_CONTINUE_PROCESSING; }
void CLocalPlayer::OnLeaveVehicle( void ) { // Set the player state SetState( PLAYERSTATE_ONFOOT ); // Is the vehicle instance valid? if( m_pVehicle ) { // Get the seat of this player EntityId seat = m_seat; // Construct a new bitstream RakNet::BitStream pBitStream; // Write the vehicle id pBitStream.WriteCompressed( m_pVehicle->GetId() ); // Write the seat pBitStream.WriteCompressed( seat ); // Write if we're exiting quickly! m_bFastExitVehicle ? pBitStream.Write1() : pBitStream.Write0(); // Send to the server pCore->GetNetworkModule()->Call( RPC_EXIT_VEHICLE, &pBitStream, HIGH_PRIORITY, RELIABLE_ORDERED, true ); #ifdef DEBUG pCore->GetChat()->AddDebugMessage( "CLocalPlayer::OnExitVehicle( %d, %d ) - Forcefully: %s", m_pVehicle->GetId(), seat, (IsBeingRemovedForcefully () ? "Yes" : "No") ); #endif // Are we not being removed forcefully? if ( !IsBeingRemovedForcefully () ) { // Handle this enter with the network vehicle m_pVehicle->HandlePlayerExit( this, seat, false ); // Do we need to respawn this vehicle? (Set to true when vehicle enters water) if( bRespawnVehicle && m_seat == 0 ) { // Respawn the vehicle m_pVehicle->Respawn(); // bRespawnVehicle = false; } // Are we a passenger? if( m_seat > 0 ) { // Restore the player controls LockControls( bOldControlState ); // Restore the camera lock state pCore->GetCamera()->LockControl( bOldCameraState ); // *(DWORD *)(m_pPlayerPed->GetPed() + 0x310) = 6; } } // Reset the vehicle SetVehicle( NULL ); // Reset the seat SetSeat( INVALID_ENTITY_ID ); // Reset the target data SetEnteringVehicle( NULL, INVALID_ENTITY_ID ); // Reset the fast vehicle exit flag FlagForFastExitVehicle ( false ); // Reset the forceful exit flag SetRemoveForcefully ( false ); } }
void NatTypeDetectionServer::Update(void) { int i=0; RakNetTimeMS time = RakNet::GetTime(); RakNet::BitStream bs; SystemAddress boundAddress; // Only socket that receives messages is s3p4, to see if the external address is different than that of the connection to rakPeerInterface char data[ MAXIMUM_MTU_SIZE ]; int len; SystemAddress senderAddr; len=NatTypeRecvFrom(data, s3p4, senderAddr); // Client is asking us if this is port restricted. Only client requests of this type come in on s3p4 while (len>0 && data[0]==NAT_TYPE_PORT_RESTRICTED) { RakNet::BitStream bsIn((unsigned char*) data,len,false); RakNetGUID senderGuid; bsIn.IgnoreBytes(sizeof(MessageID)); bool readSuccess = bsIn.Read(senderGuid); RakAssert(readSuccess); if (readSuccess) { unsigned int i = GetDetectionAttemptIndex(senderGuid); if (i!=(unsigned int)-1) { bs.Reset(); bs.Write((unsigned char) ID_NAT_TYPE_DETECTION_RESULT); // If different, then symmetric if (senderAddr!=natDetectionAttempts[i].systemAddress) { printf("Determined client is symmetric\n"); bs.Write((unsigned char) NAT_TYPE_SYMMETRIC); } else { // else port restricted printf("Determined client is port restricted\n"); bs.Write((unsigned char) NAT_TYPE_PORT_RESTRICTED); } rakPeerInterface->Send(&bs,HIGH_PRIORITY,RELIABLE,0,natDetectionAttempts[i].systemAddress,false); // Done natDetectionAttempts.RemoveAtIndexFast(i); } else { RakAssert("i==0 in Update when looking up GUID in NatTypeDetectionServer.cpp. Either a bug or a late resend" && 0); } } else { RakAssert("Didn't read GUID in Update in NatTypeDetectionServer.cpp. Message format error" && 0); } len=NatTypeRecvFrom(data, s3p4, senderAddr); } while (i < (int) natDetectionAttempts.Size()) { if (time > natDetectionAttempts[i].nextStateTime) { natDetectionAttempts[i].detectionState=(NATDetectionState)((int)natDetectionAttempts[i].detectionState+1); natDetectionAttempts[i].nextStateTime=time+natDetectionAttempts[i].timeBetweenAttempts; unsigned char c; bs.Reset(); switch (natDetectionAttempts[i].detectionState) { case STATE_TESTING_NONE_1: case STATE_TESTING_NONE_2: c = NAT_TYPE_NONE; printf("Testing NAT_TYPE_NONE\n"); // S4P5 sends to C2. If arrived, no NAT. Done. (Else S4P5 potentially banned, do not use again). SocketLayer::Instance()->SendTo_PC( s4p5, (const char*) &c, 1, natDetectionAttempts[i].systemAddress.binaryAddress, natDetectionAttempts[i].c2Port ); break; case STATE_TESTING_FULL_CONE_1: case STATE_TESTING_FULL_CONE_2: printf("Testing NAT_TYPE_FULL_CONE\n"); rakPeerInterface->WriteOutOfBandHeader(&bs, ID_OUT_OF_BAND_INTERNAL); bs.Write((unsigned char) ID_NAT_TYPE_DETECT); bs.Write((unsigned char) NAT_TYPE_FULL_CONE); // S2P3 sends to C1 (Different address, different port, to previously used port on client). If received, Full-cone nat. Done. (Else S2P3 potentially banned, do not use again). SocketLayer::Instance()->SendTo_PC( s2p3, (const char*) bs.GetData(), bs.GetNumberOfBytesUsed(), natDetectionAttempts[i].systemAddress.binaryAddress, natDetectionAttempts[i].systemAddress.port ); break; case STATE_TESTING_ADDRESS_RESTRICTED_1: case STATE_TESTING_ADDRESS_RESTRICTED_2: printf("Testing NAT_TYPE_ADDRESS_RESTRICTED\n"); rakPeerInterface->WriteOutOfBandHeader(&bs, ID_OUT_OF_BAND_INTERNAL); bs.Write((unsigned char) ID_NAT_TYPE_DETECT); bs.Write((unsigned char) NAT_TYPE_ADDRESS_RESTRICTED); // S1P2 sends to C1 (Same address, different port, to previously used port on client). If received, address-restricted cone nat. Done. SocketLayer::Instance()->SendTo_PC( s1p2, (const char*) bs.GetData(), bs.GetNumberOfBytesUsed(), natDetectionAttempts[i].systemAddress.binaryAddress, natDetectionAttempts[i].systemAddress.port ); break; case STATE_TESTING_PORT_RESTRICTED_1: case STATE_TESTING_PORT_RESTRICTED_2: // C1 sends to S3P4. If address of C1 as seen by S3P4 is the same as the address of C1 as seen by S1P1, then port-restricted cone nat. Done printf("Testing NAT_TYPE_PORT_RESTRICTED\n"); bs.Write((unsigned char) ID_NAT_TYPE_DETECTION_REQUEST); bs.Write(RakString::NonVariadic(s3p4Address)); bs.Write(s3p4Port); rakPeerInterface->Send(&bs,HIGH_PRIORITY,RELIABLE,0,natDetectionAttempts[i].systemAddress,false); break; default: printf("Warning, exceeded final check STATE_TESTING_PORT_RESTRICTED_2.\nExpected that client would have sent NAT_TYPE_PORT_RESTRICTED on s3p4.\nDefaulting to Symmetric\n"); bs.Write((unsigned char) ID_NAT_TYPE_DETECTION_RESULT); bs.Write((unsigned char) NAT_TYPE_SYMMETRIC); rakPeerInterface->Send(&bs,HIGH_PRIORITY,RELIABLE,0,natDetectionAttempts[i].systemAddress,false); natDetectionAttempts.RemoveAtIndexFast(i); i--; break; } } i++; } }
void ConnectionGraph2::AddParticipant(const SystemAddress &systemAddress, RakNetGUID rakNetGUID) { // Relay the new connection to other systems. RakNet::BitStream bs; bs.Write((MessageID)ID_REMOTE_NEW_INCOMING_CONNECTION); bs.Write((uint32_t)1); bs.Write(systemAddress); bs.Write(rakNetGUID); bs.WriteCasted<uint16_t>(rakPeerInterface->GetAveragePing(rakNetGUID)); SendUnified(&bs,HIGH_PRIORITY,RELIABLE_ORDERED,0,systemAddress,true); // Send everyone to the new guy DataStructures::List<SystemAddress> addresses; DataStructures::List<RakNetGUID> guids; rakPeerInterface->GetSystemList(addresses, guids); bs.Reset(); bs.Write((MessageID)ID_REMOTE_NEW_INCOMING_CONNECTION); BitSize_t writeOffset = bs.GetWriteOffset(); bs.Write((uint32_t) addresses.Size()); unsigned int i; uint32_t count=0; for (i=0; i < addresses.Size(); i++) { if (addresses[i]==systemAddress) continue; bs.Write(addresses[i]); bs.Write(guids[i]); bs.WriteCasted<uint16_t>(rakPeerInterface->GetAveragePing(guids[i])); count++; } if (count>0) { BitSize_t writeOffset2 = bs.GetWriteOffset(); bs.SetWriteOffset(writeOffset); bs.Write(count); bs.SetWriteOffset(writeOffset2); SendUnified(&bs,HIGH_PRIORITY,RELIABLE_ORDERED,0,systemAddress,false); } bool objectExists; unsigned int ii = remoteSystems.GetIndexFromKey(rakNetGUID, &objectExists); if (objectExists==false) { RemoteSystem* remoteSystem = RakNet::OP_NEW<RemoteSystem>(_FILE_AND_LINE_); remoteSystem->guid=rakNetGUID; remoteSystems.InsertAtIndex(remoteSystem,ii,_FILE_AND_LINE_); } }
void PlayerManager::HandlePacket(RakNet::Packet *packet) { RakNet::BitStream receivedData(packet->data, packet->length, false); RakNetwork *network = m_Network; RakNetGUID remotePeerGUID = packet->guid; unsigned char type; receivedData.Read(type); if (type == ID_NEW_INCOMING_CONNECTION) { // Notify new peers about the existing players if (NetworkManager::ArbitratorIsLocal()) { for (auto it = PlayerRegistry::PlayersBegin(), end = PlayerRegistry::PlayersEnd(); it != end; ++it) { RakNet::BitStream newPlayerNotification; newPlayerNotification.Write0(); // Tell the peer that the player is on another system newPlayerNotification.Write(it->NetID); if (it->LocalIndex >= s_MaxLocalPlayers) newPlayerNotification.Write(it->GUID); // Remote player (relative to this arbitrator) else newPlayerNotification.Write(NetworkManager::GetNetwork()->GetLocalGUID()); // Local player network->Send( NetDestination(remotePeerGUID, false), !Timestamped, MTID_ADDPLAYER, &newPlayerNotification, MEDIUM_PRIORITY, RELIABLE_ORDERED, CID_SYSTEM); } } } else if (type == MTID_ADDPLAYER) { if (NetworkManager::ArbitratorIsLocal()) { // So we can tell the remote peer what requested player we are adding: unsigned int remotePlayerIndex; receivedData.Read(remotePlayerIndex); PlayerID netId = m_NextNetId++;//m_UnusedNetIds.getFreeID(); PlayerRegistry::AddRemotePlayer(netId, remotePeerGUID); { RakNet::BitStream response; response.Write1(); // Tell the peer that the player being added is on their system response.Write(netId); response.Write(remotePlayerIndex); network->Send( NetDestination(remotePeerGUID, false), !Timestamped, MTID_ADDPLAYER, &response, MEDIUM_PRIORITY, RELIABLE_ORDERED, CID_SYSTEM); } { RakNet::BitStream newPlayerNotification; newPlayerNotification.Write0(); // Tell the peer that the player being added is on another system newPlayerNotification.Write(netId); newPlayerNotification.Write(remotePeerGUID); network->Send( NetDestination(remotePeerGUID, true), // Broadcast !Timestamped, MTID_ADDPLAYER, &newPlayerNotification, MEDIUM_PRIORITY, RELIABLE_ORDERED, CID_SYSTEM); } } else { bool localPlayer = receivedData.ReadBit(); // The net ID the arbiter has assigned to the new player: PlayerID netId; receivedData.Read(netId); if (localPlayer) { unsigned int localIndex; receivedData.Read(localIndex); PlayerRegistry::AddLocalPlayer(netId, localIndex); } else { RakNetGUID guid; receivedData.Read(guid); PlayerRegistry::AddRemotePlayer(netId, guid); } } } else if (type == MTID_REMOVEPLAYER) { PlayerID netId; receivedData.Read(netId); PlayerRegistry::RemovePlayer(netId); } }
void Equip::Render() { if (mDragSprite.GetVisible()) { SVector2 position = mDragSprite.GetPosition(); float x = Input_GetMouseScreenX() - position.x; float y = Input_GetMouseScreenY() - position.y - 32; int slot = -1; if (Input_IsMousePressed(Mouse::LBUTTON)) { // Ring Left if (x > 226 && x < 269 && y > 93 && y < 138) { slot = ring2; } // Ring Right if (x > 226 && x < 269 && y > 144 && y < 187) { slot = ring; } // Right arm if (x > 177 && x < 219 && y > 119 && y < 162) { slot = shield; } // Left arm if (x > 78 && x < 118 && y > 120 && y < 163) { slot = weapon; } // Helmet if (x > 28 && x < 70 && y > -4 && y < 40) { slot = helmet; } // Armor if (x > 28 && x < 70 && y > 94 && y < 137) { slot = armor; } // Boots if (x > 28 && x < 70 && y > 143 && y < 189) { slot = boots; } // Necklace if (x > 28 && x < 70 && y > 45 && y < 88) { slot = necklace; } if (slot >= 0 && mInventory.GetSpaceLeft() > 0 && mPlayerInfo.GetEqiupItemImage(slot) > 0) { mSprite[slot].Unload(); mPlayerInfo.SetEqiupItem(slot, 0, 0); RakNet::BitStream bsOut; bsOut.Write((RakNet::MessageID) ID_UNEQIUP_ITEM); bsOut.Write(slot); mRaknet.mPeer->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, mRaknet.mServerAddress, false); } } mDragSprite.Render(); mStats.Render(); mSprite[weapon].SetPosition(position.x + 83, position.y + 155); mSprite[shield].SetPosition(position.x + 182, position.y + 155); mSprite[helmet].SetPosition(position.x + 32, position.y + 32); mSprite[armor].SetPosition(position.x + 32, position.y + 130); mSprite[boots].SetPosition(position.x + 32, position.y + 182); mSprite[necklace].SetPosition(position.x + 32, position.y + 81); mSprite[ring].SetPosition(position.x + 230, position.y + 132); mSprite[ring2].SetPosition(position.x + 230, position.y + 182); for (int a = 0; a < 8; ++a) { if (mPlayerInfo.GetEqiupItemImage(a) > 0) { mSprite[a].Render(); } } char temp[CHAR_MAX]; sprintf(temp, "MouseX: %f", x); Graphics_DebugText(temp, 5, 225, 0XFF0000); sprintf(temp, "MouseY: %f", y); Graphics_DebugText(temp, 5, 250, 0XFF0000); sprintf(temp, "%s", mPlayerInfo.GetUsername()); mFont.Print(temp, (int) (position.x + 112.0f), (int) (position.y + 23.0f)); if (mStats.GetVisible()) { sprintf(temp, "%d", mPlayerInfo.GetStr()); mFont.Print(temp, (int) (position.x + 210.0f), (int) (position.y + 288.0f)); sprintf(temp, "%d", mPlayerInfo.GetDex()); mFont.Print(temp, (int) (position.x + 210.0f), (int) (position.y + 305.0f)); sprintf(temp, "%d", mPlayerInfo.GetInt()); mFont.Print(temp, (int) (position.x + 210.0f), (int) (position.y + 322.0f)); sprintf(temp, "%d", mPlayerInfo.GetAttack()); mFont.Print(temp, (int) (position.x + 210.0f), (int) (position.y + 339.0f)); sprintf(temp, "%d", mPlayerInfo.GetDefence()); mFont.Print(temp, (int) (position.x + 210.0f), (int) (position.y + 356.0f)); sprintf(temp, "%d", mPlayerInfo.GetCrit()); mFont.Print(temp, (int) (position.x + 210.0f), (int) (position.y + 373.0f)); } } }
bool AutoRPC::SendCall(const char *uniqueIdentifier, const char *stack, unsigned int bytesOnStack, char parameterCount) { SystemAddress systemAddr; RPCIdentifier identifier; unsigned int outerIndex; unsigned int innerIndex; if (uniqueIdentifier==0) return false; identifier.uniqueIdentifier=(char*) uniqueIdentifier; identifier.isObjectMember=(outgoingNetworkID!=UNASSIGNED_NETWORK_ID); RakNet::BitStream bs; if (outgoingTimestamp!=0) { bs.Write((MessageID)ID_TIMESTAMP); bs.Write(outgoingTimestamp); } bs.Write((MessageID)ID_AUTO_RPC_CALL); if (parameterCount>=0) { bs.Write(true); bs.Write(parameterCount); } else { bs.Write(false); } bs.WriteCompressed(outgoingExtraData.GetNumberOfBitsUsed()); bs.Write(&outgoingExtraData); if (outgoingNetworkID!=UNASSIGNED_NETWORK_ID) { bs.Write(true); bs.Write(outgoingNetworkID); } else { bs.Write(false); } // This is so the call SetWriteOffset works bs.AlignWriteToByteBoundary(); BitSize_t writeOffset = bs.GetWriteOffset(); SystemAddress outgoingSystemAddress; if (outgoingSystemIdentifier.rakNetGuid!=UNASSIGNED_RAKNET_GUID) outgoingSystemAddress = rakPeerInterface->GetSystemAddressFromGuid(outgoingSystemIdentifier.rakNetGuid); else outgoingSystemAddress = outgoingSystemIdentifier.systemAddress; if (outgoingBroadcast) { unsigned systemIndex; for (systemIndex=0; systemIndex < rakPeerInterface->GetMaximumNumberOfPeers(); systemIndex++) { systemAddr=rakPeerInterface->GetSystemAddressFromIndex(systemIndex); if (systemAddr!=UNASSIGNED_SYSTEM_ADDRESS && systemAddr!=outgoingSystemAddress) { if (GetRemoteFunctionIndex(systemAddr, identifier, &outerIndex, &innerIndex)) { // Write a number to identify the function if possible, for faster lookup and less bandwidth bs.Write(true); bs.WriteCompressed(remoteFunctions[outerIndex]->operator [](innerIndex).functionIndex); } else { bs.Write(false); stringCompressor->EncodeString(uniqueIdentifier, 512, &bs, 0); } bs.WriteCompressed(bytesOnStack); bs.WriteAlignedBytes((const unsigned char*) stack, bytesOnStack); SendUnified(&bs, outgoingPriority, outgoingReliability, outgoingOrderingChannel, systemAddr, false); // Start writing again after ID_AUTO_RPC_CALL bs.SetWriteOffset(writeOffset); } } } else { systemAddr = outgoingSystemAddress; if (systemAddr!=UNASSIGNED_SYSTEM_ADDRESS) { if (GetRemoteFunctionIndex(systemAddr, identifier, &outerIndex, &innerIndex)) { // Write a number to identify the function if possible, for faster lookup and less bandwidth bs.Write(true); bs.WriteCompressed(remoteFunctions[outerIndex]->operator [](innerIndex).functionIndex); } else { bs.Write(false); stringCompressor->EncodeString(uniqueIdentifier, 512, &bs, 0); } bs.WriteCompressed(bytesOnStack); bs.WriteAlignedBytes((const unsigned char*) stack, bytesOnStack); SendUnified(&bs, outgoingPriority, outgoingReliability, outgoingOrderingChannel, systemAddr, false); } else return false; } return true; }
void NatPunchthroughServer::Update(void) { ConnectionAttempt *connectionAttempt; User *user, *recipient; unsigned int i,j; RakNet::Time time = RakNet::GetTime(); if (time > lastUpdate+250) { lastUpdate=time; for (i=0; i < users.Size(); i++) { user=users[i]; for (j=0; j < user->connectionAttempts.Size(); j++) { connectionAttempt=user->connectionAttempts[j]; if (connectionAttempt->sender==user) { if (connectionAttempt->attemptPhase!=ConnectionAttempt::NAT_ATTEMPT_PHASE_NOT_STARTED && time > connectionAttempt->startTime && time > 10000 + connectionAttempt->startTime ) // Formerly 5000, but sometimes false positives { RakNet::BitStream outgoingBs; // that other system might not be running the plugin outgoingBs.Write((MessageID)ID_NAT_TARGET_UNRESPONSIVE); outgoingBs.Write(connectionAttempt->recipient->guid); outgoingBs.Write(connectionAttempt->sessionId); rakPeerInterface->Send(&outgoingBs,HIGH_PRIORITY,RELIABLE_ORDERED,0,connectionAttempt->sender->systemAddress,false); // 05/28/09 Previously only told sender about ID_NAT_CONNECTION_TO_TARGET_LOST // However, recipient may be expecting it due to external code // In that case, recipient would never get any response if the sender dropped outgoingBs.Reset(); outgoingBs.Write((MessageID)ID_NAT_TARGET_UNRESPONSIVE); outgoingBs.Write(connectionAttempt->sender->guid); outgoingBs.Write(connectionAttempt->sessionId); rakPeerInterface->Send(&outgoingBs,HIGH_PRIORITY,RELIABLE_ORDERED,0,connectionAttempt->recipient->systemAddress,false); connectionAttempt->sender->isReady=true; connectionAttempt->recipient->isReady=true; recipient=connectionAttempt->recipient; if (natPunchthroughServerDebugInterface) { char str[1024]; char addr1[128], addr2[128]; // 8/01/09 Fixed bug where this was after DeleteConnectionAttempt() connectionAttempt->sender->systemAddress.ToString(true,addr1); connectionAttempt->recipient->systemAddress.ToString(true,addr2); sprintf(str, "Sending ID_NAT_TARGET_UNRESPONSIVE to sender %s and recipient %s.", addr1, addr2); natPunchthroughServerDebugInterface->OnServerMessage(str); RakNet::RakString log; connectionAttempt->sender->LogConnectionAttempts(log); connectionAttempt->recipient->LogConnectionAttempts(log); } connectionAttempt->sender->DerefConnectionAttempt(connectionAttempt); connectionAttempt->recipient->DeleteConnectionAttempt(connectionAttempt); StartPunchthroughForUser(user); StartPunchthroughForUser(recipient); break; } } } } } }
void AutoRPC::OnRPCUnknownRemoteIndex(SystemAddress systemAddress, unsigned char *data, unsigned int lengthInBytes, RakNetTime timestamp) { char inputStack[ARPC_MAX_STACK_SIZE]; NetworkID networkId; bool hasNetworkId=false; unsigned int functionIndex; unsigned int bytesOnStack; int numberOfBitsUsed; char parameterCount; bool hasParameterCount=false; RakNet::BitStream extraData; RakNet::BitStream bs(data,lengthInBytes,false); bs.Read(hasParameterCount); if (hasParameterCount) bs.Read(parameterCount); bs.ReadCompressed(functionIndex); bs.ReadCompressed(numberOfBitsUsed); extraData.AddBitsAndReallocate(numberOfBitsUsed); bs.ReadBits(extraData.GetData(), numberOfBitsUsed, false); extraData.SetWriteOffset(numberOfBitsUsed); bs.Read(hasNetworkId); if (hasNetworkId) bs.Read(networkId); bs.ReadCompressed(bytesOnStack); bs.ReadAlignedBytes((unsigned char*) inputStack, bytesOnStack); unsigned outerIndex; if (remoteFunctions.Has(systemAddress)) { outerIndex = remoteFunctions.GetIndexAtKey(systemAddress); DataStructures::OrderedList<RPCIdentifier, RemoteRPCFunction, AutoRPC::RemoteRPCFunctionComp> *theList = remoteFunctions[outerIndex]; unsigned i; for (i=0; i < theList->Size(); i++) { if (theList->operator [](i).functionIndex==functionIndex) { RakNet::BitStream out; // Recover by resending the RPC with the function identifier string this time if (timestamp!=0) { out.Write((MessageID)ID_TIMESTAMP); out.Write(timestamp); } out.Write((MessageID)ID_AUTO_RPC_CALL); if (parameterCount>=0) { out.Write(true); out.Write(parameterCount); } else { out.Write(false); } out.WriteCompressed(numberOfBitsUsed); out.Write(&extraData); out.Write(hasNetworkId); if (hasNetworkId) out.Write(networkId); out.AlignWriteToByteBoundary(); out.Write(false); stringCompressor->EncodeString(theList->operator [](i).identifier.uniqueIdentifier, 512, &out, 0); out.WriteCompressed(bytesOnStack); out.WriteAlignedBytes((const unsigned char*) inputStack, bytesOnStack); SendUnified(&out, outgoingPriority, outgoingReliability, outgoingOrderingChannel, systemAddress, false); return; } } } // Failed to recover, inform the user Packet *p = rakPeerInterface->AllocatePacket(sizeof(MessageID)+sizeof(unsigned char)); RakNet::BitStream bs2(p->data, sizeof(MessageID)+sizeof(unsigned char), false); bs2.SetWriteOffset(0); bs2.Write((MessageID)ID_RPC_REMOTE_ERROR); bs2.Write((unsigned char)RPC_ERROR_FUNCTION_NO_LONGER_REGISTERED); stringCompressor->EncodeString("",256,&bs,0); p->systemAddress=systemAddress; rakPeerInterface->PushBackPacket(p, false); }
int ReliableOrderedConvertedTest::RunTest(DataStructures::List<RakNet::RakString> params,bool isVerbose,bool noPauses) { RakPeerInterface *sender, *receiver; unsigned int packetNumberSender[32],packetNumberReceiver[32], receivedPacketNumberReceiver, receivedTimeReceiver; char str[256]; char ip[32]; RakNetTime sendInterval, nextSend, currentTime, quitTime; unsigned short remotePort, localPort; unsigned char streamNumberSender,streamNumberReceiver; RakNet::BitStream bitStream; Packet *packet; bool doSend=false; for (int i=0; i < 32; i++) { packetNumberSender[i]=0; packetNumberReceiver[i]=0; } /* if (argc==2) { fp = fopen(argv[1],"wt"); SetMalloc_Ex(LoggedMalloc); SetRealloc_Ex(LoggedRealloc); SetFree_Ex(LoggedFree); } else */ fp=0; destroyList.Clear(false,__FILE__,__LINE__); sender =RakNetworkFactory::GetRakPeerInterface(); destroyList.Push( sender ,__FILE__,__LINE__); //sender->ApplyNetworkSimulator(.02, 100, 50); /* if (str[0]==0) sendInterval=30; else sendInterval=atoi(str);*///possible future params sendInterval=30; /* printf("Enter remote IP: "); gets(ip); if (ip[0]==0)*/ strcpy(ip, "127.0.0.1"); /* printf("Enter remote port: "); gets(str); if (str[0]==0)*/ strcpy(str, "60000"); remotePort=atoi(str); /* printf("Enter local port: "); gets(str); if (str[0]==0)*/ strcpy(str, "0"); localPort=atoi(str); if (isVerbose) printf("Connecting...\n"); SocketDescriptor tmp(localPort,0); sender->Startup(1, 30, &tmp, 1); sender->Connect(ip, remotePort, 0, 0); receiver =RakNetworkFactory::GetRakPeerInterface(); destroyList.Push( receiver ,__FILE__,__LINE__); /* printf("Enter local port: "); gets(str); if (str[0]==0)*/ strcpy(str, "60000"); localPort=atoi(str); if (isVerbose) printf("Waiting for connections...\n"); SocketDescriptor tmp2(localPort,0); receiver->Startup(32, 30, &tmp2, 1); receiver->SetMaximumIncomingConnections(32); // if (sender) // sender->ApplyNetworkSimulator(128000, 50, 100); // if (receiver) // receiver->ApplyNetworkSimulator(128000, 50, 100); /*printf("How long to run this test for, in seconds?\n"); gets(str); if (str[0]==0)*/ strcpy(str, "12"); currentTime = RakNet::GetTime(); quitTime = atoi(str) * 1000 + currentTime; nextSend=currentTime; while (currentTime < quitTime) //while (1) { packet = sender->Receive(); while (packet) { // PARSE TYPES switch(packet->data[0]) { case ID_CONNECTION_REQUEST_ACCEPTED: if (isVerbose) printf("ID_CONNECTION_REQUEST_ACCEPTED\n"); doSend=true; nextSend=currentTime; break; case ID_NO_FREE_INCOMING_CONNECTIONS: if (isVerbose) printf("ID_NO_FREE_INCOMING_CONNECTIONS\n"); break; case ID_DISCONNECTION_NOTIFICATION: if (isVerbose) printf("ID_DISCONNECTION_NOTIFICATION\n"); break; case ID_CONNECTION_LOST: if (isVerbose) printf("ID_CONNECTION_LOST\n"); break; case ID_CONNECTION_ATTEMPT_FAILED: if (isVerbose) printf("Connection attempt failed\n"); break; } sender->DeallocatePacket(packet); packet = sender->Receive(); } while (doSend && currentTime > nextSend) { streamNumberSender=0; // streamNumber = randomMT() % 32; // Do the send bitStream.Reset(); bitStream.Write((unsigned char) (ID_USER_PACKET_ENUM+1)); bitStream.Write(packetNumberSender[streamNumberSender]++); bitStream.Write(streamNumberSender); bitStream.Write(currentTime); char *pad; int padLength = (randomMT() % 5000) + 1; pad = new char [padLength]; bitStream.Write(pad, padLength); delete [] pad; // Send on a random priority with a random stream // if (sender->Send(&bitStream, HIGH_PRIORITY, (PacketReliability) (RELIABLE + (randomMT() %2)) ,streamNumber, UNASSIGNED_SYSTEM_ADDRESS, true)==false) if (sender->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED ,streamNumberSender, UNASSIGNED_SYSTEM_ADDRESS, true)==false) packetNumberSender[streamNumberSender]--; // Didn't finish connecting yet? RakNetStatistics *rssSender; rssSender=sender->GetStatistics(sender->GetSystemAddressFromIndex(0)); if (isVerbose) printf("Snd: %i.\n", packetNumberSender[streamNumberSender]); nextSend+=sendInterval; // Test halting // if (rand()%20==0) // nextSend+=1000; } packet = receiver->Receive(); while (packet) { switch(packet->data[0]) { case ID_NEW_INCOMING_CONNECTION: if (isVerbose) printf("ID_NEW_INCOMING_CONNECTION\n"); break; case ID_DISCONNECTION_NOTIFICATION: if (isVerbose) printf("ID_DISCONNECTION_NOTIFICATION\n"); break; case ID_CONNECTION_LOST: if (isVerbose) printf("ID_CONNECTION_LOST\n"); break; case ID_USER_PACKET_ENUM+1: bitStream.Reset(); bitStream.Write((char*)packet->data, packet->length); bitStream.IgnoreBits(8); // Ignore ID_USER_PACKET_ENUM+1 bitStream.Read(receivedPacketNumberReceiver); bitStream.Read(streamNumberReceiver); bitStream.Read(receivedTimeReceiver); if (receivedPacketNumberReceiver!=packetNumberReceiver[streamNumberReceiver]) { //WARNING: If you modify the below code make sure the whole string remains in bounds, sprintf will NOT do it for you. //The error string is 512 in length //Note: Removed buffer checking because chance is insignificant, left code if wanted in future. Needs limits.h ISO C standard. /* int maxIntWorkingCopy= INT_MAX; int maxIntCharLen =0; while (maxIntWorkingCopy>0) {maxIntCharLen++; maxIntWorkingCopy/=10; } if (strlen(lastError)>maxIntCharLen* 3 +27)//512 should be a good len for now {*/ sprintf(lastError,"Expecting %i got %i (channel %i).",packetNumberReceiver[streamNumberReceiver], receivedPacketNumberReceiver, streamNumberReceiver); /* } else { sprintf(lastError,"Did not get what was expected. More details can be given if the error string buffer size is increased."); }*/ if (isVerbose) { RakNetStatistics *rssSender,*rssReceiver; char message[2048]; rssSender=sender->GetStatistics(sender->GetSystemAddressFromIndex(0)); rssReceiver=receiver->GetStatistics(receiver->GetSystemAddressFromIndex(0)); StatisticsToString(rssSender, message, 2); printf("Server stats %s\n", message); StatisticsToString(rssReceiver, message, 2); printf("Client stats%s", message); DebugTools::ShowError(lastError,!noPauses && isVerbose,__LINE__,__FILE__); } return 1; } else if (isVerbose) { printf("Got %i.Channel %i.Len %i.", packetNumberReceiver[streamNumberReceiver], streamNumberReceiver, packet->length); printf("Sent=%u Received=%u Diff=%i.\n", receivedTimeReceiver, currentTime, (int)currentTime - (int) receivedTimeReceiver); } packetNumberReceiver[streamNumberReceiver]++; break; } receiver->DeallocatePacket(packet); packet = receiver->Receive(); } RakSleep(0); currentTime=RakNet::GetTime(); } if (isVerbose) { RakNetStatistics *rssSender,*rssReceiver; char message[2048]; rssSender=sender->GetStatistics(sender->GetSystemAddressFromIndex(0)); rssReceiver=receiver->GetStatistics(receiver->GetSystemAddressFromIndex(0)); StatisticsToString(rssSender, message, 2); printf("Server stats %s\n", message); StatisticsToString(rssReceiver, message, 2); printf("Client stats%s", message); } if (fp) fclose(fp); return 0; }