virtual void ExecuteDefaultResult(RakNet::Lobby2Message *message) { message->DebugPrintf(); if (message->resultCode==RakNet::REC_SUCCESS && executionPlan.Size()) { AutoExecutionPlanNode aepn = executionPlan.Pop(); ExecuteCommand(aepn.operation, RakNet::RakString("user%i", aepn.instanceNumber), aepn.instanceNumber); } }
void HuffmanEncodingTree::FreeMemory( void ) { if ( root == 0 ) return ; // Use an in-order traversal to delete the tree DataStructures::Queue<HuffmanEncodingTreeNode *> nodeQueue; HuffmanEncodingTreeNode *node; nodeQueue.Push( root ); while ( nodeQueue.Size() > 0 ) { node = nodeQueue.Pop(); if ( node->left ) nodeQueue.Push( node->left ); if ( node->right ) nodeQueue.Push( node->right ); delete node; } // Delete the encoding table for ( int i = 0; i < 256; i++ ) delete [] encodingTable[ i ].encoding; root = 0; }
void HuffmanEncodingTree::FreeMemory( void ) { if ( root == 0 ) return ; // Use an in-order traversal to delete the tree DataStructures::Queue<HuffmanEncodingTreeNode *> nodeQueue; HuffmanEncodingTreeNode *node; nodeQueue.Push( root, _FILE_AND_LINE_ ); while ( nodeQueue.Size() > 0 ) { node = nodeQueue.Pop(); if ( node->left ) nodeQueue.Push( node->left, _FILE_AND_LINE_ ); if ( node->right ) nodeQueue.Push( node->right, _FILE_AND_LINE_ ); RakNet::OP_DELETE(node, _FILE_AND_LINE_); } // Delete the encoding table for ( int i = 0; i < 256; i++ ) rakFree_Ex(encodingTable[ i ].encoding, _FILE_AND_LINE_ ); root = 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_AND_LINE_ ); RakAssert(dirSoFar); 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); } for (unsigned int flpcIndex=0; flpcIndex < fileListProgressCallbacks.Size(); flpcIndex++) fileListProgressCallbacks[flpcIndex]->OnAddFilesFromDirectoryStarted(this, dirSoFar); // RAKNET_DEBUG_PRINTF("Adding files from directory %s\n",dirSoFar); dirList.Push(dirSoFar, _FILE_AND_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_AND_LINE_ ); unsigned i; for (i=0; i < dirList.Size(); i++) rakFree_Ex(dirList[i], _FILE_AND_LINE_ ); return; } // RAKNET_DEBUG_PRINTF("Adding %s. %i remaining.\n", fullPath, dirList.Size()); for (unsigned int flpcIndex=0; flpcIndex < fileListProgressCallbacks.Size(); flpcIndex++) fileListProgressCallbacks[flpcIndex]->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; for (unsigned int flpcIndex=0; flpcIndex < fileListProgressCallbacks.Size(); flpcIndex++) fileListProgressCallbacks[flpcIndex]->OnFile(this, dirSoFar, fileInfo.name, fileInfo.size); if (writeData && writeHash) { fp = fopen(fullPath, "rb"); if (fp) { fileData= (char*) rakMalloc_Ex( fileInfo.size+HASH_LENGTH, _FILE_AND_LINE_ ); RakAssert(fileData); 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(); // DR_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_AND_LINE_ ); RakAssert(fileData); 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_AND_LINE_ ); } else if ((fileInfo.attrib & _A_SUBDIR) && (fileInfo.attrib & (_A_HIDDEN | _A_SYSTEM))==0 && recursive) { char *newDir=(char*) rakMalloc_Ex( 520, _FILE_AND_LINE_ ); RakAssert(newDir); strcpy(newDir, dirSoFar); strcat(newDir, fileInfo.name); strcat(newDir, "/"); dirList.Push(newDir, _FILE_AND_LINE_ ); } } while (_findnext(dir, &fileInfo ) != -1); _findclose(dir); rakFree_Ex(dirSoFar, _FILE_AND_LINE_ ); } }
void StatisticsHistory::TimeAndValueQueue::ResizeSampleSet( int maxSamples, DataStructures::Queue<StatisticsHistory::TimeAndValue> &histogram, SHDataCategory dataCategory, Time timeClipStart, Time timeClipEnd ) { histogram.Clear(_FILE_AND_LINE_); if (maxSamples==0) return; Time timeRange = GetTimeRange(); if (timeRange==0) return; if (maxSamples==1) { StatisticsHistory::TimeAndValue tav; tav.time = timeRange; tav.val = GetRecentSum(); histogram.Push(tav, _FILE_AND_LINE_); return; } Time interval = timeRange / maxSamples; if (interval==0) interval=1; unsigned int dataIndex; Time timeBoundary; StatisticsHistory::TimeAndValue currentSum; Time currentTime; SHValueType numSamples; Time endTime; numSamples=0; endTime = values[values.Size()-1].time; dataIndex=0; currentTime=values[0].time; currentSum.val=0; currentSum.time=values[0].time + interval / 2; timeBoundary = values[0].time + interval; while (timeBoundary <= endTime) { while (dataIndex < values.Size() && values[dataIndex].time <= timeBoundary) { currentSum.val += values[dataIndex].val; dataIndex++; numSamples++; } if (dataCategory==DC_CONTINUOUS) { if (dataIndex > 0 && dataIndex < values.Size() && values[dataIndex-1].time < timeBoundary && values[dataIndex].time > timeBoundary) { SHValueType interpolatedValue = Interpolate(values[dataIndex-1], values[dataIndex], timeBoundary); currentSum.val+=interpolatedValue; numSamples++; } if (numSamples > 1) { currentSum.val /= numSamples; } } histogram.Push(currentSum, _FILE_AND_LINE_); currentSum.time=timeBoundary + interval / 2; timeBoundary += interval; currentSum.val=0; numSamples=0; } if ( timeClipStart!=0 && histogram.Size()>=1) { timeClipStart = histogram.Peek().time+timeClipStart; if (histogram.PeekTail().time < timeClipStart) { histogram.Clear(_FILE_AND_LINE_); } else if (histogram.Size()>=2 && histogram.Peek().time < timeClipStart) { StatisticsHistory::TimeAndValue tav; do { tav = histogram.Pop(); if (histogram.Peek().time == timeClipStart) { break; } else if (histogram.Peek().time > timeClipStart) { StatisticsHistory::TimeAndValue tav2; tav2.val = StatisticsHistory::TimeAndValueQueue::Interpolate(tav, histogram.Peek(), timeClipStart); tav2.time=timeClipStart; histogram.PushAtHead(tav2, 0, _FILE_AND_LINE_); break; } } while (histogram.Size()>=2); } } if ( timeClipEnd!=0 && histogram.Size()>=1) { timeClipEnd = histogram.PeekTail().time-timeClipEnd; if (histogram.Peek().time > timeClipEnd) { histogram.Clear(_FILE_AND_LINE_); } else if (histogram.Size()>=2 && histogram.PeekTail().time > timeClipEnd) { StatisticsHistory::TimeAndValue tav; do { tav = histogram.PopTail(); if (histogram.PeekTail().time == timeClipEnd) { break; } else if (histogram.PeekTail().time < timeClipEnd) { StatisticsHistory::TimeAndValue tav2; tav2.val = StatisticsHistory::TimeAndValueQueue::Interpolate(tav, histogram.PeekTail(), timeClipEnd); tav2.time=timeClipEnd; histogram.Push(tav2, _FILE_AND_LINE_); break; } } while (histogram.Size()>=2); } } }
void StatisticsHistory::TimeAndValueQueue::MergeSets( const TimeAndValueQueue *lhs, SHDataCategory lhsDataCategory, const TimeAndValueQueue *rhs, SHDataCategory rhsDataCategory, TimeAndValueQueue *output ) { // Two ways to merge: // 1. Treat rhs as just more data points. // 1A. Sums are just added. If two values have the same time, just put in queue twice // 1B. longTermLowest and longTermHighest are the lowest and highest of the two sets // 2. Add by time. If time for the other set is missing, calculate slope to extrapolate // 2A. Have to recalculate recentSum, recentSumOfSquares. // 2B. longTermSum, longTermCount, longTermLowest, longTermHighest are unknown if (lhs!=output) { output->key = lhs->key; output->timeToTrackValues = lhs->timeToTrackValues; } else { output->key = rhs->key; output->timeToTrackValues = rhs->timeToTrackValues; } unsigned int lhsIndex, rhsIndex; lhsIndex=0; rhsIndex=0; // I use local valuesOutput in case lhs==output || rhs==output DataStructures::Queue<TimeAndValue> valuesOutput; if (lhsDataCategory==StatisticsHistory::DC_DISCRETE && rhsDataCategory==StatisticsHistory::DC_DISCRETE) { while (rhsIndex < rhs->values.Size() && lhsIndex < lhs->values.Size()) { if (rhs->values[rhsIndex].time < lhs->values[lhsIndex].time) { valuesOutput.Push(rhs->values[rhsIndex], _FILE_AND_LINE_ ); rhsIndex++; } else if (rhs->values[rhsIndex].time > lhs->values[lhsIndex].time) { valuesOutput.Push(lhs->values[rhsIndex], _FILE_AND_LINE_ ); lhsIndex++; } else { valuesOutput.Push(rhs->values[rhsIndex], _FILE_AND_LINE_ ); rhsIndex++; valuesOutput.Push(lhs->values[rhsIndex], _FILE_AND_LINE_ ); lhsIndex++; } } while (rhsIndex < rhs->values.Size()) { valuesOutput.Push(rhs->values[rhsIndex], _FILE_AND_LINE_ ); rhsIndex++; } while (lhsIndex < lhs->values.Size()) { valuesOutput.Push(lhs->values[lhsIndex], _FILE_AND_LINE_ ); lhsIndex++; } output->recentSum = lhs->recentSum + rhs->recentSum; output->recentSumOfSquares = lhs->recentSumOfSquares + rhs->recentSumOfSquares; output->longTermSum = lhs->longTermSum + rhs->longTermSum; output->longTermCount = lhs->longTermCount + rhs->longTermCount; if (lhs->longTermLowest < rhs->longTermLowest) output->longTermLowest = lhs->longTermLowest; else output->longTermLowest = rhs->longTermLowest; if (lhs->longTermHighest > rhs->longTermHighest) output->longTermHighest = lhs->longTermHighest; else output->longTermHighest = rhs->longTermHighest; } else { TimeAndValue lastTimeAndValueLhs, lastTimeAndValueRhs; lastTimeAndValueLhs.time=0; lastTimeAndValueLhs.val=0; lastTimeAndValueRhs.time=0; lastTimeAndValueRhs.val=0; SHValueType lastSlopeLhs=0; SHValueType lastSlopeRhs=0; Time timeSinceOppositeValue; TimeAndValue newTimeAndValue; while (rhsIndex < rhs->values.Size() && lhsIndex < lhs->values.Size()) { if (rhs->values[rhsIndex].time < lhs->values[lhsIndex].time) { timeSinceOppositeValue = rhs->values[rhsIndex].time - lastTimeAndValueLhs.time; newTimeAndValue.val = rhs->values[rhsIndex].val + lastTimeAndValueLhs.val + lastSlopeLhs * timeSinceOppositeValue; newTimeAndValue.time = rhs->values[rhsIndex].time; lastTimeAndValueRhs = rhs->values[rhsIndex]; if (rhsIndex>0 && rhs->values[rhsIndex].time != rhs->values[rhsIndex-1].time && rhsDataCategory==StatisticsHistory::DC_CONTINUOUS) lastSlopeRhs = (rhs->values[rhsIndex].val - rhs->values[rhsIndex-1].val) / (SHValueType) (rhs->values[rhsIndex].time - rhs->values[rhsIndex-1].time); rhsIndex++; } else if (lhs->values[lhsIndex].time < rhs->values[rhsIndex].time) { timeSinceOppositeValue = lhs->values[lhsIndex].time - lastTimeAndValueRhs.time; newTimeAndValue.val = lhs->values[lhsIndex].val + lastTimeAndValueRhs.val + lastSlopeRhs * timeSinceOppositeValue; newTimeAndValue.time = lhs->values[lhsIndex].time; lastTimeAndValueLhs = lhs->values[lhsIndex]; if (lhsIndex>0 && lhs->values[lhsIndex].time != lhs->values[lhsIndex-1].time && lhsDataCategory==StatisticsHistory::DC_CONTINUOUS) lastSlopeLhs = (lhs->values[lhsIndex].val - lhs->values[lhsIndex-1].val) / (SHValueType) (lhs->values[lhsIndex].time - lhs->values[lhsIndex-1].time); lhsIndex++; } else { newTimeAndValue.val = lhs->values[lhsIndex].val + rhs->values[rhsIndex].val; newTimeAndValue.time = lhs->values[lhsIndex].time; lastTimeAndValueRhs = rhs->values[rhsIndex]; lastTimeAndValueLhs = lhs->values[lhsIndex]; if (rhsIndex>0 && rhs->values[rhsIndex].time != rhs->values[rhsIndex-1].time && rhsDataCategory==StatisticsHistory::DC_CONTINUOUS) lastSlopeRhs = (rhs->values[rhsIndex].val - rhs->values[rhsIndex-1].val) / (SHValueType) (rhs->values[rhsIndex].time - rhs->values[rhsIndex-1].time); if (lhsIndex>0 && lhs->values[lhsIndex].time != lhs->values[lhsIndex-1].time && lhsDataCategory==StatisticsHistory::DC_CONTINUOUS) lastSlopeLhs = (lhs->values[lhsIndex].val - lhs->values[lhsIndex-1].val) / (SHValueType) (lhs->values[lhsIndex].time - lhs->values[lhsIndex-1].time); lhsIndex++; rhsIndex++; } valuesOutput.Push(newTimeAndValue, _FILE_AND_LINE_ ); } while (rhsIndex < rhs->values.Size()) { timeSinceOppositeValue = rhs->values[rhsIndex].time - lastTimeAndValueLhs.time; newTimeAndValue.val = rhs->values[rhsIndex].val + lastTimeAndValueLhs.val + lastSlopeLhs * timeSinceOppositeValue; newTimeAndValue.time = rhs->values[rhsIndex].time; valuesOutput.Push(newTimeAndValue, _FILE_AND_LINE_ ); rhsIndex++; } while (lhsIndex < lhs->values.Size()) { timeSinceOppositeValue = lhs->values[lhsIndex].time - lastTimeAndValueRhs.time; newTimeAndValue.val = lhs->values[lhsIndex].val + lastTimeAndValueRhs.val + lastSlopeRhs * timeSinceOppositeValue; newTimeAndValue.time = lhs->values[lhsIndex].time; valuesOutput.Push(newTimeAndValue, _FILE_AND_LINE_ ); lhsIndex++; } output->recentSum = 0; output->recentSumOfSquares = 0; for (unsigned int i=0; i < valuesOutput.Size(); i++) { output->recentSum += valuesOutput[i].val; output->recentSumOfSquares += valuesOutput[i].val * valuesOutput[i].val; } } output->values = valuesOutput; }
void UDPForwarder::UpdateThreaded(void) { fd_set readFD; //fd_set exceptionFD; FD_ZERO(&readFD); // FD_ZERO(&exceptionFD); timeval tv; int selectResult; tv.tv_sec=0; tv.tv_usec=0; RakNet::TimeMS curTime = RakNet::GetTimeMS(); SOCKET largestDescriptor=0; DataStructures::DefaultIndexType i; // Remove unused entries i=0; while (i < forwardList.GetSize()) { if (curTime > forwardList[i]->timeLastDatagramForwarded && // Account for timestamp wrap curTime > forwardList[i]->timeLastDatagramForwarded+forwardList[i]->timeoutOnNoDataMS) { RakNet::OP_DELETE(forwardList[i],_FILE_AND_LINE_); forwardList.RemoveAtIndex(i,_FILE_AND_LINE_); } else i++; } if (forwardList.GetSize()==0) return; for (i=0; i < forwardList.GetSize(); i++) { #ifdef _MSC_VER #pragma warning( disable : 4127 ) // warning C4127: conditional expression is constant #endif FD_SET(forwardList[i]->readSocket, &readFD); // FD_SET(forwardList[i]->readSocket, &exceptionFD); if (forwardList[i]->readSocket > largestDescriptor) largestDescriptor = forwardList[i]->readSocket; } #if defined(_PS3) || defined(__PS3__) || defined(SN_TARGET_PS3) #else selectResult=(int) select((int) largestDescriptor+1, &readFD, 0, 0, &tv); #endif char data[ MAXIMUM_MTU_SIZE ]; sockaddr_in sa; socklen_t len2; if (selectResult > 0) { DataStructures::Queue<ForwardEntry*> entriesToRead; ForwardEntry *feSource; for (i=0; i < forwardList.GetSize(); i++) { feSource = forwardList[i]; // I do this because I'm updating the forwardList, and don't want to lose FD_ISSET as the list is no longer in order if (FD_ISSET(feSource->readSocket, &readFD)) entriesToRead.Push(feSource,__FILE__,__LINE__); } while (entriesToRead.IsEmpty()==false) { feSource=entriesToRead.Pop(); const int flag=0; int receivedDataLen, len=0; unsigned short portnum=0; len2 = sizeof( sa ); sa.sin_family = AF_INET; receivedDataLen = recvfrom( feSource->readSocket, data, MAXIMUM_MTU_SIZE, flag, ( sockaddr* ) & sa, ( socklen_t* ) & len2 ); portnum = ntohs( sa.sin_port ); if (feSource->srcAndDest.source.binaryAddress==sa.sin_addr.s_addr) { if (feSource->updatedSourceAddress==false) { feSource->updatedSourceAddress=true; if (feSource->srcAndDest.source.port!=portnum) { // Remove both source and dest from list, update addresses, and reinsert in order DataStructures::DefaultIndexType sourceIndex, destIndex; SrcAndDest srcAndDest; srcAndDest.source=feSource->srcAndDest.destination; srcAndDest.destination=feSource->srcAndDest.source; destIndex=forwardList.GetIndexOf(srcAndDest); ForwardEntry *feDest = forwardList[destIndex]; forwardList.RemoveAtIndex(destIndex,__FILE__,__LINE__); srcAndDest.source=feSource->srcAndDest.source; srcAndDest.destination=feSource->srcAndDest.destination; sourceIndex=forwardList.GetIndexOf(srcAndDest); forwardList.RemoveAtIndex(sourceIndex,__FILE__,__LINE__); feSource->srcAndDest.source.port=portnum; feDest->srcAndDest.destination.port=portnum; feSource->timeLastDatagramForwarded=curTime; feDest->timeLastDatagramForwarded=curTime; forwardList.Push(feSource,feSource->srcAndDest,__FILE__,__LINE__); forwardList.Push(feDest,feDest->srcAndDest,__FILE__,__LINE__); } } if (feSource->srcAndDest.source.port==portnum) { // Forward to destination len=0; sockaddr_in saOut; saOut.sin_port = htons( feSource->srcAndDest.destination.port ); // User port saOut.sin_addr.s_addr = feSource->srcAndDest.destination.binaryAddress; saOut.sin_family = AF_INET; do { len = sendto( feSource->writeSocket, data, receivedDataLen, 0, ( const sockaddr* ) & saOut, sizeof( saOut ) ); } while ( len == 0 ); feSource->timeLastDatagramForwarded=curTime; } } } } }
bool RPC4::CallBlocking( const char* uniqueID, RakNet::BitStream * bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel, const AddressOrGUID systemIdentifier, RakNet::BitStream *returnData ) { RakNet::BitStream out; out.Write((MessageID) ID_RPC_PLUGIN); out.Write((MessageID) ID_RPC4_CALL); out.WriteCompressed(uniqueID); out.Write(true); // Blocking if (bitStream) { bitStream->ResetReadPointer(); out.AlignWriteToByteBoundary(); out.Write(bitStream); } RakAssert(returnData); RakAssert(rakPeerInterface); ConnectionState cs; cs = rakPeerInterface->GetConnectionState(systemIdentifier); if (cs!=IS_CONNECTED && cs!=IS_LOOPBACK) return false; SendUnified(&out,priority,reliability,orderingChannel,systemIdentifier,false); returnData->Reset(); blockingReturnValue.Reset(); gotBlockingReturnValue=false; Packet *packet; DataStructures::Queue<Packet*> packetQueue; while (gotBlockingReturnValue==false) { // TODO - block, filter until gotBlockingReturnValue==true or ID_CONNECTION_LOST or ID_DISCONNECTION_NOTIFICXATION or ID_RPC_REMOTE_ERROR/RPC_ERROR_FUNCTION_NOT_REGISTERED RakSleep(30); packet=rakPeerInterface->Receive(); if (packet) { if ( (packet->data[0]==ID_CONNECTION_LOST || packet->data[0]==ID_DISCONNECTION_NOTIFICATION) && ((systemIdentifier.rakNetGuid!=UNASSIGNED_RAKNET_GUID && packet->guid==systemIdentifier.rakNetGuid) || (systemIdentifier.systemAddress!=UNASSIGNED_SYSTEM_ADDRESS && packet->systemAddress==systemIdentifier.systemAddress)) ) { // Push back to head in reverse order rakPeerInterface->PushBackPacket(packet,true); while (packetQueue.Size()) rakPeerInterface->PushBackPacket(packetQueue.Pop(),true); return false; } else if (packet->data[0]==ID_RPC_REMOTE_ERROR && packet->data[1]==RPC_ERROR_FUNCTION_NOT_REGISTERED) { RakNet::RakString functionName; RakNet::BitStream bsIn(packet->data,packet->length,false); bsIn.IgnoreBytes(2); bsIn.Read(functionName); if (functionName==uniqueID) { // Push back to head in reverse order rakPeerInterface->PushBackPacket(packet,true); while (packetQueue.Size()) rakPeerInterface->PushBackPacket(packetQueue.Pop(),true); return false; } else { packetQueue.PushAtHead(packet,0,_FILE_AND_LINE_); } } else { packetQueue.PushAtHead(packet,0,_FILE_AND_LINE_); } } } returnData->Read(blockingReturnValue); return true; }
void UDPForwarder::UpdateThreaded_Old(void) { fd_set readFD; //fd_set exceptionFD; FD_ZERO(&readFD); // FD_ZERO(&exceptionFD); timeval tv; int selectResult; tv.tv_sec=0; tv.tv_usec=0; RakNet::TimeMS curTime = RakNet::GetTimeMS(); SOCKET largestDescriptor=0; DataStructures::DefaultIndexType i; // Remove unused entries i=0; while (i < forwardList.GetSize()) { if (curTime > forwardList[i]->timeLastDatagramForwarded && // Account for timestamp wrap curTime > forwardList[i]->timeLastDatagramForwarded+forwardList[i]->timeoutOnNoDataMS) { RakNet::OP_DELETE(forwardList[i],_FILE_AND_LINE_); forwardList.RemoveAtIndex(i,_FILE_AND_LINE_); } else i++; } if (forwardList.GetSize()==0) return; for (i=0; i < forwardList.GetSize(); i++) { #ifdef _MSC_VER #pragma warning( disable : 4127 ) // warning C4127: conditional expression is constant #endif FD_SET(forwardList[i]->socket, &readFD); // FD_SET(forwardList[i]->readSocket, &exceptionFD); if (forwardList[i]->socket > largestDescriptor) largestDescriptor = forwardList[i]->socket; } #if defined(_PS3) || defined(__PS3__) || defined(SN_TARGET_PS3) #else selectResult=(int) select((int) largestDescriptor+1, &readFD, 0, 0, &tv); #endif char data[ MAXIMUM_MTU_SIZE ]; sockaddr_in sa; socklen_t len2; if (selectResult > 0) { DataStructures::Queue<ForwardEntry*> entriesToRead; ForwardEntry *forwardEntry; for (i=0; i < forwardList.GetSize(); i++) { forwardEntry = forwardList[i]; // I do this because I'm updating the forwardList, and don't want to lose FD_ISSET as the list is no longer in order if (FD_ISSET(forwardEntry->socket, &readFD)) entriesToRead.Push(forwardEntry,_FILE_AND_LINE_); } while (entriesToRead.IsEmpty()==false) { forwardEntry=entriesToRead.Pop(); const int flag=0; int receivedDataLen, len=0; unsigned short portnum=0; len2 = sizeof( sa ); sa.sin_family = AF_INET; receivedDataLen = recvfrom( forwardEntry->socket, data, MAXIMUM_MTU_SIZE, flag, ( sockaddr* ) & sa, ( socklen_t* ) & len2 ); if (receivedDataLen<0) { #if defined(_WIN32) && defined(_DEBUG) && !defined(_XBOX) && !defined(X360) DWORD dwIOError = WSAGetLastError(); if (dwIOError!=WSAECONNRESET && dwIOError!=WSAEINTR && dwIOError!=WSAETIMEDOUT) { LPVOID messageBuffer; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), // Default language ( LPTSTR ) & messageBuffer, 0, NULL ); // something has gone wrong here... RAKNET_DEBUG_PRINTF( "recvfrom failed:Error code - %d\n%s", dwIOError, messageBuffer ); //Free the buffer. LocalFree( messageBuffer ); } #endif continue; } portnum = ntohs( sa.sin_port ); if (forwardEntry->srcAndDest.source.address.addr4.sin_addr.s_addr==sa.sin_addr.s_addr && forwardEntry->updatedSourcePort==false && forwardEntry->srcAndDest.dest.GetPort()!=portnum) { forwardEntry->updatedSourcePort=true; if (forwardEntry->srcAndDest.source.GetPort()!=portnum) { DataStructures::DefaultIndexType index; SrcAndDest srcAndDest(forwardEntry->srcAndDest.dest, forwardEntry->srcAndDest.source); index=forwardList.GetIndexOf(srcAndDest); forwardList.RemoveAtIndex(index,_FILE_AND_LINE_); forwardEntry->srcAndDest.source.SetPort(portnum); forwardList.Push(forwardEntry,forwardEntry->srcAndDest,_FILE_AND_LINE_); } } if (forwardEntry->srcAndDest.source.address.addr4.sin_addr.s_addr==sa.sin_addr.s_addr && forwardEntry->srcAndDest.source.GetPort()==portnum) { // Forward to dest len=0; sockaddr_in saOut; saOut.sin_port = forwardEntry->srcAndDest.dest.GetPortNetworkOrder(); // User port saOut.sin_addr.s_addr = forwardEntry->srcAndDest.dest.address.addr4.sin_addr.s_addr; saOut.sin_family = AF_INET; do { len = sendto( forwardEntry->socket, data, receivedDataLen, 0, ( const sockaddr* ) & saOut, sizeof( saOut ) ); } while ( len == 0 ); // printf("1. Forwarding after %i ms\n", curTime-forwardEntry->timeLastDatagramForwarded); forwardEntry->timeLastDatagramForwarded=curTime; } if (forwardEntry->srcAndDest.dest.address.addr4.sin_addr.s_addr==sa.sin_addr.s_addr && forwardEntry->updatedDestPort==false && forwardEntry->srcAndDest.source.GetPort()!=portnum) { forwardEntry->updatedDestPort=true; if (forwardEntry->srcAndDest.dest.GetPort()!=portnum) { DataStructures::DefaultIndexType index; SrcAndDest srcAndDest(forwardEntry->srcAndDest.source, forwardEntry->srcAndDest.dest); index=forwardList.GetIndexOf(srcAndDest); forwardList.RemoveAtIndex(index,_FILE_AND_LINE_); forwardEntry->srcAndDest.dest.SetPort(portnum); forwardList.Push(forwardEntry,forwardEntry->srcAndDest,_FILE_AND_LINE_); } } if (forwardEntry->srcAndDest.dest.address.addr4.sin_addr.s_addr==sa.sin_addr.s_addr && forwardEntry->srcAndDest.dest.GetPort()==portnum) { // Forward to source len=0; sockaddr_in saOut; saOut.sin_port = forwardEntry->srcAndDest.source.GetPortNetworkOrder(); // User port saOut.sin_addr.s_addr = forwardEntry->srcAndDest.source.address.addr4.sin_addr.s_addr; saOut.sin_family = AF_INET; do { len = sendto( forwardEntry->socket, data, receivedDataLen, 0, ( const sockaddr* ) & saOut, sizeof( saOut ) ); } while ( len == 0 ); // printf("2. Forwarding after %i ms\n", curTime-forwardEntry->timeLastDatagramForwarded); forwardEntry->timeLastDatagramForwarded=curTime; } } } }
void FileListTransfer::Send(FileList *fileList, RakPeerInterface *rakPeer, SystemAddress recipient, unsigned short setID, PacketPriority priority, char orderingChannel, bool compressData, IncrementalReadInterface *_incrementalReadInterface, unsigned int _chunkSize) { (void) compressData; if (callback) fileList->SetCallback(callback); unsigned int i, totalLength; RakNet::BitStream outBitstream; bool sendReference; const char *dataBlocks[2]; int lengths[2]; totalLength=0; for (i=0; i < fileList->fileList.Size(); i++) { const FileListNode &fileListNode = fileList->fileList[i]; totalLength+=fileListNode.fileLengthBytes; } // Write the chunk header, which contains the frequency table, the total number of files, and the total number of bytes bool anythingToWrite; outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_HEADER); outBitstream.Write(setID); anythingToWrite=fileList->fileList.Size()>0; outBitstream.Write(anythingToWrite); if (anythingToWrite) { outBitstream.WriteCompressed(fileList->fileList.Size()); outBitstream.WriteCompressed(totalLength); if (rakPeer) rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); else SendUnified(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); DataStructures::Queue<FileToPush*> filesToPush; for (i=0; i < fileList->fileList.Size(); i++) { sendReference = fileList->fileList[i].isAReference && _incrementalReadInterface!=0; if (sendReference) { FileToPush *fileToPush = RakNet::OP_NEW<FileToPush>(__FILE__,__LINE__); fileToPush->fileListNode.context=fileList->fileList[i].context; fileToPush->setIndex=i; fileToPush->fileListNode.filename=fileList->fileList[i].filename; fileToPush->fileListNode.fullPathToFile=fileList->fileList[i].fullPathToFile; fileToPush->fileListNode.fileLengthBytes=fileList->fileList[i].fileLengthBytes; fileToPush->fileListNode.dataLengthBytes=fileList->fileList[i].dataLengthBytes; // fileToPush->systemAddress=recipient; fileToPush->setID=setID; fileToPush->packetPriority=priority; fileToPush->orderingChannel=orderingChannel; fileToPush->currentOffset=0; fileToPush->incrementalReadInterface=_incrementalReadInterface; fileToPush->chunkSize=_chunkSize; filesToPush.Push(fileToPush,__FILE__,__LINE__); } else { outBitstream.Reset(); outBitstream.Write((MessageID)ID_FILE_LIST_TRANSFER_FILE); outBitstream.Write(fileList->fileList[i].context); outBitstream.Write(setID); stringCompressor->EncodeString(fileList->fileList[i].filename, 512, &outBitstream); outBitstream.WriteCompressed(i); outBitstream.WriteCompressed(fileList->fileList[i].dataLengthBytes); // Original length in bytes outBitstream.AlignWriteToByteBoundary(); dataBlocks[0]=(char*) outBitstream.GetData(); lengths[0]=outBitstream.GetNumberOfBytesUsed(); dataBlocks[1]=fileList->fileList[i].data; lengths[1]=fileList->fileList[i].dataLengthBytes; SendListUnified(dataBlocks,lengths,2,priority, RELIABLE_ORDERED, orderingChannel, recipient, false); } } if (filesToPush.IsEmpty()==false) { FileToPushRecipient *ftpr=0; filesToPushAllSameAddressMutex.Lock(); for (unsigned int i=0; i < filesToPushAllSameAddress.Size(); i++) { if (filesToPushAllSameAddress[i]->systemAddress==recipient) { ftpr=filesToPushAllSameAddress[i]; break; } } if (ftpr==0) { ftpr = RakNet::OP_NEW<FileToPushRecipient>(__FILE__,__LINE__); ftpr->systemAddress=recipient; filesToPushAllSameAddress.Push(ftpr, __FILE__,__LINE__); } while (filesToPush.IsEmpty()==false) { ftpr->filesToPush.Push(filesToPush.Pop(), __FILE__,__LINE__); } filesToPushAllSameAddressMutex.Unlock(); SendIRIToAddress(recipient); return; } } else { if (rakPeer) rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); else SendUnified(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); } }
int main() { printf("This sample creates two Lobby2Clients.\n"); printf("They both connect to the server and performs queued operations on startup."); printf("(RANKING AND CLANS NOT YET DONE).\n"); printf("Difficulty: Advanced\n\n"); RakNet::Lobby2ResultCodeDescription::Validate(); /// Do all these operations in this order once we are logged in. /// This is for easier testing. /// This plan will create the database, register two users, and log them both in executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_System_CreateDatabase), _FILE_AND_LINE_ ); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_System_CreateTitle), _FILE_AND_LINE_ ); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_CDKey_Add), _FILE_AND_LINE_ ); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_System_RegisterProfanity), _FILE_AND_LINE_ ); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Client_RegisterAccount), _FILE_AND_LINE_ ); executionPlan.Push(AutoExecutionPlanNode(1, RakNet::L2MID_Client_RegisterAccount), _FILE_AND_LINE_ ); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_System_SetEmailAddressValidated), _FILE_AND_LINE_ ); executionPlan.Push(AutoExecutionPlanNode(1, RakNet::L2MID_System_SetEmailAddressValidated), _FILE_AND_LINE_ ); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Client_Login), _FILE_AND_LINE_ ); executionPlan.Push(AutoExecutionPlanNode(1, RakNet::L2MID_Client_Login), _FILE_AND_LINE_ ); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Emails_Send), _FILE_AND_LINE_ ); executionPlan.Push(AutoExecutionPlanNode(1, RakNet::L2MID_Emails_Get), _FILE_AND_LINE_ ); // /// Create 2 clans // executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_Create), _FILE_AND_LINE_ ); // executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_Create), _FILE_AND_LINE_ ); // // Invite to both // executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_SendJoinInvitation), _FILE_AND_LINE_ ); // executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_SendJoinInvitation), _FILE_AND_LINE_ ); // executionPlan.Push(AutoExecutionPlanNode(1, RakNet::L2MID_Clans_RejectJoinInvitation), _FILE_AND_LINE_ ); // // Download invitations this clan has sent // executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_DownloadInvitationList), _FILE_AND_LINE_ ); /* executionPlan.Push(AutoExecutionPlanNode(1, RakNet::L2MID_Client_SetPresence), _FILE_AND_LINE_ ); executionPlan.Push(AutoExecutionPlanNode(1, RakNet::L2MID_Client_GetAccountDetails), _FILE_AND_LINE_ ); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Client_PerTitleIntegerStorage), _FILE_AND_LINE_ ); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Client_PerTitleIntegerStorage), _FILE_AND_LINE_ ); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Client_StartIgnore), _FILE_AND_LINE_ ); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Client_GetIgnoreList), _FILE_AND_LINE_ ); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Friends_SendInvite), _FILE_AND_LINE_); executionPlan.Push(AutoExecutionPlanNode(1, RakNet::L2MID_Friends_AcceptInvite), _FILE_AND_LINE_); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Ranking_SubmitMatch)); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Ranking_SubmitMatch)); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Ranking_UpdateRating)); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Ranking_GetRating)); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Ranking_WipeRatings)); */ // executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_Create), _FILE_AND_LINE_ ); // executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_Get), _FILE_AND_LINE_ ); /* executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_SetProperties)); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_SetMyMemberProperties)); */ /* executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_SendJoinInvitation)); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_WithdrawJoinInvitation)); executionPlan.Push(AutoExecutionPlanNode(1, RakNet::L2MID_Clans_DownloadInvitationList)); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_SendJoinInvitation)); executionPlan.Push(AutoExecutionPlanNode(1, RakNet::L2MID_Clans_RejectJoinInvitation)); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_SendJoinInvitation)); executionPlan.Push(AutoExecutionPlanNode(1, RakNet::L2MID_Clans_AcceptJoinInvitation)); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_SetSubleaderStatus)); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_SetMemberRank)); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_GrantLeader)); */ /* executionPlan.Push(AutoExecutionPlanNode(1, RakNet::L2MID_Clans_SendJoinRequest)); executionPlan.Push(AutoExecutionPlanNode(1, RakNet::L2MID_Clans_WithdrawJoinRequest)); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_AcceptJoinRequest)); */ // executionPlan.Push(AutoExecutionPlanNode(1, RakNet::L2MID_Clans_SendJoinRequest)); // executionPlan.Push(AutoExecutionPlanNode(1, RakNet::L2MID_Clans_DownloadRequestList)); // TODO - test from here /* executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_RejectJoinRequest)); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_AcceptJoinRequest)); executionPlan.Push(AutoExecutionPlanNode(1, RakNet::L2MID_Clans_SendJoinRequest)); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_AcceptJoinRequest)); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_KickAndBlacklistUser)); executionPlan.Push(AutoExecutionPlanNode(1, RakNet::L2MID_Clans_SendJoinRequest)); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_GetBlacklist)); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_UnblacklistUser)); executionPlan.Push(AutoExecutionPlanNode(1, RakNet::L2MID_Clans_SendJoinRequest)); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_AcceptJoinRequest)); executionPlan.Push(AutoExecutionPlanNode(0, RakNet::L2MID_Clans_GetMembers)); */ /* // TODO L2MID_Clans_CreateBoard, L2MID_Clans_DestroyBoard, L2MID_Clans_CreateNewTopic, L2MID_Clans_ReplyToTopic, L2MID_Clans_RemovePost, L2MID_Clans_GetBoards, L2MID_Clans_GetTopics, L2MID_Clans_GetPosts, */ char ip[64], serverPort[30], clientPort[30]; int i; for (i=0; i < NUM_CONNECTIONS; i++) rakPeer[i]=RakNet::RakPeerInterface::GetInstance(); puts("Enter the rakPeer1 port to listen on"); clientPort[0]=0; RakNet::SocketDescriptor socketDescriptor(atoi(clientPort),0); Gets(clientPort,sizeof(clientPort)); if (clientPort[0]==0) strcpy(clientPort, "0"); puts("Enter IP to connect to");; ip[0]=0; Gets(ip,sizeof(ip)); if (ip[0]==0) strcpy(ip, "127.0.0.1"); puts("Enter the port to connect to"); serverPort[0]=0; Gets(serverPort,sizeof(serverPort)); if (serverPort[0]==0) strcpy(serverPort, "61111"); for (i=0; i < NUM_CONNECTIONS; i++) { rakPeer[i]->Startup(1,&socketDescriptor, 1); rakPeer[i]->Connect(ip, atoi(serverPort), 0,0); rakPeer[i]->AttachPlugin(&lobby2Client[i]); lobby2Client[i].SetMessageFactory(&messageFactory); lobby2Client[i].SetCallbackInterface(&callback[i]); testUserName[i]=RakNet::RakString("user%i", i); } RakNet::Packet *packet; // Loop for input while (1) { for (i=0; i < NUM_CONNECTIONS; i++) { RakNet::RakPeerInterface *peer = rakPeer[i]; for (packet=peer->Receive(); packet; peer->DeallocatePacket(packet), packet=peer->Receive()) { switch (packet->data[0]) { case ID_DISCONNECTION_NOTIFICATION: // Connection lost normally printf("ID_DISCONNECTION_NOTIFICATION\n"); break; case ID_ALREADY_CONNECTED: // Connection lost normally printf("ID_ALREADY_CONNECTED\n"); break; case ID_CONNECTION_BANNED: // Banned from this server printf("We are banned from this server.\n"); break; case ID_CONNECTION_ATTEMPT_FAILED: printf("Connection attempt failed\n"); break; case ID_NO_FREE_INCOMING_CONNECTIONS: // Sorry, the server is full. I don't do anything here but // A real app should tell the user printf("ID_NO_FREE_INCOMING_CONNECTIONS\n"); break; case ID_INVALID_PASSWORD: printf("ID_INVALID_PASSWORD\n"); break; case ID_CONNECTION_LOST: // Couldn't deliver a reliable packet - i.e. the other system was abnormally // terminated printf("ID_CONNECTION_LOST\n"); break; case ID_CONNECTION_REQUEST_ACCEPTED: // This tells the rakPeer1 they have connected printf("ID_CONNECTION_REQUEST_ACCEPTED\n"); int j; for (j=0; j < NUM_CONNECTIONS; j++) lobby2Client[j].SetServerAddress(packet->systemAddress); if (i==NUM_CONNECTIONS-1) { PrintCommands(&messageFactory); printf("Enter instance number 1 to %i followed by command number.\n", NUM_CONNECTIONS); if (executionPlan.Size()) { /// Execute the first command now that both clients have connected. AutoExecutionPlanNode aepn = executionPlan.Pop(); ExecuteCommand(aepn.operation, RakNet::RakString("user%i", aepn.instanceNumber), aepn.instanceNumber); } } break; case ID_LOBBY2_SERVER_ERROR: { RakNet::BitStream bs(packet->data,packet->length,false); bs.IgnoreBytes(2); // ID_LOBBY2_SERVER_ERROR and error code printf("ID_LOBBY2_SERVER_ERROR: "); if (packet->data[1]==RakNet::L2SE_UNKNOWN_MESSAGE_ID) { unsigned int messageId; bs.Read(messageId); printf("L2SE_UNKNOWN_MESSAGE_ID %i", messageId); } else printf("Unknown"); printf("\n"); } break; } } } // This sleep keeps RakNet responsive RakSleep(30); if (kbhit()) { char ch = getch(); if (ch <= '0' || ch > '9') { printf("Bad instance number\n"); continue; } int instanceNumber = ch - 1 - '0'; if (instanceNumber >= NUM_CONNECTIONS) { printf("Enter between 1 and %i to pick the instance of RakPeer to run\n", 1+NUM_CONNECTIONS); continue; } printf("Enter message number or 'quit' to quit.\n"); char str[128]; Gets(str, sizeof(str)); if (_stricmp(str, "quit")==0) { printf("Quitting.\n"); break; } else { int command = atoi(str); if (command <=0 || command > RakNet::L2MID_COUNT) { printf("Invalid message index %i. Commands:\n", command); PrintCommands(&messageFactory); } else { ExecuteCommand((RakNet::Lobby2MessageID)(command-1), RakNet::RakString("user%i", instanceNumber), instanceNumber); } } } } for (i=0; i < NUM_CONNECTIONS; i++) RakNet::RakPeerInterface::DestroyInstance(rakPeer[i]); return 0; }
void FileListTransfer::Send(FileList *fileList, RakPeerInterface *rakPeer, PlayerID recipient, unsigned short setID, PacketPriority priority, char orderingChannel, bool compressData) { RakNet::BitStream outBitstream, encodedData; HuffmanEncodingTree tree; unsigned int frequencyTable[ 256 ]; unsigned int i,j; unsigned totalCompressedLength, totalLength; DataStructures::Queue<FileListNode> compressedFiles; FileListNode n; if (compressData) { memset(frequencyTable,0,256*sizeof(unsigned int)); for (i=0; i < fileList->fileList.Size(); i++) { for (j=0; j < fileList->fileList[i].dataLength; j++) { ++frequencyTable[(unsigned char)(fileList->fileList[i].data[j])]; } } tree.GenerateFromFrequencyTable(frequencyTable); // Compress all the files, so we know the total compressed size to be sent totalCompressedLength=totalLength=0; for (i=0; i < fileList->fileList.Size(); i++) { encodedData.Reset(); // Why send compressed chunks if we are not sending the whole file? assert(fileList->fileList[i].fileLength==fileList->fileList[i].fileLength); tree.EncodeArray((unsigned char*)fileList->fileList[i].data, fileList->fileList[i].dataLength, &encodedData); n.dataLength=encodedData.GetNumberOfBitsUsed(); totalCompressedLength+=BITS_TO_BYTES(n.dataLength); totalLength+=fileList->fileList[i].fileLength; n.data = new char[BITS_TO_BYTES(n.dataLength)]; memcpy(n.data, encodedData.GetData(), BITS_TO_BYTES(n.dataLength)); compressedFiles.Push(n); } } // Write the chunk header, which contains the frequency table, the total number of files, and the total number of bytes bool anythingToWrite; outBitstream.Write((unsigned char)ID_FILE_LIST_TRANSFER_HEADER); outBitstream.Write(setID); anythingToWrite=fileList->fileList.Size()>0; outBitstream.Write(anythingToWrite); if (anythingToWrite) { if (compressData) { outBitstream.Write(true); for (i=0; i < 256; i++) outBitstream.WriteCompressed(frequencyTable[i]); outBitstream.WriteCompressed(fileList->fileList.Size()); outBitstream.WriteCompressed(totalLength); outBitstream.WriteCompressed(totalCompressedLength); } else { outBitstream.Write(false); outBitstream.WriteCompressed(fileList->fileList.Size()); outBitstream.WriteCompressed(totalLength); } rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); // Send each possibly compressed file for (i=0; i < compressedFiles.Size(); i++) { outBitstream.Reset(); outBitstream.Write((unsigned char)ID_FILE_LIST_TRANSFER_FILE); outBitstream.Write(fileList->fileList[i].context); outBitstream.Write(setID); outBitstream.WriteCompressed(i); outBitstream.WriteCompressed(fileList->fileList[i].dataLength); // Original length if (compressData) outBitstream.WriteCompressed(compressedFiles[i].dataLength); // Compressed bitlength } stringCompressor->EncodeString(fileList->fileList[i].filename, 512, &outBitstream); if (compressData) { outBitstream.WriteBits((const unsigned char*)compressedFiles[i].data, compressedFiles[i].dataLength); delete [] compressedFiles[i].data; } else outBitstream.WriteBits((const unsigned char*)fileList->fileList[i].data, fileList->fileList[i].dataLength); rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); } } else rakPeer->Send(&outBitstream, priority, RELIABLE_ORDERED, orderingChannel, recipient, false); }
void FileList::AddFilesFromDirectory(const char *applicationDirectory, const char *subDirectory, bool writeHash, bool writeData, bool recursive, unsigned char context) { #ifndef _COMPATIBILITY_2 DataStructures::Queue<char*> dirList; char root[260]; char fullPath[520]; _finddata_t fileInfo; intptr_t dir; int file; FILE *fp; CSHA1 sha1; char *dirSoFar, *fileData; dirSoFar=new char[520]; if (applicationDirectory) strcpy(root, applicationDirectory); else root[0]=0; int rootLen=(int)strlen(root); if (rootLen) { strcpy(dirSoFar, root); if (dirSoFar[strlen(dirSoFar)-1]!='/' && dirSoFar[strlen(dirSoFar)-1]!='\\') { strcat(dirSoFar, "/"); rootLen++; } } else dirSoFar[0]=0; if (subDirectory) { strcat(dirSoFar, subDirectory); if (dirSoFar[strlen(dirSoFar)-1]!='/' && dirSoFar[strlen(dirSoFar)-1]!='\\') { strcat(dirSoFar, "/"); } } dirList.Push(dirSoFar); while (dirList.Size()) { dirSoFar=dirList.Pop(); strcpy(fullPath, dirSoFar); strcat(fullPath, "*.*"); dir=_findfirst(fullPath, &fileInfo ); // Read . if (dir==-1) { _findclose(dir); delete [] dirSoFar; unsigned i; for (i=0; i < dirList.Size(); i++) delete [] dirList[i]; return; } file=_findnext(dir, &fileInfo ); // Read .. file=_findnext(dir, &fileInfo ); // Skip .. while (file!=-1) { if ((fileInfo.attrib & (_A_HIDDEN | _A_SUBDIR | _A_SYSTEM))==0) { strcpy(fullPath, dirSoFar); strcat(fullPath, fileInfo.name); if (writeData && writeHash) fileData= new char [fileInfo.size+SHA1_LENGTH]; else fileData= new char [fileInfo.size]; fp = fopen(fullPath, "rb"); if (writeData && writeHash) fread(fileData+SHA1_LENGTH, fileInfo.size, 1, fp); else fread(fileData, fileInfo.size, 1, fp); fclose(fp); if (writeData && writeHash) { sha1.Reset(); sha1.Update( ( unsigned char* ) fileData+SHA1_LENGTH, fileInfo.size ); sha1.Final(); memcpy(fileData, sha1.GetHash(), SHA1_LENGTH); AddFile((const char*)fullPath+rootLen, fileData, fileInfo.size+SHA1_LENGTH, fileInfo.size, context); } else if (writeHash) { sha1.Reset(); sha1.Update( ( unsigned char* ) fileData, fileInfo.size ); sha1.Final(); AddFile((const char*)fullPath+rootLen, (const char*)sha1.GetHash(), SHA1_LENGTH, fileInfo.size, context); } else if (writeData) { AddFile(fullPath+rootLen, fileData, fileInfo.size, fileInfo.size, context); } else AddFile(fullPath+rootLen, 0, 0, fileInfo.size, context); delete [] fileData; } else if ((fileInfo.attrib & _A_SUBDIR) && (fileInfo.attrib & (_A_HIDDEN | _A_SYSTEM))==0 && recursive) { char *newDir=new char[520]; strcpy(newDir, dirSoFar); strcat(newDir, fileInfo.name); strcat(newDir, "/"); dirList.Push(newDir); } file=_findnext(dir, &fileInfo ); } _findclose(dir); delete [] dirSoFar; } #endif }
void FileListTransfer::Send(FileList *fileList, SLNet::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; SLNet::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 = SLNet::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 (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 = SLNet::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); } }