Вернуться   CoderX :: Forums > Lineage II > L2PacketHack > Разработка
Войти через OpenID

Разработка Раздел для совместной разработки/доработки программы

Чат (Новых сообщений с момента вашего последнего визита нет)
Загрузка...
Задавайте ваши вопросы на форуме. Чат предназначен для небольших разговоров.
 
Ответ
 
Опции темы Опции просмотра
Старый 28.02.2012, 22:11   #151
Местный
 
Аватар для Aries
 
Регистрация: 19.01.2011
Сообщений: 241
Сказал Спасибо: 7
Имеет 26 спасибок в 22 сообщенях
Aries пока неопределено
По умолчанию

Ребят вы бы азы хоть немного подучили)))
Нигде ничего не склеивается в какие-то пакеты "побольше".
TCP/IP - это потоковый протокол. Все данные передаются тупо в едином потоке.
Ну а как сказал sko, уже для разделения пакетов на программном уровне, перед началом передаваемой структуры пишется ее размер.

И да, сразу совет. Не считывайте все данные из сокета, как те только туда пришли, т.к. может быть ситуация, что пришла только часть пакета.

Поэтому логика правильного разбора пакетов должна быть такая:
считывается размер пакета из потока. Далее проверяется сколько байт доступно в потоке. Если байт не достаточно, то необходимо ждать, пока придет остальная часть. Далее считывается столько байт, какой размер указан вначале, а опять же не все данные из сокета. Ну и т.д. повторяется...
Aries вне форума   Ответить с цитированием
За это сообщение Aries нажился спасибкой от:
Старый 29.02.2012, 00:48   #152
Пользователь
 
Регистрация: 29.01.2012
Адрес: г. Минск
Сообщений: 64
Сказал Спасибо: 10
Имеет 5 спасибок в 5 сообщенях
Tin-moon пока неопределено
По умолчанию

Все теперь работает как надо
Tin-moon вне форума   Ответить с цитированием
Старый 29.02.2012, 13:08   #153
Новичок
 
Регистрация: 17.02.2012
Сообщений: 3
Сказал Спасибо: 2
Имеет 2 спасибок в 1 сообщении
sko пока неопределено
По умолчанию

Aries, спасибо за дополнение. Вот тут есть пример разбора входящего потока на пакеты.

Код:
while (true){
	lengthLo = _in.read();
	lengthHi = _in.read();
	length = lengthHi * 256 + lengthLo;
	
	if (lengthHi < 0)
	{
		_log.finer("LoginServerThread: Login terminated the connection.");
		break;
	}
	
	byte[] incoming = new byte[length];
	incoming[0] = (byte) lengthLo;
	incoming[1] = (byte) lengthHi;
	
	int receivedBytes = 0;
	int newBytes = 0;
	while (newBytes != -1 && receivedBytes < length - 2)
	{
		newBytes = _in.read(incoming, 2, length - 2);
		receivedBytes = receivedBytes + newBytes;
	}
	
	if (receivedBytes != length - 2)
	{
		_log.warning("Incomplete Packet is sent to the server, closing connection.(LS)");
		break;
	}
}
sko вне форума   Ответить с цитированием
Старый 29.02.2012, 14:04   #154
Новичок
 
Регистрация: 12.02.2012
Сообщений: 27
Сказал Спасибо: 8
Имеет 0 спасибок в 0 сообщенях
ErgoZ пока неопределено
По умолчанию

ребят, выручите плиз, скиньте функции дешифровки РСА ключа (дескрамбл), и саму функцию РСА шифрования, плиз. И вообще нужно ли на интерлюде делать дескрамбл рса ключа из пакета инит, или используем инитовский ключ как есть? в исходниках сервера вроде нету ничего связанного с кодированием рсашки

Вообще проблемка с РСА, у меня иногда рса ключ имеет отрицательное значение (если перевести его в бигинтегер), и из-за этого вылетает ошибка:
java.lang.ArithmeticException: BigInteger: modulus not positive

а если ошибка не вылетает (т.е. рса положительный), то в консоли логин сервера пишет такое:
Created new account : я┐╜p--"#я┐╜╤Зя┐╜▐Юя┐╜ on IP : 127.0.0.1

