Вернуться   CoderX :: Forums > Основные форумы > Программинг
Войти через OpenID

Программинг Форум для тем связанных с программированием

Чат (Новых сообщений с момента вашего последнего визита нет)
Загрузка...
Задавайте ваши вопросы на форуме. Чат предназначен для небольших разговоров.
 
Ответ
 
Опции темы Опции просмотра
Старый 28.10.2011, 17:17   #11
Пользователь
 
Аватар для Be3geBJIa3
 
Регистрация: 23.01.2008
Сообщений: 93
Сказал Спасибо: 31
Имеет 65 спасибок в 23 сообщенях
Be3geBJIa3 пока неопределено
По умолчанию

ItemName-ru.dat победил, для него не хватает масива UINT(i)
потратил 3 дня.
у меня это выглядит вот так, для скриптового парсера.

FS = "\t";
HEADER = 1;
RECCNT = OFF;
MTXCNT_OUT = 1;
MATCNT_OUT = 1;
ORD_IGNORE = 0;
{
UINT id;
UNICODE name;
UNICODE add_name;
ASCF description;
INT popup;

UINT supercnt1;
UINT item_cnt1(supercnt1);
UINT itemid_1(item_cnt1);
UINT cnt1;
ASCF set_bonus_desc(cnt1);

UINT supercnt2;
UINT item_cnt2(supercnt2);
UINT itemid_2(item_cnt2);
UINT cnt2;
ASCF set_extra_desc(cnt2);

UINT supercnt3;
UINT item_cnt3(supercnt3);
UINT itemid_3(item_cnt3);
UINT cnt3;
ASCF set_extra_desc3(cnt3);

UINT special_enchant_amount;
ASCF special_enchant_desc;
UINT unk2;
}

Для создания l2infob.dat из этого необходимо только
UINT id;
UNICODE name;
UNICODE add_name;
ASCF description;

Разобрал actionname-ru.dat, потратил 15 минут. Ничего сложного нет.
----------------------------
Пока это только простой парсер, помогите написать или посоветуйте как это все хранить в памяти и потом уже записывать в txt, проблема в том, что заранее не известно количество элементов масива и постоянно меняется и при простой записи в txt все сдвинуто в кучу.

Последний раз редактировалось Be3geBJIa3, 28.10.2011 в 18:12.
Be3geBJIa3 вне форума   Ответить с цитированием
Старый 23.07.2012, 20:21   #12
Новичок
 
Регистрация: 23.07.2012
Адрес: Красноярск
Сообщений: 1
Сказал Спасибо: 0
Имеет 0 спасибок в 0 сообщенях
METAJIJI пока неопределено
По умолчанию

Код:
#https://code.google.com/p/la2-encdec/source/browse/trunk/
# L2 file decoder (18:33 14.07.2012).
# @author METAJIJI Kadyshev Denis
#

use warnings;
use Time::HiRes qw(gettimeofday);
use strict;
use Encode;             # use Encode qw(from_to);
#use MIME::Base64;      # encode_base64 () и decode_base64 () для кодирования и декодирования соответственно.
use Compress::Zlib qw(compress uncompress);
use Math::BigInt;
use Math::BigInt only => 'GMP';
use Data::Dumper;

my $original = 0;       # временно, в дальнейшем тут надо как-то сделать "прием этого значения"

my $t0 = gettimeofday;  #начали отсчет
print qq[\n========================= -------- Start -------- =========================\n];

# RSA keys:
my $priv_key    = q[0x30B4C2D798D47086145C75063C8E841E719776E400291D7838D3E6C4405B504C6A07F8FCA27F32B86643D2649D1D5F124CDD0BF272F0909DD7352FE10A77B34D831043D9AE541F8263C6FE3D1C14C2F04E43A7253A6DDA9A8C1562CBD493C1B631A1957618AD5DFE5CA28553F746E2FC6F2DB816C7DB223EC91E955081C1DE65];
$priv_key       = Math::BigInt->new($priv_key);
my ($mod, $exp);
if ($original == 1) {   # 1 - File is Original | 0 - File is not Original
        my $s = q[0x97df398472ddf737ef0a0cd17e8d172f0fef1661a38a8ae1d6e829bc1c6e4c3cfc19292dda9ef90175e46e7394a18850b6417d03be6eea274d3ed1dde5b5d7bde72cc0a0b71d03608655633881793a02c9a67d9ef2b45eb7c08d4be329083ce450e68f7867b6749314d40511d09bc5744551baa86a89dc38123dc1668fd72d83];
        $mod = Math::BigInt->new($s);
        $exp = Math::BigInt->new('0x35');
} else {
        my $s= q[0x75b4d6de5c016544068a1acf125869f43d2e09fc55b8b1e289556daf9b8757635593446288b3653da1ce91c87bb1a5c18f16323495c55d7d72c0890a83f69bfd1fd9434eb1c02f3e4679edfa43309319070129c267c85604d87bb65bae205de3707af1d2108881abb567c3b3d069ae67c3a4c6a3aa93d26413d4c66094ae2039];
        $mod = Math::BigInt->new($s);
        $exp = Math::BigInt->new('0x1d');
}

