void FileListTransfer::OnReferencePush(Packet *packet, bool isTheFullFile) { RakNet::BitStream refPushAck; if (isTheFullFile==false) { // 12/23/09 Why do I care about ID_DOWNLOAD_PROGRESS for reference pushes? // 2/16/2012 I care because a reference push is 16 megabytes by default. Also, if it is the last file "if (ftpr->filesToPush.Size()<2)" or total file size exceeds smallFileTotalSize it always sends a reference push. // return; } FileListTransferCBInterface::OnFileStruct onFileStruct; RakNet::BitStream inBitStream(packet->data, packet->length, false); inBitStream.IgnoreBits(8); unsigned int partCount=0; unsigned int partTotal=1; unsigned int partLength=0; onFileStruct.fileData=0; if (isTheFullFile==false) { // Disable endian swapping on reading this, as it's generated locally in ReliabilityLayer.cpp inBitStream.ReadBits( (unsigned char* ) &partCount, BYTES_TO_BITS(sizeof(partCount)), true ); inBitStream.ReadBits( (unsigned char* ) &partTotal, BYTES_TO_BITS(sizeof(partTotal)), true ); inBitStream.ReadBits( (unsigned char* ) &partLength, BYTES_TO_BITS(sizeof(partLength)), true ); inBitStream.IgnoreBits(8); // The header is appended to every chunk, which we continue to read after this statement flrMemoryBlock } inBitStream >> onFileStruct.context; inBitStream.Read(onFileStruct.setID); // This is not a progress notification, it is actually the entire packet if (isTheFullFile==true) { refPushAck.Write((MessageID)ID_FILE_LIST_REFERENCE_PUSH_ACK); refPushAck.Write(onFileStruct.setID); SendUnified(&refPushAck,HIGH_PRIORITY, RELIABLE, 0, packet->systemAddress, false); } // inBitStream.Read(onFileStruct.context); FileListReceiver *fileListReceiver; if (fileListReceivers.Has(onFileStruct.setID)==false) { return; } fileListReceiver=fileListReceivers.Get(onFileStruct.setID); if (fileListReceiver->allowedSender!=packet->systemAddress) { #ifdef _DEBUG RakAssert(0); #endif return; } #ifdef _DEBUG RakAssert(fileListReceiver->gotSetHeader==true); #endif if (StringCompressor::Instance()->DecodeString(onFileStruct.fileName, 512, &inBitStream)==false) { #ifdef _DEBUG RakAssert(0); #endif return; } inBitStream.ReadCompressed(onFileStruct.fileIndex); inBitStream.ReadCompressed(onFileStruct.byteLengthOfThisFile); unsigned int offset; unsigned int chunkLength; inBitStream.ReadCompressed(offset); inBitStream.ReadCompressed(chunkLength); bool lastChunk=false; inBitStream.Read(lastChunk); bool finished = lastChunk && isTheFullFile; if (isTheFullFile==false) fileListReceiver->partLength=partLength; FLR_MemoryBlock mb; if (fileListReceiver->pushedFiles.Has(onFileStruct.fileIndex)==false) { mb.flrMemoryBlock=(char*) rakMalloc_Ex(onFileStruct.byteLengthOfThisFile, _FILE_AND_LINE_); fileListReceiver->pushedFiles.SetNew(onFileStruct.fileIndex, mb); } else { mb=fileListReceiver->pushedFiles.Get(onFileStruct.fileIndex); } unsigned int unreadBits = inBitStream.GetNumberOfUnreadBits(); unsigned int unreadBytes = BITS_TO_BYTES(unreadBits); unsigned int amountToRead; if (isTheFullFile) amountToRead=chunkLength; else amountToRead=unreadBytes; inBitStream.AlignReadToByteBoundary(); FileListTransferCBInterface::FileProgressStruct fps; if (isTheFullFile) { if (mb.flrMemoryBlock) { // Either the very first block, or a subsequent block and allocateIrIDataChunkAutomatically was true for the first block memcpy(mb.flrMemoryBlock+offset, inBitStream.GetData()+BITS_TO_BYTES(inBitStream.GetReadOffset()), amountToRead); fps.iriDataChunk=mb.flrMemoryBlock+offset; } else { // In here mb.flrMemoryBlock is null // This means the first block explicitly deallocated the memory, and no blocks will be permanently held by RakNet fps.iriDataChunk=(char*) inBitStream.GetData()+BITS_TO_BYTES(inBitStream.GetReadOffset()); } onFileStruct.bytesDownloadedForThisFile=offset+chunkLength; fileListReceiver->setTotalDownloadedLength+=chunkLength; onFileStruct.bytesDownloadedForThisSet=fileListReceiver->setTotalDownloadedLength; } else { onFileStruct.bytesDownloadedForThisFile=offset+partLength*partCount; onFileStruct.bytesDownloadedForThisSet=fileListReceiver->setTotalDownloadedLength+partCount*partLength; fps.iriDataChunk=(char*) inBitStream.GetData()+BITS_TO_BYTES(inBitStream.GetReadOffset()); } onFileStruct.numberOfFilesInThisSet=fileListReceiver->setCount; // onFileStruct.setTotalCompressedTransmissionLength=fileListReceiver->setTotalCompressedTransmissionLength; onFileStruct.byteLengthOfThisSet=fileListReceiver->setTotalFinalLength; // Note: mb.flrMemoryBlock may be null here onFileStruct.fileData=mb.flrMemoryBlock; onFileStruct.senderSystemAddress=packet->systemAddress; onFileStruct.senderGuid=packet->guid; unsigned int totalNotifications; unsigned int currentNotificationIndex; if (chunkLength==0 || chunkLength==onFileStruct.byteLengthOfThisFile) totalNotifications=1; else totalNotifications = onFileStruct.byteLengthOfThisFile / chunkLength + 1; if (chunkLength==0) currentNotificationIndex = 0; else currentNotificationIndex = offset / chunkLength; fps.onFileStruct=&onFileStruct; fps.partCount=currentNotificationIndex; fps.partTotal=totalNotifications; fps.dataChunkLength=amountToRead; fps.firstDataChunk=mb.flrMemoryBlock; fps.allocateIrIDataChunkAutomatically=true; fps.onFileStruct->fileData=mb.flrMemoryBlock; fps.iriWriteOffset=offset; fps.senderSystemAddress=packet->systemAddress; fps.senderGuid=packet->guid; if (finished) { char *oldFileData=fps.onFileStruct->fileData; if (fps.partCount==0) fps.firstDataChunk=fps.iriDataChunk; if (fps.partTotal==1) fps.onFileStruct->fileData=fps.iriDataChunk; fileListReceiver->downloadHandler->OnFileProgress(&fps); // Incremental read interface sent us a file chunk // This is the last file chunk we were waiting for to consider the file done if (fileListReceiver->downloadHandler->OnFile(&onFileStruct)) rakFree_Ex(oldFileData, _FILE_AND_LINE_ ); fileListReceiver->pushedFiles.Delete(onFileStruct.fileIndex); fileListReceiver->filesReceived++; // If this set is done, free the memory for it. if ((int) fileListReceiver->setCount==fileListReceiver->filesReceived) { FileListTransferCBInterface::DownloadCompleteStruct dcs; dcs.setID=fileListReceiver->setID; dcs.numberOfFilesInThisSet=fileListReceiver->setCount; dcs.byteLengthOfThisSet=fileListReceiver->setTotalFinalLength; dcs.senderSystemAddress=packet->systemAddress; dcs.senderGuid=packet->guid; if (fileListReceiver->downloadHandler->OnDownloadComplete(&dcs)==false) { fileListReceiver->downloadHandler->OnDereference(); fileListReceivers.Delete(onFileStruct.setID); if (fileListReceiver->deleteDownloadHandler) RakNet::OP_DELETE(fileListReceiver->downloadHandler, _FILE_AND_LINE_); RakNet::OP_DELETE(fileListReceiver, _FILE_AND_LINE_); } } } else { if (isTheFullFile) { // 12/23/09 Don't use OnReferencePush anymore, just use OnFileProgress fileListReceiver->downloadHandler->OnFileProgress(&fps); if (fps.allocateIrIDataChunkAutomatically==false) { rakFree_Ex(fileListReceiver->pushedFiles.Get(onFileStruct.fileIndex).flrMemoryBlock, _FILE_AND_LINE_ ); fileListReceiver->pushedFiles.Get(onFileStruct.fileIndex).flrMemoryBlock=0; } } else { // This is a download progress notification for a file chunk using incremental read interface // We don't have all the data for this chunk yet totalNotifications = onFileStruct.byteLengthOfThisFile / fileListReceiver->partLength + 1; if (isTheFullFile==false) currentNotificationIndex = (offset+partCount*fileListReceiver->partLength) / fileListReceiver->partLength ; else currentNotificationIndex = (offset+chunkLength) / fileListReceiver->partLength ; unreadBytes = onFileStruct.byteLengthOfThisFile - ((currentNotificationIndex+1) * fileListReceiver->partLength); fps.partCount=currentNotificationIndex; fps.partTotal=totalNotifications; if (rakPeerInterface) { // Thus chunk is incomplete fps.iriDataChunk=0; fileListReceiver->downloadHandler->OnFileProgress(&fps); } } } return; }
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()); } } }
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 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)); } } }
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; } } } } } }
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 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); }
void UDPProxyCoordinator::OnForwardingReplyFromServerToCoordinator(Packet *packet) { RakNet::BitStream incomingBs(packet->data, packet->length, false); incomingBs.IgnoreBytes(2); SenderAndTargetAddress sata; incomingBs.Read(sata.senderClientAddress); incomingBs.Read(sata.targetClientAddress); bool objectExists; unsigned int index = forwardingRequestList.GetIndexFromKey(sata, &objectExists); if (objectExists==false) { // The guy disconnected before the request finished return; } ForwardingRequest *fw = forwardingRequestList[index]; sata.senderClientGuid = fw->sata.senderClientGuid; sata.targetClientGuid = fw->sata.targetClientGuid; RakString serverPublicIp; incomingBs.Read(serverPublicIp); if (serverPublicIp.IsEmpty()) { char serverIP[64]; packet->systemAddress.ToString(false,serverIP); serverPublicIp=serverIP; } UDPForwarderResult success; unsigned char c; incomingBs.Read(c); success=(UDPForwarderResult)c; unsigned short forwardingPort; incomingBs.Read(forwardingPort); RakNet::BitStream outgoingBs; if (success==UDPFORWARDER_SUCCESS) { outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL); outgoingBs.Write((MessageID)ID_UDP_PROXY_FORWARDING_SUCCEEDED); outgoingBs.Write(sata.senderClientAddress); outgoingBs.Write(sata.targetClientAddress); outgoingBs.Write(sata.targetClientGuid); outgoingBs.Write(serverPublicIp); outgoingBs.Write(forwardingPort); rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, fw->requestingAddress, false); outgoingBs.Reset(); outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL); outgoingBs.Write((MessageID)ID_UDP_PROXY_FORWARDING_NOTIFICATION); outgoingBs.Write(sata.senderClientAddress); outgoingBs.Write(sata.targetClientAddress); outgoingBs.Write(sata.targetClientGuid); outgoingBs.Write(serverPublicIp); outgoingBs.Write(forwardingPort); rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, sata.targetClientAddress, false); // 05/18/09 Keep the entry around for some time after success, so duplicates are reported if attempting forwarding from the target system before notification of success fw->timeoutAfterSuccess=RakNet::GetTimeMS()+fw->timeoutOnNoDataMS; // forwardingRequestList.RemoveAtIndex(index); // RakNet::OP_DELETE(fw,_FILE_AND_LINE_); return; } else if (success==UDPFORWARDER_NO_SOCKETS) { // Try next server TryNextServer(sata, fw); } else { RakAssert(success==UDPFORWARDER_FORWARDING_ALREADY_EXISTS); // Return in progress outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL); outgoingBs.Write((MessageID)ID_UDP_PROXY_IN_PROGRESS); outgoingBs.Write(sata.senderClientAddress); outgoingBs.Write(sata.targetClientAddress); outgoingBs.Write(sata.targetClientGuid); outgoingBs.Write(serverPublicIp); outgoingBs.Write(forwardingPort); rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, fw->requestingAddress, false); forwardingRequestList.RemoveAtIndex(index); RakNet::OP_DELETE(fw,_FILE_AND_LINE_); } }
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; }
void UDPProxyCoordinator::OnForwardingRequestFromClientToCoordinator(Packet *packet) { RakNet::BitStream incomingBs(packet->data, packet->length, false); incomingBs.IgnoreBytes(2); SystemAddress sourceAddress; incomingBs.Read(sourceAddress); if (sourceAddress==UNASSIGNED_SYSTEM_ADDRESS) sourceAddress=packet->systemAddress; SystemAddress targetAddress; RakNetGUID targetGuid; bool usesAddress=false; incomingBs.Read(usesAddress); if (usesAddress) { incomingBs.Read(targetAddress); targetGuid=rakPeerInterface->GetGuidFromSystemAddress(targetAddress); } else { incomingBs.Read(targetGuid); targetAddress=rakPeerInterface->GetSystemAddressFromGuid(targetGuid); } ForwardingRequest *fw = RakNet::OP_NEW<ForwardingRequest>(_FILE_AND_LINE_); fw->timeoutAfterSuccess=0; incomingBs.Read(fw->timeoutOnNoDataMS); bool hasServerSelectionBitstream=false; incomingBs.Read(hasServerSelectionBitstream); if (hasServerSelectionBitstream) incomingBs.Read(&(fw->serverSelectionBitstream)); RakNet::BitStream outgoingBs; SenderAndTargetAddress sata; sata.senderClientAddress=sourceAddress; sata.targetClientAddress=targetAddress; sata.targetClientGuid=targetGuid; sata.senderClientGuid=rakPeerInterface->GetGuidFromSystemAddress(sourceAddress); SenderAndTargetAddress sataReversed; sataReversed.senderClientAddress=targetAddress; sataReversed.targetClientAddress=sourceAddress; sataReversed.senderClientGuid=sata.targetClientGuid; sataReversed.targetClientGuid=sata.senderClientGuid; unsigned int insertionIndex; bool objectExists1, objectExists2; insertionIndex=forwardingRequestList.GetIndexFromKey(sata, &objectExists1); forwardingRequestList.GetIndexFromKey(sataReversed, &objectExists2); if (objectExists1 || objectExists2) { outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL); outgoingBs.Write((MessageID)ID_UDP_PROXY_IN_PROGRESS); outgoingBs.Write(sata.senderClientAddress); outgoingBs.Write(targetAddress); outgoingBs.Write(targetGuid); // Request in progress, not completed unsigned short forwardingPort=0; RakString serverPublicIp; outgoingBs.Write(serverPublicIp); outgoingBs.Write(forwardingPort); rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false); RakNet::OP_DELETE(fw, _FILE_AND_LINE_); return; } if (serverList.Size()==0) { outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL); outgoingBs.Write((MessageID)ID_UDP_PROXY_NO_SERVERS_ONLINE); outgoingBs.Write(sata.senderClientAddress); outgoingBs.Write(targetAddress); outgoingBs.Write(targetGuid); rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false); RakNet::OP_DELETE(fw, _FILE_AND_LINE_); return; } if (rakPeerInterface->GetConnectionState(targetAddress)!=IS_CONNECTED && usesAddress==false) { outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL); outgoingBs.Write((MessageID)ID_UDP_PROXY_RECIPIENT_GUID_NOT_CONNECTED_TO_COORDINATOR); outgoingBs.Write(sata.senderClientAddress); outgoingBs.Write(targetAddress); outgoingBs.Write(targetGuid); rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false); RakNet::OP_DELETE(fw, _FILE_AND_LINE_); return; } fw->sata=sata; fw->requestingAddress=packet->systemAddress; if (serverList.Size()>1) { outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL); outgoingBs.Write((MessageID)ID_UDP_PROXY_PING_SERVERS_FROM_COORDINATOR_TO_CLIENT); outgoingBs.Write(sourceAddress); outgoingBs.Write(targetAddress); outgoingBs.Write(targetGuid); unsigned short serverListSize = (unsigned short) serverList.Size(); outgoingBs.Write(serverListSize); unsigned int idx; for (idx=0; idx < serverList.Size(); idx++) outgoingBs.Write(serverList[idx]); rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, sourceAddress, false); rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, targetAddress, false); fw->timeRequestedPings=RakNet::GetTimeMS(); unsigned int copyIndex; for (copyIndex=0; copyIndex < serverList.Size(); copyIndex++) fw->remainingServersToTry.Push(serverList[copyIndex], _FILE_AND_LINE_ ); forwardingRequestList.InsertAtIndex(fw, insertionIndex, _FILE_AND_LINE_ ); } else { fw->timeRequestedPings=0; fw->currentlyAttemptedServerAddress=serverList[0]; forwardingRequestList.InsertAtIndex(fw, insertionIndex, _FILE_AND_LINE_ ); SendForwardingRequest(sourceAddress, targetAddress, fw->currentlyAttemptedServerAddress, fw->timeoutOnNoDataMS); } }
void UDPProxyCoordinator::OnLoginRequestFromServerToCoordinator(Packet *packet) { RakNet::BitStream incomingBs(packet->data, packet->length, false); incomingBs.IgnoreBytes(2); RakNet::RakString password; incomingBs.Read(password); RakNet::BitStream outgoingBs; if (remoteLoginPassword.IsEmpty()) { outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL); outgoingBs.Write((MessageID)ID_UDP_PROXY_NO_PASSWORD_SET_FROM_COORDINATOR_TO_SERVER); outgoingBs.Write(password); rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false); return; } if (remoteLoginPassword!=password) { outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL); outgoingBs.Write((MessageID)ID_UDP_PROXY_WRONG_PASSWORD_FROM_COORDINATOR_TO_SERVER); outgoingBs.Write(password); rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false); return; } unsigned int insertionIndex; insertionIndex=serverList.GetIndexOf(packet->systemAddress); if (insertionIndex!=(unsigned int)-1) { outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL); outgoingBs.Write((MessageID)ID_UDP_PROXY_ALREADY_LOGGED_IN_FROM_COORDINATOR_TO_SERVER); outgoingBs.Write(password); rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false); return; } serverList.Push(packet->systemAddress, _FILE_AND_LINE_ ); outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL); outgoingBs.Write((MessageID)ID_UDP_PROXY_LOGIN_SUCCESS_FROM_COORDINATOR_TO_SERVER); outgoingBs.Write(password); rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false); }
void ReadAllPackets(void) { char str[64], str2[64]; Packet *packet; for (packet=rakPeer->Receive(); packet; rakPeer->DeallocatePacket(packet), packet=rakPeer->Receive()) { packet->guid.ToString(str); packet->systemAddress.ToString(true,str2); if (packet->data[0]==ID_NEW_INCOMING_CONNECTION) { printf("ID_NEW_INCOMING_CONNECTION from %s on %s\n", str, str2); } else if (packet->data[0]==ID_CONNECTION_REQUEST_ACCEPTED) { printf("ID_CONNECTION_REQUEST_ACCEPTED from %s on %s\n", str, str2); } else if (packet->data[0]==ID_ROUTER_2_FORWARDING_NO_PATH) { printf("No path to endpoint exists. Routing failed.\n"); } else if (packet->data[0]==ID_CONNECTION_LOST) { printf("ID_CONNECTION_LOST from %s\n", str); } else if (packet->data[0]==ID_USER_PACKET_ENUM+1) { printf("Got ID_USER_PACKET_ENUM from %s\n", str); } else if (packet->data[0]==ID_ROUTER_2_FORWARDING_ESTABLISHED) { RakNet::BitStream bs(packet->data, packet->length, false); bs.IgnoreBytes(sizeof(MessageID)); bs.Read(endpointGuid); printf("Routing through %s to %s successful. Connecting.\n", str, endpointGuid.ToString()); unsigned short sourceToDestPort; bs.Read(sourceToDestPort); char ipAddressString[32]; packet->systemAddress.ToString(false, ipAddressString); rakPeer->Connect(ipAddressString, sourceToDestPort, 0,0); } else if (packet->data[0]==ID_ROUTER_2_REROUTED) { // You could read the endpointGuid and sourceToDestPoint if you wanted to RakNet::BitStream bs(packet->data, packet->length, false); bs.IgnoreBytes(sizeof(MessageID)); RakNetGUID endpointGuid2; bs.Read(endpointGuid2); endpointGuid2.ToString(str); SystemAddress intermediateAddress=packet->systemAddress; unsigned short port; bs.Read(port); intermediateAddress.SetPortHostOrder(port); char str2[32]; intermediateAddress.ToString(true, str2); printf("Connection to %s rerouted through %s\n", str, str2); // Test sending a message to the endpoint RakNet::BitStream bsOut; MessageID id = ID_USER_PACKET_ENUM+1; bsOut.Write(id); rakPeer->Send(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,endpointGuid2,false); } } }
// Handles all networking events DWORD WINAPI HandleNetworking( LPVOID ) { // Create RakNet interfaces RakNet::RakPeerInterface *peer; RakNet::Packet *packet; // Initialize networking peer = RakNet::RakPeerInterface::GetInstance(); // Rev up your engines RakNet::SocketDescriptor sd( 0, "127.0.0.1" ); peer->Startup( 1, &sd, 1 ); // GO GO GO RakNet::ConnectionAttemptResult attempt = peer->Connect( "127.0.0.1", 5187, NULL, 0 ); // Success? if( attempt != RakNet::CONNECTION_ATTEMPT_STARTED ) { // Nope switch( attempt ) { // None of these should happen, EVER. case RakNet::ALREADY_CONNECTED_TO_ENDPOINT: MessageBoxA ( NULL, "A connection attempt was made to a server we're already connected to.\nPlease contact a developer.", "SC4Multi -- Network Error", MB_OK | MB_ICONERROR ); break; case RakNet::CANNOT_RESOLVE_DOMAIN_NAME: MessageBoxA ( NULL, "The given domain name could not be resolved.", "SC4Multi -- Network Error", MB_OK | MB_ICONERROR ); break; case RakNet::CONNECTION_ATTEMPT_ALREADY_IN_PROGRESS: MessageBoxA ( NULL, "Two connection attempts were being made at once by SC4Multi.\nPlease contact a developer.", "SC4Multi -- Network Error", MB_OK | MB_ICONERROR ); break; case RakNet::INVALID_PARAMETER: MessageBoxA ( NULL, "An invalid parameter was passed by SC4Multi. Please contact a developer.", "SC4Multi -- Network Error", MB_OK | MB_ICONERROR ); break; case RakNet::SECURITY_INITIALIZATION_FAILED: MessageBoxA ( NULL, "Security initialization failed. Something is terribly wrong,\nplease contact a developer.", "SC4Multi -- Network Error", MB_OK | MB_ICONERROR ); break; default: MessageBoxA ( NULL, "Something went wrong during network initialization,\nand we don't know what.", "SC4Multi -- Network Error", MB_OK | MB_ICONERROR ); break; } // Terminate via ugly hacks exit( 1 ); } // Forever and ever and ever and ever and ever and... while( isRunning ) { // If there are any packets, read it for( packet = peer->Receive(); packet; peer->DeallocatePacket( packet ), packet = peer->Receive() ) { // Get the packet type ID switch( packet->data[0] ) { case ID_REMOTE_DISCONNECTION_NOTIFICATION: MessageBoxA( NULL, "Other client quit", "SC4Multi", MB_OK | MB_ICONINFORMATION ); break; case ID_REMOTE_CONNECTION_LOST: MessageBoxA( NULL, "Other client timeout", "SC4Multi", MB_OK | MB_ICONINFORMATION ); break; case ID_REMOTE_NEW_INCOMING_CONNECTION: MessageBoxA( NULL, "Other client connection", "SC4Multi", MB_OK | MB_ICONINFORMATION ); break; case ID_CONNECTION_REQUEST_ACCEPTED: { MessageBoxA( NULL, "Our connection succeeded", "SC4Multi", MB_OK | MB_ICONINFORMATION ); // Read the machine GUID generated by Windows char guid_net[255]; bool isGuidNull = false; { // Create a wide-char GUID buffer wchar_t guid[255]; // Registry stuff HKEY hKey = 0; DWORD dwType = 0; // Get the size of our buffer DWORD dwBufSize = sizeof( guid ); // Define the subkey const wchar_t* subkey = L"Software\\Microsoft\\Cryptography"; // Open the registry if( RegOpenKey( HKEY_LOCAL_MACHINE, subkey, &hKey ) == ERROR_SUCCESS ) { // We're looking for a string dwType = REG_SZ; // Read to our buffer if( !RegQueryValueEx( hKey, L"MachineGuid", 0, &dwType, (BYTE *)guid, &dwBufSize ) == ERROR_SUCCESS ) { // Fall back to a null GUID isGuidNull = true; } else { // Convert the wide char buffer into a char buffer wcstombs( guid_net, guid, 255 ); } } else { // Fall back to a null GUID isGuidNull = true; } } // Initialize a bitstream RakNet::BitStream bsOut; // Send our user data to the server { // Packet ID bsOut.Write( (RakNet::MessageID)ID_SC4_CONNECTION_DATA ); // Nickname bsOut.Write( "Stormeus" ); // Unique GUID, or a null one if( isGuidNull ) bsOut.Write( 0 ); else { #ifdef DEBUG MessageBoxA( NULL, guid_net, "SC4Multi -- GUID", MB_ICONINFORMATION | MB_OK ); #endif bsOut.Write( guid_net ); } // City taken bsOut.Write( "Unknown City" ); } // Priority shipping to the server peer->Send ( &bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false ); break; } case ID_NEW_INCOMING_CONNECTION: MessageBoxA( NULL, "Incoming connection", "SC4Multi", MB_OK | MB_ICONINFORMATION ); break; case ID_NO_FREE_INCOMING_CONNECTIONS: MessageBoxA( NULL, "Server is full", "SC4Multi", MB_OK | MB_ICONINFORMATION ); break; case ID_DISCONNECTION_NOTIFICATION: MessageBoxA( NULL, "We disconnected", "SC4Multi", MB_OK | MB_ICONINFORMATION ); break; case ID_CONNECTION_LOST: MessageBoxA( NULL, "We lost connection", "SC4Multi", MB_OK | MB_ICONINFORMATION ); break; } } } // Destroy this instance RakNet::RakPeerInterface::DestroyInstance( peer ); // And we're done here. MessageBoxA( NULL, "Destroyed RakNet instance.", "SC4Multi -- Networking Debug", MB_OK | MB_ICONEXCLAMATION ); return 1; }
int SendIRIToAddressCB(FileListTransfer::ThreadData threadData, bool *returnOutput, void* perThreadData) { (void) perThreadData; FileListTransfer *fileListTransfer = threadData.fileListTransfer; SystemAddress systemAddress = threadData.systemAddress; unsigned short setId = threadData.setId; *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 && ftpr->setId==setId) { FileListTransfer::FileToPush *ftp; ////ftpr->filesToPushMutex.Lock(); ftp = ftpr->filesToPush.Pop(); ////ftpr->filesToPushMutex.Unlock(); // Read and send chunk. If done, delete at this index void *buff = rakMalloc_Ex(ftp->chunkSize, _FILE_AND_LINE_); if (buff==0) { ////ftpr->filesToPushMutex.Lock(); ftpr->filesToPush.PushAtHead(ftp,0,_FILE_AND_LINE_); ////ftpr->filesToPushMutex.Unlock(); 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 && smallFileTotalSize<ftp->chunkSize) { ////ftpr->filesToPushMutex.Lock(); // The reason for 2 is that ID_FILE_LIST_REFERENCE_PUSH gets ID_FILE_LIST_REFERENCE_PUSH_ACK. WIthout ID_FILE_LIST_REFERENCE_PUSH_ACK, SendIRIToAddressCB would not be called again if (ftpr->filesToPush.Size()<2) { ////ftpr->filesToPushMutex.Unlock(); break; } ////ftpr->filesToPushMutex.Unlock(); // 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(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_); smallFileTotalSize+=bytesRead; //done = bytesRead!=ftp->chunkSize; ////ftpr->filesToPushMutex.Lock(); ftp = ftpr->filesToPush.Pop(); ////ftpr->filesToPushMutex.Unlock(); 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(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, 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); char orderingChannel = ftp->orderingChannel; PacketPriority packetPriority = ftp->packetPriority; // 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->filesToPushMutex.Lock(); if (ftpr->filesToPush.Size()==0) { ////ftpr->filesToPushMutex.Unlock(); for (unsigned int flpcIndex=0; flpcIndex < fileListTransfer->fileListProgressCallbacks.Size(); flpcIndex++) fileListTransfer->fileListProgressCallbacks[flpcIndex]->OnFilePushesComplete(systemAddress, setId); // Remove ftpr from fileToPushRecipientList fileListTransfer->RemoveFromList(ftpr); } else { ////ftpr->filesToPushMutex.Unlock(); } } else { ////ftpr->filesToPushMutex.Lock(); ftpr->filesToPush.PushAtHead(ftp,0,_FILE_AND_LINE_); ////ftpr->filesToPushMutex.Unlock(); } // ftpr out of scope ftpr->Deref(); // 2/12/2012 Moved this line at after the if (done) block above. // See http://www.jenkinssoftware.com/forum/index.php?topic=4768.msg19738#msg19738 fileListTransfer->SendListUnified(dataBlocks,lengths,2, packetPriority, RELIABLE_ORDERED, orderingChannel, systemAddress, false); rakFree_Ex(buff, _FILE_AND_LINE_ ); return 0; } else { ftpr->Deref(); fileListTransfer->fileToPushRecipientListMutex.Lock(); } } fileListTransfer->fileToPushRecipientListMutex.Unlock(); return 0; }
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 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 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 ); }
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 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 DownloadFinished(RakNet::BitStream * pBitStream, RakNet::Packet * pPacket) { // 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 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)); EntityId 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); } } for (EntityId i = 0; i < CServer::GetInstance()->GetCheckpointManager()->GetMax(); ++i) { if (CServer::GetInstance()->GetCheckpointManager()->DoesExists(i)) { bitStream.Reset(); CCheckpointEntity * pCheckpoint = CServer::GetInstance()->GetCheckpointManager()->GetAt(i); if (pCheckpoint->GetVisible()) { bitStream.Write(pCheckpoint->GetId()); bitStream.Write(pCheckpoint->GetType()); CVector3 vecPosition; pCheckpoint->GetPosition(vecPosition); bitStream.Write(vecPosition); CVector3 vecTargetPosition; pCheckpoint->GetTargetPosition(vecTargetPosition); bitStream.Write(vecTargetPosition); bitStream.Write(pCheckpoint->GetRadius()); CServer::GetInstance()->GetNetworkModule()->Call(GET_RPC_CODEX(RPC_CREATE_CHECKPOINT), &bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, playerId, false); } } } for (EntityId i = 0; i < CServer::GetInstance()->GetBlipManager()->GetMax(); ++i) { if (CServer::GetInstance()->GetBlipManager()->DoesExists(i)) { bitStream.Reset(); CBlipEntity * pBlip = CServer::GetInstance()->GetBlipManager()->GetAt(i); if (pBlip->GetVisible()) { bitStream.Write(pBlip->GetId()); bitStream.Write(pBlip->GetIcon()); CVector3 vecPosition; pBlip->GetPosition(vecPosition); bitStream.Write(vecPosition); bitStream.Write(pBlip->GetRange()); CServer::GetInstance()->GetNetworkModule()->Call(GET_RPC_CODEX(RPC_CREATE_BLIP), &bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, playerId, 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 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 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() ); } } } } }
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; }
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); } } }
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; }
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; }
// 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 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; }
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); } }