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());
        }

    }
}
Example #3
0
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;
}
Example #4
0
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;
                    }
                }
            }
        }
    }
}
Example #6
0
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;
}
Example #7
0
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);
		}
	}
}
Example #13
0
// 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;
}
Example #15
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);
}
Example #16
0
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);
}
Example #17
0
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 );
}
Example #18
0
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);
}
Example #19
0
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;
}
Example #20
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);
			}
		}
	}
}
Example #21
0
void InitialData(RakNet::BitStream * pBitStream, RakNet::Packet * pPacket)
{
	// Get the playerid
	EntityId playerId = (EntityId) pPacket->guid.systemIndex;

	// Read the player version
	DWORD dwVersion;
	pBitStream->Read(dwVersion);

	// Read the player name
	RakNet::RakString _strName;
	pBitStream->Read(_strName);
	CString strName(_strName.C_String());



	// Read the player serial
	RakNet::RakString _strSerial;
	pBitStream->Read(_strSerial);
	CString strSerial(_strSerial.C_String());

	// Is the network version invalid?
	if (dwVersion != (DWORD)/*NETWORK_VERSION*/0x0)
	{
		// TODO
	}

	

	// Is the nickname already in use?
	// TODO: check is nick in use

	// Is the player banned?
	// TODO: check is banned

	// Add the player to the manager
	// TODO: add to player manager
	CPlayerEntity * pPlayer = new CPlayerEntity();

	pPlayer->SetName(strName);

	// Do we need the id; maybe internal for easier sync but definetly not public to the scripting engine
	pPlayer->SetId(CServer::GetInstance()->GetPlayerManager()->Add(pPlayer));
	playerId = pPlayer->GetId();

	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);
}
Example #23
0
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);
        }
    }
}
Example #26
0
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;
}
Example #27
0
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;
}
Example #28
0
// 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;
}
Example #29
0
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);
	}
}