XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > StarCraft (только чтение)> StarCraft 2 inside
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

 
ABBAPOH

offline
Опыт: 271
Активность:
Работа с mpq
я тут попишу у вас немного?:)
На данный момент существует единственная библиотека для работы с MPQ архивами, полностью поддерживающая все архивы близзарда - начиная от дьяблы и кончая Starcraft2 и World of Warcraft.
В процессе разработки моего вьювера для MPQ был написан класс-обертка над библиотекой libStorm.dll - QMPQArchive. Этот класс использует библиотеку Qt (так как мне была важна кроссплатформенность) и может работать на различных операционных системах - Windows, Mac, Linux (благо libStorm также портирована на эти операционные системы, хотя и местами криво (однако в последних версиях Ладислав всё исправил)). Кроме класса QMPQArchive был написан класс QMPQArchiveEx, позволяющий работать с архивом в терминах папок (рекурсивное переименование, удаление). Ну и наконец то, ради чего и задумывалась библиотека - класс QMPQFileEngine, позволяющий использовать для доступа к файлам архива стандартные средства Qt - такие как QFile, QDir, QFileInfo. На данный момент производится рефакторинг кода (особенно код engine'а). Однако класс QMPQArchive претендует на звание законченного api. Его мы и рассмотрим (а также вкратце работу с архивом через QFile/QDir).
И так, простой пример:
    QMPQArchive * archive = new QMPQArchive();
    archive->open("ahcool.SC2Map");
    qDebug() << "number of files" << archive->filesCount();
    QByteArray data = archive->read("MapScript.galaxy");
    qDebug() << data;
    archive->close();
    delete archive;
Сначала мы создаем архив - конструктор класса QMPQArchive принимает указатель на QObject, который будет являться родителем архива и будет отвечать за удаление. Я не передаю ничего, поэтому память очистить придется руками.
Затем я открываю архив "ahcool.SC2Map" (предполагается что файл лежит в той же папке, что и бинарник программы, иначе нужно указывать полный путь).
Следующая строка печатает количество файлов в архиве. Также можно получить и другую информацию об архиве - к примеру размер хэш-таблицы или атрибуты архива.
Потом я читаю содержимое файла "MapScript.galaxy" - исходного кода карты и вывожу его в консоль (qDebug() << data;)
Наконец, я закрываю архив, чтобы освободить внутренние структуры данных. На самом деле, можно было и не закрывать - close автоматически вызовется в деструкторе класса.
О файлах в архиве можно получить различную информацию через метод fileInfo:
    MPQFileInfo info = archive->fileInfo("(listfile)");
    qDebug() << "file name" << info.name();
    qDebug() << "file size" << info.fileSize();
    qDebug() << "comp size" << info.compressedSize();
Сначала я получаю класс MPQFileInfo для файла (listfile). Важно отметить, что MPQFileInfo использует Data Sharing, поэтому его можно использовать по значению, а не по указателю, как для аналогичной структуры в libStorm.
Теперь можно рассмотреть получение файлов в архиве. Пока я не совсем уверен об этой части api (так как то, как реализован листинг сейчас, достаточно медленно), поэтому что-то может поменяться.
    foreach(MPQFileInfo info, archive->entryList()) {
         qDebug() << "file name" << info.name();
    }
Сначала мы получаем список MPQFileInfo через метод entryList затем перебираем элементы в цикле.
Аналогичный код можно получить, используя класс QMPQFileEngine. Для этого где-то в программе нужно создать экземпляр класса QMPQFileEngineHandler, например в функции main
    QApplication app(argc, argv);
    QMPQFileEngineHandler engine;
После этого можно пользоваться классами QFile/QDir/QFileInfo для доступа к архиву:
    QDir d("mpq:(ahcool.SC2Map");
    qDebug() << "entry list:";
    qDebug() << d.entryList(QDir::AllEntries);

    QFile f1("mpq:ahcool.SC2Map/(listfile)");
    qDebug() << "f1 exists: " << f1.exists();

    QFile f2("mpq:ahcool.SC2Map/MapScript.galaxy");
    qDebug() << "f2 exists: " << f2.exists();
    qDebug() << "f2 contains ";
    f2.open(QFile::ReadOnly);
    qDebug() << f2.readAll();
    f2.close;
Важно иметь ввиду, что для доступа к архиву необходимо указывать префикс mpq: перед именем файла. Если написать
QFile f("ahcool.SC2Map");
то архив откроется как простой бинарный файл.
На самом деле есть небольшая ошибка в данном примере - лучше не использовать относительные пути к файлам архива, так как работа по относительному пути мной не тестировалась.
Полный список функций и более подробные примеры можно посмотреть во вложенном архиве. На данный момент примеры тестировались только под маком (под Windows всё будет готово, когда Ладислав определиться с конечным api libStorm'а)
Прикрепленные файлы
Тип файла: zip QMPQFileEngine.zip (359.5 Кбайт, 84 просмотров )

Отредактировано ABBAPOH, 23.05.2010 в 20:19.
Старый 23.05.2010, 16:52
ScorpioT1000
Работаем
offline
Опыт: отключен
Вас что, не учили, как итераторы работают?) или это так в Qt везде? O_O
ну в целом неплохо, вот только смысл в вашей кросплатформенности? на линуксе толку работать с варом ноль(остальной софт не саппортится) мак вобще для геймдева н/ц
дальше это даже проблема - вместо удобного api как у shadow flare, здесь мы имеем высокофункциональный, но высокотребовательный набор классов. Я считаю неоправданным использование Qt в столь маленьком проекте.
Тоесть допустим чтобы мне написать простенькую консольную вынималку/вставлялку/удалялку файлов архива из командной строки, я должен
  • поставить Qt sdk
  • написать функционал
  • скомпилить с рантаймами
  • таскать везде за собой рантаймы
цель оправдывает средства?)
мб я что-то не шарю в нём, тогда поправь
Старый 23.05.2010, 18:19
ABBAPOH

