void VariadicSQLParser::GetTypeMappingIndices( const char *format, DataStructures::List<IndexAndType> &indices ) { bool previousCharWasPercentSign; unsigned int i; unsigned int typeMappingIndex; indices.Clear(false, _FILE_AND_LINE_); unsigned int len = (unsigned int) strlen(format); previousCharWasPercentSign=false; for (i=0; i < len; i++) { if (previousCharWasPercentSign==true ) { typeMappingIndex = GetTypeMappingIndex(format[i]); if (typeMappingIndex!=(unsigned int) -1) { IndexAndType iat; iat.strIndex=i-1; iat.typeMappingIndex=typeMappingIndex; indices.Insert(iat, _FILE_AND_LINE_ ); } } previousCharWasPercentSign=format[i]=='%'; } }
void LightweightDatabaseServer::RemoveRowsFromIP(PlayerID playerId) { // Remove rows for tables that do so on a system disconnect DatabaseTable *databaseTable; DataStructures::List<unsigned> removeList; DataStructures::Page<unsigned, DataStructures::Table::Row*, _TABLE_BPLUS_TREE_ORDER> *cur; unsigned i,j; for (i=0; i < database.Size(); i++) { databaseTable=database[i]; if (databaseTable->removeRowOnDisconnect) { DataStructures::BPlusTree<unsigned, DataStructures::Table::Row*, _TABLE_BPLUS_TREE_ORDER> &rows = databaseTable->table.GetRows(); cur = rows.GetListHead(); while (cur) { // Mark dropped entities for (j=0; j < (unsigned)cur->size; j++) { if (RowHasIP(cur->data[j], playerId, databaseTable->systemIdColumnIndex)) removeList.Insert(cur->keys[j]); } cur=cur->next; } for (j=0; j < removeList.Size(); j++) databaseTable->table.RemoveRow(removeList[i]); removeList.Clear(true); } } }
void StatisticsHistory::GetUniqueKeyList(DataStructures::List<RakString> &keys) { keys.Clear(true, _FILE_AND_LINE_); for (unsigned int idx=0; idx < objects.Size(); idx++) { TrackedObject *to = objects[idx]; DataStructures::List<TimeAndValueQueue*> itemList; DataStructures::List<RakNet::RakString> keyList; to->dataQueues.GetAsList(itemList, keyList, _FILE_AND_LINE_); for (unsigned int k=0; k < keyList.Size(); k++) { bool hasKey=false; for (unsigned int j=0; j < keys.Size(); j++) { if (keys[j]==keyList[k]) { hasKey=true; break; } } if (hasKey==false) keys.Push(keyList[k], _FILE_AND_LINE_); } } }
void FullyConnectedMesh2::GetVerifiedJoinAcceptedAdditionalData(Packet *packet, bool *thisSystemAccepted, DataStructures::List<RakNetGUID> &systemsAccepted, BitStream *additionalData) { systemsAccepted.Clear(true, _FILE_AND_LINE_); RakNet::BitStream bsIn(packet->data, packet->length, false); bsIn.IgnoreBytes(sizeof(MessageID)); RakNetGUID systemToAddGuid; bsIn.Read(systemToAddGuid); *thisSystemAccepted = systemToAddGuid == rakPeerInterface->GetMyGUID(); unsigned short listSize; bsIn.Read(listSize); bsIn.IgnoreBytes(listSize*RakNetGUID::size()); bsIn.Read(listSize); if (systemToAddGuid==rakPeerInterface->GetMyGUID()) { for (unsigned short i=0; i < listSize; i++) { bsIn.Read(systemToAddGuid); systemsAccepted.Push(systemToAddGuid, _FILE_AND_LINE_); } systemsAccepted.Push(packet->guid, _FILE_AND_LINE_); } else { systemsAccepted.Push(systemToAddGuid, _FILE_AND_LINE_); bsIn.IgnoreBytes(listSize*RakNetGUID::size()); } if (additionalData) { additionalData->Reset(); additionalData->Write(bsIn); } }
void GridSectorizer::GetEntries(DataStructures::List<void*>& intersectionList, const float minX, const float minY, const float maxX, const float maxY) { #ifdef _USE_ORDERED_LIST DataStructures::OrderedList<void*, void*>* cell; #else DataStructures::List<void*>* cell; #endif int xStart, yStart, xEnd, yEnd, xCur, yCur; unsigned index; xStart=WorldToCellXOffsetAndClamped(minX); yStart=WorldToCellYOffsetAndClamped(minY); xEnd=WorldToCellXOffsetAndClamped(maxX); yEnd=WorldToCellYOffsetAndClamped(maxY); intersectionList.Clear(true, _FILE_AND_LINE_); for (xCur=xStart; xCur <= xEnd; ++xCur) { for (yCur=yStart; yCur <= yEnd; ++yCur) { cell = grid+yCur*gridCellWidthCount+xCur; for (index=0; index < cell->Size(); ++index) intersectionList.Insert(cell->operator [](index), _FILE_AND_LINE_); } } }
void FullyConnectedMesh2::GetParticipantList(DataStructures::List<RakNetGUID> &participantList) { participantList.Clear(true, _FILE_AND_LINE_); unsigned int i; for (i=0; i < fcm2ParticipantList.Size(); i++) participantList.Push(fcm2ParticipantList[i].rakNetGuid, _FILE_AND_LINE_); }
void TeamBalancer::GetOverpopulatedTeams(DataStructures::List<TeamId> &overpopulatedTeams, int maxTeamSize) { overpopulatedTeams.Clear(true,_FILE_AND_LINE_); for (TeamId i=0; i < teamMemberCounts.Size(); i++) { if (teamMemberCounts[i]>=maxTeamSize) overpopulatedTeams.Push(i,_FILE_AND_LINE_); } }
void FullyConnectedMesh2::GetVerifiedJoinRequiredProcessingList(RakNetGUID host, DataStructures::List<SystemAddress> &addresses, DataStructures::List<RakNetGUID> &guids) { addresses.Clear(true, _FILE_AND_LINE_); guids.Clear(true, _FILE_AND_LINE_); unsigned int curIndex = GetJoinsInProgressIndex(host); if (curIndex!=(unsigned int) -1) { VerifiedJoinInProgress *vjip = joinsInProgress[curIndex]; unsigned int j; for (j=0; j < vjip->members.Size(); j++) { if (vjip->members[j].joinInProgressState==JIPS_PROCESSING) { addresses.Push(vjip->members[j].systemAddress, _FILE_AND_LINE_); guids.Push(vjip->members[j].guid, _FILE_AND_LINE_); } } } }
void NatPunchthrough::ConnectionRequest::GetAddressList(RakPeerInterface *rakPeer, DataStructures::List<SystemAddress> &fallbackAddresses, SystemAddress publicAddress, SystemAddress privateAddress, bool excludeConnected) { SystemAddress fallback; fallbackAddresses.Clear(true); fallback.binaryAddress=publicAddress.binaryAddress; fallback.port=publicAddress.port; if (excludeConnected==false || rakPeer->IsConnected(fallback,true)==false) fallbackAddresses.Insert(fallback); if (privateAddress!=publicAddress && privateAddress!=UNASSIGNED_SYSTEM_ADDRESS && (excludeConnected==false ||rakPeer->IsConnected(privateAddress,true)==false)) fallbackAddresses.Insert(privateAddress); fallback.port=publicAddress.port+1; if (excludeConnected==false || rakPeer->IsConnected(fallback,true)==false) fallbackAddresses.Insert(fallback); fallback.port=publicAddress.port+2; if (excludeConnected==false || rakPeer->IsConnected(fallback,true)==false) fallbackAddresses.Insert(fallback); fallback.port=rakPeer->GetInternalID().port; if (fallbackAddresses.GetIndexOf(fallback)==(unsigned) -1 && (excludeConnected==false || rakPeer->IsConnected(fallback,true)==false)) fallbackAddresses.Insert(fallback); fallback.port=rakPeer->GetInternalID().port+1; if (fallbackAddresses.GetIndexOf(fallback)==(unsigned) -1 && (excludeConnected==false || rakPeer->IsConnected(fallback,true)==false)) fallbackAddresses.Insert(fallback); fallback.port=rakPeer->GetInternalID().port+2; if (fallbackAddresses.GetIndexOf(fallback)==(unsigned) -1 && (excludeConnected==false || rakPeer->IsConnected(fallback,true)==false)) fallbackAddresses.Insert(fallback); // Try to keep down the number of fallbacks or the router may run out of mappings /* fallback.port=publicAddress.port+3; if (excludeConnected==false || rakPeer->IsConnected(fallback,true)==false) fallbackAddresses.Insert(fallback); fallback.port=publicAddress.port+4; if (excludeConnected==false || rakPeer->IsConnected(fallback,true)==false) fallbackAddresses.Insert(fallback); fallback.port=rakPeer->GetInternalID().port+3; if (fallbackAddresses.GetIndexOf(fallback)==(unsigned) -1 && (excludeConnected==false || rakPeer->IsConnected(fallback,true)==false)) fallbackAddresses.Insert(fallback); fallback.port=rakPeer->GetInternalID().port+4; if (fallbackAddresses.GetIndexOf(fallback)==(unsigned) -1 && (excludeConnected==false || rakPeer->IsConnected(fallback,true)==false)) fallbackAddresses.Insert(fallback); */ }
void LightweightDatabaseServer::RemoveRowsFromIP(SystemAddress systemAddress) { // Remove rows for tables that do so on a system disconnect DatabaseTable *databaseTable; DataStructures::List<unsigned> removeList; DataStructures::Table::Row* row; DataStructures::Page<unsigned, DataStructures::Table::Row*, _TABLE_BPLUS_TREE_ORDER> *cur; unsigned i,j; for (i=0; i < database.Size(); i++) { databaseTable=database[i]; if ((unsigned int) databaseTable->SystemAddressColumnIndex!=(unsigned int)-1) { const DataStructures::BPlusTree<unsigned, DataStructures::Table::Row*, _TABLE_BPLUS_TREE_ORDER> &rows = databaseTable->table.GetRows(); cur = rows.GetListHead(); while (cur) { // Mark dropped entities for (j=0; j < (unsigned)cur->size; j++) { if (RowHasIP(cur->data[j], systemAddress, databaseTable->SystemAddressColumnIndex)) { if (databaseTable->removeRowOnDisconnect) { removeList.Insert(cur->keys[j], __FILE__, __LINE__); } else if (databaseTable->removeRowOnPingFailure) { row = cur->data[j]; row->cells[databaseTable->nextPingSendColumnIndex]->i=(double)(RakNet::GetTime()+SEND_PING_INTERVAL+(randomMT()%1000)); } } } cur=cur->next; } } for (j=0; j < removeList.Size(); j++) databaseTable->table.RemoveRow(removeList[j]); removeList.Clear(true, __FILE__,__LINE__); } }
void FullyConnectedMesh2::GetHostOrder(DataStructures::List<RakNetGUID> &hostList) { hostList.Clear(true, _FILE_AND_LINE_); if (ourFCMGuid==0 || fcm2ParticipantList.Size()==0) { hostList.Push(rakPeerInterface->GetMyGUID(), _FILE_AND_LINE_); return; } FCM2Participant fcm2; fcm2.fcm2Guid=ourFCMGuid; fcm2.rakNetGuid=rakPeerInterface->GetMyGUID(); DataStructures::OrderedList<FCM2Participant, FCM2Participant, FCM2ParticipantComp> olist; olist.Insert(fcm2, fcm2, true, _FILE_AND_LINE_); for (unsigned int i=0; i < fcm2ParticipantList.Size(); i++) olist.Insert(fcm2ParticipantList[i], fcm2ParticipantList[i], true, _FILE_AND_LINE_); for (unsigned int i=0; i < olist.Size(); i++) { hostList.Push(olist[i].rakNetGuid, _FILE_AND_LINE_); } }
void LightweightDatabaseServer::Update(void) { RakNetTime time=0; DatabaseTable *databaseTable; DataStructures::Page<unsigned, DataStructures::Table::Row*, _TABLE_BPLUS_TREE_ORDER> *cur; unsigned i,j; DataStructures::Table::Row* row; DataStructures::List<unsigned> removeList; SystemAddress systemAddress; // periodic ping if removing system that do not respond to pings. for (i=0; i < database.Size(); i++) { databaseTable=database[i]; if (databaseTable->removeRowOnPingFailure) { // Reading the time is slow - only do it once if necessary. if (time==0) time = RakNet::GetTime(); if (databaseTable->nextRowPingCheck < time) { databaseTable->nextRowPingCheck=time+1000+(randomMT()%1000); const DataStructures::BPlusTree<unsigned, DataStructures::Table::Row*, _TABLE_BPLUS_TREE_ORDER> &rows = databaseTable->table.GetRows(); cur = rows.GetListHead(); while (cur) { // Mark dropped entities for (j=0; j < (unsigned)cur->size; j++) { row = cur->data[j]; row->cells[databaseTable->SystemAddressColumnIndex]->Get((char*)&systemAddress, 0); if (rakPeerInterface->IsConnected(systemAddress)==false) { if (time > time - (unsigned int) row->cells[databaseTable->lastPingResponseColumnIndex]->i && time - (unsigned int) row->cells[databaseTable->lastPingResponseColumnIndex]->i > (unsigned int) DROP_SERVER_INTERVAL) { removeList.Insert(cur->keys[j], __FILE__, __LINE__); } else { if (row->cells[databaseTable->nextPingSendColumnIndex]->i < (int) time) { char str1[64]; systemAddress.ToString(false, str1); rakPeerInterface->Ping(str1, systemAddress.port, false); row->cells[databaseTable->nextPingSendColumnIndex]->i=(double)(time+SEND_PING_INTERVAL+(randomMT()%1000)); } } } } cur=cur->next; } // Remove dropped entities for (j=0; j < removeList.Size(); j++) databaseTable->table.RemoveRow(removeList[i]); removeList.Clear(true, __FILE__,__LINE__); } } } }
PGresult * PostgreSQLInterface::QueryVariadic( const char * input, ... ) { RakNet::RakString query; PGresult *result; DataStructures::List<VariadicSQLParser::IndexAndType> indices; if ( input==0 || input[0]==0 ) return 0; // Lookup this query in the stored query table. If it doesn't exist, prepare it. RakNet::RakString inputStr; inputStr=input; unsigned int preparedQueryIndex; for (preparedQueryIndex=0; preparedQueryIndex < preparedQueries.Size(); preparedQueryIndex++) { if (preparedQueries[preparedQueryIndex].StrICmp(inputStr)==0) break; } // Find out how many params there are // Find out the type of each param (%f, %s) indices.Clear(false, _FILE_AND_LINE_); GetTypeMappingIndices( input, indices ); if (preparedQueryIndex==preparedQueries.Size()) { // if (indices.Size()>0) // query += " ("; RakNet::RakString formatCopy; RakNet::RakString insertion; formatCopy=input; unsigned int i; unsigned int indexOffset=0; for (i=0; i < indices.Size(); i++) { // if (i!=0) // query += ","; // query+=typeMappings[indices[i].typeMappingIndex].type; formatCopy.SetChar(indices[i].strIndex+indexOffset, '$'); // if (i < 9) // formatCopy.SetChar(indices[i].strIndex+1, i+1+'0'); // else insertion=RakNet::RakString("%i::%s", i+1, VariadicSQLParser::GetTypeMappingAtIndex(indices[i].typeMappingIndex)); formatCopy.SetChar(indices[i].strIndex+1+indexOffset, insertion); indexOffset+=(unsigned int) insertion.GetLength()-1; } // if (indices.Size()>0) // query += ")"; // query += " AS "; query += formatCopy; // query += ";\n"; formatCopy+= ";\n"; result = PQprepare(pgConn, RakNet::RakString("PGSQL_ExecuteVariadic_%i", preparedQueries.Size()), formatCopy.C_String(), indices.Size(), NULL); if (IsResultSuccessful(result, false)) { PQclear(result); preparedQueries.Insert(inputStr, _FILE_AND_LINE_); } else { printf(formatCopy.C_String()); printf("\n"); printf(lastError); RakAssert(0); PQclear(result); return 0; } } // char *paramData[512]; // int paramLength[512]; // int paramFormat[512]; va_list argptr; va_start(argptr, input); char **paramData; int *paramLength; int *paramFormat; ExtractArguments(argptr, indices, ¶mData, ¶mLength); paramFormat=RakNet::OP_NEW_ARRAY<int>(indices.Size(),_FILE_AND_LINE_); for (unsigned int i=0; i < indices.Size(); i++) paramFormat[i]=PQEXECPARAM_FORMAT_BINARY; result = PQexecPrepared(pgConn, RakNet::RakString("PGSQL_ExecuteVariadic_%i", preparedQueryIndex), indices.Size(), paramData, paramLength, paramFormat, PQEXECPARAM_FORMAT_BINARY ); VariadicSQLParser::FreeArguments(indices, paramData, paramLength); RakNet::OP_DELETE_ARRAY(paramFormat,_FILE_AND_LINE_); va_end(argptr); if (IsResultSuccessful(result, false)==false) { printf(lastError); PQclear(result); return 0; } return result; }
void LightweightDatabaseServer::Update(RakPeerInterface *peer) { RakNetTime time=0; DatabaseTable *databaseTable; DataStructures::Page<unsigned, DataStructures::Table::Row*, _TABLE_BPLUS_TREE_ORDER> *cur; unsigned i,j; DataStructures::Table::Row* row; DataStructures::List<unsigned> removeList; PlayerID playerId; // periodic ping if removing system that do not respond to pings. for (i=0; i < database.Size(); i++) { databaseTable=database[i]; if (databaseTable->removeRowOnPingFailure) { // Reading the time is slow - only do it once if necessary. if (time==0) time = RakNet::GetTime(); if (databaseTable->nextRowPingCheck < time) { databaseTable->nextRowPingCheck=time+1000+(randomMT()%1000); DataStructures::BPlusTree<unsigned, DataStructures::Table::Row*, _TABLE_BPLUS_TREE_ORDER> &rows = databaseTable->table.GetRows(); cur = rows.GetListHead(); while (cur) { // Mark dropped entities for (j=0; j < (unsigned)cur->size; j++) { row = cur->data[j]; if (time - row->cells[databaseTable->lastPingResponseColumnIndex]->i > DROP_SERVER_INTERVAL) removeList.Insert(cur->keys[j]); } cur=cur->next; } // Remove dropped entities for (j=0; j < removeList.Size(); j++) databaseTable->table.RemoveRow(removeList[i]); removeList.Clear(true); cur = rows.GetListHead(); // Ping remaining entities if they are not connected. If they are connected just increase the ping interval. while (cur) { for (j=0; j < (unsigned)cur->size; j++) { row = cur->data[j]; if (row->cells[databaseTable->nextPingSendColumnIndex]->i < (int) time) { row->cells[databaseTable->systemIdColumnIndex]->Get((char*)&playerId, 0); if (peer->GetIndexFromPlayerID(playerId)==-1) { peer->Ping(playerId.ToString(false), playerId.port, false); } else { // Consider the fact that they are connected to be a ping response row->cells[databaseTable->lastPingResponseColumnIndex]->i=time; } row->cells[databaseTable->nextPingSendColumnIndex]->i=time+SEND_PING_INTERVAL+(randomMT()%1000); } } cur=cur->next; } } } } }
void NatPunchthrough::Update(RakPeerInterface *peer) { (void) peer; if (connectionRequestList.Size()) { RakNetTime time = RakNet::GetTime(); RakNet::BitStream outBitstream; unsigned i; i=0; while (i < connectionRequestList.Size()) { // Remove old connection requests that get no answer if (connectionRequestList[i]->timeoutTime < time) { rakFree(connectionRequestList[i]->passwordData); delete connectionRequestList[i]; connectionRequestList.RemoveAtIndex(i); continue; } // If we are a facilitator, do pings if (connectionRequestList[i]->facilitatingConnection) { if (time >= connectionRequestList[i]->nextActionTime ) { if (connectionRequestList[i]->pingCount < PING_COUNT) { // Ping connectionRequestList[i]->pingCount++; rakPeer->Ping(connectionRequestList[i]->receiverPublic); rakPeer->Ping(connectionRequestList[i]->senderPublic); connectionRequestList[i]->nextActionTime=time+PING_INTERVAL; } else if (connectionRequestList[i]->pingCount == PING_COUNT) { // Done pinging. Wait till the next stage int receiverPing, senderPing; receiverPing=rakPeer->GetAveragePing(connectionRequestList[i]->receiverPublic); senderPing=rakPeer->GetAveragePing(connectionRequestList[i]->senderPublic); if (receiverPing > senderPing) connectionRequestList[i]->nextActionTime=(RakNetTime)(receiverPing*SEND_TIMESTAMP_DELAY_PING_MULTIPLE); else connectionRequestList[i]->nextActionTime=(RakNetTime)(senderPing*SEND_TIMESTAMP_DELAY_PING_MULTIPLE); connectionRequestList[i]->pingCount++; } else { // Send the timestamped message to both systems so they send datagrams to each other simultaneously int receiverPing, senderPing; RakNetTime delayTime; receiverPing=rakPeer->GetAveragePing(connectionRequestList[i]->receiverPublic); senderPing=rakPeer->GetAveragePing(connectionRequestList[i]->senderPublic); if (receiverPing > senderPing) delayTime=(RakNetTime)(receiverPing*SEND_PUNCHTHROUGH_DELAY_PING_MULTIPLE); else delayTime=(RakNetTime)(senderPing*SEND_PUNCHTHROUGH_DELAY_PING_MULTIPLE); if (delayTime < 500) delayTime=500; outBitstream.Reset(); outBitstream.Write((MessageID)ID_TIMESTAMP); outBitstream.Write(time+delayTime); outBitstream.Write((MessageID)ID_NAT_CONNECT_AT_TIME); // A few poorly behaved NATs are known to scan the body of UDP datagrams for 4-byte fields that look like IP addresses, and translate them as they would the IP address fields in the IP header. outBitstream.Write(true); outBitstream.Write(rakPeer->GetInternalID(connectionRequestList[i]->receiverPublic)); rakPeer->Send(&outBitstream, SYSTEM_PRIORITY, RELIABLE, 0, connectionRequestList[i]->senderPublic, false); outBitstream.Reset(); outBitstream.Write((MessageID)ID_TIMESTAMP); outBitstream.Write(time+delayTime); outBitstream.Write((MessageID)ID_NAT_SEND_OFFLINE_MESSAGE_AT_TIME); // A few poorly behaved NATs are known to scan the body of UDP datagrams for 4-byte fields that look like IP addresses, and translate them as they would the IP address fields in the IP header. outBitstream.Write(true); outBitstream.Write(connectionRequestList[i]->senderPublic); outBitstream.Write(rakPeer->GetInternalID(connectionRequestList[i]->senderPublic)); rakPeer->Send(&outBitstream, SYSTEM_PRIORITY, RELIABLE, 0, connectionRequestList[i]->receiverPublic, false); delete [] connectionRequestList[i]->passwordData; delete connectionRequestList[i]; connectionRequestList.RemoveAtIndex(i); continue; } } } // Else not a facilitator. If nextActionTime is non-zero, connect or send the offline message else if (connectionRequestList[i]->nextActionTime && time >= connectionRequestList[i]->nextActionTime && connectionRequestList[i]->attemptedConnection==false) { ConnectionRequest *connectionRequest = connectionRequestList[i]; DataStructures::List<SystemAddress> fallbackAddresses; // unsigned fallbackIndex; RakNet::BitStream oob; if (connectionRequest->receiverPublic!=UNASSIGNED_SYSTEM_ADDRESS) { // fallbackAddresses.Clear(); // connectionRequest->GetAddressList(peer, fallbackAddresses, connectionRequest->senderPublic, connectionRequest->senderPrivate, true); // for (unsigned fallbackIndex=0; fallbackIndex < fallbackAddresses.Size(); fallbackIndex++) // peer->Ping(fallbackAddresses[fallbackIndex].ToString(false),fallbackAddresses[fallbackIndex].port,false); // Connect to this system. LogOut(FormatString("Connecting to public address %s\n", connectionRequest->receiverPublic.ToString(true))); rakPeer->Connect(connectionRequest->receiverPublic.ToString(false), connectionRequest->receiverPublic.port, connectionRequest->passwordData, connectionRequest->passwordDataLength); connectionRequest->attemptedConnection=true; /* if (connectionRequestList[i]->receiverPrivate==connectionRequestList[i]->receiverPublic) { // Otherwise done with this connection, as it's a normal connection attempt rakFree(connectionRequestList[i]->passwordData); delete connectionRequestList[i]; connectionRequestList.RemoveAtIndex(i); continue; } */ } else { RakAssert(connectionRequestList[i]->senderPublic!=UNASSIGNED_SYSTEM_ADDRESS); // Send ID_NAT_ADVERTISE_RECIPIENT_PORT to all possible remote ports fallbackAddresses.Clear(); connectionRequest->GetAddressList(peer, fallbackAddresses, connectionRequest->senderPublic, connectionRequest->senderPrivate, true); /// 04/13/08 I think if I send to all possible fallbacks in order it starts reusing external ports or else assigns them in a random way /// Sending 4X to each port in order did work however. /// Timing matches that of RakPeer's failure notices and retries if ((unsigned int) connectionRequestList[i]->recipientOfflineCount < fallbackAddresses.Size()) { unsigned k; //for (k=0; k < 4; k++) for (k=0; k < (unsigned) connectionRequestList[i]->recipientOfflineCount && k < fallbackAddresses.Size(); k++) { oob.Write(ID_NAT_ADVERTISE_RECIPIENT_PORT); oob.Write(rakPeer->GetExternalID(connectionRequest->facilitator)); // This is duplicated intentionally, since the first packet is often dropped peer->SendOutOfBand(fallbackAddresses[k].ToString(false),fallbackAddresses[k].port,ID_OUT_OF_BAND_INTERNAL,(const char*) oob.GetData(),oob.GetNumberOfBytesUsed(),0); peer->SendOutOfBand(fallbackAddresses[k].ToString(false),fallbackAddresses[k].port,ID_OUT_OF_BAND_INTERNAL,(const char*) oob.GetData(),oob.GetNumberOfBytesUsed(),0); } LogOut(FormatString("Recipient sending ID_OUT_OF_BAND_INTERNAL to %s\n", fallbackAddresses[connectionRequestList[i]->recipientOfflineCount].ToString(true))); } /* for (fallbackIndex=0; fallbackIndex < fallbackAddresses.Size(); fallbackIndex++) { // This follows a similar path to the sender connecting to us. // If this message arrives, it lets the sender know our external port. // The sender can then use this port instead of just going down the fallbackAddresses guessing. // This saves us if the recipient is impossible to connect to, but the sender is not. oob.Reset(); oob.Write(ID_NAT_ADVERTISE_RECIPIENT_PORT); oob.Write(rakPeer->GetExternalID(connectionRequest->facilitator)); peer->SendOutOfBand(fallbackAddresses[fallbackIndex].ToString(false),fallbackAddresses[fallbackIndex].port,ID_OUT_OF_BAND_INTERNAL,(const char*) oob.GetData(),oob.GetNumberOfBytesUsed(),0); // bool SendOutOfBand(const char *host, unsigned short remotePort, MessageID header, const char *data, BitSize_t dataLength, unsigned connectionSocketIndex=0 ); } */ // LogOut(FormatString("Pinging %s\n", connectionRequest->senderPublic.ToString(true))); // rakPeer->Connect(connectionRequestList[i]->senderPublic.ToString(false),connectionRequestList[i]->senderPublic.port,0,0,0); /* SystemAddress senderAddrWithFPort; SystemAddress senderAddrWithRPort; SystemAddress senderAddrWithIPort; senderAddrWithFPort=connectionRequestList[i]->senderPublic; senderAddrWithFPort.port=connectionRequestList[i]->facilitator.port; senderAddrWithRPort=connectionRequestList[i]->senderPublic; senderAddrWithRPort.port=rakPeer->GetExternalID(connectionRequestList[i]->facilitator).port; senderAddrWithIPort=connectionRequestList[i]->senderPublic; senderAddrWithIPort.port=rakPeer->GetInternalID().port; */ // LogOut(FormatString("Recipient sending TTL %i hops to %s\n", TTL_HOPS, connectionRequestList[i]->senderPublic.ToString())); // rakPeer->SendTTL(connectionRequestList[i]->senderPublic.ToString(false), connectionRequestList[i]->senderPublic.port, false); // Send offline message to this system, hopefully at the exact same time that system tries to connect to us. // rakPeer->Ping(connectionRequestList[i]->senderPublic.ToString(false), connectionRequestList[i]->senderPublic.port, false); /* rakPeer->Ping(senderAddrWithFPort.ToString(false), senderAddrWithFPort.port, false); rakPeer->Ping(senderAddrWithRPort.ToString(false), senderAddrWithRPort.port, false); rakPeer->Ping(senderAddrWithIPort.ToString(false), senderAddrWithIPort.port, false); */ // if (connectionRequestList[i]->senderPrivate!=connectionRequestList[i]->senderPublic) // rakPeer->Ping(connectionRequestList[i]->senderPrivate.ToString(false), connectionRequestList[i]->senderPrivate.port, false); // LogOut(FormatString("Recipient sending TTL %i hops to %s\n", TTL_HOPS, connectionRequestList[i]->senderPublic.ToString(false))); // peer->SendTTL(connectionRequestList[i]->senderPublic.ToString(false),connectionRequestList[i]->senderPublic.port, TTL_HOPS+connectionRequestList[i]->recipientOfflineCount, 0); // peer->SendTTL(connectionRequestList[i]->senderPublic.ToString(false),connectionRequestList[i]->senderPublic.port+1, TTL_HOPS+connectionRequestList[i]->recipientOfflineCount, 0); // peer->SendTTL(connectionRequestList[i]->senderPrivate.ToString(false),connectionRequestList[i]->senderPrivate.port, TTL_HOPS+connectionRequestList[i]->recipientOfflineCount, 0); connectionRequestList[i]->recipientOfflineCount++; if (connectionRequestList[i]->recipientOfflineCount==RECIPIENT_OFFLINE_MAX_COUNT) { rakFree(connectionRequestList[i]->passwordData); delete connectionRequestList[i]; connectionRequestList.RemoveAtIndex(i); } else { connectionRequestList[i]->nextActionTime=time+RECIPIENT_OFFLINE_MESSAGE_INTERVAL; } continue; } } i++; } } }
HTTPReadResult PHPDirectoryServer2::ProcessHTTPRead(RakNet::RakString httpRead) { const char *c = (const char*) httpRead.C_String(); // current position HTTPReadResult resultCode=HTTP_RESULT_EMPTY; lastDownloadedTable.Clear(); if (*c=='\n') c++; char buff[256]; int buffIndex; bool isCommand=true; DataStructures::List<RakNet::RakString> columns; DataStructures::List<RakNet::RakString> values; RakNet::RakString curString; bool isComment=false; buffIndex=0; while(c && *c) { // 3 is comment if (*c=='\003') { isComment=!isComment; c++; continue; } if (isComment) { c++; continue; } // 1 or 2 separates fields // 4 separates rows if (*c=='\001') { if (isCommand) { buff[buffIndex]=0; columns.Push(RakString::NonVariadic(buff), _FILE_AND_LINE_); isCommand=false; if (buff[0]!=0) resultCode=HTTP_RESULT_GOT_TABLE; } else { buff[buffIndex]=0; values.Push(RakString::NonVariadic(buff), _FILE_AND_LINE_); isCommand=true; } buffIndex=0; } else if (*c=='\002') { buff[buffIndex]=0; buffIndex=0; values.Push(RakString::NonVariadic(buff), _FILE_AND_LINE_); isCommand=true; PushColumnsAndValues(columns, values); columns.Clear(true, _FILE_AND_LINE_); values.Clear(true, _FILE_AND_LINE_); } else { if (buffIndex<256-1) buff[buffIndex++]=*c; } c++; } if (buff[0] && columns.Size()==values.Size()+1) { buff[buffIndex]=0; values.Push(RakString::NonVariadic(buff), _FILE_AND_LINE_); } PushColumnsAndValues(columns, values); return resultCode; }
int main(int argc, char *argv[]) { int returnVal; char str[512]; int numTests=0; int testListSize=0; int passedTests=0; DataStructures::List <TestInterface*> testList;//Pointer list DataStructures::List <int> testResultList;//A list of pass and/or fail and the error codes DataStructures::List <RakString> testsToRun;//A list of tests to run DataStructures::List <int> testsToRunIndexes;//A list of tests to run by index //Add all the tests to the test list testList.Push(new EightPeerTest(),_FILE_AND_LINE_); testList.Push(new MaximumConnectTest(),_FILE_AND_LINE_); testList.Push(new PeerConnectDisconnectWithCancelPendingTest(),_FILE_AND_LINE_); testList.Push(new PeerConnectDisconnectTest(),_FILE_AND_LINE_); testList.Push(new ManyClientsOneServerBlockingTest(),_FILE_AND_LINE_); testList.Push(new ManyClientsOneServerNonBlockingTest(),_FILE_AND_LINE_); testList.Push(new ManyClientsOneServerDeallocateBlockingTest(),_FILE_AND_LINE_); testList.Push(new ReliableOrderedConvertedTest(),_FILE_AND_LINE_); testList.Push(new DroppedConnectionConvertTest(),_FILE_AND_LINE_); testList.Push(new ComprehensiveConvertTest(),_FILE_AND_LINE_); testList.Push(new CrossConnectionConvertTest(),_FILE_AND_LINE_); testList.Push(new PingTestsTest(),_FILE_AND_LINE_); testList.Push(new OfflineMessagesConvertTest(),_FILE_AND_LINE_); testList.Push(new LocalIsConnectedTest(),_FILE_AND_LINE_); testList.Push(new SecurityFunctionsTest(),_FILE_AND_LINE_); testList.Push(new ConnectWithSocketTest(),_FILE_AND_LINE_); testList.Push(new SystemAddressAndGuidTest(),_FILE_AND_LINE_); testList.Push(new PacketAndLowLevelTestsTest(),_FILE_AND_LINE_); testList.Push(new MiscellaneousTestsTest(),_FILE_AND_LINE_); testListSize=testList.Size(); bool isVerbose=true; bool disallowTestToPause=false; DataStructures::List<RakString> testcases; if (argc>1)//we have command line arguments { for (int p=1;p<argc;p++) { testsToRun.Push(argv[p],_FILE_AND_LINE_); } } DataStructures::List<RakString> noParamsList; if (testsToRun.Size()==0&&testsToRunIndexes.Size()==0) { numTests=testListSize; for(int i=0;i<testListSize;i++) { printf("\n\nRunning test %s.\n\n",testList[i]->GetTestName().C_String()); returnVal=testList[i]->RunTest(noParamsList,isVerbose,disallowTestToPause); testList[i]->DestroyPeers(); if (returnVal==0) {passedTests++;} else { printf("Test %s returned with error %s",testList[i]->GetTestName().C_String(),testList[i]->ErrorCodeToString(returnVal).C_String()); } } } if (testsToRun.Size()!=0)//If string arguments convert to indexes.Suggestion: if speed becoms an issue keep a sorted list and binary search it { int TestsToRunSize= testsToRun.Size(); RakString testName; for(int i=0;i<TestsToRunSize;i++) { testName=testsToRun[i]; for(int j=0;j<testListSize;j++) { if (testList[j]->GetTestName().StrICmp(testName)==0) { testsToRunIndexes.Push(j,_FILE_AND_LINE_); } } } } if (testsToRunIndexes.Size()!=0)//Run selected indexes { numTests=testsToRunIndexes.Size(); for(int i=0;i<numTests;i++) { if (testsToRunIndexes[i]<testListSize) { printf("\n\nRunning test %s.\n\n",testList[testsToRunIndexes[i]]->GetTestName().C_String()); returnVal=testList[testsToRunIndexes[i]]->RunTest(noParamsList,isVerbose,disallowTestToPause); testList[i]->DestroyPeers(); if (returnVal==0) {passedTests++;} else { printf("Test %s returned with error %s",testList[testsToRunIndexes[i]]->GetTestName().C_String(),testList[testsToRunIndexes[i]]->ErrorCodeToString(returnVal).C_String()); } } } } if (numTests>0) { printf("\nPassed %i out of %i tests.\n",passedTests,numTests); } printf("Press enter to continue \n"); Gets(str, sizeof(str)); //Cleanup int len=testList.Size(); for (int i=0;i<len;i++) { delete testList[i]; } testList.Clear(false,_FILE_AND_LINE_); return 0; }