Я не могу понять, это проблема в РСА, в дескрамбле, или потому что кодировку неправильную выбрал для логина и пароля... и как исправить ошибку modulus not positive
ErgoZ вне форума   Ответить с цитированием
Старый 29.02.2012, 15:17   #155
Пользователь
 
Регистрация: 17.12.2010
Сообщений: 37
Сказал Спасибо: 13
Имеет 1 спасибку в 1 сообщении
glukmaker пока неопределено
По умолчанию

Цитата:
Сообщение от Aries Посмотреть сообщение
И да, сразу совет. Не считывайте все данные из сокета, как те только туда пришли, т.к. может быть ситуация, что пришла только часть пакета.
Правда гуру почему-то советуют все же считывать все данные с сокета в буфер и уже в буфере разбирать их по пакетам...

Вот, когда-то интересовался подобным вопросом.
http://delphimaster.ru/cgi-bin/forum...1319485327&n=4

пришлось вместо первоначального варианта:
Код:
type TPacket: packed record
 case boolean of
 true: (buf: array[0..8191] of byte;);
 false: (len:word;
         typepack:byte;);
 end;

var
 Packet:TPacket;

...
begin
 while true do
   begin
     if recv(FSocket,Packet,2,MSG_PEEK)<2 then Exit;
     if recv(FSocket,Packet,Packet.len,MSG_PEEK)<packet.len then Exit;
     recv(FSocket,Packet,Packet.len,0);
     Obrabotka(Packet); // функция обработки пакета
   end;
end;
переписать приблизительно так (ну это мой вариант на тот момент, сейчас он уже еще доработан, но исходники не при мне):

Код:
...
private
   FBuffer: packed array[0..8191] of byte;
   FStartBuffer:integer;
   FEndBuffer:integer;
...

procedure TMyClass.ReceivePackets;
var
 s:Integer;
begin
 s:=recv(FSocket,FBuffer[FEndBuffer],length(FBuffer)-FEndBuffer,0);

// тут нужно обработать возможные ошибки.

 inc(FEndBuffer,s);
 while true do
   begin
     if FEndBuffer-FStartBuffer<2 then Break;
     move(FBuffer[FStartBuffer],Fpacket,2);
     if FPacket.len>sizeof(FPacket) then
       begin
         // Тут нужно закрыть сокет, и сгенерировать исключение
         // так как прием таких пакетов не планируется
         Exit;
       end;
     if FEndBuffer-FStartBuffer<Fpacket.len then Break;
     move(FBuffer[FStartBuffer],FPacket,Fpacket.len);
     inc(FstartBuffer,Fpacket.len);  // увеличиваем значение стартовой позиции буфера на величину забранных данных
     if FGame then ProcessingGame else ProcessingAuth;  // обработка выделенного пакета
    end;

  // Оптимизация буфера (чтобы обойтись без постоянных сдвигов буфера
  // сдвигать будем только при крайней необходимости)

  // Если буфер пустой, устанавливаем позиции начала и конца на 0
  if FStartBuffer>=FEndBuffer then
  begin
    FStartBuffer:=0;
    FEndBuffer:=0;
  end;
  // Оцениваем длину свободного хвоста буфера, если он менее 2 кб, то сдвигаем данные к началу буфера
  if length(FBuffer)-FEndBuffer<2048 then
  begin
    move(FBuffer[FStartBuffer],FBuffer[0], FEndBuffer-FStartBuffer);
    FEndBuffer:=FEndBuffer-FStartBuffer;
    FStartBuffer:=0;
  end;
end;

Последний раз редактировалось glukmaker, 29.02.2012 в 15:24.
glukmaker вне форума   Ответить с цитированием
Старый 29.02.2012, 15:45   #156
Местный
 
Аватар для Aries
 
Регистрация: 19.01.2011
Сообщений: 241
Сказал Спасибо: 7
Имеет 26 спасибок в 22 сообщенях
Aries пока неопределено
По умолчанию

