bool StatisticsHistory::GetHistorySorted(uint64_t objectId, SHSortOperation sortType, DataStructures::List<StatisticsHistory::TimeAndValueQueue *> &values) const
{
	unsigned int idx = GetObjectIndex(objectId);
	if (idx == (unsigned int) -1)
		return false;
	TrackedObject *to = objects[idx];
	DataStructures::List<TimeAndValueQueue*> itemList;
	DataStructures::List<RakString> keyList;
	to->dataQueues.GetAsList(itemList,keyList,_FILE_AND_LINE_);
	Time curTime = GetTime();

	DataStructures::OrderedList<TimeAndValueQueue*, TimeAndValueQueue*,TimeAndValueQueueCompAsc> sortedQueues;
	for (unsigned int i=0; i < itemList.Size(); i++)
	{
		TimeAndValueQueue *tavq = itemList[i];
		tavq->CullExpiredValues(curTime);

		if (sortType == SH_SORT_BY_RECENT_SUM_ASCENDING || sortType == SH_SORT_BY_RECENT_SUM_DESCENDING)
			tavq->sortValue = tavq->GetRecentSum();
		else if (sortType == SH_SORT_BY_LONG_TERM_SUM_ASCENDING || sortType == SH_SORT_BY_LONG_TERM_SUM_DESCENDING)
			tavq->sortValue = tavq->GetLongTermSum();
		else if (sortType == SH_SORT_BY_RECENT_SUM_OF_SQUARES_ASCENDING || sortType == SH_SORT_BY_RECENT_SUM_OF_SQUARES_DESCENDING)
			tavq->sortValue = tavq->GetRecentSumOfSquares();
		else if (sortType == SH_SORT_BY_RECENT_AVERAGE_ASCENDING || sortType == SH_SORT_BY_RECENT_AVERAGE_DESCENDING)
			tavq->sortValue = tavq->GetRecentAverage();
		else if (sortType == SH_SORT_BY_LONG_TERM_AVERAGE_ASCENDING || sortType == SH_SORT_BY_LONG_TERM_AVERAGE_DESCENDING)
			tavq->sortValue = tavq->GetLongTermAverage();
		else if (sortType == SH_SORT_BY_RECENT_HIGHEST_ASCENDING || sortType == SH_SORT_BY_RECENT_HIGHEST_DESCENDING)
			tavq->sortValue = tavq->GetRecentHighest();
		else if (sortType == SH_SORT_BY_RECENT_LOWEST_ASCENDING || sortType == SH_SORT_BY_RECENT_LOWEST_DESCENDING)
			tavq->sortValue = tavq->GetRecentLowest();
		else if (sortType == SH_SORT_BY_LONG_TERM_HIGHEST_ASCENDING || sortType == SH_SORT_BY_LONG_TERM_HIGHEST_DESCENDING)
			tavq->sortValue = tavq->GetLongTermHighest();
		else
			tavq->sortValue = tavq->GetLongTermLowest();

		if (
			sortType == SH_SORT_BY_RECENT_SUM_ASCENDING ||
			sortType == SH_SORT_BY_LONG_TERM_SUM_ASCENDING ||
			sortType == SH_SORT_BY_RECENT_SUM_OF_SQUARES_ASCENDING ||
			sortType == SH_SORT_BY_RECENT_AVERAGE_ASCENDING ||
			sortType == SH_SORT_BY_LONG_TERM_AVERAGE_ASCENDING ||
			sortType == SH_SORT_BY_RECENT_HIGHEST_ASCENDING ||
			sortType == SH_SORT_BY_RECENT_LOWEST_ASCENDING ||
			sortType == SH_SORT_BY_LONG_TERM_HIGHEST_ASCENDING ||
			sortType == SH_SORT_BY_LONG_TERM_LOWEST_ASCENDING)
			sortedQueues.Insert(tavq, tavq, false, _FILE_AND_LINE_, TimeAndValueQueueCompAsc);
		else
			sortedQueues.Insert(tavq, tavq, false, _FILE_AND_LINE_, TimeAndValueQueueCompDesc);
	}

	for (unsigned int i=0; i < sortedQueues.Size(); i++)
		values.Push(sortedQueues[i], _FILE_AND_LINE_);
	return true;
}
void ConnectionGraph::SerializeIgnoreListAndBroadcast(RakNet::BitStream *outBitstream, DataStructures::OrderedList<SystemAddress,SystemAddress> &ignoreList, RakPeerInterface *peer)
{
	DataStructures::List<SystemAddress> sendList;
	unsigned i;
	for (i=0; i < participantList.Size(); i++)
	{
		if (ignoreList.HasData(participantList[i])==false)
			sendList.Insert(participantList[i], __FILE__, __LINE__);
	}
	if (sendList.Size()==0)
		return;

	SystemAddress self = peer->GetExternalID(sendList[0]);
	ignoreList.Insert(self,self, false, __FILE__, __LINE__);
	outBitstream->Write((unsigned short) (ignoreList.Size()+sendList.Size()));
	for (i=0; i < ignoreList.Size(); i++)
		outBitstream->Write(ignoreList[i]);
	for (i=0; i < sendList.Size(); i++)
		outBitstream->Write(sendList[i]);

	for (i=0; i < sendList.Size(); i++)
	{
		peer->Send(outBitstream, LOW_PRIORITY, RELIABLE_ORDERED, connectionGraphChannel, sendList[i], false);
	}
}
void UDPProxyCoordinator::ForwardingRequest::OrderRemainingServersToTry(void)
{
    //DataStructures::Multilist<ML_ORDERED_LIST,UDPProxyCoordinator::ServerWithPing,unsigned short> swpList;
    DataStructures::OrderedList<unsigned short, UDPProxyCoordinator::ServerWithPing, ServerWithPingComp> swpList;
    // swpList.SetSortOrder(true);

    if (sourceServerPings.Size()==0 && targetServerPings.Size()==0)
        return;

    unsigned int idx;
    UDPProxyCoordinator::ServerWithPing swp;
    for (idx=0; idx < remainingServersToTry.Size(); idx++)
    {
        swp.serverAddress=remainingServersToTry[idx];
        swp.ping=0;
        if (sourceServerPings.Size())
            swp.ping+=(unsigned short) (sourceServerPings[idx].ping);
        else
            swp.ping+=(unsigned short) (DEFAULT_CLIENT_UNRESPONSIVE_PING_TIME);
        if (targetServerPings.Size())
            swp.ping+=(unsigned short) (targetServerPings[idx].ping);
        else
            swp.ping+=(unsigned short) (DEFAULT_CLIENT_UNRESPONSIVE_PING_TIME);
        swpList.Insert(swp.ping, swp, false, _FILE_AND_LINE_);
    }
    remainingServersToTry.Clear(_FILE_AND_LINE_ );
    for (idx=0; idx < swpList.Size(); idx++)
    {
        remainingServersToTry.Push(swpList[idx].serverAddress, _FILE_AND_LINE_ );
    }
}
void ConnectionGraph::AddAndRelayConnection(DataStructures::OrderedList<SystemAddress,SystemAddress> &ignoreList, const SystemAddressAndGroupId &conn1, const SystemAddressAndGroupId &conn2, unsigned short ping, RakPeerInterface *peer)
{
	if (graph.HasConnection(conn1,conn2))
		return;

	if (ping==65535)
		ping=0;
	RakAssert(conn1.systemAddress!=UNASSIGNED_SYSTEM_ADDRESS);
	RakAssert(conn2.systemAddress!=UNASSIGNED_SYSTEM_ADDRESS);

	if (IsNewRemoteConnection(conn1,conn2,peer))
	{
		NotifyUserOfRemoteConnection(conn1,conn2,ping,peer);

		// What was this return here for?
	//	return;
	}

	graph.AddConnection(conn1,conn2,ping);

	RakNet::BitStream outBitstream;
	outBitstream.Write((MessageID)ID_CONNECTION_GRAPH_NEW_CONNECTION);
	outBitstream.Write(conn1.systemAddress);
	outBitstream.Write(conn1.groupId);
	outBitstream.Write(conn1.guid);
	outBitstream.Write(conn2.systemAddress);
	outBitstream.Write(conn2.groupId);
	outBitstream.Write(conn2.guid);
	outBitstream.Write(ping);
	ignoreList.Insert(conn2.systemAddress,conn2.systemAddress, false, __FILE__, __LINE__);
	ignoreList.Insert(conn1.systemAddress,conn1.systemAddress, false, __FILE__, __LINE__);
	SerializeIgnoreListAndBroadcast(&outBitstream, ignoreList, peer);
}
void Lobby2Client_Steam_Impl::GetRoomMembers(DataStructures::OrderedList<uint64_t, uint64_t> &_roomMembers)
{
	_roomMembers.Clear(true,_FILE_AND_LINE_);
	int cLobbyMembers = SteamMatchmaking()->GetNumLobbyMembers( roomId );
	for ( int i = 0; i < cLobbyMembers; i++ )
	{
		CSteamID steamIDLobbyMember = SteamMatchmaking()->GetLobbyMemberByIndex( roomId, i ) ;
		uint64_t memberid=steamIDLobbyMember.ConvertToUint64();
		_roomMembers.Insert(memberid,memberid,true,_FILE_AND_LINE_);
	}
}
void Table::SortTable(Table::SortQuery *sortQueries, unsigned numSortQueries, Table::Row** out)
{
	unsigned i;
	unsigned outLength;
	DataStructures::List<unsigned> columnIndices;
	_sortQueries=sortQueries;
	_numSortQueries=numSortQueries;
	_columnIndices=&columnIndices;
	_columns=&columns;
	bool anyValid=false;

	for (i=0; i < numSortQueries; i++)
	{
		if (sortQueries[i].columnIndex<columns.Size() && columns[sortQueries[i].columnIndex].columnType!=BINARY)
		{
			columnIndices.Insert(sortQueries[i].columnIndex, _FILE_AND_LINE_);
			anyValid=true;
		}
		else
			columnIndices.Insert((unsigned)-1, _FILE_AND_LINE_); // Means don't check this column
	}

	DataStructures::Page<unsigned, Row*, _TABLE_BPLUS_TREE_ORDER> *cur;
	cur = rows.GetListHead();
	if (anyValid==false)
	{
		outLength=0;
		while (cur)
		{
			for (i=0; i < (unsigned)cur->size; i++)
			{
				out[(outLength)++]=cur->data[i];
			}
			cur=cur->next;
		}
		return;
	}

	// Start adding to ordered list.
	DataStructures::OrderedList<Row*, Row*, RowSort> orderedList;
	while (cur)
	{
		for (i=0; i < (unsigned)cur->size; i++)
		{
			RakAssert(cur->data[i]);
			orderedList.Insert(cur->data[i],cur->data[i], true, _FILE_AND_LINE_);
		}
		cur=cur->next;
	}

	outLength=0;
	for (i=0; i < orderedList.Size(); i++)
		out[(outLength)++]=orderedList[i];
}
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_);
	}
}
bool ConnectionGraph::DeserializeIgnoreList(DataStructures::OrderedList<SystemAddress,SystemAddress> &ignoreList, RakNet::BitStream *inBitstream )
{
	unsigned short count;
	SystemAddress temp;
	unsigned i;
	inBitstream->Read(count);
	for (i=0; i < count; i++)
	{
		if (inBitstream->Read(temp)==false)
		{
			RakAssert(0);
			return false;
		}
		ignoreList.Insert(temp,temp, false, __FILE__, __LINE__);
	}
	return true;
}
bool ConnectionGraph::OnConnectionLostInternal(Packet *packet, unsigned char packetId)
{
	// Only accept from participants
	if (participantList.HasData(packet->systemAddress)==false)
		return false;

	SystemAddress node1, node2;
	RakNet::BitStream inBitstream(packet->data, packet->length, false);
	inBitstream.IgnoreBits(8);
	// This is correct - group IDs are not written for removal, only addition.
	inBitstream.Read(node1);
	if (inBitstream.Read(node2)==false)
		return false;
	DataStructures::OrderedList<SystemAddress,SystemAddress> ignoreList;
	DeserializeIgnoreList(ignoreList, &inBitstream);
	ignoreList.Insert(packet->systemAddress, packet->systemAddress, false, __FILE__, __LINE__);
	
	return RemoveAndRelayConnection(ignoreList, packetId, node1, node2, rakPeerInterface);
}
void ConnectionGraph::OnConnectionGraphUpdate(Packet *packet)
{
	// Only accept from participants
	if (participantList.HasData(packet->systemAddress)==false)
		return;

	RakNet::BitStream inBitstream(packet->data, packet->length, false);
	inBitstream.IgnoreBits(8);
	
	if (DeserializeWeightedGraph(&inBitstream, rakPeerInterface)==false)
		return;

	DataStructures::OrderedList<SystemAddress,SystemAddress> ignoreList;
	DeserializeIgnoreList(ignoreList, &inBitstream);

	// Forward the updated graph to all participants.
	ignoreList.Insert(packet->systemAddress,packet->systemAddress, false, __FILE__, __LINE__);
	BroadcastGraphUpdate(ignoreList, rakPeerInterface);
}
Exemple #11
0
// connectionRequestsMutex should already be locked
void Router2::RequestForwarding(ConnnectRequest* connectionRequest)
{
	RakAssert(connectionRequest->requestState==R2RS_REQUEST_STATE_QUERY_FORWARDING);
	connectionRequest->requestState=REQUEST_STATE_REQUEST_FORWARDING;

	if (connectionRequest->GetGuidIndex(connectionRequest->lastRequestedForwardingSystem)!=(unsigned int)-1)
	{
		char buff[512];
		if (debugInterface)	debugInterface->ShowFailure(FormatStringTS(buff,"Router2 failed at %s:%i\n", _FILE_AND_LINE_));
		return;
	}

	// Prioritize systems to request forwarding
	DataStructures::OrderedList<ConnectionRequestSystem, ConnectionRequestSystem, ConnectionRequestSystemComp> commandList;
	unsigned int connectionRequestGuidIndex;
	connectionRequest->connectionRequestSystemsMutex.Lock();
	for (connectionRequestGuidIndex=0; connectionRequestGuidIndex < connectionRequest->connectionRequestSystems.Size(); connectionRequestGuidIndex++)
	{
		RakAssert(connectionRequest->connectionRequestSystems[connectionRequestGuidIndex].pingToEndpoint>=0);
		commandList.Insert(connectionRequest->connectionRequestSystems[connectionRequestGuidIndex],
			connectionRequest->connectionRequestSystems[connectionRequestGuidIndex],
			true,
			_FILE_AND_LINE_);
	}
	connectionRequest->connectionRequestSystemsMutex.Unlock();

	connectionRequest->lastRequestedForwardingSystem=commandList[0].guid;

	RakNet::BitStream bsOut;
	bsOut.Write((MessageID)ID_ROUTER_2_INTERNAL);
	bsOut.Write((unsigned char) ID_ROUTER_2_REQUEST_FORWARDING);
	bsOut.Write(connectionRequest->endpointGuid);
	rakPeerInterface->Send(&bsOut,MEDIUM_PRIORITY,RELIABLE_ORDERED,0,connectionRequest->lastRequestedForwardingSystem,false);

	if (debugInterface)
	{
		char buff[512];
		debugInterface->ShowDiagnostic(FormatStringTS(buff,"Sending ID_ROUTER_2_REQUEST_FORWARDING "
            "(connectionRequest->lastRequestedForwardingSystem = %I64d, connectionRequest->endpointGuid = %I64d) at %s:%i\n", 
            connectionRequest->lastRequestedForwardingSystem.g,connectionRequest->endpointGuid.g, __FILE__, __LINE__));
	}
}
void ConnectionGraph::OnConnectionGraphReply(Packet *packet)
{
	unsigned char password[256];
	RakNet::BitStream inBitstream(packet->data, packet->length, false);
	inBitstream.IgnoreBits(8);
	stringCompressor->DecodeString((char*)password,256,&inBitstream);
	if (pw && pw[0] && strcmp(pw, (const char*)password)!=0)
		return;

	// Serialize the weighted graph and send it to them
	RakNet::BitStream outBitstream;
	outBitstream.Write((MessageID)ID_CONNECTION_GRAPH_UPDATE);

#ifdef _CONNECTION_GRAPH_DEBUG_PRINT
	RAKNET_DEBUG_PRINTF("ID_CONNECTION_GRAPH_UPDATE ");
#endif

	// Send our current graph to the sender
	SerializeWeightedGraph(&outBitstream, graph);


	// Write the systems that have processed this graph so we don't resend to these systems
	outBitstream.Write((unsigned short) 1);
	outBitstream.Write(rakPeerInterface->GetExternalID(packet->systemAddress));

#ifdef _CONNECTION_GRAPH_DEBUG_PRINT
	RAKNET_DEBUG_PRINTF("from %i to %i\n", peer->GetInternalID().port, packet->systemAddress.port);
#endif

	SendUnified(&outBitstream, LOW_PRIORITY, RELIABLE_ORDERED, connectionGraphChannel, packet->systemAddress, false);

	// Add packet->systemAddress to the participant list if it is not already there
	AddParticipant(packet->systemAddress);

	if (DeserializeWeightedGraph(&inBitstream, rakPeerInterface)==false)
		return;

	// Forward the updated graph to all current participants
	DataStructures::OrderedList<SystemAddress,SystemAddress> ignoreList;
	ignoreList.Insert(packet->systemAddress,packet->systemAddress, true, __FILE__, __LINE__);
	BroadcastGraphUpdate(ignoreList, rakPeerInterface);
}
bool ConnectionGraph::RemoveAndRelayConnection(DataStructures::OrderedList<SystemAddress,SystemAddress> &ignoreList, unsigned char packetId, const SystemAddress node1, const SystemAddress node2, RakPeerInterface *peer)
{
	SystemAddressAndGroupId n1, n2;
	n1.systemAddress=node1;
	n2.systemAddress=node2;
	if (graph.HasConnection(n1,n2)==false)
		return false;
	graph.RemoveConnection(n1,n2);

	// TODO - clear islands

	RakNet::BitStream outBitstream;
	outBitstream.Write(packetId);
	outBitstream.Write(node1);
	outBitstream.Write(node2);

	ignoreList.Insert(node1,node1, false, __FILE__, __LINE__);
	ignoreList.Insert(node2,node2, false, __FILE__, __LINE__);
	SerializeIgnoreListAndBroadcast(&outBitstream, ignoreList, peer);

	return true;
}
void ConnectionGraph::OnNewConnectionInternal(Packet *packet)
{
	// Only accept from participants
	if (participantList.HasData(packet->systemAddress)==false)
		return;

	SystemAddressAndGroupId node1, node2;
	unsigned short ping;
	RakNet::BitStream inBitstream(packet->data, packet->length, false);
	inBitstream.IgnoreBits(8);
	inBitstream.Read(node1.systemAddress);
	inBitstream.Read(node1.groupId);
	inBitstream.Read(node1.guid);
	inBitstream.Read(node2.systemAddress);
	inBitstream.Read(node2.groupId);
	inBitstream.Read(node2.guid);
	if (inBitstream.Read(ping)==false)
		return;
	DataStructures::OrderedList<SystemAddress,SystemAddress> ignoreList;
	DeserializeIgnoreList(ignoreList, &inBitstream);
	ignoreList.Insert(packet->systemAddress,packet->systemAddress, false, __FILE__, __LINE__);
	AddAndRelayConnection(ignoreList, node1, node2, ping, rakPeerInterface);	
}
void Lobby2Client_Steam_Impl::CallRoomCallbacks()
{
	DataStructures::OrderedList<uint64_t,uint64_t> currentMembers;
	GetRoomMembers(currentMembers);
	DataStructures::OrderedList<uint64_t, RoomMember, SteamIDAndRoomMemberComp> updatedRoomMembers;
	bool anyChanges=false;

	unsigned int currentMemberIndex=0, oldMemberIndex=0;
	while (currentMemberIndex < currentMembers.Size() && oldMemberIndex < roomMembersById.Size())
	{
		if (currentMembers[currentMemberIndex]<roomMembersById[oldMemberIndex].steamIDRemote)
		{
			RoomMember roomMember;
			roomMember.steamIDRemote=currentMembers[currentMemberIndex];
			roomMember.systemAddress.address.addr4.sin_addr.s_addr=nextFreeSystemAddress++;
			roomMember.systemAddress.SetPortHostOrder(STEAM_UNUSED_PORT);
			updatedRoomMembers.Insert(roomMember.steamIDRemote,roomMember,true,_FILE_AND_LINE_);

			anyChanges=true;

			// new member
			NotifyNewMember(currentMembers[currentMemberIndex], roomMember.systemAddress);
			currentMemberIndex++;
		}
		else if (currentMembers[currentMemberIndex]>roomMembersById[oldMemberIndex].steamIDRemote)
		{
			anyChanges=true;

			// dropped member
			NotifyDroppedMember(roomMembersById[oldMemberIndex].steamIDRemote, roomMembersById[oldMemberIndex].systemAddress);
			oldMemberIndex++;
		}
		else
		{
			updatedRoomMembers.Insert(roomMembersById[oldMemberIndex].steamIDRemote,roomMembersById[oldMemberIndex],true,_FILE_AND_LINE_);

			currentMemberIndex++;
			oldMemberIndex++;
		}
	}

	while (oldMemberIndex < roomMembersById.Size())
	{
		anyChanges=true;

		// dropped member
		NotifyDroppedMember(roomMembersById[oldMemberIndex].steamIDRemote, roomMembersById[oldMemberIndex].systemAddress);

		oldMemberIndex++;
	}
	while (currentMemberIndex < currentMembers.Size())
	{
		RoomMember roomMember;
		roomMember.steamIDRemote=currentMembers[currentMemberIndex];
		roomMember.systemAddress.address.addr4.sin_addr.s_addr=nextFreeSystemAddress++;
		roomMember.systemAddress.SetPortHostOrder(STEAM_UNUSED_PORT);
		updatedRoomMembers.Insert(roomMember.steamIDRemote,roomMember,true,_FILE_AND_LINE_);

		anyChanges=true;

		// new member
		NotifyNewMember(currentMembers[currentMemberIndex], roomMember.systemAddress);

		currentMemberIndex++;
	}

	if (anyChanges)
	{
		roomMembersById=updatedRoomMembers;
		roomMembersByAddr.Clear(true, _FILE_AND_LINE_);
		for (currentMemberIndex=0; currentMemberIndex < roomMembersById.Size(); currentMemberIndex++)
		{
			roomMembersByAddr.Insert(roomMembersById[currentMemberIndex].systemAddress, roomMembersById[currentMemberIndex], true, _FILE_AND_LINE_);
		}
	}
}