示例#1
0
unsigned DataCompressor::DecompressAndAllocate( RakNet::BitStream * input, unsigned char **output )
{
	HuffmanEncodingTree tree;
	unsigned int bitsUsed, destinationSizeInBytes, decompressedBytes;
	unsigned int frequencyTable[ 256 ];
	unsigned i;
	
	input->ReadCompressed(destinationSizeInBytes);
	for (i=0; i < 256; i++)
		input->ReadCompressed(frequencyTable[i]);
	input->AlignReadToByteBoundary();
	if (input->Read(bitsUsed)==false)
	{
		// Read error
#ifdef _DEBUG
		RakAssert(0);
#endif
		return 0;
	}
	*output = (unsigned char*) rakMalloc_Ex(destinationSizeInBytes, __FILE__, __LINE__);
	tree.GenerateFromFrequencyTable(frequencyTable);
	decompressedBytes=tree.DecodeArray(input, bitsUsed, destinationSizeInBytes, *output );
	RakAssert(decompressedBytes==destinationSizeInBytes);
	return destinationSizeInBytes;
}
bool SystemAddressList::Load(const char *filename)
{
	FILE *fp = NULL;
	unsigned long fileSize;

	if ( ( fp = fopen( filename, "rb" ) ) == 0 )
		return false;

	fseek( fp, 0, SEEK_END );
	fileSize = ftell( fp );
	fseek( fp, 0, SEEK_SET );
	if (fileSize==0)
	{
		fclose(fp);
		return false;
	}
	unsigned char *filedata = (unsigned char*) rakMalloc_Ex( fileSize, __FILE__, __LINE__ );
	fread(filedata, fileSize, 1, fp);
	fclose(fp);

	RakNet::BitStream bs(filedata, fileSize, false);
	Deserialize(&bs);
	rakFree_Ex(filedata, __FILE__, __LINE__ );
	return true;
}
示例#3
0
void FileList::AddFile(const char *filepath, const char *filename, FileListNodeContext context)
{
	if (filepath == 0 || filename == 0)
		return;
	char *data;
	//std::fstream file;
	//file.open(filename, std::ios::in | std::ios::binary);
	FILE *fp = fopen(filepath, "rb");
	if (fp == 0)
		return;
	fseek(fp, 0, SEEK_END);
	int length = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	if (length > (int)((unsigned int) - 1 / 8)) {
		// If this assert hits, split up your file. You could also change BitSize_t in RakNetTypes.h to unsigned long long but this is not recommended for performance reasons
		RakAssert("Cannot add files over 536 MB" && 0);
		fclose(fp);
		return;
	}
	bool usedAlloca = false;
	if (length < MAX_ALLOCA_STACK_ALLOCATION) {
		data = (char*) alloca(length);
		usedAlloca = true;
	} else
		data = (char*) rakMalloc_Ex(length, __FILE__, __LINE__);
	fread(data, 1, length, fp);
	AddFile(filename, filepath, data, length, length, context);
	fclose(fp);
	if (usedAlloca == false)
		rakFree_Ex(data, __FILE__, __LINE__);
}
void ThreadsafePacketLogger::AddToLog(const char *str)
{
	char **msg = logMessages.WriteLock();
	*msg = (char*) rakMalloc_Ex( strlen(str)+1, __FILE__, __LINE__ );
	strcpy(*msg, str);
	logMessages.WriteUnlock();
}
void FileListTransfer::PushReference(SystemAddress systemAddress)
{
	// Was previously using GetStatistics to get outgoing buffer size, but TCP with UnifiedSend doesn't have this
	unsigned int i=0;
	unsigned int bytesRead;	
	char *dataBlocks[2];
	int lengths[2];
	RakNet::BitStream outBitstream;
	while (i < filesToPush.Size())
	{
		if (filesToPush[i].systemAddress==systemAddress)
		{
			outBitstream.Reset();
			outBitstream.Write((MessageID)ID_FILE_LIST_REFERENCE_PUSH);
			outBitstream.Write(filesToPush[i].fileListNode.context);
			outBitstream.Write(filesToPush[i].setID);
			stringCompressor->EncodeString(filesToPush[i].fileListNode.filename, 512, &outBitstream);
			outBitstream.WriteCompressed(filesToPush[i].setIndex);
			outBitstream.WriteCompressed(filesToPush[i].fileListNode.dataLengthBytes); // Original length in bytes

			// Read and send chunk. If done, delete at this index
			void *buff = rakMalloc_Ex(filesToPush[i].chunkSize, __FILE__, __LINE__);
			if (buff==0)
			{
				notifyOutOfMemory(__FILE__, __LINE__);
				continue;
			}
			bytesRead=filesToPush[i].incrementalReadInterface->GetFilePart(filesToPush[i].fileListNode.fullPathToFile, filesToPush[i].currentOffset, filesToPush[i].chunkSize, buff, filesToPush[i].fileListNode.context);
			outBitstream.WriteCompressed(filesToPush[i].currentOffset);
			filesToPush[i].currentOffset+=bytesRead;
			outBitstream.WriteCompressed(bytesRead);
			bool done = bytesRead!=filesToPush[i].chunkSize;
			outBitstream.Write(done);

			if (callback)
			{
				callback->OnFilePush(filesToPush[i].fileListNode.filename, filesToPush[i].fileListNode.fileLengthBytes, filesToPush[i].currentOffset-bytesRead, bytesRead, done, filesToPush[i].systemAddress);
			}

			dataBlocks[0]=(char*) outBitstream.GetData();
			lengths[0]=outBitstream.GetNumberOfBytesUsed();
			dataBlocks[1]=(char*) buff;
			lengths[1]=bytesRead;
			//rakPeerInterface->SendList(dataBlocks,lengths,2,filesToPush[i].packetPriority, RELIABLE_ORDERED, filesToPush[i].orderingChannel, filesToPush[i].systemAddress, false);
			SendListUnified(dataBlocks,lengths,2,filesToPush[i].packetPriority, RELIABLE_ORDERED, filesToPush[i].orderingChannel, filesToPush[i].systemAddress, false);
			if (done)
			{
				// Done
				RakNet::OP_DELETE_ARRAY(filesToPush[i].fileListNode.filename, __FILE__, __LINE__);
				filesToPush.RemoveAtIndex(i);
			}
			rakFree_Ex(buff, __FILE__, __LINE__ );
			return;
		}			
		else
			i++;
	}	
}
示例#6
0
bool FileList::Deserialize(RakNet::BitStream *inBitStream)
{
	bool b, dataLenNonZero = false, fileLenMatchesDataLen = false;
	char filename[512];
	unsigned int fileListSize;
	FileListNode n;
	b = inBitStream->ReadCompressed(fileListSize);
#ifdef _DEBUG
	RakAssert(b);
	RakAssert(fileListSize < 10000);
#endif
	if (b == false || fileListSize > 10000)
		return false; // Sanity check
	Clear();
	unsigned i;
	for (i = 0; i < fileListSize; i++) {
		inBitStream->ReadCompressed(n.context.op);
		inBitStream->ReadCompressed(n.context.fileId);
		stringCompressor->DecodeString((char*)filename, MAX_FILENAME_LENGTH, inBitStream);
		inBitStream->Read(dataLenNonZero);
		if (dataLenNonZero) {
			inBitStream->ReadCompressed(n.dataLengthBytes);
			// sanity check
			if (n.dataLengthBytes > 2000000000) {
#ifdef _DEBUG
				RakAssert(n.dataLengthBytes <= 2000000000);
#endif
				return false;
			}
			n.data = (char*) rakMalloc_Ex((size_t) n.dataLengthBytes, __FILE__, __LINE__);
			inBitStream->Read(n.data, n.dataLengthBytes);
		} else {
			n.dataLengthBytes = 0;
			n.data = 0;
		}
		b = inBitStream->Read(fileLenMatchesDataLen);
		if (fileLenMatchesDataLen)
			n.fileLengthBytes = (unsigned) n.dataLengthBytes;
		else
			b = inBitStream->ReadCompressed(n.fileLengthBytes);
#ifdef _DEBUG
		RakAssert(b);
#endif
		if (b == 0) {
			Clear();
			return false;
		}
		n.filename = filename;
		n.fullPathToFile = filename;
		fileList.Insert(n, __FILE__, __LINE__);
	}
	return true;
}
RakNet::RakString PostgreSQLInterface::GetEscapedString(const char *input) const
{
	unsigned long len = (unsigned long) strlen(input);
	char *fn = (char*) rakMalloc_Ex(len*2+1,_FILE_AND_LINE_);
	int error;
	PQescapeStringConn(pgConn, fn, input, len, &error);
	RakNet::RakString output;
	// Use assignment so it doesn't parse printf escape strings
	output = fn;
	rakFree_Ex(fn,_FILE_AND_LINE_);
	return output;
}
示例#8
0
Packet* TCPInterface::AllocatePacket(unsigned dataSize)
{
    Packet*p = RakNet::OP_NEW<Packet>(__FILE__,__LINE__);
    p->data=(unsigned char*) rakMalloc_Ex(dataSize,__FILE__,__LINE__);
    p->length=dataSize;
    p->bitSize=BYTES_TO_BITS(dataSize);
    p->deleteData=false;
    p->guid=UNASSIGNED_RAKNET_GUID;
    p->systemAddress=UNASSIGNED_SYSTEM_ADDRESS;
    p->systemAddress.systemIndex=(SystemIndex)-1;
    return p;
}
示例#9
0
void MessageFilter::SetAllowRPC(bool allow, const char *functionName, int filterSetID)
{
	(void) allow;
	FilterSet *filterSet = GetFilterSetByID(filterSetID);
	bool objectExists;
	unsigned index = filterSet->allowedRPCs.GetIndexFromKey((char *const) functionName, &objectExists);
	if (objectExists == false) {
		char *str = (char*) rakMalloc_Ex(strlen(functionName) + 1, __FILE__, __LINE__);
		strcpy(str, functionName);
		filterSet->allowedRPCs.InsertAtIndex(str, index, __FILE__, __LINE__);
	}
}
示例#10
0
void TelnetTransport::SetSendPrefix(const char *prefix)
{
	if (sendPrefix)
	{
		rakFree_Ex(sendPrefix, __FILE__, __LINE__ );
		sendPrefix=0;
	}
	if (prefix)
	{
		sendPrefix = (char*) rakMalloc_Ex(strlen(prefix)+1, __FILE__, __LINE__);
		strcpy(sendPrefix, prefix);
	}
}
示例#11
0
void ConsoleServer::SetPrompt(const char *_prompt)
{
	if (prompt)
		rakFree_Ex(prompt,__FILE__,__LINE__);
	if (_prompt && _prompt[0])
	{
		size_t len = strlen(_prompt);
		prompt = (char*) rakMalloc_Ex(len+1,__FILE__,__LINE__);
		strcpy(prompt,_prompt);
	}
	else
		prompt=0;
}
示例#12
0
void FileList::AddFile(const char *filename, const char *fullPathToFile, const char *data, const unsigned dataLength, const unsigned fileLength, FileListNodeContext context, bool isAReference)
{
	if (filename==0)
		return;
	if (strlen(filename)>MAX_FILENAME_LENGTH)
	{
		// Should be enough for anyone
		RakAssert(0);
		return;
	}
	// If adding a reference, do not send data
	RakAssert(isAReference==false || data==0);
	// Avoid duplicate insertions unless the data is different, in which case overwrite the old data
	unsigned i;
	for (i=0; i<fileList.Size();i++)
	{
		if (strcmp(fileList[i].filename, filename)==0)
		{
			if (fileList[i].fileLengthBytes==fileLength && fileList[i].dataLengthBytes==dataLength &&
				(dataLength==0 || fileList[i].data==0 ||
				memcmp(fileList[i].data, data, dataLength)==0
				))
				// Exact same file already here
				return;

			// File of the same name, but different contents, so overwrite
			rakFree_Ex(fileList[i].data, __FILE__, __LINE__ );
			fileList.RemoveAtIndex(i);
			break;
		}
	}

	FileListNode n;
//	size_t fileNameLen = strlen(filename);
	if (dataLength && data)
	{
		n.data=(char*) rakMalloc_Ex( dataLength, __FILE__, __LINE__ );
		memcpy(n.data, data, dataLength);
	}
	else
		n.data=0;
	n.dataLengthBytes=dataLength;
	n.fileLengthBytes=fileLength;
	n.isAReference=isAReference;
	n.context=context;
	n.filename=filename;
	n.fullPathToFile=fullPathToFile;
		
	fileList.Insert(n, __FILE__, __LINE__);
}
示例#13
0
void RakVoice::Init(unsigned short sampleRate, unsigned bufferSizeBytes)
{
	// Record the parameters
	RakAssert(sampleRate==8000 || sampleRate==16000 || sampleRate==32000);
	this->sampleRate=sampleRate;
	this->bufferSizeBytes=bufferSizeBytes;
	bufferedOutputCount=bufferSizeBytes/SAMPLESIZE;
	bufferedOutput = (float*) rakMalloc_Ex(sizeof(float)*bufferedOutputCount, __FILE__, __LINE__);
	unsigned i;
	for (i=0; i < bufferedOutputCount; i++)
		bufferedOutput[i]=0.0f;
	zeroBufferedOutput=false;

}
void FullyConnectedMesh::Startup(const char *password, int _passwordLength)
{
	if (pw)
		rakFree_Ex(pw, __FILE__, __LINE__ );
	if (password)
	{
		pw = (char*) rakMalloc_Ex( _passwordLength, __FILE__, __LINE__ );
		memcpy(pw, password, _passwordLength);
		passwordLength=_passwordLength;
	}
	else
		pw=0;
	
}
示例#15
0
void ConnectionGraph::SetPassword(const char *password)
{
	if (pw)
	{
		RakNet::OP_DELETE_ARRAY(pw, __FILE__, __LINE__);
		pw=0;
	}

	if (password && password[0])
	{
		RakAssert(strlen(password)<256);
		pw=(char*) rakMalloc_Ex( strlen(password)+1, __FILE__, __LINE__ );
		strcpy(pw, password);
	}
}
示例#16
0
PluginReceiveResult RakNetTransport2::OnReceive(Packet *packet)
{
	switch (packet->data[0])
	{
	case ID_TRANSPORT_STRING:
		{
			if (packet->length==sizeof(MessageID))
				return RR_STOP_PROCESSING_AND_DEALLOCATE;

			Packet *p = RakNet::OP_NEW<Packet>(__FILE__,__LINE__);
			*p=*packet;
			p->bitSize-=8;
			p->length--;
			p->data=(unsigned char*) rakMalloc_Ex(p->length,__FILE__,__LINE__);
			memcpy(p->data, packet->data+1, p->length);
			packetQueue.Push(p, __FILE__, __LINE__ );

		}
		return RR_STOP_PROCESSING_AND_DEALLOCATE;
	}
	return RR_CONTINUE_PROCESSING;
}
bool PostgreSQLInterface::PQGetValueFromBinary(char **output, int *outputLength, PGresult *result, int rowIndex, const char *columnName)
{
	int columnIndex = PQfnumber(result, columnName);
	if (columnIndex!=-1)
	{
		*outputLength=PQgetlength(result, rowIndex, columnIndex);
		if (*outputLength==0)
		{
			*output=0;
			return false;
		}
		else
		{
			*output = (char*) rakMalloc_Ex(*outputLength,_FILE_AND_LINE_);
			memcpy(*output, PQgetvalue(result, rowIndex, columnIndex), *outputLength);
			return true;
		}
	}
	else
		return false;
	
}
示例#18
0
bool WriteFileWithDirectories( const char *path, char *data, unsigned dataLength )
{
    int index;
    FILE *fp;
    char *pathCopy;
    int res;

    if ( path == 0 || path[ 0 ] == 0 )
        return false;

    pathCopy = (char*) rakMalloc_Ex( strlen( path ) + 1, _FILE_AND_LINE_ );

    strcpy( pathCopy, path );

    // Ignore first / if there is one
    if (pathCopy[0])
    {
        index = 1;
        while ( pathCopy[ index ] )
        {
            if ( pathCopy[ index ] == '/' || pathCopy[ index ] == '\\')
            {
                pathCopy[ index ] = 0;

#ifdef _WIN32
#pragma warning( disable : 4966 ) // mkdir declared deprecated by Microsoft in order to make it harder to be cross platform.  I don't agree it's deprecated.
                res = mkdir( pathCopy );
#else

                res = mkdir( pathCopy, 0744 );
#endif
                if (res<0 && errno!=EEXIST && errno!=EACCES)
                {
                    rakFree_Ex(pathCopy, _FILE_AND_LINE_ );
                    return false;
                }

                pathCopy[ index ] = '/';
            }

            index++;
        }
    }

    if (data)
    {
        fp = fopen( path, "wb" );

        if ( fp == 0 )
        {
            rakFree_Ex(pathCopy, _FILE_AND_LINE_ );
            return false;
        }

        fwrite( data, 1, dataLength, fp );

        fclose( fp );
    }
    else
    {
#ifdef _WIN32
#pragma warning( disable : 4966 ) // mkdir declared deprecated by Microsoft in order to make it harder to be cross platform.  I don't agree it's deprecated.
        res = mkdir( pathCopy );
#else
        res = mkdir( pathCopy, 0744 );
#endif

        if (res<0 && errno!=EEXIST)
        {
            rakFree_Ex(pathCopy, _FILE_AND_LINE_ );
            return false;
        }
    }

    rakFree_Ex(pathCopy, _FILE_AND_LINE_ );

    return true;
}
bool FileListTransfer::DecodeFile(Packet *packet, bool fullFile)
{
	FileListTransferCBInterface::OnFileStruct onFileStruct;
	RakNet::BitStream inBitStream(packet->data, packet->length, false);
	inBitStream.IgnoreBits(8);

	unsigned int partCount=0;
	unsigned int partTotal=0;
	unsigned int partLength=0;
	onFileStruct.fileData=0;
	if (fullFile==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 block
	}
	inBitStream.Read(onFileStruct.context);
	inBitStream.Read(onFileStruct.setID);
	FileListReceiver *fileListReceiver;
	if (fileListReceivers.Has(onFileStruct.setID)==false)
	{
		return false;
	}
	fileListReceiver=fileListReceivers.Get(onFileStruct.setID);
	if (fileListReceiver->allowedSender!=packet->systemAddress)
	{
#ifdef _DEBUG
		RakAssert(0);
#endif
		return false;
	}

#ifdef _DEBUG
	RakAssert(fileListReceiver->gotSetHeader==true);
#endif

	if (stringCompressor->DecodeString(onFileStruct.fileName, 512, &inBitStream)==false)
	{
#ifdef _DEBUG
		RakAssert(0);
#endif
		return false;
	}

	inBitStream.ReadCompressed(onFileStruct.fileIndex);
	inBitStream.ReadCompressed(onFileStruct.finalDataLength);

	// Read header uncompressed so the data is byte aligned, for speed
	onFileStruct.compressedTransmissionLength=(unsigned int) onFileStruct.finalDataLength;

	if (fullFile)
	{
		// Support SendLists
		inBitStream.AlignReadToByteBoundary();

		onFileStruct.fileData = (char*) rakMalloc_Ex( (size_t) onFileStruct.finalDataLength, __FILE__, __LINE__ );

		inBitStream.Read((char*)onFileStruct.fileData, onFileStruct.finalDataLength);
	}
	

	onFileStruct.setCount=fileListReceiver->setCount;
	onFileStruct.setTotalCompressedTransmissionLength=fileListReceiver->setTotalCompressedTransmissionLength;
	onFileStruct.setTotalFinalLength=fileListReceiver->setTotalFinalLength;

	// User callback for this file.
	if (fullFile)
	{
		if (fileListReceiver->downloadHandler->OnFile(&onFileStruct))
			rakFree_Ex(onFileStruct.fileData, __FILE__, __LINE__ );

		fileListReceiver->filesReceived++;

		// If this set is done, free the memory for it.
		if ((int) fileListReceiver->setCount==fileListReceiver->filesReceived)
		{
			if (fileListReceiver->downloadHandler->OnDownloadComplete()==false)
			{
				fileListReceiver->downloadHandler->OnDereference();
				if (fileListReceiver->deleteDownloadHandler)
					RakNet::OP_DELETE(fileListReceiver->downloadHandler, __FILE__, __LINE__);
				fileListReceivers.Delete(onFileStruct.setID);
				RakNet::OP_DELETE(fileListReceiver, __FILE__, __LINE__);
			}
		}

	}
	else
	{
		inBitStream.AlignReadToByteBoundary();

		bool usedAlloca=false;
		char *firstDataChunk;
		unsigned int unreadBits = inBitStream.GetNumberOfUnreadBits();
		unsigned int unreadBytes = BITS_TO_BYTES(unreadBits);
		if (unreadBytes>0)
		{
#if !defined(_XBOX) && !defined(_X360)
			if (unreadBits < MAX_ALLOCA_STACK_ALLOCATION)
			{
				firstDataChunk = ( char* ) alloca( unreadBytes );
				usedAlloca=true;
			}
			else
#endif
				firstDataChunk = (char*) rakMalloc_Ex( unreadBytes, __FILE__, __LINE__ );

			// Read partLength bytes, reported to OnFileProgress

			inBitStream.Read((char*)firstDataChunk, unreadBytes );

		}
		else
			firstDataChunk=0;

		fileListReceiver->downloadHandler->OnFileProgress(&onFileStruct, partCount, partTotal, unreadBytes, firstDataChunk);

		if (usedAlloca==false)
			RakNet::OP_DELETE_ARRAY(firstDataChunk, __FILE__, __LINE__);
	}

	return true;
}
示例#20
0
void FileListTransfer::SendIRIToAddress(SystemAddress systemAddress)
{
	// Was previously using GetStatistics to get outgoing buffer size, but TCP with UnifiedSend doesn't have this
	unsigned int bytesRead;	
	const char *dataBlocks[2];
	int lengths[2];
	unsigned int smallFileTotalSize=0;
	RakNet::BitStream outBitstream;

	filesToPushAllSameAddressMutex.Lock();
	for (unsigned int ftpIndex=0; ftpIndex < filesToPushAllSameAddress.Size(); ftpIndex++)
	{
		FileToPushRecipient *ftpr = filesToPushAllSameAddress[ftpIndex];
		if (ftpr->systemAddress==systemAddress)
		{
			FileToPush *ftp = ftpr->filesToPush.Peek();

			// Read and send chunk. If done, delete at this index
			void *buff = rakMalloc_Ex(ftp->chunkSize, __FILE__, __LINE__);
			if (buff==0)
			{
				filesToPushAllSameAddressMutex.Unlock();
				notifyOutOfMemory(__FILE__, __LINE__);
				return;
			}

			bytesRead=ftp->incrementalReadInterface->GetFilePart(ftp->fileListNode.fullPathToFile, ftp->currentOffset, ftp->chunkSize, buff, ftp->fileListNode.context);
			bool done = bytesRead!=ftp->chunkSize;
			while (done && ftp->currentOffset==0 && ftpr->filesToPush.Size()>=2 && smallFileTotalSize<ftp->chunkSize)
			{
				// Send all small files at once, rather than wait for ID_FILE_LIST_REFERENCE_PUSH. But at least one ID_FILE_LIST_REFERENCE_PUSH must be sent
				outBitstream.Reset();
				outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_FILE);
				outBitstream.Write(ftp->fileListNode.context);
				outBitstream.Write(ftp->setID);
				stringCompressor->EncodeString(ftp->fileListNode.filename, 512, &outBitstream);
				outBitstream.WriteCompressed(ftp->setIndex);
				outBitstream.WriteCompressed(ftp->fileListNode.dataLengthBytes); // Original length in bytes
				outBitstream.AlignWriteToByteBoundary();
				dataBlocks[0]=(char*) outBitstream.GetData();
				lengths[0]=outBitstream.GetNumberOfBytesUsed();
				dataBlocks[1]=(const char*) buff;
				lengths[1]=bytesRead;
				SendListUnified(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, systemAddress, false);

				RakNet::OP_DELETE(ftp,__FILE__,__LINE__);
				ftpr->filesToPush.Pop();
				smallFileTotalSize+=bytesRead;
				done = bytesRead!=ftp->chunkSize;
				ftp = ftpr->filesToPush.Peek();
				bytesRead=ftp->incrementalReadInterface->GetFilePart(ftp->fileListNode.fullPathToFile, ftp->currentOffset, ftp->chunkSize, buff, ftp->fileListNode.context);
			}


			outBitstream.Reset();
			outBitstream.Write((MessageID)ID_FILE_LIST_REFERENCE_PUSH);
			outBitstream.Write(ftp->fileListNode.context);
			outBitstream.Write(ftp->setID);
			stringCompressor->EncodeString(ftp->fileListNode.filename, 512, &outBitstream);
			outBitstream.WriteCompressed(ftp->setIndex);
			outBitstream.WriteCompressed(ftp->fileListNode.dataLengthBytes); // Original length in bytes
			outBitstream.WriteCompressed(ftp->currentOffset);
			ftp->currentOffset+=bytesRead;
			outBitstream.WriteCompressed(bytesRead);
			outBitstream.Write(done);

			if (callback)
			{
				callback->OnFilePush(ftp->fileListNode.filename, ftp->fileListNode.fileLengthBytes, ftp->currentOffset-bytesRead, bytesRead, done, systemAddress);
			}

			dataBlocks[0]=(char*) outBitstream.GetData();
			lengths[0]=outBitstream.GetNumberOfBytesUsed();
			dataBlocks[1]=(char*) buff;
			lengths[1]=bytesRead;
			//rakPeerInterface->SendList(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, ftp->systemAddress, false);
			SendListUnified(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, systemAddress, false);
			if (done)
			{
				// Done
				RakNet::OP_DELETE(ftp,__FILE__,__LINE__);
				ftpr->filesToPush.Pop();
				if (ftpr->filesToPush.Size()==0)
				{
					RakNet::OP_DELETE(ftpr,__FILE__,__LINE__);
					filesToPushAllSameAddress.RemoveAtIndexFast(ftpIndex);
				}
			}
			rakFree_Ex(buff, __FILE__, __LINE__ );
			break;
		}
	}
	filesToPushAllSameAddressMutex.Unlock();
}
示例#21
0
Packet* TelnetTransport::Receive( void )
{
	if (tcpInterface==0) return 0;
	Packet *p = tcpInterface->Receive();
	if (p==0)
		return 0;

	/*
	if (p->data[0]==255)
	{
		unsigned i;
		for (i=0; i < p->length; i++)
		{
			RAKNET_DEBUG_PRINTF("%i ", p->data[i]);
		}
		RAKNET_DEBUG_PRINTF("\n");
		tcpInterface->DeallocatePacket(p);
		return 0;
	}
	*/

	// Get this guy's cursor buffer.  This is real bullcrap that I have to do this.
	unsigned i;
	TelnetClient *remoteClient=0;
	for (i=0; i < remoteClients.Size(); i++)
	{
		if (remoteClients[i]->systemAddress==p->systemAddress)
			remoteClient=remoteClients[i];
	}
	//RakAssert(remoteClient);
	if (remoteClient==0)
	{
		tcpInterface->DeallocatePacket(p);
		return 0;
	}


	if (p->length==3 && p->data[0]==27 && p->data[1]==91 && p->data[2]==65)
	{
		if (remoteClient->lastSentTextInput[0])
		{
			// Up arrow, return last string
			for (int i=0; remoteClient->textInput[i]; i++)
				remoteClient->textInput[i]=8;
			strcat(remoteClient->textInput, remoteClient->lastSentTextInput);
			tcpInterface->Send((const char *)remoteClient->textInput, strlen(remoteClient->textInput), p->systemAddress, false);
			strcpy(remoteClient->textInput,remoteClient->lastSentTextInput);
			remoteClient->cursorPosition=strlen(remoteClient->textInput);
		}
		
		return 0;
	}


	// 127 is delete - ignore that
	// 9 is tab
	// 27 is escape
	if (p->data[0]>=127 || p->data[0]==9 || p->data[0]==27)
	{
		tcpInterface->DeallocatePacket(p);
		return 0;
	}

	// Hack - I don't know what the hell this is about but cursor keys send 3 characters at a time.  I can block these
	//Up=27,91,65
	//Down=27,91,66
	//Right=27,91,67
	//Left=27,91,68
	if (p->length==3 && p->data[0]==27 && p->data[1]==91 && p->data[2]>=65 && p->data[2]<=68)
	{
		tcpInterface->DeallocatePacket(p);
		return 0;
	}



	// Echo
#ifdef ECHO_INPUT
	tcpInterface->Send((const char *)p->data, p->length, p->systemAddress, false);
#endif

	bool gotLine;
	// Process each character in turn
	for (i=0; i < p->length; i++)
	{

#ifdef ECHO_INPUT
		if (p->data[i]==8)
		{
			char spaceThenBack[2];
			spaceThenBack[0]=' ';
			spaceThenBack[1]=8;
			tcpInterface->Send((const char *)spaceThenBack, 2, p->systemAddress, false);
		}
#endif

		gotLine=ReassembleLine(remoteClient, p->data[i]);
		if (gotLine && remoteClient->textInput[0])
		{

			Packet *reassembledLine = (Packet*) rakMalloc_Ex(sizeof(Packet), __FILE__, __LINE__);
			reassembledLine->length=(unsigned int) strlen(remoteClient->textInput);
			memcpy(remoteClient->lastSentTextInput, remoteClient->textInput, reassembledLine->length+1);
			RakAssert(reassembledLine->length < REMOTE_MAX_TEXT_INPUT);
			reassembledLine->data= (unsigned char*) rakMalloc_Ex( reassembledLine->length+1, __FILE__, __LINE__ );
			memcpy(reassembledLine->data, remoteClient->textInput, reassembledLine->length);
#ifdef _PRINTF_DEBUG
			memset(remoteClient->textInput, 0, REMOTE_MAX_TEXT_INPUT);
#endif
			reassembledLine->data[reassembledLine->length]=0;
			reassembledLine->systemAddress=p->systemAddress;
			tcpInterface->DeallocatePacket(p);
			return reassembledLine;
		}
	}

	tcpInterface->DeallocatePacket(p);
	return 0;
}
示例#22
0
	virtual PatchContext ApplyPatchBase(const char *oldFilePath, char **newFileContents, unsigned int *newFileSize, char *patchContents, unsigned int patchSize, uint32_t patchAlgorithm)
	{
		if (patchAlgorithm==0)
		{
			return ApplyPatchBSDiff(oldFilePath, newFileContents, newFileSize, patchContents, patchSize);
		}
		else
		{
			char WORKING_DIRECTORY[MAX_PATH];
			GetTempPath(MAX_PATH, WORKING_DIRECTORY);
			if (WORKING_DIRECTORY[strlen(WORKING_DIRECTORY)-1]=='\\' || WORKING_DIRECTORY[strlen(WORKING_DIRECTORY)-1]=='/')
				WORKING_DIRECTORY[strlen(WORKING_DIRECTORY)-1]=0;

			char buff[128];
			RakNet::TimeUS time = RakNet::GetTimeUS();
#if defined(_WIN32)
			sprintf(buff, "%I64u", time);
#else
			sprintf(buff, "%llu", (long long unsigned int) time);
#endif

			char pathToPatch1[MAX_PATH], pathToPatch2[MAX_PATH];
			sprintf(pathToPatch1, "%s/patchClient_%s.tmp", WORKING_DIRECTORY, buff);
			FILE *fpPatch = fopen(pathToPatch1, "wb");
			if (fpPatch==0)
				return PC_ERROR_PATCH_TARGET_MISSING;
			fwrite(patchContents, 1, patchSize, fpPatch);
			fclose(fpPatch);

			// Invoke xdelta
			// See https://code.google.com/p/xdelta/wiki/CommandLineSyntax
			char commandLine[512];
			_snprintf(commandLine, sizeof(commandLine)-1, "-d -f -s %s %s/patchClient_%s.tmp %s/newFile_%s.tmp", oldFilePath, WORKING_DIRECTORY, buff, WORKING_DIRECTORY, buff);
			commandLine[511]=0;
			
			SHELLEXECUTEINFO shellExecuteInfo;
			shellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFO);
			shellExecuteInfo.fMask = SEE_MASK_NOASYNC | SEE_MASK_NO_CONSOLE;
			shellExecuteInfo.hwnd = NULL;
			shellExecuteInfo.lpVerb = "open";
			shellExecuteInfo.lpFile = "xdelta3-3.0.6-win32.exe";
			shellExecuteInfo.lpParameters = commandLine;
			shellExecuteInfo.lpDirectory = NULL;
			shellExecuteInfo.nShow = SW_SHOWNORMAL;
			shellExecuteInfo.hInstApp = NULL;
			ShellExecuteEx(&shellExecuteInfo);

			// // ShellExecute is blocking, but if it writes a file to disk that file is not always immediately accessible after it returns. And this only happens in release, and only when not running in the debugger
			// ShellExecute(NULL, "open", "xdelta3-3.0.6-win32.exe", commandLine, NULL, SW_SHOWNORMAL);

			sprintf(pathToPatch2, "%s/newFile_%s.tmp", WORKING_DIRECTORY, buff);
			fpPatch = fopen(pathToPatch2, "r+b");
			RakNet::TimeUS stopWaiting = time + 60000000;
			while (fpPatch==0 && RakNet::GetTimeUS() < stopWaiting)
			{
				RakSleep(1000);
				fpPatch = fopen(pathToPatch2, "r+b");
			}
			if (fpPatch==0)
			{
				printf("\nERROR: Could not open %s.\nerr=%i (%s)\narguments=%s\n", pathToPatch2, errno, strerror(errno), commandLine);
				return PC_ERROR_PATCH_TARGET_MISSING;
			}

			fseek(fpPatch, 0, SEEK_END);
			*newFileSize = ftell(fpPatch);
			fseek(fpPatch, 0, SEEK_SET);
			*newFileContents = (char*) rakMalloc_Ex(*newFileSize, _FILE_AND_LINE_);
			fread(*newFileContents, 1, *newFileSize, fpPatch);
			fclose(fpPatch);

			int unlinkRes1 = _unlink(pathToPatch1);
			int unlinkRes2 = _unlink(pathToPatch2);
			while ((unlinkRes1!=0 || unlinkRes2!=0) && RakNet::GetTimeUS() < stopWaiting)
			{
				RakSleep(1000);
				if (unlinkRes1!=0)
					unlinkRes1 = _unlink(pathToPatch1);
				if (unlinkRes2!=0)
					unlinkRes2 = _unlink(pathToPatch2);
			}

			if (unlinkRes1!=0)
				printf("\nWARNING: unlink %s failed.\nerr=%i (%s)\n", pathToPatch1, errno, strerror(errno));
			if (unlinkRes2!=0)
				printf("\nWARNING: unlink %s failed.\nerr=%i (%s)\n", pathToPatch2, errno, strerror(errno));

			return PC_WRITE_FILE;
		}
	}