offline
Опыт: 271
Активность:
я это писал для своего просмотрщика, что написано в 1х строках. Для меня оправдано. Я просто выложил апи, хз
Старый 23.05.2010, 18:28
ScorpioT1000
Работаем
offline
Опыт: отключен
Я думал, ты для всех мутишь что-то :)
Старый 23.05.2010, 18:33
ABBAPOH

offline
Опыт: 271
Активность:
Я решил поделиться чтобы услышать мысли умных людей, как раз по поводу итератора:)
це в жабастайле итератор, думаешь с++ стиль лучше будет?
Старый 23.05.2010, 18:40
ScorpioT1000
Работаем
offline
Опыт: отключен
посмотри например stl как он там устроен
там полуоткрытое множество:
collection.begin() - начальный элемент (возвращает итератор)
collection.end() - элемент, после последнего, он же пустой (возвращает итератор)
итератор не проверяется внутри, а сравнивается с .end()
ScorpioT1001 добавил:
да и указателей у тебя немало - как то уныло для C++
Старый 23.05.2010, 18:46
ABBAPOH

offline
Опыт: 271
Активность:
тут этот итератор для служебных скорее целей (он сцука жутко медленный) - наружу я наверно сделаю метод QList<MPQFileInfo> entryList() к-ый его перебирает и предоставляет нормальные плюсовые итераторы
А указатели... а зачем? есть d_ptr в 2х архивах, внутри MPQFileInfo shared указатель на структуру данных (чтобы не было 100500 копирований). Нафига им наружу торчать?)
Старый 23.05.2010, 18:52
Toadcop

offline
Опыт: 54,313
Активность:
а причём sc2 ?
// Bear and Lampshade - Overexposure To Mars Ponies <3

особено какая это статья ? это рекламы твоей тулы/либы.

Цитата:
ScorpioT1001 добавил:
да и указателей у тебя немало - как то уныло для C++
у него С с классами и нассать на тебя О_О.

такие вещи вообще лучше "ловлвльно" писать что бы быстро работало а поверх уже делай что хочеш...
Старый 23.05.2010, 19:42
ABBAPOH

offline
Опыт: 271
Активность:
привет, жаба:)
много указателей?)
fixed

Отредактировано ABBAPOH, 23.05.2010 в 20:20.
Старый 23.05.2010, 19:47
Toadcop

offline
Опыт: 54,313
Активность:
Цитата:
много указателей?)

незнаю не смотрел и как по мне то неважно.
Старый 23.05.2010, 20:44
ABBAPOH

offline
Опыт: 271
Активность:
ну ты возмущаешься на си с классами)))
Старый 23.05.2010, 20:46
adic3x

