2015-07-23 2 views
1

Je me demandais comment envoyer un paquet au client dans une architecture client-serveur avec RakNet. Dans ce sample code nous avons cette ligne:Meilleure façon d'envoyer un paquet avec RakNet

peer->Send(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false); 

Cependant, le prototype est le suivant (de la classe d'interface):

virtual uint32_t Send(const RakNet::BitStream * bitStream, 
         PacketPriority priority, 
         PacketReliability reliability, 
         char orderingChannel, 
         const AddressOrGUID systemIdentifier, 
         bool broadcast, 
         uint32_t forceReceiptNumber=0)=0; 

Comme vous pouvez le voir, le 5ème paramètre prend un AddressOrGUID, cela signifie nous pouvons envoyer le SystemAddress comme dans l'exemple, mais aussi envoyer le GUID unique d'une machine connectée.

Il y a une fonction appelée:

RakNet::GetSystemAddressFromGUID(); 

Mais je ne sais pas si RakNet utilise pour convertir le GUID nous pouvons envoyer comme paramètre (je ne trouve pas l'utilisation de cette méthode dans RakPeer (Implémentation de RakPeerInterface) et je ne suis pas capable de trouver comment les paquets tamponnés sont envoyés chaque tick).

Le problème est le suivant:

Le code exemple répond directement au paquet reçu. Cependant, dans un jeu, le serveur doit envoyer des informations sans recevoir de paquet du client. Donc, je n'ai pas accès à quelque chose comme

packet->systemAddress 

parce qu'il n'y a pas de paquet reçu.

Donc je vais devoir stocker quelque chose dans ma classe Player pour savoir comment leur envoyer des paquets: SystemAddress ou RakNetGUID. RakNetGUID est plus simple et plus léger à stocker qu'une SystemAddress. Mais si RakNet utilise GetSystemAddressFromGUID(), cela ne vaut pas car il a un algorithme O (log (n)).

Ai-je besoin de stocker le SystemAddress pour chaque lecteur moi-même ou RakNet :: Send() n'utilise pas cette méthode avec un RakNetGUID?

Merci!

Répondre

0

Ok Je viens de faire une erreur en ne suivant pas correctement l'énoncé de condition la première fois que j'ai essayé de comprendre le code source, et parce que cette question est vraiment spécifique, je pense que ce serait génial de regarder le code source.

La réponse est simple Oui, magasin RakNetGUID dans la classe du joueur

Détails ici:

Ok donc d'abord, fichier concerné est RakPeer.cpp seulement.Le point de départ est la suivante:

uint32_t RakPeer::Send(const RakNet::BitStream * bitStream, 
         PacketPriority priority, 
         PacketReliability reliability, 
         char orderingChannel, 
         const AddressOrGUID systemIdentifier, 
         bool broadcast, 
         uint32_t forceReceiptNumber) // Line 1366 

Ensuite, nous avons cette ligne où SendBuffered est appelée:

SendBuffered((const char*)bitStream->GetData(), 
      bitStream->GetNumberOfBitsUsed(), 
      priority, 
      reliability, 
      orderingChannel, 
      systemIdentifier, // This is the initial AddressOrGUID 
      broadcast, 
      RemoteSystemStruct::NO_ACTION, 
      usedSendReceipt); // Line 1408 

Dans la méthode ci-dessus, nous pouvons connaître le nom de la variable tampon:

bufferedCommands.Push(bcs); // Line 4216 

Et en recherchant chaque endroit où bufferedCommands est utilisé, nous trouvons un nom significatif de méthode:

bool RakPeer::RunUpdateCycle(BitStream &updateBitStream) // Line 5567 

Nous pouvons trouver une boucle qui envoie chaque message en mémoire tampon ici:

callerDataAllocationUsed=SendImmediate((char*)bcs->data, 
             bcs->numberOfBitsToSend, 
             bcs->priority, 
             bcs->reliability, 
             bcs->orderingChannel, 
             bcs->systemIdentifier, // Initial AddressOfGUID 
             bcs->broadcast, 
             true, 
             timeNS, 
             bcs->receipt); // Line 5630 

RakPeer :: SendImmediate() demandera RakPeer :: GetSystemIndexFromGuid() pour trouver l'indice approprié:

else if (systemIdentifier.rakNetGuid!=UNASSIGNED_RAKNET_GUID) 
     remoteSystemIndex=GetSystemIndexFromGuid(systemIdentifier.rakNetGuid); // Line 4300 

Enfin, cette dernière méthode stocker l'index directement dans le RakNet :: RakNetGUID une fois trouvé:

unsigned int i; 
    for (i = 0; i < maximumNumberOfPeers; i++) 
    { 
     if (remoteSystemList[ i ].guid == input) 
     { 
      // Set the systemIndex so future lookups will be fast 
      remoteSystemList[i].guid.systemIndex = (SystemIndex) i; 

      return i; 
     } 
    } // Line 2440 

Si nous appelons Envoyer() avec RakNetGUID, il vérifiera si RakNetGUID :: systemIndex est défini. Si oui, il n'a pas besoin de chercher. Sinon, il aura un temps de recherche linéaire O (n) (n = maximumNumbersOfPeers) pour le premier paquet envoyé.

J'ai écrit ceci pour aider les gens à comprendre comment cela fonctionne s'ils ont la même question en tête.

+0

Ceci ne donne pas la réponse complète. Comment obtenez-vous GUID en premier lieu? Lorsque vous obtenez l'événement ID_REMOTE_NEW_INCOMING_CONNECTION sur le serveur, comment obtenez-vous le GUID du nouveau client? –