Shadowrun: Awakened
Classes | Public Member Functions | Protected Member Functions | Protected Attributes

ConnectionGraph Class Reference
[ConnectionGraph]

A connection graph. Each peer will know about all other peers. More...

#include <ConnectionGraph.h>

Inheritance diagram for ConnectionGraph:
Inheritance graph
[legend]

List of all members.

Classes

struct  SystemAddressAndGroupId
 A node in the connection graph. More...

Public Member Functions

void AddNewConnection (RakPeerInterface *peer, SystemAddress systemAddress, RakNetGUID guid, ConnectionGraphGroupID groupId)
 Adds a new connection to the connection graph from this system to the specified system. Also assigns a group identifier for that system.
 ConnectionGraph ()
DataStructures::WeightedGraph
< ConnectionGraph::SystemAddressAndGroupId,
unsigned short, false > * 
GetGraph (void)
 Returns the connection graph.
virtual void OnClosedConnection (SystemAddress systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason)
virtual void OnNewConnection (SystemAddress systemAddress, RakNetGUID rakNetGUID, bool isIncoming)
virtual void OnRakPeerShutdown (void)
 Called when RakPeer is shutdown.
virtual PluginReceiveResult OnReceive (Packet *packet)
void RequestConnectionGraph (SystemAddress systemAddress)
 Requests the connection graph from another system.
void SetAutoAddNewConnections (bool autoAdd)
 Automatically add new connections to the connection graph.
void SetGroupId (ConnectionGraphGroupID groupId)
 Sets our own group ID.
void SetPassword (const char *password)
 Plaintext encoding of the password, or 0 for none. If you use a password, use secure connections.
void SubscribeToGroup (ConnectionGraphGroupID groupId)
 Allows adding to the connection graph nodes with this groupId.
void UnsubscribeFromGroup (ConnectionGraphGroupID groupId)
 Disables addition of graph nodes with this groupId.
virtual void Update (void)
 Update is called every time a packet is checked for .
virtual ~ConnectionGraph ()

Protected Member Functions

void AddAndRelayConnection (DataStructures::OrderedList< SystemAddress, SystemAddress > &ignoreList, const SystemAddressAndGroupId &conn1, const SystemAddressAndGroupId &conn2, unsigned short ping, RakPeerInterface *peer)
void AddParticipant (SystemAddress systemAddress)
void BroadcastGraphUpdate (DataStructures::OrderedList< SystemAddress, SystemAddress > &ignoreList, RakPeerInterface *peer)
void DeleteFromPeerList (SystemAddress systemAddress)
bool DeserializeIgnoreList (DataStructures::OrderedList< SystemAddress, SystemAddress > &ignoreList, RakNet::BitStream *inBitstream)
bool DeserializeWeightedGraph (RakNet::BitStream *inBitstream, RakPeerInterface *peer)
void HandleDroppedConnection (RakPeerInterface *peer, SystemAddress systemAddress, unsigned char packetId)
bool IsNewRemoteConnection (const SystemAddressAndGroupId &conn1, const SystemAddressAndGroupId &conn2, RakPeerInterface *peer)
void NotifyUserOfRemoteConnection (const SystemAddressAndGroupId &conn1, const SystemAddressAndGroupId &conn2, unsigned short ping, RakPeerInterface *peer)
void OnConnectionAddition (Packet *packet)
void OnConnectionGraphReply (Packet *packet)
void OnConnectionGraphRequest (Packet *packet)
void OnConnectionGraphUpdate (Packet *packet)
bool OnConnectionLostInternal (Packet *packet, unsigned char packetId)
void OnConnectionRemoval (Packet *packet)
void OnNewConnectionInternal (Packet *packet)
void OnNewIncomingConnection (Packet *packet)
bool RemoveAndRelayConnection (DataStructures::OrderedList< SystemAddress, SystemAddress > &ignoreList, unsigned char packetId, const SystemAddress node1, const SystemAddress node2, RakPeerInterface *peer)
void RemoveParticipant (SystemAddress systemAddress)
void SendConnectionGraph (SystemAddress target, unsigned char packetId, RakPeerInterface *peer)
void SerializeIgnoreListAndBroadcast (RakNet::BitStream *outBitstream, DataStructures::OrderedList< SystemAddress, SystemAddress > &ignoreList, RakPeerInterface *peer)
void SerializeWeightedGraph (RakNet::BitStream *out, const DataStructures::WeightedGraph< ConnectionGraph::SystemAddressAndGroupId, unsigned short, false > &g) const

Protected Attributes