offline
Опыт: 108,439
Активность:
Ну как уже сказали это не статья и не о mpq. Сейчас переименую тему.
Речь идет о SFmpq.dll?
Старый 23.05.2010, 21:05
Hellfim
Новичок
offline
Опыт: 79,707
Активность:
ADOLF, речь идет о его собственно либе, которая расширяет возможности работы SFMPQ.dll
Старый 23.05.2010, 21:15
ABBAPOH

offline
Опыт: 271
Активность:
брр, sfmpq - прошлый век... я юзаю libStorm.dll (*.dylib/*.so) (и немного помогаю аффтору)
Старый 23.05.2010, 21:17
adic3x

offline
Опыт: 108,439
Активность:
Если о ней, то я тогда решительно не понимаю. Ведь в ней есть вполне адекватный интерфейс функций? Хотя возможно я, как более низкоуровневый программист и утрирую, но я решительно не понимаю зачем тут объектная ориентация и прочее.
ADOLF добавил:
libStorm.dll
Всетаки нет? А можно ссыль на нее?
ADOLF добавил:
брр, sfmpq - прошлый век...
Раз уж зашло, да и у Вас есть опыт работы с обоими библиотеками - расскажите , чем она лучше.
Старый 23.05.2010, 21:22
ABBAPOH

offline
Опыт: 271
Активность:
ООП здесь исключительно для удобства. Ну и логика моего приложения, для к-го это писалось требует все-таки наличие какого-то класса-обертки. Собсно изначально он и не был особо жирный, но вот, решил причесать и дописал кое-что, благо времени заняло не так много. Все равно для получения всей инфы об архиве пришлось бы либо писать обертки, либо таскать ф-ии либшторма по всему коду
ссыль: www.zezula.net/download/stormlib.zip
когда я ковырял sfmpq.dll, я так и не смог понять как ей открыть архивы версии старше чем 1й вов. Также были косяки с ее портом под Мак (пишу я на маке) - но это мелочи. Не понравилось - практически никакой работы с неизвестными файлами. У штормлиба есть андокументед фича работы с файлом по индексу - файл можно открыть и удалить
MPQFileInfo QMPQArchive::fileInfo(quint32 index)
{
  ...
    void * hFile;
    bool result = SFileOpenFileEx(d_func()->mpq, (const char *)index, SFILE_OPEN_BY_INDEX, &hFile);
  ...
}
Из еще плюсов - поддержка lzma и sparse компрессий (добавлены в ск2), возможность открывать архивы WoW Cataclysm

Отредактировано ABBAPOH, 23.05.2010 в 21:35.
Старый 23.05.2010, 21:27
ShadoW DaemoN

offline
Опыт: 37,078
Активность:
ADOLF, sfmpq работает только с варовскими архивами (MPQ первой версии). Stormlib работает с обеими версиями MPQ, то есть может открывать как варовские, так и Sc2 и WoW архивы.
sfmpq - за авторством Shadow Flare, Stormlib - Ladislav Zezula (ladik). Это наиболее распространенные библиотеки для работы с mpq. Есть еще от d07riv, но она используется только им, а также существуют малопопулярные ремейки на sfmpq.
Ссыль на официальную страницу Stormlib
Старый 23.05.2010, 21:31
adic3x

offline
Опыт: 108,439
Активность:
Ну и логика моего приложения, для к-го это писалось требует все-таки наличие какого-то класса-обертки.
Я никогда не пойму, как код может что то "требовать". Но да ладно. Скажу лишь, что код, приведенный на странице библиотеки замечателен, и уродование его всякими Вашими ООП не одобряется мной.
Также были косяки с ее портом под Мак (пишу я на маке)
Забавно. А кроме Вас кто то использует mpq редакторы под Mac?
Старый 23.05.2010, 21:49
ABBAPOH

offline
Опыт: 271
Активность:
толсто, толсто:)
под мак есть свои редакторы, но они и юзают свои же тулзы, менее хорошие чем либшторм
Старый 23.05.2010, 21:53
adic3x

offline
Опыт: 108,439
Активность:
толсто, толсто:)
Наверное у Вас уже рефлекс, при любом упоминании о продукции Apple сразу видить в нем троллинг. Я спросил просто из интереса.
А еще я не пойму зачем раскидывать почти каждый элемент кода в свой файл.
Старый 23.05.2010, 22:03

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

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

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 12:13.