Лучший способ отправить пакет с RakNet

Мне было интересно, как отправить пакет клиенту в архитектуре клиент-сервер с RakNet. В этом образец кода у нас есть эта строка:

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

Тем не менее, прототип является следующим (из класса интерфейса):

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

Как видите, 5-й параметр принимает AddressOrGUID, это означает, что мы можем отправить SystemAddress, как в примере, но также можем отправить уникальный GUID подключенного компьютера.

Есть функция с именем:

RakNet::GetSystemAddressFromGUID();

Но я не уверен, использует ли RakNet его для преобразования GUID, который мы можем отправить в качестве параметра (я не нашел никакого использования этого метода в RakPeer (реализация RakPeerInterface), и я не могу найти, как буферизуются пакеты отправил каждый тик).

Проблема заключается в следующем:

Пример кода отвечает непосредственно на полученный пакет. Однако в игре сервер должен отправлять информацию без получения пакета от клиента. Так что у меня нет доступа к чему-то вроде

packet->systemAddress

потому что нет принятого пакета.

Поэтому мне нужно будет что-то купить в своем классе Player, чтобы знать, как отправлять им пакеты: SystemAddress или RakNetGUID. RakNetGUID проще и легче для хранения, чем SystemAddress.

Но если RakNet использует GetSystemAddressFromGUID (), это не стоит того, потому что он имеет алгоритм O (log (n)).

Нужно ли мне хранить SystemAddress для каждого игрока самостоятельно, или RakNet :: Send () не использует этот метод с RakNetGUID?

Спасибо!

1

Решение

Хорошо, я просто сделал ошибку, неправильно следуя условному утверждению, когда впервые попытался понять исходный код, и, поскольку этот вопрос действительно специфичен, я думаю, что было бы здорово заглянуть в исходный код.

Простой ответ Да, хранить RakNetGUID в классе Player

Подробности здесь:

Итак, во-первых, речь идет только о RakPeer.cpp. Отправной точкой является:

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

Затем у нас есть строка, где вызывается SendBuffered:

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

В методе выше мы можем знать имя переменной буфера:

bufferedCommands.Push(bcs); // Line 4216

И, просматривая каждое место, где используется bufferedCommands, мы находим осмысленное имя метода:

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

Мы можем найти цикл, который отправляет каждое буферизованное сообщение здесь:

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 () попросит RakPeer :: GetSystemIndexFromGuid () найти соответствующий индекс:

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

Наконец, этот последний метод будет хранить индекс непосредственно в RakNet :: RakNetGUID при обнаружении:

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

Если мы вызовем Send () с RakNetGUID, он проверит, установлен ли RakNetGUID :: systemIndex. Если да, то не нужно искать. Иначе, у него будет время линейного поиска O (n) (n = MaximumNumbersOfPeers) для первого отправленного пакета.

Я написал это, чтобы помочь людям понять, как это работает, если у них есть один и тот же вопрос.

0

Другие решения


По вопросам рекламы [email protected]