# Вычисление времени выполения скрипта
sub work_time {
        my ($t0) = @_;

        my $t1 = gettimeofday;                          # Узнаем время в текущей точке
        my $elapsed = sprintf("%1.7f",$t1 - $t0);       # Округляем до 3 знаков после запятой
        print qq[\n===================== --- Done in: $elapsed sec. --- =====================\n];
}

# Запись в файл
sub save_file {
#&save_file($cfg->{'file_out'}, @a);
        my ($file, $act, $data) = @_;

        if (!$data) {
                print qq[No Data, Error!\n];
                exit 1;
        };

        open(FILE, ">$file-$act");
        binmode FILE;
        print(FILE $data);
        close(FILE);
        print qq[\t\tFile: ${file}-${act}\n\t\t\t successfully writed!\n];
        &work_time($t0);
}

sub la2_decode {
        my ($file) = @_;
        &save_file($file, 'dec', &l2decode_413($file));
}

sub la2_encode {
        my ($file) = @_;
        &save_file($file, 'enc', &l2encode_413($file));
}


sub l2decode_413 {
        my ($filename) = @_;
#       use IO::Uncompress::AnyInflate qw(anyinflate $AnyInflateError);

        open(FILE, "<$filename") || die qq[Error: Can not read '$filename'];
        binmode FILE;

        my $filesize = (stat(FILE))[7];
        return if ($filesize < 28 + 128);

        my $blocks = int(($filesize - 28)/128);
        return if ($blocks < 1);

        my $file;
        read(FILE, $file, $filesize);
        close(FILE);
        return if (!$file);

        my $head = substr($file, 0, 28); #print Dumper($head);
        Encode::from_to($head, 'UTF-16LE', 'UTF-8');
        return if ($head ne 'Lineage2Ver413');

        my $size = $blocks * (128 * 2);
        $file = unpack('H*', substr($file, 28, $size)); # переводим файл в hex, т.к. perl не умеет работать с бинарными данными. в нашем случае substr.

        my $data_gz;
        for (my $i = 0; $i < $blocks; ++$i) {
                my $block = substr($file, $i * (128 * 2), 128 * 2);
                my $res = '0x' . $block;#               my $res = '0x' . unpack('H*', $block);
#print '$enc: ['.$res."]\n";
                my $hex = Math::BigInt->new($res)->bmodpow($exp,$mod)->as_hex();
#print '$dec: ['.$hex."]\n";
#my $enc = Math::BigInt->new($hex)->bmodpow($priv_key,$mod)->as_hex();
#print '$enc: ['.$enc."]\n";

                return if (length($hex) != 252);
                substr($hex, 0, 2) =~ s/^0x//;

                my $s = pack('H*' , $hex);
                $size = ord($s);
                return if ($size > length($s) - 1);

                if ($size ne 124) {     #($size ne 0x7c) | ($size ne oct('0x7c'))
                        my $p = length($s) - $size;
                        while ($p > 2 && substr($s, $p - 1, 1) ne "\0") { --$p; }
                        $s = substr($s, $p, $size);
                } else {
                        $s = substr($s, -$size);
                }
                $data_gz .= $s;
        }

        my $a = unpack('L', $data_gz);
        return if (!defined($a));
        $size = int($a);

        $data_gz = substr($data_gz, 4);

        my $result = uncompress($data_gz);
#print $result;
        return if (length($result) != $size);

        return $result;
}

