Цитата:
Сообщение от Persy
f1redark, агась, хелиос. Да, там нет экспорта UNetworkHandler::*, но эту проблему решили еще на ранних этапах.
Зуб ответит точнее.
|
Как решили то, если не секрет?) Можно в общих словах, у меня руки еще не дошли до этих хроник, я все хф ковырял) Судя по его сообщению на форуме, и по времени поста, на хф таки все взлетело в итоге, а вот на руофе там хз, вполне и Фрост может сразу критовать, если обнаружит изменение вмт.
Добавлено через 16 минут
Цитата:
Сообщение от Zubastic
Запилил себе создание новых пакетов:
UNetworkPacket* CreatePacket(uint8_t packetId, uint32_t size)
{
auto new_packet = reinterpret_cast<UNetworkPacket *>(gmalloc(sizeof(UNetworkPacket)));
new_packet->id = packetId;
new_packet->id2 = 0xFFFF;
new_packet->size = size;
new_packet->data = gmalloc(size);
return new_packet;
}Code: C++ Однако у меня разрыв шаблона в коде:
*packet = current_packet;Code: C++ Забираем пакет из пула.
*packet = new_packet;Code: C++ В итоге присваиваем новый пакет указателю.
packets.push(current_packet);Code: C++ Посылаем текущий пакет в пул..., но у него такой же опкод, в итоге не будет ли рекурсии?) 
Собственно вопрос: WTF?! 
|
На самом деле все проще:
if (!packets.empty())
{
*packet = packets.front();
packets.pop();
result = 1;
}
Code: C++
Логика тут такая, у нашей очереди
packets специально сделан приоритет выше, чем у игровой. Таким образом, если у нас в нашей очереди есть пакет, мы сразу отдаем его клиенту, а
DispatchNetworkQueue оригинальный вообще не вызываем, т.е. настоящие пакеты от сервера начнут обрабатываться только тогда, когда клиент разгребет пакеты из нашей очереди.
result = (*DispatchNetworkQueueOrig)(This, 0, ¤t_packet);
if (result)
{
*packet = current_packet;
Code: C++
Здесь дергаем оригинал, если он вернул в
result что то, отличное от нуля, то так как мы этот
result потом возвращем клиенту, мы обязаны заполнить переданный нам в функцию
UNetworkPacket **packet указателем на валидный пакет, я делаю это сразу, чтобы потом не оказалось, что вернули
result != 0, а
*packet не заполнили, и ловим крит, т.е. это как значение по умолчанию, я сразу задаю
*packet как значение, которое вернула оригинальная
DispatchNetworkQueue, а ниже его перезатираю, если возникает такая необходимость.
*packet = new_packet;Code: C++
Собственно, возникла эта самая необходимость, мы хотим, чтобы наш пакет клиент обработал раньше, чем настоящий от сервера, поэтому перезаписываем
*packet.
packets.push(current_packet);Code: C++
Тут мы в нашу очередь записываем настоящий пакет от сервера, чтобы он не потерялся, и когда клиент в очередной раз дернет нашу
DispatchNetworkQueue, сработает код:
if (!packets.empty())
{
*packet = packets.front();
packets.pop();
result = 1;
}
Code: C++
который отдаст клиенту оригинальный пакет. Если оригинальный не нужно передавать, его можно прямо тут грохнуть:
gfree(current_packet->data);
gfree(current_packet);
Code: C++
Добавлено через 19 минут
Цитата:
Сообщение от Zubastic
Такой вопрос по поводу пакетов: судя по логике кода, если пакет удовлетворяет требованиям, то мы создаем новый экземпляр и добавляем его в список, но я не вижу удаления пакета. Только создание нового...
|
Все, чем ты заполнишь выходной формальный параметр
UNetworkHandler **packet, удалит сам клиент, после того, как дернет хендлер для обработки пакета, так что тут все хорошо.