示例#23
0
	bool MakePatch(const char *oldFile, const char *newFile, char **patch, unsigned int *patchLength, int *patchAlgorithm)
	{
		FILE *fpOld = fopen(oldFile, "rb");
		fseek(fpOld, 0, SEEK_END);
		int contentLengthOld = ftell(fpOld);
		FILE *fpNew = fopen(newFile, "rb");
		fseek(fpNew, 0, SEEK_END);
		int contentLengthNew = ftell(fpNew);

		if ((contentLengthOld < 33554432 && contentLengthNew < 33554432) || PATH_TO_XDELTA_EXE[0]==0)
		{
			// Use bsdiff, which does a good job but takes a lot of memory based on the size of the file
			*patchAlgorithm=0;
			bool b = MakePatchBSDiff(fpOld, contentLengthOld, fpNew, contentLengthNew, patch, patchLength);
			fclose(fpOld);
			fclose(fpNew);
			return b;
		}
		else
		{
			*patchAlgorithm=1;
			fclose(fpOld);
			fclose(fpNew);

			char buff[128];
			RakNet::TimeUS time = RakNet::GetTimeUS();
#if defined(_WIN32)
			sprintf(buff, "%I64u", time);
#else
			sprintf(buff, "%llu", (long long unsigned int) time);
#endif

			// Invoke xdelta
			// See https://code.google.com/p/xdelta/wiki/CommandLineSyntax
			char commandLine[512];
			_snprintf(commandLine, sizeof(commandLine)-1, "-f -s %s %s patchServer_%s.tmp", oldFile, newFile, buff);
			commandLine[511]=0;
			
			SHELLEXECUTEINFO shellExecuteInfo;
			shellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFO);
			shellExecuteInfo.fMask = SEE_MASK_NOASYNC | SEE_MASK_NO_CONSOLE;
			shellExecuteInfo.hwnd = NULL;
			shellExecuteInfo.lpVerb = "open";
			shellExecuteInfo.lpFile = PATH_TO_XDELTA_EXE;
			shellExecuteInfo.lpParameters = commandLine;
			shellExecuteInfo.lpDirectory = WORKING_DIRECTORY;
			shellExecuteInfo.nShow = SW_SHOWNORMAL;
			shellExecuteInfo.hInstApp = NULL;
			ShellExecuteEx(&shellExecuteInfo);
			//ShellExecute(NULL, "open", PATH_TO_XDELTA_EXE, commandLine, WORKING_DIRECTORY, SW_SHOWNORMAL);

			char pathToPatch[MAX_PATH];
			sprintf(pathToPatch, "%s/patchServer_%s.tmp", WORKING_DIRECTORY, buff);
			// r+ instead of r, because I want exclusive access in case xdelta is still working
			FILE *fpPatch = fopen(pathToPatch, "r+b");
			RakNet::TimeUS stopWaiting = time + 60000000 * 5;
			while (fpPatch==0 && RakNet::GetTimeUS() < stopWaiting)
			{
				RakSleep(1000);
				fpPatch = fopen(pathToPatch, "r+b");
			}
			if (fpPatch==0)
				return false;
			fseek(fpPatch, 0, SEEK_END);
			*patchLength = ftell(fpPatch);
			fseek(fpPatch, 0, SEEK_SET);
			*patch = (char*) rakMalloc_Ex(*patchLength, _FILE_AND_LINE_);
			fread(*patch, 1, *patchLength, fpPatch);
			fclose(fpPatch);

			int unlinkRes = _unlink(pathToPatch);
			while (unlinkRes!=0 && RakNet::GetTimeUS() < stopWaiting)
			{
				RakSleep(1000);
				unlinkRes = _unlink(pathToPatch);
			}
			if (unlinkRes!=0)
				printf("\nWARNING: unlink %s failed.\nerr=%i (%s)\n", pathToPatch, errno, strerror(errno));

			return true;
		}
	}
