void Network::send_input(){ if(status=="client"){ if(game.in_progress){ if(commands_this_second<rate_commands && ++counter_commands>=(uint32_t)ceil(UPDATE_RATE/(double)rate_commands)){ counter_commands=0; commands_this_second++; RakNet::BitStream bitstream; bitstream.Write((RakNet::MessageID)ID_GAME_INPUT); bitstream.WriteCompressed((int)command_buffer.size()); for(int i=0;i<command_buffer.size();i++){ bitstream.WriteCompressed((RakNet::RakString)command_buffer[i].c_str()); } command_buffer.clear(); bitstream.WriteCompressed((int)game.command_states.size()); for(int i=0;i<game.command_states.size();i++){ bitstream.WriteCompressed((RakNet::RakString)game.command_states[i].c_str()); } stat_counter_bytes_sent+=bitstream.GetNumberOfBytesUsed(); peer->Send(&bitstream,HIGH_PRIORITY,RELIABLE_ORDERED,ORDERING_CHANNEL_INPUT,server_id,false); } } } }
void FileListTransfer::PushReference(SystemAddress systemAddress) { // Was previously using GetStatistics to get outgoing buffer size, but TCP with UnifiedSend doesn't have this unsigned int i=0; unsigned int bytesRead; char *dataBlocks[2]; int lengths[2]; RakNet::BitStream outBitstream; while (i < filesToPush.Size()) { if (filesToPush[i].systemAddress==systemAddress) { outBitstream.Reset(); outBitstream.Write((MessageID)ID_FILE_LIST_REFERENCE_PUSH); outBitstream.Write(filesToPush[i].fileListNode.context); outBitstream.Write(filesToPush[i].setID); stringCompressor->EncodeString(filesToPush[i].fileListNode.filename, 512, &outBitstream); outBitstream.WriteCompressed(filesToPush[i].setIndex); outBitstream.WriteCompressed(filesToPush[i].fileListNode.dataLengthBytes); // Original length in bytes // Read and send chunk. If done, delete at this index void *buff = rakMalloc_Ex(filesToPush[i].chunkSize, __FILE__, __LINE__); if (buff==0) { notifyOutOfMemory(__FILE__, __LINE__); continue; } bytesRead=filesToPush[i].incrementalReadInterface->GetFilePart(filesToPush[i].fileListNode.fullPathToFile, filesToPush[i].currentOffset, filesToPush[i].chunkSize, buff, filesToPush[i].fileListNode.context); outBitstream.WriteCompressed(filesToPush[i].currentOffset); filesToPush[i].currentOffset+=bytesRead; outBitstream.WriteCompressed(bytesRead); bool done = bytesRead!=filesToPush[i].chunkSize; outBitstream.Write(done); if (callback) { callback->OnFilePush(filesToPush[i].fileListNode.filename, filesToPush[i].fileListNode.fileLengthBytes, filesToPush[i].currentOffset-bytesRead, bytesRead, done, filesToPush[i].systemAddress); } dataBlocks[0]=(char*) outBitstream.GetData(); lengths[0]=outBitstream.GetNumberOfBytesUsed(); dataBlocks[1]=(char*) buff; lengths[1]=bytesRead; //rakPeerInterface->SendList(dataBlocks,lengths,2,filesToPush[i].packetPriority, RELIABLE_ORDERED, filesToPush[i].orderingChannel, filesToPush[i].systemAddress, false); SendListUnified(dataBlocks,lengths,2,filesToPush[i].packetPriority, RELIABLE_ORDERED, filesToPush[i].orderingChannel, filesToPush[i].systemAddress, false); if (done) { // Done RakNet::OP_DELETE_ARRAY(filesToPush[i].fileListNode.filename, __FILE__, __LINE__); filesToPush.RemoveAtIndex(i); } rakFree_Ex(buff, __FILE__, __LINE__ ); return; } else i++; } }
void CPickupSendPackets::SetRespawnTime( unsigned char uc ) { RakNet::BitStream bs; PreparePacket(ID_PICKUP_SETRESPAWNTIME, bs); bs.WriteCompressed( uc ); CNet::GetInterface()->Send(&bs, HIGH_PRIORITY, RELIABLE, 0); }
void Network::send_client_data(bool first_send){ if(status=="client"){ char ordering_channel=ORDERING_CHANNEL_CLIENT_DATA; if(first_send){ ordering_channel=ORDERING_CHANNEL_CONNECTION; } RakNet::BitStream bitstream; bitstream.Write((RakNet::MessageID)ID_GAME_CLIENT_DATA); bitstream.WriteCompressed(first_send); bitstream.WriteCompressed((RakNet::RakString)game.option_name.c_str()); bitstream.WriteCompressed(rate_bytes); bitstream.WriteCompressed(rate_updates); stat_counter_bytes_sent+=bitstream.GetNumberOfBytesUsed(); peer->Send(&bitstream,MEDIUM_PRIORITY,RELIABLE_ORDERED,ordering_channel,server_id,false); } }
void CLocalPlayer::OnDeath( CNetworkPlayer * pKiller ) { // Are we not marked as dead? if( !IsDead() ) { // Get the old camera lock state bOldCameraState = pCore->GetCamera()->IsLocked (); // Get the old control state bOldCTRLState = AreControlsLocked (); // Mark as dead SetDead( true ); // Set the death time m_ulDeathTime = SharedUtility::GetTime(); // Mark as not spawned SetSpawned( false ); // Mark as not aiming SetAiming( false ); // Mark as not shooting SetShooting( false ); // Set the death time SetDeathTime( SharedUtility::GetTime() ); // Remove all the weapons m_pPlayerPed->RemoveAllWeapons (); // Construct a new bitstream RakNet::BitStream pBitStream; // Write the killerid pBitStream.WriteCompressed( (pKiller ? pKiller->GetId() : INVALID_ENTITY_ID) ); // Send RPC to server pCore->GetNetworkModule()->Call( RPC_PLAYER_DEATH, &pBitStream, HIGH_PRIORITY, RELIABLE, true ); // Fade out the screen pCore->GetHud()->FadeOut ( 3000 ); // Fade out the sound pCore->GetGame()->FadeSound ( true, 3 ); // Lock the camera control pCore->GetCamera()->LockControl ( true ); // Lock the player controls LockControls ( true ); } }
void CPickupSendPackets::SetPickupRespawnTime( unsigned int ui, unsigned char uc ) { CPickupPool* pPickup = CPickupPoolManager::Find( ui ); if ( pPickup ) { RakNet::BitStream bs; PreparePacket(ID_PICKUP_SETPICKUPRESPAWNTIME, bs); bs.Write( ui ); bs.WriteCompressed( uc ); CNet::GetInterface()->Send(&bs, HIGH_PRIORITY, RELIABLE, 0); } }
void RPC4::Call( const char* uniqueID, RakNet::BitStream * bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel, const AddressOrGUID systemIdentifier, bool broadcast ) { 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); } SendUnified(&out,priority,reliability,orderingChannel,systemIdentifier,broadcast); }
int main(void) { printf("Demonstration of the RPC4 plugin.\n"); printf("Difficulty: Beginner\n\n"); rakPeer1=RakNet::RakPeerInterface::GetInstance(); rakPeer2=RakNet::RakPeerInterface::GetInstance(); RakNet::SocketDescriptor sd1(1234,0); RakNet::SocketDescriptor sd2(1235,0); rakPeer1->Startup(8,&sd1,1); rakPeer2->Startup(8,&sd2,1); rakPeer1->SetMaximumIncomingConnections(8); rakPeer2->Connect("127.0.0.1", sd1.port, 0, 0); RakSleep(100); RPC4 rpc1, rpc2; rakPeer1->AttachPlugin(&rpc1); rakPeer2->AttachPlugin(&rpc2); rpc1.RegisterSlot("Event1", CFunc1, 0); rpc2.RegisterSlot("Event1", CFunc1, 0); rpc1.RegisterSlot("Event1", CFunc2, 0); rpc2.RegisterSlot("Event1", CFunc2, 0); RakNet::BitStream testBs; testBs.WriteCompressed("testData"); rpc1.Signal("Event1", &testBs, HIGH_PRIORITY,RELIABLE_ORDERED,0,rakPeer2->GetSystemAddressFromIndex(0),false, true); RakNet::Packet *packet; packet = rakPeer1->Receive(); RakAssert(packet->data[0]==ID_NEW_INCOMING_CONNECTION); rakPeer1->DeallocatePacket(packet); packet = rakPeer2->Receive(); RakAssert(packet->data[0]==ID_CONNECTION_REQUEST_ACCEPTED); rakPeer2->DeallocatePacket(packet); RakSleep(100); for (packet=rakPeer1->Receive(); packet; rakPeer1->DeallocatePacket(packet), rakPeer1->Receive()) ; for (packet=rakPeer2->Receive(); packet; rakPeer2->DeallocatePacket(packet), rakPeer2->Receive()) ; rakPeer1->Shutdown(100,0); rakPeer2->Shutdown(100,0); RakNet::RakPeerInterface::DestroyInstance(rakPeer1); RakNet::RakPeerInterface::DestroyInstance(rakPeer2); return 1; }
void PlayerChat(RakNet::BitStream * pBitStream, RakNet::Packet * pPacket) { // Get the playerid EntityId playerId = (EntityId) pPacket->guid.systemIndex; // Read if this is a command bool bIsCommand = pBitStream->ReadBit(); // Read the input RakNet::RakString strInput; pBitStream->Read(strInput); // Is the player active? if (CServer::GetInstance()->GetPlayerManager()->DoesExists(playerId)) { // Get a pointer to the player CPlayerEntity * pPlayer = CServer::GetInstance()->GetPlayerManager()->GetAt(playerId); // Is the pointer valid? if (pPlayer) { // Is this not a command? if (!bIsCommand) { CLogFile::Printf("[chat] %s: %s", pPlayer->GetName().Get(), strInput.C_String()); // Send the RPC back to other players RakNet::BitStream bitStream; bitStream.WriteCompressed(playerId); bitStream.Write(strInput); CServer::GetInstance()->GetNetworkModule()->Call(GET_RPC_CODEX(RPC_PLAYER_CHAT), &bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, playerId, true); } else { CLogFile::Printf("[command] %s: %s", pPlayer->GetName().Get(), strInput.C_String()); CScriptArguments args; args.push(strInput); args.push(pPlayer->GetScriptPlayer()); CEvents::GetInstance()->Call("onCommand", &args, CEventHandler::eEventType::GLOBAL_EVENT, nullptr); } } } }
void CPickupSendPackets::RespawnPickupForPlayer( unsigned char uc, unsigned int ui ) { CPlayerPool* pPlayer = CPlayerPoolManager::Find( ui ); if ( pPlayer ) { CPickupPool* pPickup = CPickupPoolManager::Find( ui ); if ( pPickup ) { RakNet::BitStream bs; PreparePacket(ID_PICKUP_RESPAWNPICKUPFORPLAYER, bs); bs.WriteCompressed( uc ); bs.Write( ui ); CNet::GetInterface()->Send(&bs, HIGH_PRIORITY, RELIABLE, 0); } } }
void InitGameForPlayer(PLAYERID playerID) { RakNet::BitStream bsInitGame; bsInitGame.WriteCompressed((bool)1); // m_bZoneNames bsInitGame.WriteCompressed((bool)1); // m_bUseCJWalk bsInitGame.WriteCompressed((bool)1); // m_bAllowWeapons bsInitGame.WriteCompressed((bool)0); // m_bLimitGlobalChatRadius bsInitGame.Write((float)200.00f); // m_fGlobalChatRadius bsInitGame.WriteCompressed((bool)0); // bStuntBonus bsInitGame.Write((float)70.0f); // m_fNameTagDrawDistance bsInitGame.WriteCompressed((bool)0); // m_bDisableEnterExits bsInitGame.WriteCompressed((bool)1); // m_bNameTagLOS bsInitGame.WriteCompressed((bool)1); // m_bTirePopping bsInitGame.Write((int)1); // m_iSpawnsAvailable bsInitGame.Write(playerID); // MyPlayerID bsInitGame.WriteCompressed((bool)1); // m_bShowPlayerTags bsInitGame.Write((int)1); // m_iShowPlayerMarkers bsInitGame.Write((BYTE)12); // m_byteWorldTime bsInitGame.Write((BYTE)10); // m_byteWeather bsInitGame.Write((float)0.008); // m_fGravity bsInitGame.WriteCompressed((bool)0); // bLanMode bsInitGame.Write((int)0); // m_iDeathDropMoney bsInitGame.WriteCompressed((bool)0); // m_bInstagib bsInitGame.Write((int)40); // iNetModeNormalOnfootSendRate bsInitGame.Write((int)40); // iNetModeNormalIncarSendRate bsInitGame.Write((int)40); // iNetModeFiringSendRate bsInitGame.Write((int)10); // iNetModeSendMultiplier BYTE bServerNameLen = (BYTE)strlen(serverName); bsInitGame.Write(bServerNameLen); bsInitGame.Write(serverName, bServerNameLen); BYTE vehModels[212]; memset(vehModels, 1, 212); bsInitGame.Write((char *)&vehModels, 212); pRakServer->RPC(&RPC_InitGame, &bsInitGame, HIGH_PRIORITY, RELIABLE, 0, pRakServer->GetPlayerIDFromIndex(playerID), FALSE, FALSE, UNASSIGNED_NETWORK_ID, NULL); }
void RPC4::Signal(const char *sharedIdentifier, RakNet::BitStream *bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel, const AddressOrGUID systemIdentifier, bool broadcast, bool invokeLocal) { RakNet::BitStream out; out.Write((MessageID) ID_RPC_PLUGIN); out.Write((MessageID) ID_RPC4_SIGNAL); out.WriteCompressed(sharedIdentifier); if (bitStream) { bitStream->ResetReadPointer(); out.AlignWriteToByteBoundary(); out.Write(bitStream); } SendUnified(&out,priority,reliability,orderingChannel,systemIdentifier,broadcast); if (invokeLocal) { DataStructures::HashIndex functionIndex; functionIndex = localSlots.GetIndexOf(sharedIdentifier); if (functionIndex.IsInvalid()) return; Packet p; p.guid=rakPeerInterface->GetMyGUID(); p.systemAddress=rakPeerInterface->GetMyBoundAddress(0); p.wasGeneratedLocally=true; RakNet::BitStream *bsptr, bstemp; if (bitStream) { bitStream->ResetReadPointer(); p.length=bitStream->GetNumberOfBytesUsed(); p.bitSize=bitStream->GetNumberOfBitsUsed(); bsptr=bitStream; } else { p.length=0; p.bitSize=0; bsptr=&bstemp; } InvokeSignal(functionIndex, bsptr, &p); } }
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 ); } }
int SendIRIToAddressCB(FileListTransfer::ThreadData threadData, bool *returnOutput, void* perThreadData) { (void) perThreadData; FileListTransfer *fileListTransfer = threadData.fileListTransfer; SystemAddress systemAddress = threadData.systemAddress; *returnOutput=false; // Was previously using GetStatistics to get outgoing buffer size, but TCP with UnifiedSend doesn't have this unsigned int bytesRead; const char *dataBlocks[2]; int lengths[2]; unsigned int smallFileTotalSize=0; RakNet::BitStream outBitstream; unsigned int ftpIndex; fileListTransfer->fileToPushRecipientListMutex.Lock(); for (ftpIndex=0; ftpIndex < fileListTransfer->fileToPushRecipientList.Size(); ftpIndex++) { FileListTransfer::FileToPushRecipient *ftpr = fileListTransfer->fileToPushRecipientList[ftpIndex]; // Referenced by both ftpr and list ftpr->AddRef(); fileListTransfer->fileToPushRecipientListMutex.Unlock(); if (ftpr->systemAddress==systemAddress) { FileListTransfer::FileToPush *ftp = ftpr->filesToPush.Peek(); // Read and send chunk. If done, delete at this index void *buff = rakMalloc_Ex(ftp->chunkSize, _FILE_AND_LINE_); if (buff==0) { ftpr->Deref(); notifyOutOfMemory(_FILE_AND_LINE_); return 0; } // Read the next file chunk bytesRead=ftp->incrementalReadInterface->GetFilePart(ftp->fileListNode.fullPathToFile, ftp->currentOffset, ftp->chunkSize, buff, ftp->fileListNode.context); bool done = ftp->fileListNode.dataLengthBytes == ftp->currentOffset+bytesRead; while (done && ftp->currentOffset==0 && ftpr->filesToPush.Size()>=2 && smallFileTotalSize<ftp->chunkSize) { // Send all small files at once, rather than wait for ID_FILE_LIST_REFERENCE_PUSH. But at least one ID_FILE_LIST_REFERENCE_PUSH must be sent outBitstream.Reset(); outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_FILE); // outBitstream.Write(ftp->fileListNode.context); outBitstream << ftp->fileListNode.context; outBitstream.Write(ftp->setID); StringCompressor::Instance()->EncodeString(ftp->fileListNode.filename, 512, &outBitstream); outBitstream.WriteCompressed(ftp->setIndex); outBitstream.WriteCompressed(ftp->fileListNode.dataLengthBytes); // Original length in bytes outBitstream.AlignWriteToByteBoundary(); dataBlocks[0]=(char*) outBitstream.GetData(); lengths[0]=outBitstream.GetNumberOfBytesUsed(); dataBlocks[1]=(const char*) buff; lengths[1]=bytesRead; fileListTransfer->SendListUnified(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, systemAddress, false); // LWS : fixed freed pointer reference // unsigned int chunkSize = ftp->chunkSize; RakNet::OP_DELETE(ftp,_FILE_AND_LINE_); ftpr->filesToPush.Pop(); smallFileTotalSize+=bytesRead; //done = bytesRead!=ftp->chunkSize; ftp = ftpr->filesToPush.Peek(); bytesRead=ftp->incrementalReadInterface->GetFilePart(ftp->fileListNode.fullPathToFile, ftp->currentOffset, ftp->chunkSize, buff, ftp->fileListNode.context); done = ftp->fileListNode.dataLengthBytes == ftp->currentOffset+bytesRead; } outBitstream.Reset(); outBitstream.Write((MessageID)ID_FILE_LIST_REFERENCE_PUSH); // outBitstream.Write(ftp->fileListNode.context); outBitstream << ftp->fileListNode.context; outBitstream.Write(ftp->setID); StringCompressor::Instance()->EncodeString(ftp->fileListNode.filename, 512, &outBitstream); outBitstream.WriteCompressed(ftp->setIndex); outBitstream.WriteCompressed(ftp->fileListNode.dataLengthBytes); // Original length in bytes outBitstream.WriteCompressed(ftp->currentOffset); ftp->currentOffset+=bytesRead; outBitstream.WriteCompressed(bytesRead); outBitstream.Write(done); for (unsigned int flpcIndex=0; flpcIndex < fileListTransfer->fileListProgressCallbacks.Size(); flpcIndex++) fileListTransfer->fileListProgressCallbacks[flpcIndex]->OnFilePush(ftp->fileListNode.filename, ftp->fileListNode.fileLengthBytes, ftp->currentOffset-bytesRead, bytesRead, done, systemAddress, ftp->setID); dataBlocks[0]=(char*) outBitstream.GetData(); lengths[0]=outBitstream.GetNumberOfBytesUsed(); dataBlocks[1]=(char*) buff; lengths[1]=bytesRead; //rakPeerInterface->SendList(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, ftp->systemAddress, false); fileListTransfer->SendListUnified(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, systemAddress, false); // Mutex state: FileToPushRecipient (ftpr) has AddRef. fileToPushRecipientListMutex not locked. if (done) { // Done unsigned short setId = ftp->setID; RakNet::OP_DELETE(ftp,_FILE_AND_LINE_); ftpr->filesToPush.Pop(); if (ftpr->filesToPush.Size()==0) { for (unsigned int flpcIndex=0; flpcIndex < fileListTransfer->fileListProgressCallbacks.Size(); flpcIndex++) fileListTransfer->fileListProgressCallbacks[flpcIndex]->OnFilePushesComplete(systemAddress, setId); // Remove ftpr from fileToPushRecipientList fileListTransfer->RemoveFromList(ftpr); } } // ftpr out of scope ftpr->Deref(); rakFree_Ex(buff, _FILE_AND_LINE_ ); return 0; } else { ftpr->Deref(); fileListTransfer->fileToPushRecipientListMutex.Lock(); } } fileListTransfer->fileToPushRecipientListMutex.Unlock(); return 0; }
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 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(); 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::GLOBAL_EVENT, 0); // Construct a new bitstream RakNet::BitStream bitStream; // Write the player id bitStream.WriteCompressed(playerId); // Write the player colour bitStream.Write(0xFFFFFF/*CServer::GetInstance()->GetPlayerManager()->GetAt(playerId)->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, playerId, false); CServer::GetInstance()->GetNetworkModule()->Call(GET_RPC_CODEX(RPC_START_GAME), &bitStream, HIGH_PRIORITY, RELIABLE, playerId, false); for (EntityId i = 0; i < CServer::GetInstance()->GetPlayerManager()->GetMax(); ++i) { if (CServer::GetInstance()->GetPlayerManager()->DoesExists(i) && i != playerId) { bitStream.Reset(); bitStream.WriteCompressed(i); bitStream.Write(CServer::GetInstance()->GetPlayerManager()->GetAt(i)->GetName().Get()); CServer::GetInstance()->GetNetworkModule()->Call(GET_RPC_CODEX(RPC_NEW_PLAYER), &bitStream, HIGH_PRIORITY, RELIABLE, playerId, false); } } for (EntityId i = 0; i < CServer::GetInstance()->GetPlayerManager()->GetMax(); ++i) { if (CServer::GetInstance()->GetPlayerManager()->DoesExists(i) && i != playerId) { bitStream.Reset(); bitStream.WriteCompressed(playerId); bitStream.Write(strName.Get()); CServer::GetInstance()->GetNetworkModule()->Call(GET_RPC_CODEX(RPC_NEW_PLAYER), &bitStream, HIGH_PRIORITY, RELIABLE, 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()*/90); CVector3 vecPosition; pVehicle->GetPosition(vecPosition); bitStream.Write(vecPosition); CServer::GetInstance()->GetNetworkModule()->Call(GET_RPC_CODEX(RPC_CREATE_VEHICLE), &bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, -1, true); } } bitStream.Reset(); bitStream.WriteCompressed(playerId); bitStream.Write(7); bitStream.Write(3); bitStream.Write(3); bitStream.Write(1); }
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 ); }
int main(void) { printf("Demonstration of the RPC4 plugin.\n"); printf("Difficulty: Beginner\n\n"); rakPeer=RakNet::RakPeerInterface::GetInstance(); // Holds user data char ip[64], serverPort[30], clientPort[30]; // Get our input puts("Enter the port to listen on"); Gets(clientPort,sizeof(clientPort)); if (clientPort[0]==0) strcpy(clientPort, "0"); RakNet::SocketDescriptor sd1(atoi(clientPort),0); rakPeer->Startup(8,&sd1,1); rakPeer->SetMaximumIncomingConnections(8); puts("Enter IP to connect to, or enter for none"); Gets(ip, sizeof(ip)); rakPeer->AllowConnectionResponseIPMigration(false); RPC4 rpc; rakPeer->AttachPlugin(&rpc); rpc.RegisterSlot("Event1", CFunc1, 0); rpc.RegisterSlot("Event1", CFunc2, 0); rpc.RegisterBlockingFunction("Blocking", CFunc3); RakNet::Packet *packet; if (ip[0]) { puts("Enter the port to connect to"); Gets(serverPort,sizeof(serverPort)); rakPeer->Connect(ip, atoi(serverPort), 0, 0); RakSleep(1000); for (packet=rakPeer->Receive(); packet; rakPeer->DeallocatePacket(packet), packet=rakPeer->Receive()) ; RakNet::BitStream testBs; testBs.WriteCompressed("testData"); // rpc.Signal("Event1", &testBs, HIGH_PRIORITY,RELIABLE_ORDERED,0,rakPeer->GetSystemAddressFromIndex(0),false, true); RakSleep(100); for (packet=rakPeer->Receive(); packet; rakPeer->DeallocatePacket(packet), rakPeer->Receive()) ; // Needs 2 program instances, because while the call is blocking rakPeer2->Receive() isn't getting called RakNet::BitStream testBlockingReturn; rpc.CallBlocking("Blocking", &testBs, HIGH_PRIORITY,RELIABLE_ORDERED,0,rakPeer->GetSystemAddressFromIndex(0),&testBlockingReturn); RakNet::RakString data; bool read = testBlockingReturn.ReadCompressed(data); printf("%s\n", data.C_String()); } else { printf("Waiting for connections.\n"); while (1) { RakSleep(100); for (packet=rakPeer->Receive(); packet; rakPeer->DeallocatePacket(packet), packet=rakPeer->Receive()) ; } } rakPeer->Shutdown(100,0); RakNet::RakPeerInterface::DestroyInstance(rakPeer); return 1; }
void FileListTransfer::SendIRIToAddress(SystemAddress systemAddress) { // Was previously using GetStatistics to get outgoing buffer size, but TCP with UnifiedSend doesn't have this unsigned int bytesRead; const char *dataBlocks[2]; int lengths[2]; unsigned int smallFileTotalSize=0; RakNet::BitStream outBitstream; filesToPushAllSameAddressMutex.Lock(); for (unsigned int ftpIndex=0; ftpIndex < filesToPushAllSameAddress.Size(); ftpIndex++) { FileToPushRecipient *ftpr = filesToPushAllSameAddress[ftpIndex]; if (ftpr->systemAddress==systemAddress) { FileToPush *ftp = ftpr->filesToPush.Peek(); // Read and send chunk. If done, delete at this index void *buff = rakMalloc_Ex(ftp->chunkSize, __FILE__, __LINE__); if (buff==0) { filesToPushAllSameAddressMutex.Unlock(); notifyOutOfMemory(__FILE__, __LINE__); return; } bytesRead=ftp->incrementalReadInterface->GetFilePart(ftp->fileListNode.fullPathToFile, ftp->currentOffset, ftp->chunkSize, buff, ftp->fileListNode.context); bool done = bytesRead!=ftp->chunkSize; while (done && ftp->currentOffset==0 && ftpr->filesToPush.Size()>=2 && smallFileTotalSize<ftp->chunkSize) { // Send all small files at once, rather than wait for ID_FILE_LIST_REFERENCE_PUSH. But at least one ID_FILE_LIST_REFERENCE_PUSH must be sent outBitstream.Reset(); outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_FILE); outBitstream.Write(ftp->fileListNode.context); outBitstream.Write(ftp->setID); stringCompressor->EncodeString(ftp->fileListNode.filename, 512, &outBitstream); outBitstream.WriteCompressed(ftp->setIndex); outBitstream.WriteCompressed(ftp->fileListNode.dataLengthBytes); // Original length in bytes outBitstream.AlignWriteToByteBoundary(); dataBlocks[0]=(char*) outBitstream.GetData(); lengths[0]=outBitstream.GetNumberOfBytesUsed(); dataBlocks[1]=(const char*) buff; lengths[1]=bytesRead; SendListUnified(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, systemAddress, false); RakNet::OP_DELETE(ftp,__FILE__,__LINE__); ftpr->filesToPush.Pop(); smallFileTotalSize+=bytesRead; done = bytesRead!=ftp->chunkSize; ftp = ftpr->filesToPush.Peek(); bytesRead=ftp->incrementalReadInterface->GetFilePart(ftp->fileListNode.fullPathToFile, ftp->currentOffset, ftp->chunkSize, buff, ftp->fileListNode.context); } outBitstream.Reset(); outBitstream.Write((MessageID)ID_FILE_LIST_REFERENCE_PUSH); outBitstream.Write(ftp->fileListNode.context); outBitstream.Write(ftp->setID); stringCompressor->EncodeString(ftp->fileListNode.filename, 512, &outBitstream); outBitstream.WriteCompressed(ftp->setIndex); outBitstream.WriteCompressed(ftp->fileListNode.dataLengthBytes); // Original length in bytes outBitstream.WriteCompressed(ftp->currentOffset); ftp->currentOffset+=bytesRead; outBitstream.WriteCompressed(bytesRead); outBitstream.Write(done); if (callback) { callback->OnFilePush(ftp->fileListNode.filename, ftp->fileListNode.fileLengthBytes, ftp->currentOffset-bytesRead, bytesRead, done, systemAddress); } dataBlocks[0]=(char*) outBitstream.GetData(); lengths[0]=outBitstream.GetNumberOfBytesUsed(); dataBlocks[1]=(char*) buff; lengths[1]=bytesRead; //rakPeerInterface->SendList(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, ftp->systemAddress, false); SendListUnified(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, systemAddress, false); if (done) { // Done RakNet::OP_DELETE(ftp,__FILE__,__LINE__); ftpr->filesToPush.Pop(); if (ftpr->filesToPush.Size()==0) { RakNet::OP_DELETE(ftpr,__FILE__,__LINE__); filesToPushAllSameAddress.RemoveAtIndexFast(ftpIndex); } } rakFree_Ex(buff, __FILE__, __LINE__ ); break; } } filesToPushAllSameAddressMutex.Unlock(); }
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; }
bool RPC3::SendCallOrSignal(RakString uniqueIdentifier, char parameterCount, RakNet::BitStream *serializedParameters, bool isCall) { SystemAddress systemAddr; // unsigned int outerIndex; // unsigned int innerIndex; if (uniqueIdentifier.IsEmpty()) return false; RakNet::BitStream bs; if (outgoingTimestamp!=0) { bs.Write((MessageID)ID_TIMESTAMP); bs.Write(outgoingTimestamp); } bs.Write((MessageID)ID_AUTO_RPC_CALL); bs.Write(parameterCount); if (outgoingNetworkID!=UNASSIGNED_NETWORK_ID && isCall) { bs.Write(true); bs.Write(outgoingNetworkID); } else { bs.Write(false); } bs.Write(isCall); // This is so the call SetWriteOffset works bs.AlignWriteToByteBoundary(); BitSize_t writeOffset = bs.GetWriteOffset(); 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, uniqueIdentifier, &outerIndex, &innerIndex, isCall)) // { // // Write a number to identify the function if possible, for faster lookup and less bandwidth // bs.Write(true); // if (isCall) // bs.WriteCompressed(remoteFunctions[outerIndex]->operator [](innerIndex).functionIndex); // else // bs.WriteCompressed(remoteSlots[outerIndex]->operator [](innerIndex).functionIndex); // } // else // { // bs.Write(false); stringCompressor->EncodeString(uniqueIdentifier, 512, &bs, 0); // } bs.WriteCompressed(serializedParameters->GetNumberOfBitsUsed()); bs.WriteAlignedBytes((const unsigned char*) serializedParameters->GetData(), serializedParameters->GetNumberOfBytesUsed()); 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, uniqueIdentifier, &outerIndex, &innerIndex, isCall)) // { // // Write a number to identify the function if possible, for faster lookup and less bandwidth // bs.Write(true); // if (isCall) // bs.WriteCompressed(remoteFunctions[outerIndex]->operator [](innerIndex).functionIndex); // else // bs.WriteCompressed(remoteSlots[outerIndex]->operator [](innerIndex).functionIndex); // } // else // { // bs.Write(false); stringCompressor->EncodeString(uniqueIdentifier, 512, &bs, 0); // } bs.WriteCompressed(serializedParameters->GetNumberOfBitsUsed()); bs.WriteAlignedBytes((const unsigned char*) serializedParameters->GetData(), serializedParameters->GetNumberOfBytesUsed()); SendUnified(&bs, outgoingPriority, outgoingReliability, outgoingOrderingChannel, systemAddr, false); } else return false; } return true; }
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 FileListTransfer::Send(FileList *fileList, RakPeerInterface *rakPeer, SystemAddress recipient, unsigned short setID, PacketPriority priority, char orderingChannel, bool compressData, IncrementalReadInterface *_incrementalReadInterface, unsigned int _chunkSize) { (void) compressData; if (callback) fileList->SetCallback(callback); unsigned int i, totalLength; RakNet::BitStream outBitstream; bool sendReference; const char *dataBlocks[2]; int lengths[2]; totalLength=0; for (i=0; i < fileList->fileList.Size(); i++) { const FileListNode &fileListNode = fileList->fileList[i]; totalLength+=fileListNode.fileLengthBytes; } // Write the chunk header, which contains the frequency table, the total number of files, and the total number of bytes bool anythingToWrite; outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_HEADER); outBitstream.Write(setID); anythingToWrite=fileList->fileList.Size()>0; outBitstream.Write(anythingToWrite); if (anythingToWrite) { outBitstream.WriteCompressed(fileList->fileList.Size()); outBitstream.WriteCompressed(totalLength); if (rakPeer) rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); else SendUnified(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); DataStructures::Queue<FileToPush*> filesToPush; for (i=0; i < fileList->fileList.Size(); i++) { sendReference = fileList->fileList[i].isAReference && _incrementalReadInterface!=0; if (sendReference) { FileToPush *fileToPush = RakNet::OP_NEW<FileToPush>(__FILE__,__LINE__); fileToPush->fileListNode.context=fileList->fileList[i].context; fileToPush->setIndex=i; fileToPush->fileListNode.filename=fileList->fileList[i].filename; fileToPush->fileListNode.fullPathToFile=fileList->fileList[i].fullPathToFile; fileToPush->fileListNode.fileLengthBytes=fileList->fileList[i].fileLengthBytes; fileToPush->fileListNode.dataLengthBytes=fileList->fileList[i].dataLengthBytes; // fileToPush->systemAddress=recipient; fileToPush->setID=setID; fileToPush->packetPriority=priority; fileToPush->orderingChannel=orderingChannel; fileToPush->currentOffset=0; fileToPush->incrementalReadInterface=_incrementalReadInterface; fileToPush->chunkSize=_chunkSize; filesToPush.Push(fileToPush,__FILE__,__LINE__); } else { outBitstream.Reset(); outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_FILE); outBitstream.Write(fileList->fileList[i].context); outBitstream.Write(setID); stringCompressor->EncodeString(fileList->fileList[i].filename, 512, &outBitstream); outBitstream.WriteCompressed(i); outBitstream.WriteCompressed(fileList->fileList[i].dataLengthBytes); // Original length in bytes outBitstream.AlignWriteToByteBoundary(); dataBlocks[0]=(char*) outBitstream.GetData(); lengths[0]=outBitstream.GetNumberOfBytesUsed(); dataBlocks[1]=fileList->fileList[i].data; lengths[1]=fileList->fileList[i].dataLengthBytes; SendListUnified(dataBlocks,lengths,2,priority, RELIABLE_ORDERED, orderingChannel, recipient, false); } } if (filesToPush.IsEmpty()==false) { FileToPushRecipient *ftpr=0; filesToPushAllSameAddressMutex.Lock(); for (unsigned int i=0; i < filesToPushAllSameAddress.Size(); i++) { if (filesToPushAllSameAddress[i]->systemAddress==recipient) { ftpr=filesToPushAllSameAddress[i]; break; } } if (ftpr==0) { ftpr = RakNet::OP_NEW<FileToPushRecipient>(__FILE__,__LINE__); ftpr->systemAddress=recipient; filesToPushAllSameAddress.Push(ftpr, __FILE__,__LINE__); } while (filesToPush.IsEmpty()==false) { ftpr->filesToPush.Push(filesToPush.Pop(), __FILE__,__LINE__); } filesToPushAllSameAddressMutex.Unlock(); SendIRIToAddress(recipient); return; } } else { if (rakPeer) rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); else SendUnified(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); } }
void FileListTransfer::Send(FileList *fileList, RakPeerInterface *rakPeer, SystemAddress recipient, unsigned short setID, PacketPriority priority, char orderingChannel, bool compressData, IncrementalReadInterface *_incrementalReadInterface, unsigned int _chunkSize) { (void) compressData; if (callback) fileList->SetCallback(callback); unsigned int i, totalLength; RakNet::BitStream outBitstream; bool sendReference; char *dataBlocks[2]; int lengths[2]; totalLength=0; for (i=0; i < fileList->fileList.Size(); i++) { const FileListNode &fileListNode = fileList->fileList[i]; totalLength+=fileListNode.fileLengthBytes; } // Write the chunk header, which contains the frequency table, the total number of files, and the total number of bytes bool anythingToWrite; outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_HEADER); outBitstream.Write(setID); anythingToWrite=fileList->fileList.Size()>0; outBitstream.Write(anythingToWrite); if (anythingToWrite) { outBitstream.WriteCompressed(fileList->fileList.Size()); outBitstream.WriteCompressed(totalLength); if (rakPeer) rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); else SendUnified(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); for (i=0; i < fileList->fileList.Size(); i++) { outBitstream.Reset(); sendReference = fileList->fileList[i].isAReference && _incrementalReadInterface!=0; if (sendReference) { StoreForPush(fileList->fileList[i].context, setID, fileList->fileList[i].filename, fileList->fileList[i].fullPathToFile, i, fileList->fileList[i].fileLengthBytes, fileList->fileList[i].dataLengthBytes, recipient, priority, orderingChannel, _incrementalReadInterface, _chunkSize); continue; } outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_FILE); outBitstream.Write(fileList->fileList[i].context); outBitstream.Write(setID); stringCompressor->EncodeString(fileList->fileList[i].filename, 512, &outBitstream); outBitstream.WriteCompressed(i); outBitstream.WriteCompressed(fileList->fileList[i].dataLengthBytes); // Original length in bytes outBitstream.AlignWriteToByteBoundary(); dataBlocks[0]=(char*) outBitstream.GetData(); lengths[0]=outBitstream.GetNumberOfBytesUsed(); dataBlocks[1]=fileList->fileList[i].data; lengths[1]=fileList->fileList[i].dataLengthBytes; if (rakPeer) rakPeer->SendList(dataBlocks,lengths,2,priority, RELIABLE_ORDERED, orderingChannel, recipient, false); else SendListUnified(dataBlocks,lengths,2,priority, RELIABLE_ORDERED, orderingChannel, recipient, false); } } else { if (rakPeer) rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); else SendUnified(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); } }
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 FileListTransfer::Send(FileList *fileList, RakNet::RakPeerInterface *rakPeer, SystemAddress recipient, unsigned short setID, PacketPriority priority, char orderingChannel, IncrementalReadInterface *_incrementalReadInterface, unsigned int _chunkSize) { for (unsigned int flpcIndex=0; flpcIndex < fileListProgressCallbacks.Size(); flpcIndex++) fileList->AddCallback(fileListProgressCallbacks[flpcIndex]); unsigned int i, totalLength; RakNet::BitStream outBitstream; bool sendReference; const char *dataBlocks[2]; int lengths[2]; totalLength=0; for (i=0; i < fileList->fileList.Size(); i++) { const FileListNode &fileListNode = fileList->fileList[i]; totalLength+=fileListNode.dataLengthBytes; } // Write the chunk header, which contains the frequency table, the total number of files, and the total number of bytes bool anythingToWrite; outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_HEADER); outBitstream.Write(setID); anythingToWrite=fileList->fileList.Size()>0; outBitstream.Write(anythingToWrite); if (anythingToWrite) { outBitstream.WriteCompressed(fileList->fileList.Size()); outBitstream.WriteCompressed(totalLength); if (rakPeer) rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); else SendUnified(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); DataStructures::Queue<FileToPush*> filesToPush; for (i=0; i < fileList->fileList.Size(); i++) { sendReference = fileList->fileList[i].isAReference && _incrementalReadInterface!=0; if (sendReference) { FileToPush *fileToPush = RakNet::OP_NEW<FileToPush>(_FILE_AND_LINE_); fileToPush->fileListNode.context=fileList->fileList[i].context; fileToPush->setIndex=i; fileToPush->fileListNode.filename=fileList->fileList[i].filename; fileToPush->fileListNode.fullPathToFile=fileList->fileList[i].fullPathToFile; fileToPush->fileListNode.fileLengthBytes=fileList->fileList[i].fileLengthBytes; fileToPush->fileListNode.dataLengthBytes=fileList->fileList[i].dataLengthBytes; // fileToPush->systemAddress=recipient; //fileToPush->setID=setID; fileToPush->packetPriority=priority; fileToPush->orderingChannel=orderingChannel; fileToPush->currentOffset=0; fileToPush->incrementalReadInterface=_incrementalReadInterface; fileToPush->chunkSize=_chunkSize; filesToPush.Push(fileToPush,_FILE_AND_LINE_); } else { outBitstream.Reset(); outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_FILE); outBitstream << fileList->fileList[i].context; // outBitstream.Write(fileList->fileList[i].context); outBitstream.Write(setID); StringCompressor::Instance()->EncodeString(fileList->fileList[i].filename, 512, &outBitstream); outBitstream.WriteCompressed(i); outBitstream.WriteCompressed(fileList->fileList[i].dataLengthBytes); // Original length in bytes outBitstream.AlignWriteToByteBoundary(); dataBlocks[0]=(char*) outBitstream.GetData(); lengths[0]=outBitstream.GetNumberOfBytesUsed(); dataBlocks[1]=fileList->fileList[i].data; lengths[1]=fileList->fileList[i].dataLengthBytes; SendListUnified(dataBlocks,lengths,2,priority, RELIABLE_ORDERED, orderingChannel, recipient, false); } } if (filesToPush.IsEmpty()==false) { FileToPushRecipient *ftpr; fileToPushRecipientListMutex.Lock(); for (unsigned int i=0; i < fileToPushRecipientList.Size(); i++) { if (fileToPushRecipientList[i]->systemAddress==recipient && fileToPushRecipientList[i]->setId==setId) { // ftpr=fileToPushRecipientList[i]; // ftpr->AddRef(); // break; RakAssert("setId already in use for this recipient" && 0); } } fileToPushRecipientListMutex.Unlock(); //if (ftpr==0) //{ ftpr = RakNet::OP_NEW<FileToPushRecipient>(_FILE_AND_LINE_); ftpr->systemAddress=recipient; ftpr->setId=setID; ftpr->refCount=2; // Allocated and in the list fileToPushRecipientList.Push(ftpr, _FILE_AND_LINE_); //} while (filesToPush.IsEmpty()==false) { ////ftpr->filesToPushMutex.Lock(); ftpr->filesToPush.Push(filesToPush.Pop(), _FILE_AND_LINE_); ////ftpr->filesToPushMutex.Unlock(); } // ftpr out of scope ftpr->Deref(); SendIRIToAddress(recipient, setID); return; } else { for (unsigned int flpcIndex=0; flpcIndex < fileListProgressCallbacks.Size(); flpcIndex++) fileListProgressCallbacks[flpcIndex]->OnFilePushesComplete(recipient, setID); } } else { for (unsigned int flpcIndex=0; flpcIndex < fileListProgressCallbacks.Size(); flpcIndex++) fileListProgressCallbacks[flpcIndex]->OnFilePushesComplete(recipient, setID); if (rakPeer) rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); else SendUnified(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); } }
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=packetizedTCP->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=packetizedTCP->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; }
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); }
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 && cs!=IS_LOOPBACK) 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->Read(blockingReturnValue); return true; }
// This is the entry point into the server (the main() function) int main() { // Print starting info to the console cout << "LL EE EE GG GG OO\n"; cout << "LL EE EE GGG GG OO\n"; cout << "LL EE EE GGG GG OO\n"; cout << "LL EE EE GG G GG OO\n"; cout << "LL EE EE GG G GG OO\n"; cout << "LLLLLL EE EE GG G GG OO\n"; cout << "LLLLLLLL EEEEEE GG GGG OO Server\n"; cout << "\tOriginal project: luniserver.sf.net\n\n\n"; cout << "Initializing LUNI test server...\n \nPress enter type \"help\" and enter again for commands\n\n"; // Initialize the auth, character, and world CONNECT_INFO structs CONNECT_INFO auth, character, world; // Load the values for them and store them into their structs LoadConfig(auth, character, world); // Create the directory .//logs// if it does not exist _mkdir("logs"); // If debug is on, print additional data to the console #ifdef DEBUG { cout << "\nDEBUG is ON!\n"; //cout << "\n Minifigure size: " << sizeof(MinifigureData) << endl; auto testbin = OpenPacket(".\\char\\char_aw2.bin"); //PacketCharacter * pk = (PacketCharacter*) testbin; /*vector< Ref<Character> > characters(4); auto aux = (uchar*)testbin.data() +22; characters[0] = Ref<Character>(new Character(aux)); cout << "\nTest (reading characters form char\\char_aw2.bin) character1 : " << characters[0]->GetName() << endl; //cout << characters[0]->Data.travelling << endl; aux += characters[0]->GetGeneratedPacketSize(); characters[1] = Ref<Character>(new Character(aux)); cout << "\nTest character2 : " << characters[1]->GetName() << endl;*/ string s = "ciao"; RakNet::BitStream bs; bs.WriteCompressed(s); cout << endl << RawDataToString(bs.GetData(), bs.GetNumberOfBytesUsed()) << endl; SavePacket("the Test.bin", (char*)bs.GetData(), bs.GetNumberOfBytesUsed()); cout << endl; } #endif // Create the UserPool to store all users by their systemAddress (shared by threads) Ref< UsersPool > OnlineUsers = new UsersPool(); Ref< CharactersPool > OnlineCharacters = new CharactersPool(); // Create a new CrossThreadQueue for writing output to the console from a thread Ref< CrossThreadQueue< string > > OutputQueue = new CrossThreadQueue< string >(); // Start the three new threads (Auth, Char, and World servers) thread thauth(AuthLoop, &auth, OnlineUsers, OutputQueue); thread thchar(CharactersLoop, &character, OnlineUsers, OnlineCharacters, OutputQueue); thread thworld(WorldLoop, &world, OnlineUsers, OnlineCharacters, OutputQueue); // If quit is ever equal to true, quit the server bool quit = false; // Keep the server from quitting by using a infinite loop while (!quit) { if (OutputQueue->Count() > 0) { // Pop the thread messages cout << OutputQueue->Pop(); } if (_kbhit()) { // Parsing server commands. Press enter to start writing a command (may need to lock consoleoutmutex...) string command; // Initialize command string... cout << "> "; // Print "> " to show user where to type cin >> command; // Get the command cout << endl; // End the line // Match command to a pre-specified command here... if (command == "help") cout << "\nAvailable commands: \nquit = Quit the Server \nregister = Register New User \nuser_online = Show Number of Online Users"; else if (command == "quit") quit = LUNIterminate = true; else if (command == "character_log_enable") character.logFile = true; else if (command == "character_log_disable") character.logFile = false; else if (command == "world_log_enable") world.logFile = true; else if (command == "world_log_disable") world.logFile = false; else if (command == "user_online") { cout << "\n Online user: "******"register") { string username, password; cout << "Username: "******"Password: "******"INSERT INTO `accounts` (`id`, `name`, `password`, `email`, `ip`, `rank`, `numChars`, `frontChar`, `lastLog`, `activeSub`, `subTime`, `legoClub`, `locked`, `banned`, `loginTries`) VALUES (NULL, '" + username + "', '" + password + "', '', '127.0.0.1', '0', '0', '0', CURRENT_TIMESTAMP, '0', '', '', '0', '0', '0');"); } else cout << "Username already exist!\n"; } else cout << "Invalid Command: " << command << "!" << endl;