Цитата:
Сообщение от glukmaker Посмотреть сообщение
Правда гуру почему-то советуют все же считывать все данные с сокета в буфер и уже в буфере разбирать их по пакетам...
ну собственная буферизация имеет смысл только в том случае если обработка данных слишком долгая, и возможно переполнение буфера сокета.
Aries вне форума   Ответить с цитированием
Старый 01.03.2012, 23:35   #157
Новичок
 
Регистрация: 12.02.2012
Сообщений: 27
Сказал Спасибо: 8
Имеет 0 спасибок в 0 сообщенях
ErgoZ пока неопределено
По умолчанию

Ребят. помогите плиз. Вопрос в этом сообщении http://coderx.ru/showpost.php?p=181717&postcount=154
ErgoZ вне форума   Ответить с цитированием
Старый 02.03.2012, 05:01   #158
Пользователь
 
Регистрация: 27.10.2009
Сообщений: 63
Сказал Спасибо: 6
Имеет 21 спасибок в 19 сообщенях
Demion пока неопределено
По умолчанию

Код:
VOID unscrambleRSAKey(BYTE *n)
{
	INT i;

	for(i=0; i<0x40; i++)
		n[0x40 + i] = (BYTE)(n[0x40 + i] ^ n[i]);

	for(i=0; i<4; i++)
		n[0x0d + i] = (BYTE)(n[0x0d + i] ^ n[0x34 + i]);

	for(i=0; i<0x40; i++)
		n[i] = (BYTE)(n[i] ^ n[0x40 + i]);

	for(i=0; i<4; i++)
	{
		BYTE temp = n[0x00 + i];
		n[0x00 + i] = n[0x4d + i];
		n[0x4d + i] = temp;
    	}
}
Demion вне форума   Ответить с цитированием
Старый 02.03.2012, 14:18   #159
Местный
 
Аватар для Sherman
 
Регистрация: 24.04.2008
Сообщений: 364
Сказал Спасибо: 15
Имеет 116 спасибок в 83 сообщенях
Sherman пока неопределено
По умолчанию

Цитата:
Сообщение от Aries Посмотреть сообщение
ну собственная буферизация имеет смысл только в том случае если обработка данных слишком долгая, и возможно переполнение буфера сокета.
Несогласен, т.к. своя буферизация еще и избавляет от проблем связанных с приемом данных из разных фреймов. Если пришел не полный пакет, отпадает необходимость ожидания дочитывания остатка, а такое по моему опыту бывает часто, когда прилетает нецелое количество пакетов. Можно спокойно отпустить сокет для приема дальше, и заняться обработкой имеющихся полных пакетов. Ассинхронное использование сокета короче.

Последний раз редактировалось Sherman, 02.03.2012 в 14:28.
Sherman вне форума   Ответить с цитированием
Старый 02.03.2012, 14:53   #160
Новичок
 
Регистрация: 12.02.2012
Сообщений: 27
Сказал Спасибо: 8
Имеет 0 спасибок в 0 сообщенях
ErgoZ пока неопределено
По умолчанию

Demion, проблема в том, что этот код пробовал использовать, я ему скармливаю свой рса ключ, а в ответ он отдаёт его же, т.е. ничего не изменив... может у меня рса не закодирован???

Добавлено через 6 минут
и проблема в том что вышибает постоянно вот эта ошибка (через раз) :

java.lang.ArithmeticException: BigInteger: modulus not positive

Я понимаю что это потому что после перевода ключа в биг интегер оно может иметь отрицательное значение и при использовании функции:
r = d.modPow(exp, m);
Оно вылетает (в переменную m записан биг интегер, полученный из РСА)

Последний раз редактировалось ErgoZ, 02.03.2012 в 14:53. Причина: Добавлено сообщение
ErgoZ вне форума   Ответить с цитированием
Ответ

  CoderX :: Forums > Lineage II > L2PacketHack > Разработка



Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +4, время: 00:55.

vBulletin style designed by MSC Team.
Powered by vBulletin® Version 3.6.11
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Locations of visitors to this page
Rambler's Top100

Вы хотите чувствовать себя в безопасности? чоп Белган обеспечит её!