示例#24
0
void FileList::AddFilesFromDirectory(const char *applicationDirectory, const char *subDirectory, bool writeHash, bool writeData, bool recursive, FileListNodeContext context)
{
	DataStructures::Queue<char*> dirList;
	char root[260];
	char fullPath[520];
	_finddata_t fileInfo;
	intptr_t dir;
	FILE *fp;
	char *dirSoFar, *fileData;
	dirSoFar=(char*) rakMalloc_Ex( 520, __FILE__, __LINE__ );

	if (applicationDirectory)
		strcpy(root, applicationDirectory);
	else
		root[0]=0;

	int rootLen=(int)strlen(root);
	if (rootLen)
	{
		strcpy(dirSoFar, root);
		if (FixEndingSlash(dirSoFar))
			rootLen++;
	}
	else
		dirSoFar[0]=0;
	
	if (subDirectory)
	{
		strcat(dirSoFar, subDirectory);
		FixEndingSlash(dirSoFar);
	}
	if (callback)
		callback->OnAddFilesFromDirectoryStarted(this, dirSoFar);
	// RAKNET_DEBUG_PRINTF("Adding files from directory %s\n",dirSoFar);
	dirList.Push(dirSoFar, __FILE__, __LINE__ );
	while (dirList.Size())
	{
		dirSoFar=dirList.Pop();
		strcpy(fullPath, dirSoFar);
		// Changed from *.* to * for Linux compatibility
		strcat(fullPath, "*");


                dir=_findfirst(fullPath, &fileInfo );
		if (dir==-1)
		{
			_findclose(dir);
			rakFree_Ex(dirSoFar, __FILE__, __LINE__ );
			unsigned i;
			for (i=0; i < dirList.Size(); i++)
				rakFree_Ex(dirList[i], __FILE__, __LINE__ );
			return;
		}

//		RAKNET_DEBUG_PRINTF("Adding %s. %i remaining.\n", fullPath, dirList.Size());
		if (callback)
			callback->OnDirectory(this, fullPath, dirList.Size());

                do
		{
                    // no guarantee these entries are first...
                    if (strcmp("." , fileInfo.name) == 0 ||
                        strcmp("..", fileInfo.name) == 0)
                    {
                        continue;
                    }
                    
			if ((fileInfo.attrib & (_A_HIDDEN | _A_SUBDIR | _A_SYSTEM))==0)
			{
				strcpy(fullPath, dirSoFar);
				strcat(fullPath, fileInfo.name);
				fileData=0;

				if (callback)
					callback->OnFile(this, dirSoFar, fileInfo.name, fileInfo.size);

				if (writeData && writeHash)
				{
					fileData= (char*) rakMalloc_Ex( fileInfo.size+HASH_LENGTH, __FILE__, __LINE__ );
					fp = fopen(fullPath, "rb");
					fread(fileData+HASH_LENGTH, fileInfo.size, 1, fp);
					fclose(fp);

					unsigned int hash = SuperFastHash(fileData+HASH_LENGTH, fileInfo.size);
					if (RakNet::BitStream::DoEndianSwap())
						RakNet::BitStream::ReverseBytesInPlace((unsigned char*) &hash, sizeof(hash));
					memcpy(fileData, &hash, HASH_LENGTH);

//					sha1.Reset();
//					sha1.Update( ( unsigned char* ) fileData+HASH_LENGTH, fileInfo.size );
//					sha1.Final();
//					memcpy(fileData, sha1.GetHash(), HASH_LENGTH);
					// File data and hash
					AddFile((const char*)fullPath+rootLen, fullPath, fileData, fileInfo.size+HASH_LENGTH, fileInfo.size, context);
				}
				else if (writeHash)
				{
//					sha1.Reset();
//					sha1.HashFile((char*)fullPath);
//					sha1.Final();

					unsigned int hash = SuperFastHashFile(fullPath);
					if (RakNet::BitStream::DoEndianSwap())
						RakNet::BitStream::ReverseBytesInPlace((unsigned char*) &hash, sizeof(hash));

					// Hash only
				//	AddFile((const char*)fullPath+rootLen, (const char*)sha1.GetHash(), HASH_LENGTH, fileInfo.size, context);
					AddFile((const char*)fullPath+rootLen, fullPath, (const char*)&hash, HASH_LENGTH, fileInfo.size, context);
				}
				else if (writeData)
				{
					fileData= (char*) rakMalloc_Ex( fileInfo.size, __FILE__, __LINE__ );
					fp = fopen(fullPath, "rb");
					fread(fileData, fileInfo.size, 1, fp);
					fclose(fp);

					// File data only
					AddFile(fullPath+rootLen, fullPath, fileData, fileInfo.size, fileInfo.size, context);
				}
				else
				{
					// Just the filename
					AddFile(fullPath+rootLen, fullPath, 0, 0, fileInfo.size, context);
				}

				if (fileData)
					rakFree_Ex(fileData, __FILE__, __LINE__ );
			}
			else if ((fileInfo.attrib & _A_SUBDIR) && (fileInfo.attrib & (_A_HIDDEN | _A_SYSTEM))==0 && recursive)
			{
				char *newDir=(char*) rakMalloc_Ex( 520, __FILE__, __LINE__ );
				strcpy(newDir, dirSoFar);
				strcat(newDir, fileInfo.name);
				strcat(newDir, "/");
				dirList.Push(newDir, __FILE__, __LINE__ );
			}

		} while (_findnext(dir, &fileInfo ) != -1);

		_findclose(dir);
		rakFree_Ex(dirSoFar, __FILE__, __LINE__ );
	}
}
void FileListTransfer::OnReferencePush(Packet *packet, bool fullFile)
{
	// fullFile is always true for TCP, since TCP does not return SPLIT_PACKET_NOTIFICATION

	RakNet::BitStream refPushAck;
	refPushAck.Write((MessageID)ID_FILE_LIST_REFERENCE_PUSH_ACK);
	SendUnified(&refPushAck,HIGH_PRIORITY, RELIABLE, 0, packet->systemAddress, false);

	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 (fullFile==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 block
	}

	inBitStream.Read(onFileStruct.context);
	inBitStream.Read(onFileStruct.setID);
	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->DecodeString(onFileStruct.fileName, 512, &inBitStream)==false)
	{
#ifdef _DEBUG
		RakAssert(0);
#endif
		return;
	}

	inBitStream.ReadCompressed(onFileStruct.fileIndex);
	inBitStream.ReadCompressed(onFileStruct.finalDataLength);
	unsigned int offset;
	unsigned int chunkLength;
	inBitStream.ReadCompressed(offset);
	inBitStream.ReadCompressed(chunkLength);