sub l2encode_413 {
        my ($filename) = @_;
print qq[filename: $filename\n];
        open(FILE, "<$filename") || die qq[Error: Can not read '$filename'];
        binmode FILE;

        my $filesize = (stat(FILE))[7];
        return if ($filesize < 128);    # тут мы пока еще в binmode, поэтому 128
print qq[filesize: $filesize\n];

        read(FILE, my $file, $filesize);
        return if (!$file);
        close(FILE);

        my $data_gz = compress($file,6);        # Сжимаем файл
        my $size = pack('L', $filesize);# Конвертируем размер файла в Long вид.
        $data_gz = $size . $data_gz;    # пихаем в начало архива 4 байта с размером архива.

#open(FILE, ">${filename}+head4") || die qq[Error: Can not read '$filename'];
#binmode FILE;
#print FILE $data_gz;
#close(FILE);

        $data_gz = unpack('H*', $data_gz);      # Конвертируем в HEX вид, чтобы perl'у было легче работать с архивом :) ну не любит он бинарные данные...
        $data_gz = substr($data_gz, 0, 12) . pack('H*', unpack('H*', substr($data_gz, 12, 2)) - 1) . substr($data_gz, 14);# исправляем какой-то байт в начале файла...
        $size = length($data_gz);
        my $block_size = 248;
        my $blocks = int(($size)/$block_size);  # Тут 248, т.к. нужно 250 для функции криптования, но 2 байта уйдут на "заголовок строки" в котором будет размер блока - 7c
        return if ($blocks < 1);
        my $last_str = $size % $block_size;     # Проверяем остаток от деления, чтобы узнать сколько у нас осталось неполных байт.
print 'size: ['.($size/2)."]\n";
print qq[blocks: $blocks\n];

        my $data;
        for (my $i = 0; $i < $blocks; ++$i) {
                my $block = substr($data_gz, $i * $block_size, $block_size);
                $block = '0x7c' . $block;
                my $hex = Math::BigInt->from_hex($block)->bmodpow($priv_key,$mod)->as_hex();
                substr($hex, 0, 2) =~ s/^0x//;
                my $zeroNUM = 256 - length($hex);
                if ($zeroNUM != 0) {
                        my $zeros;
                        for (my $i = 0; $i < $zeroNUM; $i++) { $zeros .= '0'}
                        $hex = $zeros . $hex;
                }
                return if (length($hex) != 256);
#print '$enc: [0x'.$hex."]\n"; print '$dec: ['.$block."]\n";
#print 'length($hex): ['.length($hex)."]\n";

                $data .= pack('H*' , $hex);
        }

        my $block = substr($data_gz, -$last_str, -8);
        my $size_str = unpack('H2' , pack('L' , length($block)));
        $block = $block . '000000ffff0300' . substr($data_gz, -8);

#print 'size_str: ['.$size_str."]\n";

        my $zeros = '';
        for (my $i = 18; $i < $block_size - $last_str; $i++) { $zeros .= '0'}
        $block = '0x' . $size_str . $zeros . $block . '0000';

        my $hex = Math::BigInt->new($block)->bmodpow($priv_key,$mod)->as_hex();
        substr($hex, 0, 2) =~ s/^0x//;
        $data .= pack('H*' , $hex);
#print '$enc: [0x'.$hex."]\n"; print '$dec: ['.$block."]\n";
#print 'length($hex): ['.length($hex)."]\n";


        my $result = q[Lineage2Ver413];
        Encode::from_to($result, 'UTF-8', 'UTF-16LE');  # Получаем заголовок файла в UTF-16LE кодировке.
        $result .= $data;
        $result .= pack('H*', '000000000000000000000000');# добавляем 24 ноля, чтобы "выровнять файл"
        $result .= pack('H*', '00000000');      #TODO - узнать что сюда добавляется.
        $result .= pack('H*', '00000000');# добавляем 8 нолей, чтобы "выровнять файл"

#print unpack('L', pack('H*', 'dda08f96'))."\n";
        return $result;

}
return 1;
Попробовал написать на perl, декодирование очень даже работает, а вот кодирование что-то не очень, может кто поможет?
METAJIJI вне форума   Ответить с цитированием
Старый 07.08.2016, 02:54   #13
Новичок
 
Регистрация: 25.03.2014
Сообщений: 11
Сказал Спасибо: 4
Имеет 0 спасибок в 0 сообщенях
user713 пока неопределено
По умолчанию

Ой чувствую щас за некропостинг получу по ушам, но всёже... В конце всех фалов закриптованных 413 алгоритмом присутствуют дополнительные 20 байт... Линейка 20 нулей прекрасно кушает, НО всёже интересно откуда l2encdec берет эти байты? Заметил что при изменении 413 на 414 меняются только 4 байта в конце. Крипт/декрипт свой сделал, но вот непойму что это в конце. Какая-то контрольная сумма? Кто знает как ее просчитать?

