artlavrov
-
Публикации
13 -
Зарегистрирован
-
Посещение
Сообщения, опубликованные пользователем artlavrov
-
-
Вот этот проект умеет разбирать .nmo, судя по коду:
https://github.com/yesterday/Syberia
public Composition read(InputStream stream) throws IOException, DecodingException { byte[] bytes = new byte[HeaderSize]; if (HeaderSize != stream.read(bytes)) throw error("Cannot read"); CompositionHeader c = Codecs.decode(codec, bytes); if (!c.sign.equals("Nemo Fi\0")) throw error("Not a composition file");...
Не знаю как насчет шрифтов, которые внутри nmo.
-
Нет, у меня не стимовская и без DLC.
Картинку в формате DefineBitsJPEG3, как оказалось, можно вшить через SoThink SWF Decompiler.
Зато JPEXS хорошо работает со шрифтами, в отличие от Sothink.
C пакетным режимом (swfmill?) пока вообще все плохо.
-
-
Обновил paktools (https://github.com/artlavrov/paktools). Версия в мастере даже может файлы смотреть через Far Manager + MultiArc. Хотя, наверное, причины никакой так заморачиваться не было, можно было и на питоне наскрести пакер и точно так же вызывать. Сейчас бы как нибудь шрифты научиться обновлять автоматически, ни разу у меня не получилось через swfmill подменить шрифт, а заставку в DefineBitsJPEG3 (с отдельной маской) даже через JPEXS подменить не выходит. И еще непонятно, есть ли в природе упаковщик в .anb - wfLZEx умеет только распаковывать.
-
Отправил. Скачать можно тут (ATETDBIDK-rus.0.4.ZoG.zip)
https://drive.google.com/folderview?id=0BxJ...amp;usp=sharing
Cкриншоты для версии 0.4:
http://i.imgur.com/ZqlKJ0I.png
http://i.imgur.com/1n0VFAr.png
http://i.imgur.com/pcqcvrw.png
http://i.imgur.com/YSq2KLU.png
А какой самый популярный распаковщик на скриптах чтобы вместо ducktalestools скрипт написать и можно было его включить в состав русификатора? А то с гуем очень неудобно получается. На сях как-то некрасиво писать, мне кажется, лучше уж скрипт для какой-нибудь популярной консольной тулзы (quickbms? mrripper?) сделать.
Написал-таки сишный упаковщик *.pak а то руками надоедает собирать, вот он весь (paktools.cpp):
Собранный можно скачать тут https://drive.google.com/folderview?id=0BxJ...amp;usp=sharing (paktools-0.1.zip)
Spoiler#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <string.h>#include <direct.h>#include <malloc.h>#include <windows.h> // FindFirstFile#include <sys/stat.h>#include <sys/types.h> // for stat#define SIG_LINK "FILELINK_____END"#define SIG_DATA "MANAGEDFILE_DATA BLOCK_USED_IN_ENGINE________________________END"#ifndef MAX_PATH#define MAX_PATH 4096#endiftypedef struct { int at; int size; char *name;} file_t;int write_to_file(char *path, char *data, int size){ char cwd[MAX_PATH]; _getcwd(cwd, sizeof(cwd)); char *p = path; while (1) { char *c = strchr(p, '/'); if (!c) c = strchr(p, '\\'); if (!c) break; *c = 0; _mkdir(p); _chdir(p); p = c + 1; } FILE *fp = fopen(p, "wb"); if (fp) { fwrite(data, size, 1, fp); fclose(fp); } _chdir(cwd); return 0;}int unpack(const char *fname, const char *dir){ FILE *fp; size_t size; fp = fopen(fname, "rb"); if (!fp) { fprintf(stderr, "Could not open `%s`, exiting...\n", fname); return 1; } fseek(fp, 0, SEEK_END); size = ftell(fp); fseek(fp, 0, SEEK_SET); int loc, files, ofs, at; fread(&loc, 4, 1, fp); fread(&files, 4, 1, fp); char outdir[MAX_PATH]; if (!dir) sprintf(outdir, "%s_extracted", fname); else strcpy(outdir, dir); fprintf(stderr, "Loaded %s (%d bytes, %d files), extracting files to %s...\n", fname, size, files, outdir); ofs = 8; for (int i = 0; i < files; i++) { fseek(fp, ofs, SEEK_SET); char sig[16 + 1] = { 0 }; fread(sig, 16, 1, fp); // 16 bytes for FILELINK_____END if (memcmp(sig, SIG_LINK, 16) != 0) { fprintf(stderr, "Not a pak file, exiting..."); fclose(fp); return 1; } fread(&at, 4, 1, fp); fread(&size, 4, 1, fp); char name[MAX_PATH]; fgets(name, MAX_PATH, fp); int len = strlen(name); at += loc + 64; // 64 bytes for MANAGEDFILE_DATA BLOCK_USED_IN_ENGINE_________________________END //printf("%d %d %s\n", at, size, name); ofs += 16 + 4 * 2 + len + 1; while (ofs % 8 != 0) ofs++; char *data = (char *)malloc(size); fseek(fp, at, SEEK_SET); fread(data, size, 1, fp); char *c = strchr(name, ':'); if © *c = '/'; char path[MAX_PATH]; sprintf(path, "%s/%s", outdir, name); write_to_file(path, data, size); free(data); } fclose(fp); return 0;}int list_dir(char *dir, file_t * files, int i){ HANDLE hf; WIN32_FIND_DATA ffd; char path[MAX_PATH]; sprintf(path, "%s/*.*", dir); for (hf = FindFirstFile(path, &ffd); FindNextFile(hf, &ffd);) { if (strcmp(ffd.cFileName, ".") == strcmp(ffd.cFileName, "..")) { sprintf(path, "%s/%s", dir, ffd.cFileName); if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) i = list_dir(path, files, i); else files[i++].name = _strdup(path); } } FindClose(hf); return i;}void fix_path(char *dest, char *dir, char *src){ // example: dir='a/b' src='a/b/c/d/e' => dest='c:d/e' char buf[MAX_PATH]; strcpy(buf, src); // set cursor at 'c/d/e' char *p = buf + strlen(dir) + 1; // make it look like c:d/e char *c = strchr(p, '/'); if (!c) c = strchr(p, '\\'); if © *c = ':'; strcpy(dest, p);// printf("Fixed path: `%s` + `%s` => `%s`\n", dir, src, dest);}int pack(char *dir, char *fname){ file_t r[16384]; int files = list_dir(dir, r, 0); if (files == 0) { fprintf(stderr, "No files, exiting..."); return 1; } char path[MAX_PATH]; if (!fname) { strcpy(path, dir); strcat(path, ".pak"); } else strcpy(path, fname); fprintf(stderr, "Writing %s, %d file(s)...\n", path, files); FILE *fp = fopen(path, "wb"); if (!fp) { fprintf(stderr, "Could not open `%s`, exiting...\n", path); return 1; } int tmp, ofs = 0; char filler = 0x3f; char zero = 0; fwrite(&tmp, 4, 1, fp); fwrite(&tmp, 4, 1, fp); ofs += 8; for (int i = 0; i < files; i++) {// printf("%s\n", r[i].name); fwrite(SIG_LINK, 16, 1, fp); fwrite(&tmp, 4, 1, fp); fwrite(&tmp, 4, 1, fp); char name[MAX_PATH]; fix_path(name, dir, r[i].name);// printf("%s\n", name); fwrite(name, strlen(name) + 1, 1, fp); ofs += 16 + 4 * 2 + strlen(name) + 1; while (ofs % 8 != 0) fwrite(&filler, 1, 1, fp), ofs++; } // fill to 16 bytes (why? idk) while (ofs % 16 != 0) fwrite(&filler, 1, 1, fp), ofs++; int loc = ofs; for (int i = 0; i < files; i++) { // load file into memory FILE *in = fopen(r[i].name, "rb"); fseek(in, 0, SEEK_END); int size = ftell(in); fseek(in, 0, SEEK_SET); char *data = (char *)malloc(size); fread(data, size, 1, in); fclose(in); // loaded fwrite(SIG_DATA, 64, 1, fp); fwrite(data, size, 1, fp); free(data); r[i].at = ofs - loc; r[i].size = size;// printf ("%d %d\n", r[i].at, r[i].size); ofs += 64 + size; while (ofs % 16 != 0) fwrite(&filler, 1, 1, fp), ofs++; } while (ofs % 32 != 0) fwrite(&filler, 1, 1, fp), ofs++; // fixup offsets, etc. ofs = 0; fseek(fp, ofs, SEEK_SET); fwrite(&loc, 4, 1, fp); fwrite(&files, 4, 1, fp); ofs += 8; for (int i = 0; i < files; i++) { ofs += 16; fseek(fp, ofs, SEEK_SET); fwrite(&r[i].at, 4, 1, fp); fwrite(&r[i].size, 4, 1, fp); char name[MAX_PATH]; fix_path(name, dir, r[i].name); ofs += 4 * 2 + strlen(name) + 1; while (ofs % 8 != 0) ofs++; free(r[i].name); } fclose(fp); return 0;}int main(int argc, char **argv){ if (argc < 2) { printf("WayForward Engine resource packer (for Duck Tales Remastered, etc.) by artlavrov\n"); printf("Usage: paktools input.pak [output_dir]\n"); printf(" paktools input_dir [output.pak]\n"); return (0); } char *from = argv[1]; char *to = argc > 2 ? argv[2] : 0; struct _stat st; if (_stat(from, &st) == -1) return 1; if ((st.st_mode & S_IFDIR) == S_IFDIR) pack(from, to); else unpack(from, to); return 0;}
Использую я его таким образом:
Spoilerset data=C:\Games\AdventureTime\dataset tmp=tmpset bak=bakset res=resrem create backup directory (only once!) and backup original filesif not exist %bak% ( mkdir %bak% copy /y %data%\global.pak %bak% copy /y %data%\menus.pak %bak%)mkdir %tmp%paktools %bak%\global.pak %tmp%\globalpaktools %bak%\menus.pak %tmp%\menuspython ltbtools.py .\%tmp%\global\global\localization.ltb --write < res\ru.txtcopy /y %res%\global\*.* %tmp%\global\globalcopy /y %res%\menus\*.* %tmp%\menus\menuspaktools %tmp%\global global.pakpaktools %tmp%\menus menus.pakrmdir /s /q %tmp%copy /y menus.pak %data%\menus.pakcopy /y global.pak %data%\global.pak
Написал еще работающий скрипт распаковки *.pak для QuickBMS (tf_unpak.bms). Почитал форумы, похоже QuickBMS не умеет толком файлы обратно паковать, есть reimport mode - но он только для файлов у которых не меняется длина при модификации, а у меня swf с кириллицей практически всегда жирнее, чем оригинальные получаются, так что вряд ли пойдойдёт. Короче, QuickBMS, похоже, не вариант (если только длины файлов не подгонять). Кто-нибудь знает еще похожие движки для работы с архивами? Круто было бы чтобы он еще и с Far работал, например через multiarc (который, к сожалению, враги убрали из дистрибутива).
Spoiler# WayForward Engine assets extractor# Version 0.1 by artlavrov## Unpack files to to "global.pak_extract":# quickbms -o -d wf_unpak.bms global.pak ## Reimport files from "global.pak_extract" back to global.pak:# quickbms -o -d -r -w wf_unpak.bms global.pak## Note QuickBMS reimports only files of the same or smaller size# this is the built-in limitation that cannot be avoided (yet?)endian littleget FILES_OFFSET longget FILES_COUNT longfor i = 0 < FILES_COUNT # read file entry from the file list getdstring FILE_SIG 16 # skip FILELINK_____END signature get FILE_OFFSET long get FILE_SIZE long getct FILE_DIR string ':' getct FILE_NAME string 0 padding 8 # print "%i%) ofs:%FILE_OFFSET% size: %FILE_SIZE% dir: %FILE_DIR% name: %FILE_NAME%" # write file body math FILE_OFFSET + FILES_OFFSET math FILE_OFFSET + 64 # skip MANAGEDFILE_DATA BLOCK_USED_IN_ENGINE________________________END string FNAME p= "%s/%s" FILE_DIR FILE_NAME log FNAME FILE_OFFSET FILE_SIZE next i
Странно, но не могу толком картинку на заставке заменить в swf (через JPEXS Free Flash Decompiler). Подменяю английскую версию png на русскую версию png (наспех сделанную - http://i.imgur.com/syXVMKx.png может кто перерисует), обычный png с прозрачностью, пробовал и 8 и 24 бита. В игре вместо картинки - непрозрачная зелёная плашка, там какая-то маска ещё отдельно лежит что ли? Файл menus.pak/mainmenu.swf, может кто-нибудь знает, в чём дело.
Добавил остальные флешки и обновил фонт везде, а то он был разный (было заметно по букве З), отписался сержанту, файл залит на mediafire:
http://www.mediafire.com/download/w2xz7mo6...rus.0.5.ZoG.zip
Создал репозитории на гитхабе:
https://github.com/artlavrov/adventuretime-rus
https://github.com/artlavrov/paktools
В первом лежит самый последний файл ru.txt со всеми исправлениями, можно сабмитить пулреквесты туда.
Ни у кого нет русского шрифта Adventure Time для заставки и для loading icon?
Вот тут есть Latin1 в ttf http://www.mediafire.com/?0cbzjr319cru1o2
Может makc_ar сможет перерисовать. Хотя проще наверное руками сделать эти картинки, т.к. там объемные буквы, шрифт не сильно поможет.
Loading: http://i.imgur.com/d5VUlPi.png (loadingicons.pak/loading.anb)
Adventure time: http://i.imgur.com/UcvkwsU.png (global.pak/mainmenu.swf)
-
Я, честно говоря, не знаю, к чему эта фраза относилась там - они, оно или она.
Поэтому и предлагаю выложить исправленный текст, или отдельные фразы.
#610 These aren't very effective, unfortunately, but it's the best I could do on short notice. Они не очень эффективны, но это лучшее, что я мог сделать в короткие сроки.
-
В смысле кто он и кто она? КШР это она? Лучше уж сами исправьте текст.
Русский взят с нотабеноида, но там фиг скачаешь что-нибудь просто так, модераторы гуляют.
В Joystix Monospace выше плохие буквы Л и У.
Еще нашел глюк у себя - забыл global/pausequit.swf обновить, проверю.
Ещё вероятно надо проверить флешки в endingcreditseu.pak, shop.pak и tutorial.pak, но долго все делать руками.
Обновил патчилку ltb, теперь она может сдампить исходный текст из localization.ltb и залить его обратно, может пригодится.
Формат пока не ясен толком, но с 0х40 начинаются офсеты строк, а английская версия лежит со строки 2294 по строку 4588.
Русский текст можно заливать в файл прямо в UTF-8, с \n вместо переводов строк.
Spoiler# -*- coding: utf-8 -*-ltbtool_version = "0.3"import structimport sysdef read_strings(ofs, start_line, lines, b): for i in xrange(start_line+lines): loc = struct.unpack("q", str(b[ofs:ofs+8]))[0] end = b.find(chr(0),loc) s = str(b[loc:end]) s = s.replace('\n','\\n') if i>=start_line: print "%s" % (s) ofs+=8def write_strings(ofs, start_line, lines, b): ofs += start_line*8 loc = struct.unpack("q", str(b[ofs:ofs+8]))[0] for s in sys.stdin: s = s.rstrip('\r\n') s = s.replace('\\n','\n') w = bytearray(s) w.append(0) # pad to 8 bytes while len(w)%8!=0: w.append(0) # paste string for i in xrange(len(w)): b[loc+i] = w[i] # write string offset bytes = struct.pack("q", loc) for i in xrange(8): b[ofs+i] = bytes[i] ofs += 8 loc += len(w)if __name__=='__main__': if len(sys.argv)<2: print "WayForward's Adventure Time text resource files (.ltb) tool ver. %s" % ltbtool_version print "Usage: ltbtools.py localization.ltb > strings.txt" print " ltbtools.py --write localization.ltb < strings.txt " else: write = False for arg in sys.argv: if arg=='--write': write = True else: fname = arg ofs = 0x40 start_line = 2294 lines = 2294 b = bytearray(file(fname,'rb').read()) if write: write_strings(ofs, start_line, lines, b) file(fname, "wb").write(b) else: read_strings(ofs, start_line, lines, b)
Версия 0.3 adventuretime-rus-bin-0.3.zip с обновленными шрифтами и КШР.
https://drive.google.com/file/d/0BxJga0T44n...iew?usp=sharing
И вот тут каталог со всеми версиями и тулзами, если что - смотрите там.
https://drive.google.com/folderview?id=0BxJ...amp;usp=sharing
-
Круто, я не думал что этот From Where You Are кто-то перерисовывал.
Скинь Joystix Monospace русский тоже тогда, а то сам его русскую версию делал в спешке, и кажется, буква ё там так и не отображается в итоге.
Я могу пересобрать с новыми шрифтами.
Может еще есть хайрез лого Аdventure Time на русском? В гугле все маленькие, а надо вот такое здоровое, на прозрачном фоне (лежит в menus/mainmenu.swf):
http://i.imgur.com/Tpdf8FI.png
К тексту еще есть претензии, кроме КЕКСОШВЫР - КШР? Кто-нибудь скачайте архив, просмотрите там строки глазами, а то я могу пропустить такие вещи.
Вот архив с текстами, два файла, русский и английский, и патчилка ltb, в одном архиве.
https://drive.google.com/file/d/0BxJga0T44n...iew?usp=sharing
-
Нет, я пока этим заниматься не могу. Там есть архив с текстовой таблицей строк, который как раз для таких вот небольших правок и пересборки, было бы хорошо если бы взялись фанаты серии. Там, в принципе, уже не нужен краудсорсинг, достаточно одного шарящего. А мы лучше пока поиграем в Finn & Jake's Epic Quest, она не такая хардкорная.
Технология простая - распаковываете в orig оригинальные паки через DuckTalesTools.exe, берете таблицу строк в каталоге ru, правите по месту, потом запускаете patch_strings.py. Если надо заменить шрифт диалогов (v_CCTimSaleLower.ttf может показаться мелковат, а оригинального русского fromwhereyouare.ttf у меня не было) - открываете genericdialog.swf в JPEXS Free Flash Decompiler и заменяете шрифт на другой (выбрать embed, диапазоны latin1 и cyrillic). Картинки на заставке и картинка loading лежит в menus/mainmenu.swf, разбирается тем же JPEXS, там ничего сложного (править надо английские версии). Потом делаете сopy_files.cmd и собираете паки обратно, в том же DuckTalesTools.exe (каталог out). Архив с версией 0.2, напоминаю, лежит тут - https://drive.google.com/file/d/0BxJga0T44n...iew?usp=sharing
-
Понял, в чём дело с перепаковкой через DuckTalesTools.exe - надо просто pak собирать на один каталог выше (в бинарнике видно, что у файлов есть свои пути). Т.е. если например файлы из menus.pak распаковались в подкаталог menus, нужно натравливать DuckTalesTools.exe на tmp\menus\ а не на menus\, иначе каталог не будет учитываться. Пересобрал таким способом - все заработало.
Допилил руками, с помощью DuckTalesTools и JPEXS Free Flash Decompiler.
Скрипты и readme:
https://drive.google.com/file/d/0BxJga0T44n...iew?usp=sharing
Перевод в целом хороший. Пришлось немного править таблицу строк, слишком длинные надписи.
В принципе локализация готова, желающие могут заменить пару картинок на заставке, но необязательно.
Шрифт меню использован игровой (joystix), русифицирован в редакторе TTF на скорую руку.
Шрифт диалогов - v_CCTimSaleLower.ttf.
Готовые ресурсы (global.pak и menus.pak, просто перезапишите поверх игры и всё):
https://drive.google.com/file/d/0BxJga0T44n...iew?usp=sharing
-
Вот тут //forum.zoneofgames.ru/index.php?showtopic=33059 просто завал флешек, руками сначала правил, потом надоело.
Разработчики совсем дубу дались, два десятка флешек для разных игровых экранов и в каждой свой embedded шрифт.
Как бы батник такой написать чтобы заменять шрифт автоматически? Через swmill? И как ttf шрифт подготовить для этого?
-
Сделал тестовую версию русификатора для Adventure Time: Explore the Dungeon, может вам интересно будет
https://drive.google.com/file/d/0BxJga0T44n...iew?usp=sharing
Игра на движке WayForward, как Duck Tales Remastered, но, похоже, с измененным форматом *.pak.
Скрины
http://i.imgur.com/ZqlKJ0I.png
http://i.imgur.com/crqxfdy.png
http://i.imgur.com/IM4cwKH.png
К сожалению, не разобрался с перепаковкой pak, игра вылетает если патчить не по бинарникам.
Может кто знает, как их пересобирать (DuckTalesTools.exe собирает инвалидный пак, может исходники есть к нему?).
И интересно как автоматизировать замену шрифтов в swf (там их двадцать штук).
Все реально в принципе, только swf перепаковывать и за размерами следить напрягает, из за бинарных патчей.
И как разбирать localization.ltb правильно, тоже интересно.
Если кто-нибудь возмется доделать, будет вообще круто, а то я пока не осиливаю.
BloodRayne: Betrayal
в Русификаторы
Опубликовано:
Сделал консольный (чтобы запускать в пакетном режиме) пакер с поддержкой bloodrayne (там просто файлы чуть более компактные, чем в ducktales) https://github.com/artlavrov/paktools