Показать сообщение отдельно
Непрочитано 04.08.2016, 07:08   #97
Пользователь

По умолчанию Re: C++ перехват пакетов

Цитата:
Сообщение от 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, &current_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, удалит сам клиент, после того, как дернет хендлер для обработки пакета, так что тут все хорошо.

Последний раз редактировалось f1redark; 04.08.2016 в 07:34. Причина: Добавлено сообщение
f1redark вне форума Ответить с цитированием