P.S: в оригинальных файлах ладвы эти байты в конце не пустые, собственно это и смущает...

P.P.S: а еще кому знакома цифра 143114 - подскажите как бороться, у меня уже моск вывернулся в непонятном направлении :\

Последний раз редактировалось user713, 07.08.2016 в 08:14.
user713 вне форума   Ответить с цитированием
Старый 11.08.2016, 22:38   #14
Местный
 
Аватар для ScythLab
 
Регистрация: 24.10.2014
Сообщений: 190
Сказал Спасибо: 4
Имеет 42 спасибок в 40 сообщенях
ScythLab пока неопределено
По умолчанию

Цитата:
Сообщение от user713 Посмотреть сообщение
Какая-то контрольная сумма? Кто знает как ее просчитать?
Очень похоже на нее. Попробуй обычный xor DWORD'ов, если не поможет, то расчет Crc32, не думаю что туда что-то сложное запихали.

Цитата:
P.P.S: а еще кому знакома цифра 143114 - подскажите как бороться, у меня уже моск вывернулся в непонятном направлении :\
если скажешь откуда эту цифру взял, может кто-то и подскажет
__________________
Хобби: разработка бота для Lineage.
ScythLab вне форума   Ответить с цитированием
Старый 15.08.2016, 10:01   #15
Новичок
 
Регистрация: 25.03.2014
Сообщений: 11
Сказал Спасибо: 4
Имеет 0 спасибок в 0 сообщенях
user713 пока неопределено
По умолчанию

Цитата:
Сообщение от ScythLab Посмотреть сообщение
если скажешь откуда эту цифру взял, может кто-то и подскажет
После сжатия большого количества данных ZLIB'ом именно это количество байт (уже сжатых) сходится с данными упакованными темже l2encdec, все что выше - полностью разное. И вдобавок zlib не хочет распаковывать информацию которую сам же и упаковал, которая больше этого числа Я конечно понимаю что это скорей всего мой косяк, но перепробовав десятки разных версий zlib'a и встретив эту цифру абсолютно везде, я всетаки сделал выводы что ошибка "типична" для данного продукта.

P.S: жму стандартным compress, в то время как l2encdec напрямую использует методы inflateInit, inflate и inflateEnd

Последний раз редактировалось user713, 15.08.2016 в 10:19.
user713 вне форума   Ответить с цитированием
Старый 22.08.2016, 10:49   #16
Местный
 
Аватар для ScythLab
 
Регистрация: 24.10.2014
Сообщений: 190
Сказал Спасибо: 4
Имеет 42 спасибок в 40 сообщенях
ScythLab пока неопределено
По умолчанию

Цитата:
Сообщение от user713 Посмотреть сообщение
После сжатия большого количества данных ZLIB'ом именно это количество байт (уже сжатых) сходится с данными упакованными темже l2encdec, все что выше - полностью разное. И вдобавок zlib не хочет распаковывать информацию которую сам же и упаковал, которая больше этого числа Я конечно понимаю что это скорей всего мой косяк, но перепробовав десятки разных версий zlib'a и встретив эту цифру абсолютно везде, я всетаки сделал выводы что ошибка "типична" для данного продукта.

P.S: жму стандартным compress, в то время как l2encdec напрямую использует методы inflateInit, inflate и inflateEnd
Уверен, что это твой косяк, когда работал с ZLib'ом вообще не помню каких либо сложностей, все сжималось и разжималось, для любых файлов ла2.
__________________
Хобби: разработка бота для Lineage.
ScythLab вне форума   Ответить с цитированием
За это сообщение ScythLab нажился спасибкой от:
Старый 25.08.2016, 11:02   #17
Новичок
 
Регистрация: 25.03.2014
Сообщений: 11
Сказал Спасибо: 4
Имеет 0 спасибок в 0 сообщенях
user713 пока неопределено
По умолчанию

Спасибо) Будем исправляться
user713 вне форума   Ответить с цитированием
Старый 14.11.2016, 11:25   #18
Новичок
 
Регистрация: 14.11.2016
Сообщений: 1
Сказал Спасибо: 0
Имеет 0 спасибок в 0 сообщенях
Stenly76 пока неопределено
По умолчанию

