Я играю в Heroes of Might and Magic со времен царя Гороха королевы Ламанды, и за это время накопилось такое количество карт для 3-х Героев, что я решил их как-то упорядочить и структурировать.
Цели были следующие:
- Избавиться от дубликатов карт
- Точно знать, играл я в эту карту или нет, если играл, то знать статус: выиграл, проиграл или пропустил
- Иметь возможность загружать в органайзер новые карты с проверкой на уникальность
- Писать свой личный комментарий к карте
- Иметь возможность мгновенно отсортировать каталог карт по следующим параметрам:
названию, статусу, версии, кодировке, размеру карты, наличию подземелья, уровню сложности и размеру файла
Скриншоты
Скриншоты кликабельные
Полный каталог карт
Работа с фильтрами. Здесь я отсортировал карты, в которые я не играл, версии SOD (The Shadow of Death), кодировка ascii, размер Extra Large, на картах есть подземелье, уровень сложности Impossible. Зеленая иконка — для загрузки карты из каталога на локальный компьютер.
Работа с картой, если нажать на иконку с ручкой. В модальном окне все очевидно и видно, когда я последний раз играл в эту карту.
Попытка загрузки карты, которая уже есть в каталоге.
Установка и запуск
- Скачиваем и распаковываем архив с виртуальной-машиной:
Скачать с Dropbox 4,69GB - Скачиваем и устанавливаем VMware Workstation Player (Пропускаем этот пункт, если VMware-Workstation установлен).
- Запускаем виртуальную машину. Дожидаемся, когда она загрузится, и смотрим IP адрес, который ей присвоил VMware:
Если IP не назначилсяТо либо перезагрузите виртуалку средствами vmware, либо авторизуйтесь
Логин: root
Пароль: heroИ введите команду:
ifconfig
Увидите текущий IP.
А с помощью команды:
nmtui
Можно его зафиксировать, чтобы он не менялся, настроив статику.Вбиваем этот адрес в браузер и попадем в органайзер со всеми картами, как на скриншотах.
Подробности для программистов и для интересующихся
Все это «хозяйство» написано на python3.
В качестве фреймворка выбрал Flask.
База данных: MongoDB.
Фронтенд: bootstrap3 и DataTables
Парсить карту Heroes III можно с помощь стандартных python модулей: gzip и struct. Модуль gzip распаковывает файл, так как он хранится в сжатом виде. Модуль struct предлагает функцию unpack() для работы с форматами двоичных записей переменной длины, а функция calcsize возвращает размер структуры. Код «I» для четырех байтовых без знаковых чисел. Код "<" обозначает, что числа стандартного размера и байты записаны в порядке «сначала младший» (little-endian).
Нижеследующий код получает версию Героев у файла с именем Zyconia.h3m
>>> h3m_versions = {0x0E: "RoE", 0x15: "AB", 0x1C: "SoD", 0x33: "WoG"}
>>> import gzip
>>> import struct
>>> h3m_data = gzip.open('Zyconia.h3m')
>>> def r(s):
... return struct.unpack(s, h3m_data.read(struct.calcsize(s)))
...
>>> print(h3m_versions[r("<I")[0]])
RoE
- RoE — The Restoration of Erathia
- AB — Armageddon's Blade
- SoD — The Shadow of Death
- WoG — In the Wake of Gods
Полный код парсера можно посмотреть на гитхабе.
Используя работу с двоичными данными я добрался до следующих данных:
- Размер карты
- Наличие подземелья
- Название карты
- Описание карты
- Уровень сложности
Уникальный идентификатор для каждой карты (файла) посчитал обычным md5.
tmp = res['Version'] + res['underground'] + res['mapsize'] + res['name'].lower() + res['difficulty']
res['_id'] = hashlib.md5(str(tmp).encode('utf-8')).hexdigest()
Засунул в md5-хэш все данные, кроме описания, потому что в описание карты иногда добавляют название сайта, откуда ее скачали, и получится дубль, это одна из причин, почему нельзя просто взять и посчитать хэш сумму у файла с картой для проверки на уникальность.
Автор: pcdesign