//	if (chunkLength==0)
//		return;
	bool lastChunk;
	inBitStream.Read(lastChunk);
	bool finished = lastChunk && fullFile;

	if (fullFile==false)
		fileListReceiver->partLength=partLength;

	FLR_MemoryBlock mb;
	if (fileListReceiver->pushedFiles.Has(onFileStruct.fileIndex)==false)
	{
		if (chunkLength > 1000000000 || onFileStruct.finalDataLength > 1000000000)
		{
			RakAssert("FileListTransfer::OnReferencePush: file too large" && 0);
			return;
		}

		mb.allocatedLength=onFileStruct.finalDataLength;
		mb.block = (char*) rakMalloc_Ex(onFileStruct.finalDataLength, __FILE__, __LINE__);
		if (mb.block==0)
		{
			notifyOutOfMemory(__FILE__, __LINE__);
			return;
		}

		fileListReceiver->pushedFiles.SetNew(onFileStruct.fileIndex, mb);
	}
	else
		mb=fileListReceiver->pushedFiles.Get(onFileStruct.fileIndex);

	if (offset+chunkLength > mb.allocatedLength)
	{
		// Overrun
		RakAssert("FileListTransfer::OnReferencePush: Write would overrun allocated block" && 0);
		return;
	}

	// Read header uncompressed so the data is byte aligned, for speed
	onFileStruct.compressedTransmissionLength=(unsigned int) onFileStruct.finalDataLength;

	unsigned int unreadBits = inBitStream.GetNumberOfUnreadBits();
	unsigned int unreadBytes = BITS_TO_BYTES(unreadBits);
	unsigned int amountToRead;
	if (fullFile)
		amountToRead=chunkLength;
	else
		amountToRead=unreadBytes;

	inBitStream.AlignReadToByteBoundary();
	if (fullFile || (rakPeerInterface->GetSplitMessageProgressInterval() != 0 && (int)partCount==rakPeerInterface->GetSplitMessageProgressInterval()))
	{
		inBitStream.Read(mb.block+offset, amountToRead);
	}

	onFileStruct.setCount=fileListReceiver->setCount;
	onFileStruct.setTotalCompressedTransmissionLength=fileListReceiver->setTotalCompressedTransmissionLength;
	onFileStruct.setTotalFinalLength=fileListReceiver->setTotalFinalLength;
	onFileStruct.fileData=mb.block;

	if (finished)
	{
		if (fileListReceiver->downloadHandler->OnFile(&onFileStruct))
			rakFree_Ex(onFileStruct.fileData, __FILE__, __LINE__ );
		fileListReceiver->pushedFiles.Delete(onFileStruct.fileIndex);

		fileListReceiver->filesReceived++;

		// If this set is done, free the memory for it.
		if ((int) fileListReceiver->setCount==fileListReceiver->filesReceived)
		{
			if (fileListReceiver->downloadHandler->OnDownloadComplete()==false)
			{
				fileListReceiver->downloadHandler->OnDereference();
				fileListReceivers.Delete(onFileStruct.setID);
				if (fileListReceiver->deleteDownloadHandler)
					RakNet::OP_DELETE(fileListReceiver->downloadHandler, __FILE__, __LINE__);
				RakNet::OP_DELETE(fileListReceiver, __FILE__, __LINE__);
			}
		}
	}
	else
	{
		unsigned int totalNotifications;
		unsigned int currentNotificationIndex;
		unsigned int unreadBytes;

		if (rakPeerInterface==0 || rakPeerInterface->GetSplitMessageProgressInterval()==0)
		{
			totalNotifications = onFileStruct.finalDataLength / chunkLength + 1;
			currentNotificationIndex = offset / chunkLength;
			unreadBytes = mb.allocatedLength - ((offset+1)*chunkLength);
		}
		else
		{
			totalNotifications = onFileStruct.finalDataLength / fileListReceiver->partLength + 1;
			if (fullFile==false)
				currentNotificationIndex = (offset+partCount*fileListReceiver->partLength) / fileListReceiver->partLength ;
			else
				currentNotificationIndex = (offset+chunkLength) / fileListReceiver->partLength ;
			unreadBytes = onFileStruct.finalDataLength - ((currentNotificationIndex+1) * fileListReceiver->partLength);
		}
		fileListReceiver->downloadHandler->OnFileProgress(&onFileStruct, currentNotificationIndex, totalNotifications, unreadBytes, mb.block);
	}

	return;
}
示例#26
0
void FileList::PopulateDataFromDisk(const char *applicationDirectory, bool writeFileData, bool writeFileHash, bool removeUnknownFiles)
{
	FILE *fp;
	char fullPath[512];
	unsigned i;
//	CSHA1 sha1;

	i=0;
	while (i < fileList.Size())
	{
		rakFree_Ex(fileList[i].data, __FILE__, __LINE__ );
		strcpy(fullPath, applicationDirectory);
		FixEndingSlash(fullPath);
		strcat(fullPath,fileList[i].filename.C_String());
		fp=fopen(fullPath, "rb");
		if (fp)
		{
			if (writeFileHash || writeFileData)
			{
				fseek(fp, 0, SEEK_END);
				fileList[i].fileLengthBytes = ftell(fp);
				fseek(fp, 0, SEEK_SET);
				if (writeFileHash)
				{
					if (writeFileData)
					{
						// Hash + data so offset the data by HASH_LENGTH
						fileList[i].data=(char*) rakMalloc_Ex( fileList[i].fileLengthBytes+HASH_LENGTH, __FILE__, __LINE__ );
						fread(fileList[i].data+HASH_LENGTH, fileList[i].fileLengthBytes, 1, fp);
//						sha1.Reset();
//						sha1.Update((unsigned char*)fileList[i].data+HASH_LENGTH, fileList[i].fileLength);
//						sha1.Final();
						unsigned int hash = SuperFastHash(fileList[i].data+HASH_LENGTH, fileList[i].fileLengthBytes);
						if (RakNet::BitStream::DoEndianSwap())
							RakNet::BitStream::ReverseBytesInPlace((unsigned char*) &hash, sizeof(hash));
//						memcpy(fileList[i].data, sha1.GetHash(), HASH_LENGTH);
						memcpy(fileList[i].data, &hash, HASH_LENGTH);
					}
					else
					{
						// Hash only
						fileList[i].dataLengthBytes=HASH_LENGTH;
						if (fileList[i].fileLengthBytes < HASH_LENGTH)
							fileList[i].data=(char*) rakMalloc_Ex( HASH_LENGTH, __FILE__, __LINE__ );
						else
							fileList[i].data=(char*) rakMalloc_Ex( fileList[i].fileLengthBytes, __FILE__, __LINE__ );
						fread(fileList[i].data, fileList[i].fileLengthBytes, 1, fp);
				//		sha1.Reset();
				//		sha1.Update((unsigned char*)fileList[i].data, fileList[i].fileLength);
				//		sha1.Final();
						unsigned int hash = SuperFastHash(fileList[i].data, fileList[i].fileLengthBytes);
						if (RakNet::BitStream::DoEndianSwap())
							RakNet::BitStream::ReverseBytesInPlace((unsigned char*) &hash, sizeof(hash));
						// memcpy(fileList[i].data, sha1.GetHash(), HASH_LENGTH);
						memcpy(fileList[i].data, &hash, HASH_LENGTH);
					}
				}
				else
				{
					// Data only
					fileList[i].dataLengthBytes=fileList[i].fileLengthBytes;
					fileList[i].data=(char*) rakMalloc_Ex( fileList[i].fileLengthBytes, __FILE__, __LINE__ );
					fread(fileList[i].data, fileList[i].fileLengthBytes, 1, fp);
				}

				fclose(fp);
				i++;
			}
			else
			{
				fileList[i].data=0;
				fileList[i].dataLengthBytes=0;
			}
		}
		else
		{
			if (removeUnknownFiles)
			{
				fileList.RemoveAtIndex(i);
			}
			else
				i++;			
		}
	}
}
示例#27
0
int SendIRIToAddressCB(FileListTransfer::ThreadData threadData, bool *returnOutput, void* perThreadData)
{
	(void) perThreadData;

	FileListTransfer *fileListTransfer = threadData.fileListTransfer;
	SystemAddress systemAddress = threadData.systemAddress;
	*returnOutput=false;

	// Was previously using GetStatistics to get outgoing buffer size, but TCP with UnifiedSend doesn't have this
	unsigned int bytesRead;	
	const char *dataBlocks[2];
	int lengths[2];
	unsigned int smallFileTotalSize=0;
	RakNet::BitStream outBitstream;
	unsigned int ftpIndex;

	fileListTransfer->fileToPushRecipientListMutex.Lock();
	for (ftpIndex=0; ftpIndex < fileListTransfer->fileToPushRecipientList.Size(); ftpIndex++)
	{
		FileListTransfer::FileToPushRecipient *ftpr = fileListTransfer->fileToPushRecipientList[ftpIndex];
		// Referenced by both ftpr and list
		ftpr->AddRef();

		fileListTransfer->fileToPushRecipientListMutex.Unlock();

		if (ftpr->systemAddress==systemAddress)
		{
			FileListTransfer::FileToPush *ftp = ftpr->filesToPush.Peek();

			// Read and send chunk. If done, delete at this index
			void *buff = rakMalloc_Ex(ftp->chunkSize, _FILE_AND_LINE_);
			if (buff==0)
			{
				ftpr->Deref();
				notifyOutOfMemory(_FILE_AND_LINE_);
				return 0;
			}

			// Read the next file chunk
			bytesRead=ftp->incrementalReadInterface->GetFilePart(ftp->fileListNode.fullPathToFile, ftp->currentOffset, ftp->chunkSize, buff, ftp->fileListNode.context);

			bool done = ftp->fileListNode.dataLengthBytes == ftp->currentOffset+bytesRead;
			while (done && ftp->currentOffset==0 && ftpr->filesToPush.Size()>=2 && smallFileTotalSize<ftp->chunkSize)
			{
				// Send all small files at once, rather than wait for ID_FILE_LIST_REFERENCE_PUSH. But at least one ID_FILE_LIST_REFERENCE_PUSH must be sent
				outBitstream.Reset();
				outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_FILE);
				// outBitstream.Write(ftp->fileListNode.context);
				outBitstream << ftp->fileListNode.context;
				outBitstream.Write(ftp->setID);
				StringCompressor::Instance()->EncodeString(ftp->fileListNode.filename, 512, &outBitstream);
				outBitstream.WriteCompressed(ftp->setIndex);
				outBitstream.WriteCompressed(ftp->fileListNode.dataLengthBytes); // Original length in bytes
				outBitstream.AlignWriteToByteBoundary();
				dataBlocks[0]=(char*) outBitstream.GetData();
				lengths[0]=outBitstream.GetNumberOfBytesUsed();
				dataBlocks[1]=(const char*) buff;
				lengths[1]=bytesRead;

				fileListTransfer->SendListUnified(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, systemAddress, false);

				// LWS : fixed freed pointer reference
//				unsigned int chunkSize = ftp->chunkSize;
				RakNet::OP_DELETE(ftp,_FILE_AND_LINE_);
				ftpr->filesToPush.Pop();
				smallFileTotalSize+=bytesRead;
				//done = bytesRead!=ftp->chunkSize;
				ftp = ftpr->filesToPush.Peek();

				bytesRead=ftp->incrementalReadInterface->GetFilePart(ftp->fileListNode.fullPathToFile, ftp->currentOffset, ftp->chunkSize, buff, ftp->fileListNode.context);
				done = ftp->fileListNode.dataLengthBytes == ftp->currentOffset+bytesRead;
			}


			outBitstream.Reset();
			outBitstream.Write((MessageID)ID_FILE_LIST_REFERENCE_PUSH);
			// outBitstream.Write(ftp->fileListNode.context);
			outBitstream << ftp->fileListNode.context;
			outBitstream.Write(ftp->setID);
			StringCompressor::Instance()->EncodeString(ftp->fileListNode.filename, 512, &outBitstream);
			outBitstream.WriteCompressed(ftp->setIndex);
			outBitstream.WriteCompressed(ftp->fileListNode.dataLengthBytes); // Original length in bytes
			outBitstream.WriteCompressed(ftp->currentOffset);
			ftp->currentOffset+=bytesRead;
			outBitstream.WriteCompressed(bytesRead);
			outBitstream.Write(done);

			for (unsigned int flpcIndex=0; flpcIndex < fileListTransfer->fileListProgressCallbacks.Size(); flpcIndex++)
				fileListTransfer->fileListProgressCallbacks[flpcIndex]->OnFilePush(ftp->fileListNode.filename, ftp->fileListNode.fileLengthBytes, ftp->currentOffset-bytesRead, bytesRead, done, systemAddress, ftp->setID);

			dataBlocks[0]=(char*) outBitstream.GetData();
			lengths[0]=outBitstream.GetNumberOfBytesUsed();
			dataBlocks[1]=(char*) buff;
			lengths[1]=bytesRead;
			//rakPeerInterface->SendList(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, ftp->systemAddress, false);
			fileListTransfer->SendListUnified(dataBlocks,lengths,2,ftp->packetPriority, RELIABLE_ORDERED, ftp->orderingChannel, systemAddress, false);

			// Mutex state: FileToPushRecipient (ftpr) has AddRef. fileToPushRecipientListMutex not locked.
			if (done)
			{
				// Done
				unsigned short setId = ftp->setID;
				RakNet::OP_DELETE(ftp,_FILE_AND_LINE_);
				ftpr->filesToPush.Pop();

				if (ftpr->filesToPush.Size()==0)
				{
					for (unsigned int flpcIndex=0; flpcIndex < fileListTransfer->fileListProgressCallbacks.Size(); flpcIndex++)
						fileListTransfer->fileListProgressCallbacks[flpcIndex]->OnFilePushesComplete(systemAddress, setId);

					// Remove ftpr from fileToPushRecipientList
					fileListTransfer->RemoveFromList(ftpr);
				}
			}

			// ftpr out of scope
			ftpr->Deref();

			rakFree_Ex(buff, _FILE_AND_LINE_ );
			return 0;
		}
		else
		{
			ftpr->Deref();
			fileListTransfer->fileToPushRecipientListMutex.Lock();
		}
	}

	fileListTransfer->fileToPushRecipientListMutex.Unlock();

	return 0;
}
示例#28
0
void RakVoice::OpenChannel(Packet *packet)
{
	RakNet::BitStream in(packet->data, packet->length, false);
	in.IgnoreBits(8);

	FreeChannelMemory(packet->guid);

	VoiceChannel *channel=RakNet::OP_NEW<VoiceChannel>( __FILE__, __LINE__ );
	channel->guid=packet->guid;
	channel->isSendingVoiceData=false;
	int sampleRate;
	in.Read(sampleRate);
	channel->remoteSampleRate=sampleRate;

	if (channel->remoteSampleRate!=8000 && channel->remoteSampleRate!=16000 && channel->remoteSampleRate!=32000)
	{
#ifdef _DEBUG
		RakAssert(0);
#endif
		RakNet::OP_DELETE(channel, __FILE__, __LINE__);
		return;
	}

	if (sampleRate==8000)
		channel->enc_state=speex_encoder_init(&speex_nb_mode);
	else if (sampleRate==16000)
		channel->enc_state=speex_encoder_init(&speex_wb_mode);
	else // 32000
		channel->enc_state=speex_encoder_init(&speex_uwb_mode);

	if (channel->remoteSampleRate==8000)
		channel->dec_state=speex_decoder_init(&speex_nb_mode);
	else if (channel->remoteSampleRate==16000)
		channel->dec_state=speex_decoder_init(&speex_wb_mode);
	else // 32000
		channel->dec_state=speex_decoder_init(&speex_uwb_mode);

	// make sure encoder and decoder are created
	RakAssert((channel->enc_state)&&(channel->dec_state));

	int ret;
	ret=speex_encoder_ctl(channel->enc_state, SPEEX_GET_FRAME_SIZE, &channel->speexOutgoingFrameSampleCount);
	RakAssert(ret==0);
	channel->outgoingBuffer = (char*) rakMalloc_Ex(bufferSizeBytes * FRAME_OUTGOING_BUFFER_COUNT, __FILE__, __LINE__);
	channel->outgoingReadIndex=0;
	channel->outgoingWriteIndex=0;
	channel->bufferOutput=true;
	channel->outgoingMessageNumber=0;
	channel->copiedOutgoingBufferToBufferedOutput=false;

	ret=speex_decoder_ctl(channel->dec_state, SPEEX_GET_FRAME_SIZE, &channel->speexIncomingFrameSampleCount);
	RakAssert(ret==0);
	channel->incomingBuffer = (char*) rakMalloc_Ex(bufferSizeBytes * FRAME_INCOMING_BUFFER_COUNT, __FILE__, __LINE__);
	channel->incomingReadIndex=0;
	channel->incomingWriteIndex=0;
	channel->lastSend=0;
	channel->incomingMessageNumber=0;

	// Initialize preprocessor
	channel->pre_state = speex_preprocess_state_init(channel->speexOutgoingFrameSampleCount, sampleRate);
	RakAssert(channel->pre_state);

	// Set encoder default parameters
	SetEncoderParameter(channel->enc_state, SPEEX_SET_VBR, (defaultVBRState) ? 1 : 0 );
	SetEncoderParameter(channel->enc_state, SPEEX_SET_COMPLEXITY, defaultEncoderComplexity);
	// Set preprocessor default parameters
	SetPreprocessorParameter(channel->pre_state, SPEEX_PREPROCESS_SET_DENOISE, (defaultDENOISEState) ? 1 : 2);
	SetPreprocessorParameter(channel->pre_state, SPEEX_PREPROCESS_SET_VAD, (defaultVADState) ? 1 : 2);

	voiceChannels.Insert(packet->guid, channel, true, __FILE__, __LINE__);
}
示例#29
0
Packet* PacketizedTCP::Receive( void )
{
	PushNotificationsToQueues();

	unsigned int i;
	for (i=0; i < messageHandlerList.Size(); i++)
		messageHandlerList[i]->Update();

	Packet *outgoingPacket=ReturnOutgoingPacket();
	if (outgoingPacket)
		return outgoingPacket;

	Packet *incomingPacket;
	incomingPacket = TCPInterface::Receive();
	unsigned int index;

	while (incomingPacket)
	{
		if (connections.Has(incomingPacket->systemAddress))
			index = connections.GetIndexAtKey(incomingPacket->systemAddress);
		else
			index=(unsigned int) -1;
		if ((unsigned int)index==(unsigned int)-1)
		{
			DeallocatePacket(incomingPacket);
			incomingPacket = TCPInterface::Receive();
			continue;
		}


		if (incomingPacket->deleteData==true)
		{
			// Came from network
			SystemAddress systemAddressFromPacket;
			if (index < connections.Size())
			{
				DataStructures::ByteQueue *bq = connections[index];
				// Buffer data
				bq->WriteBytes((const char*) incomingPacket->data,incomingPacket->length, __FILE__,__LINE__);
				systemAddressFromPacket=incomingPacket->systemAddress;
				PTCPHeader dataLength;

				// Peek the header to see if a full message is waiting
				bq->ReadBytes((char*) &dataLength,sizeof(PTCPHeader),true);
				if (RakNet::BitStream::DoEndianSwap())
					RakNet::BitStream::ReverseBytesInPlace((unsigned char*) &dataLength,sizeof(dataLength));
				// Header indicates packet length. If enough data is available, read out and return one packet
				if (bq->GetBytesWritten()>=dataLength+sizeof(PTCPHeader))
				{
					do 
					{
						bq->IncrementReadOffset(sizeof(PTCPHeader));
						outgoingPacket = RakNet::OP_NEW<Packet>(__FILE__, __LINE__);
						outgoingPacket->length=dataLength;
						outgoingPacket->bitSize=BYTES_TO_BITS(dataLength);
						outgoingPacket->guid=UNASSIGNED_RAKNET_GUID;
						outgoingPacket->systemAddress=systemAddressFromPacket;
						outgoingPacket->deleteData=false; // Did not come from the network
						outgoingPacket->data=(unsigned char*) rakMalloc_Ex(dataLength, __FILE__, __LINE__);
						if (outgoingPacket->data==0)
						{
							notifyOutOfMemory(__FILE__, __LINE__);
							RakNet::OP_DELETE(outgoingPacket,__FILE__,__LINE__);
							return 0;
						}
						bq->ReadBytes((char*) outgoingPacket->data,dataLength,false);

						waitingPackets.Push(outgoingPacket, __FILE__, __LINE__ );

						// Peek the header to see if a full message is waiting
						if (bq->ReadBytes((char*) &dataLength,sizeof(PTCPHeader),true))
						{
							if (RakNet::BitStream::DoEndianSwap())
								RakNet::BitStream::ReverseBytesInPlace((unsigned char*) &dataLength,sizeof(dataLength));
						}
						else
							break;
					} while (bq->GetBytesWritten()>=dataLength+sizeof(PTCPHeader));
				}
				else
				{

					unsigned int oldWritten = bq->GetBytesWritten()-incomingPacket->length;
					unsigned int newWritten = bq->GetBytesWritten();

					// Return ID_DOWNLOAD_PROGRESS
					if (newWritten/65536!=oldWritten/65536)
					{
						outgoingPacket = RakNet::OP_NEW<Packet>(__FILE__, __LINE__);
						outgoingPacket->length=sizeof(MessageID) +
							sizeof(unsigned int)*2 +
							sizeof(unsigned int) +
							65536;
						outgoingPacket->bitSize=BYTES_TO_BITS(incomingPacket->length);
						outgoingPacket->guid=UNASSIGNED_RAKNET_GUID;
						outgoingPacket->systemAddress=incomingPacket->systemAddress;
						outgoingPacket->deleteData=false;
						outgoingPacket->data=(unsigned char*) rakMalloc_Ex(outgoingPacket->length, __FILE__, __LINE__);
						if (outgoingPacket->data==0)
						{
							notifyOutOfMemory(__FILE__, __LINE__);
							RakNet::OP_DELETE(outgoingPacket,__FILE__,__LINE__);
							return 0;
						}

						outgoingPacket->data[0]=(MessageID)ID_DOWNLOAD_PROGRESS;
						unsigned int totalParts=dataLength/65536;
						unsigned int partIndex=newWritten/65536;
						unsigned int oneChunkSize=65536;
						memcpy(outgoingPacket->data+sizeof(MessageID), &partIndex, sizeof(unsigned int));
						memcpy(outgoingPacket->data+sizeof(MessageID)+sizeof(unsigned int)*1, &totalParts, sizeof(unsigned int));
						memcpy(outgoingPacket->data+sizeof(MessageID)+sizeof(unsigned int)*2, &oneChunkSize, sizeof(unsigned int));
						bq->IncrementReadOffset(sizeof(PTCPHeader));
						bq->ReadBytes((char*) outgoingPacket->data+sizeof(MessageID)+sizeof(unsigned int)*3,oneChunkSize,true);
						bq->DecrementReadOffset(sizeof(PTCPHeader));

						waitingPackets.Push(outgoingPacket, __FILE__, __LINE__ );
					}
				}

			}

			DeallocatePacket(incomingPacket);
			incomingPacket=0;
		}
		else
			waitingPackets.Push(incomingPacket, __FILE__, __LINE__ );

		incomingPacket = TCPInterface::Receive();
	}

	return ReturnOutgoingPacket();
}