Цитата:
Сообщение от user713 Посмотреть сообщение
Ой чувствую щас за некропостинг получу по ушам, но всёже... В конце всех фалов закриптованных 413 алгоритмом присутствуют дополнительные 20 байт... Линейка 20 нулей прекрасно кушает, НО всёже интересно откуда l2encdec берет эти байты? Заметил что при изменении 413 на 414 меняются только 4 байта в конце. Крипт/декрипт свой сделал, но вот непойму что это в конце. Какая-то контрольная сумма? Кто знает как ее просчитать?

P.S: в оригинальных файлах ладвы эти байты в конце не пустые, собственно это и смущает...

P.P.S: а еще кому знакома цифра 143114 - подскажите как бороться, у меня уже моск вывернулся в непонятном направлении :\
и от меня некропост
это CRC32 взятый начиная с самого начала включая заголовок (Lineage2Ver) и по результат от Енкрипта (до выравнивания нулями)

Добавлено через 9 минут
Цитата:
Сообщение от Hint Посмотреть сообщение
Зато теперь есть общедоступная реализация на php и delphi

В интернете подробной информации нет. Про RSA понятно по l2encdec (вывод процесса распаковки). Сжатие - логично, потому что размер файла меньше (плюс DStuff написал про использование zlib у себя в USAGE). То, что сначала сжимают, а потом шифруют через RSA - тоже понятно (иначе бы ничего не сжималось Заголовок и CRC видно в hex-редакторе (размер остального кратен 128, что намекает на RSA и размер ключа и блоков).
Так что единственное темное пятно - ключи, а вот их нигде нет

Кстати, твой вариант не всегда будет работать, потому что в последнем блоке, который неполный, данные могут быть смещены (не знаю почему и зачем). Из-за этого пришлось добавить костыль:
PHP код:
    if ($size != 0x7c
    { 
      
$p strlen($s) - $size
      while (
$p && $s[$p 1] != "\0") --$p
      
$s substr($s$p$size); 
    } 
    else 
    { 
      
$s substr($s, -$size); 
    } 
Добавлено через 3 минуты
Честно говоря, копался в этом больше из-за любопытства, а не по необходимости. Началось с разбора нового 'itemname-*.dat' (l2disasm уже не помогает, поэтому пришлось писать свою программу), а потом захотелось разобраться и с l2encdec.
Похоже догадался: идет выравнивание до кратности в 4ре байта.

Последний раз редактировалось Stenly76, 14.11.2016 в 11:25. Причина: Добавлено сообщение
Stenly76 вне форума   Ответить с цитированием
Старый 29.12.2016, 08:31   #19
Новичок
 
Регистрация: 25.03.2014
Сообщений: 11
Сказал Спасибо: 4
Имеет 0 спасибок в 0 сообщенях
user713 пока неопределено
По умолчанию

Цитата:
Сообщение от Stenly76 Посмотреть сообщение
это CRC32 взятый начиная с самого начала включая заголовок (Lineage2Ver) и по результат от Енкрипта (до выравнивания нулями)
Спасибо, то что нужно

Цитата:
Сообщение от Stenly76 Посмотреть сообщение
Похоже догадался: идет выравнивание до кратности в 4ре байта.
Именно так, тоже просчитал это, немного поэкспериментировав, и убрал все костыли из кода)

Цитата:
Сообщение от user713 Посмотреть сообщение
P.P.S: а еще кому знакома цифра 143114 - подскажите как бороться, у меня уже моск вывернулся в непонятном направлении :\
Цитата:
Сообщение от ScythLab Посмотреть сообщение
Уверен, что это твой косяк, когда работал с ZLib'ом вообще не помню каких либо сложностей, все сжималось и разжималось, для любых файлов ла2.
Как показали эксперименты - косяк не мой) Взял оригинальные файлы Ла2 - и все разжалось, сжалось байт в байт) А если брать файлы уже обработанные через l2encdec - тут начинаются расхождения (l2encdec жмёт чуть сильней и заголовок и хвост потока отличаются от оригинального zlib) Клиент ладвы кушает оба варианта без проблем. Моя тулза понимает файлы l2encdec, l2encdec понимает файлы от моей тулзы, но при взаимной обработки блоки могут отличаться (чаще это первый и последний блоки). Но главное что всё работает
user713 вне форума   Ответить с цитированием
Ответ

  CoderX :: Forums > Основные форумы > Программинг


Опции темы
Опции просмотра

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

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


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

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

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