bool autoAddNewConnections
DataStructures::WeightedGraph
< ConnectionGraph::SystemAddressAndGroupId,
unsigned short, false > 
graph
ConnectionGraphGroupID myGroupId
RakNetTime nextWeightUpdate
DataStructures::OrderedList
< SystemAddress, SystemAddress
participantList
char * pw
DataStructures::OrderedList
< ConnectionGraphGroupID,
ConnectionGraphGroupID
subscribedGroups

Detailed Description

Definition at line 34 of file ConnectionGraph.h.


Constructor & Destructor Documentation

ConnectionGraph::ConnectionGraph (  ) 
ConnectionGraph::~ConnectionGraph (  )  [virtual]

Definition at line 69 of file ConnectionGraph.cpp.

References RakNet::OP_DELETE_ARRAY(), and pw.

{
    if (pw)
        RakNet::OP_DELETE_ARRAY(pw, __FILE__, __LINE__);
}


Member Function Documentation

void ConnectionGraph::AddAndRelayConnection ( DataStructures::OrderedList< SystemAddress, SystemAddress > &  ignoreList,
const SystemAddressAndGroupId conn1,
const SystemAddressAndGroupId conn2,
unsigned short  ping,
RakPeerInterface peer 
) [protected]

Definition at line 483 of file ConnectionGraph.cpp.

References DataStructures::WeightedGraph< node_type, weight_type, allow_unlinkedNodes >::AddConnection(), graph, ConnectionGraph::SystemAddressAndGroupId::groupId, ConnectionGraph::SystemAddressAndGroupId::guid, DataStructures::WeightedGraph< node_type, weight_type, allow_unlinkedNodes >::HasConnection(), ID_CONNECTION_GRAPH_NEW_CONNECTION, DataStructures::OrderedList< key_type, data_type, default_comparison_function >::Insert(), IsNewRemoteConnection(), NotifyUserOfRemoteConnection(), RakAssert, SerializeIgnoreListAndBroadcast(), ConnectionGraph::SystemAddressAndGroupId::systemAddress, UNASSIGNED_SYSTEM_ADDRESS(), and RakNet::BitStream::Write().

Referenced by AddNewConnection(), and OnNewConnectionInternal().

{
    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 ConnectionGraph::AddNewConnection ( RakPeerInterface peer,
SystemAddress  systemAddress,
RakNetGUID  guid,
ConnectionGraphGroupID  groupId 
)

Only used and valid when SetAutoAddNewConnections(false) is called. Call this for this system sometime after getting ID_NEW_INCOMING_CONNECTION or ID_CONNECTION_REQUEST_ACCEPTED for systems that contain a connection graph Groups are sets of one or more nodes in the total graph We only add to the graph groups which we subscribe to

Parameters:
[in] peer The instance of RakPeer to send through
[in] systemAddress The system that is connected to us.
[in] guid The system that is connected to us.
[in] groupId Just a number representing a group. Important: 0 is reserved to mean unassigned group ID and is assigned to all systems added with SetAutoAddNewConnections(true)

Definition at line 191 of file ConnectionGraph.cpp.

References AddAndRelayConnection(), autoAddNewConnections, RakPeerInterface::GetAveragePing(), RakPeerInterface::GetExternalID(), RakPeerInterface::GetGuidFromSystemAddress(), ConnectionGraph::SystemAddressAndGroupId::groupId, ConnectionGraph::SystemAddressAndGroupId::guid, DataStructures::OrderedList< key_type, data_type, default_comparison_function >::HasData(), myGroupId, subscribedGroups, ConnectionGraph::SystemAddressAndGroupId::systemAddress, and UNASSIGNED_SYSTEM_ADDRESS().

Referenced by OnNewConnection().

{
    if (autoAddNewConnections==false && subscribedGroups.HasData(groupId)==false)
        return;

    DataStructures::OrderedList<SystemAddress,SystemAddress> ignoreList;
    
    SystemAddressAndGroupId first, second;
    first.systemAddress=systemAddress;
    first.groupId=groupId;
    first.guid=guid;
    second.systemAddress=peer->GetExternalID(systemAddress);
    second.groupId=myGroupId;
    second.guid=peer->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS);

    AddAndRelayConnection(ignoreList, first, second, (unsigned short)peer->GetAveragePing(systemAddress), peer);
}

void ConnectionGraph::AddParticipant ( SystemAddress  systemAddress  )  [protected]

Definition at line 478 of file ConnectionGraph.cpp.

References DataStructures::OrderedList< key_type, data_type, default_comparison_function >::Insert(), and participantList.

Referenced by OnConnectionGraphReply(), and OnConnectionGraphRequest().

{
    participantList.Insert(systemAddress,systemAddress, false, __FILE__, __LINE__);
}

void ConnectionGraph::BroadcastGraphUpdate ( DataStructures::OrderedList< SystemAddress, SystemAddress > &  ignoreList,
RakPeerInterface peer 
) [protected]
void ConnectionGraph::DeleteFromPeerList ( SystemAddress  systemAddress  )  [protected]
bool ConnectionGraph::DeserializeIgnoreList ( DataStructures::OrderedList< SystemAddress, SystemAddress > &  ignoreList,
RakNet::BitStream inBitstream 
) [protected]

Definition at line 356 of file ConnectionGraph.cpp.

References DataStructures::OrderedList< key_type, data_type, default_comparison_function >::Insert(), RakAssert, and RakNet::BitStream::Read().

Referenced by OnConnectionGraphUpdate(), OnConnectionLostInternal(), and OnNewConnectionInternal().

{
    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::DeserializeWeightedGraph ( RakNet::BitStream inBitstream,
RakPeerInterface peer 
) [protected]

Definition at line 423 of file ConnectionGraph.cpp.

References DataStructures::WeightedGraph< node_type, weight_type, allow_unlinkedNodes >::AddConnection(), RakNet::BitStream::AlignReadToByteBoundary(), graph, ConnectionGraph::SystemAddressAndGroupId::groupId, ConnectionGraph::SystemAddressAndGroupId::guid, DataStructures::WeightedGraph< node_type, weight_type, allow_unlinkedNodes >::HasConnection(), DataStructures::OrderedList< key_type, data_type, default_comparison_function >::HasData(), IsNewRemoteConnection(), NotifyUserOfRemoteConnection(), RakAssert, RakNet::BitStream::Read(), RakNet::BitStream::ReadCompressed(), subscribedGroups, ConnectionGraph::SystemAddressAndGroupId::systemAddress, and UNASSIGNED_SYSTEM_ADDRESS().

Referenced by OnConnectionGraphReply(), and OnConnectionGraphUpdate().

{
    unsigned nodeCount, nodeIndex, connectionIndex;
    unsigned short connectionCount;
    SystemAddressAndGroupId node, connection;
    bool anyConnectionsNew=false;
    unsigned short weight;
    inBitstream->ReadCompressed(nodeCount);
    for (nodeIndex=0; nodeIndex < nodeCount; nodeIndex++)
    {
        inBitstream->Read(node.systemAddress);
        inBitstream->Read(node.groupId);
        inBitstream->Read(node.guid);

        inBitstream->AlignReadToByteBoundary();
        if (inBitstream->Read(connectionCount)==false)
        {
            RakAssert(0);
            return false;
        }
        for (connectionIndex=0; connectionIndex < connectionCount; connectionIndex++)
        {
            inBitstream->Read(connection.systemAddress);
            inBitstream->Read(connection.groupId);
            inBitstream->Read(connection.guid);
            if (inBitstream->Read(weight)==false)
            {
                RakAssert(0);
                return false;
            }
            if (subscribedGroups.HasData(connection.groupId)==false ||
                subscribedGroups.HasData(node.groupId)==false)
                continue;
            RakAssert(node.systemAddress!=UNASSIGNED_SYSTEM_ADDRESS);
            RakAssert(connection.systemAddress!=UNASSIGNED_SYSTEM_ADDRESS);
            if (IsNewRemoteConnection(node,connection,peer))
                NotifyUserOfRemoteConnection(node,connection,weight,peer);

            if (graph.HasConnection(node,connection)==false)
                anyConnectionsNew=true;

            graph.AddConnection(node,connection,weight);
        }
    }
    return anyConnectionsNew;
}

DataStructures::WeightedGraph< ConnectionGraph::SystemAddressAndGroupId, unsigned short, false > * ConnectionGraph::GetGraph ( void   ) 
Returns:
The connection graph, stored as map of adjacency lists

Definition at line 90 of file ConnectionGraph.cpp.

References graph.

{
    return &graph;
}

void ConnectionGraph::HandleDroppedConnection ( RakPeerInterface peer,
SystemAddress  systemAddress,
unsigned char  packetId 
) [protected]

Definition at line 180 of file ConnectionGraph.cpp.

References RakPeerInterface::GetExternalID(), RakAssert, RemoveAndRelayConnection(), and RemoveParticipant().

Referenced by OnClosedConnection().

{
    RakAssert(peer);
    RemoveParticipant(systemAddress);
    DataStructures::OrderedList<SystemAddress,SystemAddress> ignoreList;
    RemoveAndRelayConnection(ignoreList, packetId, systemAddress, peer->GetExternalID(systemAddress), peer);
}

bool ConnectionGraph::IsNewRemoteConnection ( const SystemAddressAndGroupId conn1,
const SystemAddressAndGroupId conn2,
RakPeerInterface peer 
) [protected]

Definition at line 571 of file ConnectionGraph.cpp.

References RakPeerInterface::GetExternalID(), graph, ConnectionGraph::SystemAddressAndGroupId::groupId, DataStructures::WeightedGraph< node_type, weight_type, allow_unlinkedNodes >::HasConnection(), DataStructures::OrderedList< key_type, data_type, default_comparison_function >::HasData(), RakPeerInterface::IsConnected(), subscribedGroups, and ConnectionGraph::SystemAddressAndGroupId::systemAddress.

Referenced by AddAndRelayConnection(), and DeserializeWeightedGraph().

{
    if (graph.HasConnection(conn1,conn2)==false &&
        subscribedGroups.HasData(conn1.groupId) &&
        subscribedGroups.HasData(conn2.groupId) &&
        (peer->IsConnected(conn1.systemAddress)==false || peer->IsConnected(conn2.systemAddress)==false))
    {
        SystemAddress externalId1, externalId2;
        externalId1=peer->GetExternalID(conn1.systemAddress);
        externalId2=peer->GetExternalID(conn2.systemAddress);
        return (externalId1!=conn1.systemAddress && externalId1!=conn2.systemAddress &&
            externalId2!=conn1.systemAddress && externalId2!=conn2.systemAddress);
    }
    return false;
}

void ConnectionGraph::NotifyUserOfRemoteConnection ( const SystemAddressAndGroupId conn1,
const SystemAddressAndGroupId conn2,
unsigned short  ping,
RakPeerInterface peer 
) [protected]

Definition at line 586 of file ConnectionGraph.cpp.

References RakPeerInterface::AllocatePacket(), Packet::bitSize, Packet::data, ConnectionGraph::SystemAddressAndGroupId::groupId, Packet::guid, ConnectionGraph::SystemAddressAndGroupId::guid, ID_REMOTE_NEW_INCOMING_CONNECTION, RakPeerInterface::IsConnected(), Packet::length, p, RakPeerInterface::PushBackPacket(), RakNet::BitStream::SetWriteOffset(), RakNetGUID::size(), SystemAddress::size(), Packet::systemAddress, ConnectionGraph::SystemAddressAndGroupId::systemAddress, and RakNet::BitStream::Write().

Referenced by AddAndRelayConnection(), and DeserializeWeightedGraph().

{
    // Create a packet to tell the user of this event
    static const int length=(const int) (sizeof(MessageID) + (SystemAddress::size() + sizeof(ConnectionGraphGroupID) + RakNetGUID::size()) * 2 + sizeof(unsigned short));
    Packet *p = peer->AllocatePacket(length);
    RakNet::BitStream b(p->data, length, false);
    p->bitSize=p->length*8;
    b.SetWriteOffset(0);
    b.Write((MessageID)ID_REMOTE_NEW_INCOMING_CONNECTION);
    b.Write(conn1.systemAddress);
    b.Write(conn1.groupId);
    b.Write(conn1.guid);
    b.Write(conn2.systemAddress);
    b.Write(conn2.groupId);
    b.Write(conn2.guid);
    b.Write(ping);
    if (peer->IsConnected(conn2.systemAddress)==false)
    {
        p->systemAddress=conn2.systemAddress;
        p->guid=conn2.guid;
    }
    else
    {
        p->systemAddress=conn1.systemAddress;
        p->guid=conn1.guid;
    }
    peer->PushBackPacket(p, false);
}

void ConnectionGraph::OnClosedConnection ( SystemAddress  systemAddress,
RakNetGUID  rakNetGUID,
PI2_LostConnectionReason  lostConnectionReason 
) [virtual]

Called when a connection is dropped because the user called RakPeer::CloseConnection() for a particular system

Parameters:
[in] systemAddress The system whose connection was closed
[in] rakNetGuid The guid of the specified system
[in] lostConnectionReason How the connection was closed: manually, connection lost, or notification of disconnection

Reimplemented from PluginInterface2.

Definition at line 170 of file ConnectionGraph.cpp.

References HandleDroppedConnection(), ID_CONNECTION_GRAPH_CONNECTION_LOST, ID_CONNECTION_GRAPH_DISCONNECTION_NOTIFICATION, LCR_CLOSED_BY_USER, LCR_DISCONNECTION_NOTIFICATION, and PluginInterface2::rakPeerInterface.

void ConnectionGraph::OnConnectionAddition ( Packet packet  )  [protected]
void ConnectionGraph::OnConnectionGraphReply ( Packet packet  )  [protected]

Definition at line 253 of file ConnectionGraph.cpp.

References AddParticipant(), BroadcastGraphUpdate(), connectionGraphChannel, Packet::data, DeserializeWeightedGraph(), RakPeerInterface::GetExternalID(), graph, ID_CONNECTION_GRAPH_UPDATE, RakNet::BitStream::IgnoreBits(), DataStructures::OrderedList< key_type, data_type, default_comparison_function >::Insert(), Packet::length, LOW_PRIORITY, SystemAddress::port, pw, RAKNET_DEBUG_PRINTF, PluginInterface2::rakPeerInterface, RELIABLE_ORDERED, PluginInterface2::SendUnified(), SerializeWeightedGraph(), stringCompressor, Packet::systemAddress, and RakNet::BitStream::Write().

Referenced by OnReceive().

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

void ConnectionGraph::OnConnectionGraphRequest ( Packet packet  )  [protected]

Definition at line 227 of file ConnectionGraph.cpp.

References AddParticipant(), connectionGraphChannel, Packet::data, graph, ID_CONNECTION_GRAPH_REPLY, RakNet::BitStream::IgnoreBits(), Packet::length, LOW_PRIORITY, SystemAddress::port, pw, RAKNET_DEBUG_PRINTF, RELIABLE_ORDERED, PluginInterface2::SendUnified(), SerializeWeightedGraph(), stringCompressor, Packet::systemAddress, and RakNet::BitStream::Write().

Referenced by OnReceive().

{
    char password[256];
    RakNet::BitStream inBitstream(packet->data, packet->length, false);
    inBitstream.IgnoreBits(8);
    stringCompressor->DecodeString(password,256,&inBitstream);
    if (pw && pw[0] && strcmp(pw, password)!=0)
        return;

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

    RakNet::BitStream outBitstream;
    outBitstream.Write((MessageID)ID_CONNECTION_GRAPH_REPLY);
    stringCompressor->EncodeString(pw,256,&outBitstream);
    SerializeWeightedGraph(&outBitstream, graph);
    SendUnified(&outBitstream, LOW_PRIORITY, RELIABLE_ORDERED, connectionGraphChannel, packet->systemAddress, false);

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

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

void ConnectionGraph::OnConnectionGraphUpdate ( Packet packet  )  [protected]
bool ConnectionGraph::OnConnectionLostInternal ( Packet packet,
unsigned char  packetId 
) [protected]

Definition at line 337 of file ConnectionGraph.cpp.

References Packet::data, DeserializeIgnoreList(), DataStructures::OrderedList< key_type, data_type, default_comparison_function >::HasData(), RakNet::BitStream::IgnoreBits(), DataStructures::OrderedList< key_type, data_type, default_comparison_function >::Insert(), Packet::length, participantList, PluginInterface2::rakPeerInterface, RakNet::BitStream::Read(), RemoveAndRelayConnection(), and Packet::systemAddress.

Referenced by OnReceive().

{
    // 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::OnConnectionRemoval ( Packet packet  )  [protected]
void ConnectionGraph::OnNewConnection ( SystemAddress  systemAddress,
RakNetGUID  rakNetGUID,
bool  isIncoming 
) [virtual]

Called when we got a new connection

Parameters:
[in] systemAddress Address of the new connection
[in] rakNetGuid The guid of the specified system
[in] isIncoming If true, this is ID_NEW_INCOMING_CONNECTION, or the equivalent

Reimplemented from PluginInterface2.

Definition at line 117 of file ConnectionGraph.cpp.

References AddNewConnection(), autoAddNewConnections, PluginInterface2::rakPeerInterface, and RequestConnectionGraph().

{
    if (isIncoming==false)
    {
        if (autoAddNewConnections==false)
            return;

        RequestConnectionGraph(systemAddress);

        // 0 is the default groupId
        AddNewConnection(rakPeerInterface, systemAddress, rakNetGUID, 0);
    }
    else
    {
        if (autoAddNewConnections==false)
            return;

        // 0 is the default groupId
        AddNewConnection(rakPeerInterface, systemAddress, rakNetGUID, 0);
    }
}

void ConnectionGraph::OnNewConnectionInternal ( Packet packet  )  [protected]

Definition at line 314 of file ConnectionGraph.cpp.

References AddAndRelayConnection(), Packet::data, DeserializeIgnoreList(), ConnectionGraph::SystemAddressAndGroupId::groupId, ConnectionGraph::SystemAddressAndGroupId::guid, DataStructures::OrderedList< key_type, data_type, default_comparison_function >::HasData(), RakNet::BitStream::IgnoreBits(), DataStructures::OrderedList< key_type, data_type, default_comparison_function >::Insert(), Packet::length, participantList, PluginInterface2::rakPeerInterface, RakNet::BitStream::Read(), ConnectionGraph::SystemAddressAndGroupId::systemAddress, and Packet::systemAddress.

Referenced by OnReceive().

{
    // 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 ConnectionGraph::OnNewIncomingConnection ( Packet packet  )  [protected]
void ConnectionGraph::OnRakPeerShutdown ( void   )  [virtual]
PluginReceiveResult ConnectionGraph::OnReceive ( Packet packet  )  [virtual]

OnReceive is called for every packet.

Parameters:
[in] packet the packet that is being returned to the user
Returns:
True to allow the game and other plugins to get this message, false to absorb it

Reimplemented from PluginInterface2.

Definition at line 138 of file ConnectionGraph.cpp.

References Packet::data, ID_CONNECTION_GRAPH_CONNECTION_LOST, ID_CONNECTION_GRAPH_DISCONNECTION_NOTIFICATION, ID_CONNECTION_GRAPH_NEW_CONNECTION, ID_CONNECTION_GRAPH_REPLY, ID_CONNECTION_GRAPH_REQUEST, ID_CONNECTION_GRAPH_UPDATE, OnConnectionGraphReply(), OnConnectionGraphRequest(), OnConnectionGraphUpdate(), OnConnectionLostInternal(), and OnNewConnectionInternal().

{
    switch (packet->data[0]) 
    {
    case ID_CONNECTION_GRAPH_REQUEST:
        OnConnectionGraphRequest(packet);
        return RR_STOP_PROCESSING_AND_DEALLOCATE;
    case ID_CONNECTION_GRAPH_REPLY:
        OnConnectionGraphReply(packet);
        return RR_CONTINUE_PROCESSING;
    case ID_CONNECTION_GRAPH_UPDATE:
        OnConnectionGraphUpdate(packet);
        return RR_STOP_PROCESSING_AND_DEALLOCATE;
    case ID_CONNECTION_GRAPH_NEW_CONNECTION:
        OnNewConnectionInternal(packet);
        return RR_STOP_PROCESSING_AND_DEALLOCATE;
        // Remove connection lost
    case ID_CONNECTION_GRAPH_CONNECTION_LOST:
    case ID_CONNECTION_GRAPH_DISCONNECTION_NOTIFICATION:
        if (OnConnectionLostInternal(packet, packet->data[0]))
        {
            if (packet->data[0]==ID_CONNECTION_GRAPH_CONNECTION_LOST)
                packet->data[0]=ID_REMOTE_CONNECTION_LOST;
            else
                packet->data[0]=ID_REMOTE_DISCONNECTION_NOTIFICATION;
            return RR_CONTINUE_PROCESSING; // Return this packet to the user
        }       
        return RR_STOP_PROCESSING_AND_DEALLOCATE;
    }

    return RR_CONTINUE_PROCESSING;
}

bool ConnectionGraph::RemoveAndRelayConnection ( DataStructures::OrderedList< SystemAddress, SystemAddress > &  ignoreList,
unsigned char  packetId,
const SystemAddress  node1,
const SystemAddress  node2,
RakPeerInterface peer 
) [protected]

Definition at line 516 of file ConnectionGraph.cpp.

References graph, DataStructures::WeightedGraph< node_type, weight_type, allow_unlinkedNodes >::HasConnection(), DataStructures::OrderedList< key_type, data_type, default_comparison_function >::Insert(), DataStructures::WeightedGraph< node_type, weight_type, allow_unlinkedNodes >::RemoveConnection(), SerializeIgnoreListAndBroadcast(), ConnectionGraph::SystemAddressAndGroupId::systemAddress, and RakNet::BitStream::Write().

Referenced by HandleDroppedConnection(), and OnConnectionLostInternal().

{
    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::RemoveParticipant ( SystemAddress  systemAddress  )  [protected]
void ConnectionGraph::RequestConnectionGraph ( SystemAddress  systemAddress  ) 

Only necessary to call if SetAutoAddNewConnections(false) is called. You should call this sometime after getting ID_CONNECTION_REQUEST_ACCEPTED and systemAddress is or should be a node on the connection graph

Parameters:
[in] systemAddress The system to send to

Definition at line 216 of file ConnectionGraph.cpp.

References connectionGraphChannel, ID_CONNECTION_GRAPH_REQUEST, LOW_PRIORITY, SystemAddress::port, pw, RAKNET_DEBUG_PRINTF, PluginInterface2::rakPeerInterface, RELIABLE_ORDERED, RakPeerInterface::Send(), stringCompressor, and RakNet::BitStream::Write().

Referenced by OnNewConnection().

{
    RakNet::BitStream outBitstream;
    outBitstream.Write((MessageID)ID_CONNECTION_GRAPH_REQUEST);
    stringCompressor->EncodeString(pw,256,&outBitstream);
    rakPeerInterface->Send(&outBitstream, LOW_PRIORITY, RELIABLE_ORDERED, connectionGraphChannel, systemAddress, false);

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

void ConnectionGraph::SendConnectionGraph ( SystemAddress  target,
unsigned char  packetId,
RakPeerInterface peer 
) [protected]
void ConnectionGraph::SerializeIgnoreListAndBroadcast ( RakNet::BitStream outBitstream,
DataStructures::OrderedList< SystemAddress, SystemAddress > &  ignoreList,
RakPeerInterface peer 
) [protected]

Definition at line 546 of file ConnectionGraph.cpp.

References connectionGraphChannel, RakPeerInterface::GetExternalID(), DataStructures::OrderedList< key_type, data_type, default_comparison_function >::HasData(), DataStructures::OrderedList< key_type, data_type, default_comparison_function >::Insert(), DataStructures::List< list_type >::Insert(), LOW_PRIORITY, participantList, RELIABLE_ORDERED, RakPeerInterface::Send(), DataStructures::List< list_type >::Size(), DataStructures::OrderedList< key_type, data_type, default_comparison_function >::Size(), and RakNet::BitStream::Write().

Referenced by AddAndRelayConnection(), BroadcastGraphUpdate(), and RemoveAndRelayConnection().

{
    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 ConnectionGraph::SerializeWeightedGraph ( RakNet::BitStream out,
const DataStructures::WeightedGraph< ConnectionGraph::SystemAddressAndGroupId, unsigned short, false > &  g 
) const [protected]

Definition at line 373 of file ConnectionGraph.cpp.

References RakNet::BitStream::AlignWriteToByteBoundary(), DataStructures::WeightedGraph< node_type, weight_type, allow_unlinkedNodes >::GetConnectionAtIndex(), DataStructures::WeightedGraph< node_type, weight_type, allow_unlinkedNodes >::GetConnectionCount(), DataStructures::WeightedGraph< node_type, weight_type, allow_unlinkedNodes >::GetNodeAtIndex(), DataStructures::WeightedGraph< node_type, weight_type, allow_unlinkedNodes >::GetNodeCount(), RakNet::BitStream::GetWriteOffset(), ConnectionGraph::SystemAddressAndGroupId::groupId, ConnectionGraph::SystemAddressAndGroupId::guid, SystemAddress::port, RAKNET_DEBUG_PRINTF, RakNet::BitStream::SetWriteOffset(), ConnectionGraph::SystemAddressAndGroupId::systemAddress, RakNet::BitStream::Write(), and RakNet::BitStream::WriteCompressed().

Referenced by BroadcastGraphUpdate(), OnConnectionGraphReply(), and OnConnectionGraphRequest().

{
    unsigned nodeIndex, connectionIndex;
    BitSize_t countOffset, oldOffset;
    unsigned short count;
    SystemAddressAndGroupId node1, node2;
    unsigned short weight;
    out->WriteCompressed(g.GetNodeCount());
    for (nodeIndex=0; nodeIndex < g.GetNodeCount(); nodeIndex++)
    {
        // Write the node
        node1=g.GetNodeAtIndex(nodeIndex);
#ifdef _CONNECTION_GRAPH_DEBUG_PRINT
        RAKNET_DEBUG_PRINTF("[%i] ", node1.systemAddress.port);
#endif
        out->Write(node1.systemAddress);
        out->Write(node1.groupId);
        out->Write(node1.guid);

        // Write the adjacency list count
        count=(unsigned short)g.GetConnectionCount(nodeIndex);
        out->AlignWriteToByteBoundary();
        countOffset=out->GetWriteOffset();
        out->Write(count);
        count=0;
        for (connectionIndex=0; connectionIndex < g.GetConnectionCount(nodeIndex); connectionIndex++)
        {
            g.GetConnectionAtIndex(nodeIndex, connectionIndex, node2, weight);
            // For efficiencies' sake, only serialize the upper half of the connection pairs
            if (node2 > node1)
            {
                count++;
                out->Write(node2.systemAddress);
                out->Write(node2.groupId);
                out->Write(node2.guid);
                out->Write(weight);

#ifdef _CONNECTION_GRAPH_DEBUG_PRINT
                RAKNET_DEBUG_PRINTF("(%i) ", node2.systemAddress.port);
#endif
            }
        }

        // Go back and change how many elements were written
        oldOffset=out->GetWriteOffset();
        out->SetWriteOffset(countOffset);
        out->Write(count);
        out->SetWriteOffset(oldOffset);
    }
}

void ConnectionGraph::SetAutoAddNewConnections ( bool  autoAdd  ) 

Defaults to true If true, then the system will automatically add all new connections for you, assigning groupId 0 to these systems. If you want more control, you should call SetAutoAddNewConnections(false); When false, it is up to you to call RequestConnectionGraph and AddNewConnection to complete the graph However, this way you can choose which nodes are on the graph for this system and can assign groupIds to those nodes

Parameters:
[in] autoAdd true to automatically add new connections to the connection graph. False to not do so.

Definition at line 94 of file ConnectionGraph.cpp.

References autoAddNewConnections.

{
    autoAddNewConnections=autoAdd;
}

void ConnectionGraph::SetGroupId ( ConnectionGraphGroupID  groupId  ) 

Only used and valid when SetAutoAddNewConnections(false) is called. Defaults to 0

Parameters:
[in] groupId Our group ID

Definition at line 187 of file ConnectionGraph.cpp.

References myGroupId.

{
    myGroupId=groupId;
}

void ConnectionGraph::SetPassword ( const char *  password  ) 

Definition at line 75 of file ConnectionGraph.cpp.

References RakNet::OP_DELETE_ARRAY(), pw, RakAssert, and rakMalloc_Ex.

{
    if (pw)
    {
        RakNet::OP_DELETE_ARRAY(pw, __FILE__, __LINE__);
        pw=0;
    }

    if (password && password[0])
    {
        RakAssert(strlen(password)<256);
        pw=(char*) rakMalloc_Ex( strlen(password)+1, __FILE__, __LINE__ );
        strcpy(pw, password);
    }
}

void ConnectionGraph::SubscribeToGroup ( ConnectionGraphGroupID  groupId  ) 

By default, you subscribe to group 0, which are all systems automatically added with SetAutoAddNewConnections(true) Calling this does not add nodes which were previously rejected due to an unsubscribed group - it only allows addition of nodes after the fact

Parameters:
[in] groupId Just a number representing a group. 0 is reserved to mean unassigned group ID, automatically added with SetAutoAddNewConnections(true)

Definition at line 208 of file ConnectionGraph.cpp.

References DataStructures::OrderedList< key_type, data_type, default_comparison_function >::Insert(), and subscribedGroups.

{
    subscribedGroups.Insert(groupId, groupId, true, __FILE__, __LINE__);
}

void ConnectionGraph::UnsubscribeFromGroup ( ConnectionGraphGroupID  groupId  ) 

Calling this does not add remove nodes with this groupId which are already present in the graph. It only disables addition of nodes after the fact

Parameters:
[in] groupId Just a number representing a group. 0 is reserved to mean unassigned group ID, automatically added with SetAutoAddNewConnections(true)

Definition at line 212 of file ConnectionGraph.cpp.

References DataStructures::OrderedList< key_type, data_type, default_comparison_function >::Remove(), and subscribedGroups.

{
    subscribedGroups.Remove(groupId);
}

void ConnectionGraph::Update ( void   )  [virtual]

Reimplemented from PluginInterface2.

Definition at line 104 of file ConnectionGraph.cpp.

{

//  RakNetTime time = RakNet::GetTime();

    // If the time is past the next weight update time, then refresh all pings of all connected participants and send these out if substantially different.
//  if (forceBroadcastTime && time > forceBroadcastTime)
//  {
//      DataStructures::OrderedList<SystemAddress,SystemAddress> none;
    //  BroadcastGraphUpdate(none, peer);
//      forceBroadcastTime=0;
//  }
}


Member Data Documentation

Definition at line 155 of file ConnectionGraph.h.

Referenced by AddNewConnection(), ConnectionGraph(), and SetGroupId().

Definition at line 149 of file ConnectionGraph.h.

char* ConnectionGraph::pw [protected]

The documentation for this class was generated from the following files:

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net