Try   HackMD

Лаунчер Minecraft: Java edition

Є така гра, називається Minecraft.

Ця гра запускається через "лаунчер".

launcher: з англійської "to launch" - запустити, наприклад, "to launch a rocket" - запустити ракету.

Запускатор, запускальщик по нашому.

Навіть якщо ви запускаєте гру даблкліком на робочому столі, це запускає лаунчер, з якого запускається сама гра.

Для скачування Майнкрафту (особливо якщо ми говоримо про Java edition) достатньо скачати лаунчер, а лаунчер зможе скачати саму гру і запустити її.

Окрім стандартного лаунчера, існує повно інших лаунчерів:

  • MultiMC
  • TLauncher
  • GDLauncher
  • кожен піратський сервер випускає свої лаунчери, які загружають свою "особливу" версію майкрафту, з фіксами, плагінами, патчами, модами, текстурпаками і тп.

Я якось написав свій лаунчер. І я хотів би щоб ви також зрозуміли як це робиться.

Якщо комусь цікаво подивитись мій код - ось він:

Технічні терміни

  • операційна система (ОС), платформа - Windows, Linux або MacOS.
    • кросплатформернність - підтримка кількох операційних систем. Як правило один і той же лаунчер файл не буде працювати на різних системах, тому потрібні платформо-специфічні версії
  • файл - дані на диску. Найважливішим є те, що ці дані мають ім'я ("шлях до файлу") і залишаються після того як комп'ютер вимикається. Ці дані можна дістати програмно, якщо знати шлях до файлу
  • папка, директорія - частина шляху до файлу до останнього слешу. Тобто, в шляху C:\Users\test\somefile.exe папкою буде C:\Users\test\
  • ресурси - файли для закачки. Файли можуть бути будь-які - картинки, екзешники, аудіо, текстові,
  • ассети - список ресурсів, тобто, пакет файлів на закачку.
  • артефакт (artifact) - фактично те саме, що і ресурс, але з точки зору розробника. Також може бути архівом і містити додаткову інформацію - час створення, хеш, і тп.
  • сервер ресурсів - сервер, з якого викачуються ресурси. Може співпадати з ігровим сервером, а може бути і стороннім. Якщо ресурс має хеш, то це дозволяє робити дзеркала серверів ресурсів
    • дзеркало - альтернативний сервер, копія в іншому місці
  • launcher - система, яка дозволяє запускати гру. Часто включає в себе докачку додаткових файлів (DLC), автентифікацію (логін-пароль) і верифікацію файлів гри (античіт)
  • клієнт - та частина гри, яка знаходиться на комп'ютерів гравця. Іноді є просто папкою з файлами десь на диску, тому її можна переносити по диску. Але часто деякі файли роблять зашивки на шляхи, і переносити з місця на місце стає неможливим.
  • версія - клієнт гри з іншим набором файлів та фіч. Якщо розробник додає нові фічі, то він називає їх новою версією, яку юзер може наново скачати
    • альфа версія - версія з новими фічами і не дуже відтестована
    • бета версія - версія з новими фічами і відтестована альфа-тестерами
    • реліз кандидат - версія, відтестована бета-тестерами
    • реліз - офіційний пакет гри, як правило це останній реліз-кандидат
    • патч версія - версія після релізної, де виправляють баги та хаки, які не відловили тестери, альфа-тестери, бета-тестери та реліз-кандидат тестери
  • параметри, аргументи - при запуску програми з командного рядка вказуються після назви програми. Дозволяють передавати в програму додаткові параметри (як це робить в функціях в Python).
  • сервер - код, який отримує запити з клієнтів і реалізує механіку мультиплеєра. Як правило знаходиться НЕ НА комп'ютері гравця, але для деяких ігор можна запускати сервер на своєму комп'ютері.
  • Java - мова програмування та крос-платформенна віртуальна машина.
  • ліби, бібліотеки - куски коду (скопмпільованого або некомпільованого), які розширують або спрощують роботу з мовою програмування. Можуть використовуватися як і при компіляції, так і при фінальному запуску програми.
    • LWJGL - бібліотека для Java для роботи з OpenGL (3D-графіка)
  • .jar - файловий формат для біблотеки в Java. Є ZIP-архівом, тобто, його можна розпакувати архіватором. Містить скомпільовані класи Java
  • Java аргументи - параметри запуску java.exe. Контролюють технічні нюанси, наприклад, кількість оперативної пам'яті та список біблотек для використання
  • classpath - список шляхів бібліотек Java. Розділювач крапка з комою (на відновсі) або двокрапка (на лінуксі і MacOS). https://en.wikipedia.org/wiki/Classpath
  • хеш - коротка послідовність символів, яка є "унікальною" для різних послдовностей даних. "Унікальною" в лапках, бо насправді існують два набори різних даних, які мають одинаковий хеш, але знайти такі пари майже нереально.
  • JSON - текстовий формат даних. Складається з словників, списків, рядків та чисел. Його можуть читати та створювати всі мови програмування, тому він використовується для обміну даними між різними середовищами, і особливо його любить інтернет
  • словник - структура даних, яка є набором пар "ключ-значення". Ключі в словнику завжди унікальні, значення можуть повторюватись.
  • індекс - (тут) документ, який вказує лінки на файли які треба скачувати. Тобто, містить не файли для закачки, а список лінків для закачки
  • парсинг - отримування структурної інформації з рядка. Наприклад, з рядків "01.10.2021" та "2021-04-21" (які є датами у різних форматах) дістати інформацію про "рік" можна тільки після парсингу
  • запит, реквест (request) - взаємодія з інтернет сервером. Може бути запит на закачку документу, може бути запит на викачку файлу.

Маніфест версій

В цьому файлі знаходиться інформація про всі версії, які підтримуються для запуску стандартним лаунчером.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Це файл у форматі JSON. Ключ "latest" вказує на останню версію клієнта, а ключ "versions" є списком всіх можливих версій Майкрафта.

Окрім снепшот версій є ще release версії:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

І є різні альфа і бета версії:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Завдання: Написати код, який пише на екран дату релізу найпершої версії майнкрафту, використовуючи маніфест версій.

Завдання: Написати код, який виводить на екран всі релізні версії майнкрафту.

Завдання: Написати код, який порахує, скільки різних версій майнкрафту (релізних і нерелізних) було випущено в кожен з років 20092021.

Пакетний індекс

Адреса, яка знаходиться в url ключі версії з маніфесту версій. Наприклад,

https://launchermeta.mojang.com/v1/packages/dc5f9e134da9e18a2db42ddc246aba5cdfe28d3c/1.2.1.json

Пакетний індекс містить багато інформації про файли (з яких складається клієнт) і додаткову інформацію про те, як робити запуск.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • assetIndex вказує на список ассетів. Список ассетів знаходиться в іншому документі
  • downloads вказує на основні файли для завантаження. Наприклад, основний файл для запуску клієнту. Файл є ресурсом, тому скачується з серверу ресурсів (про це пізніше)
  • libraries вказує на додаткові бібліотеки для завантаження. Бібліотеки відповідають за 3Д графіку і інші системні задачі
  • mainClass вказує який клас з .jar клієнту треба запускати (нюанси Java)
  • minecraftArguments параметри запуску
  • і всякі інші параметри, непотрібні для запуску гри

Сторонні ліби

Окремо про бібліотеки в цьому документів. Інформація про лібу може бути "простою" (коли треба просто скачати і покласти в папку):

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

А може бути складною.

В яку папку класти бібліотеку? В принципі, це неважливо, головне потім вказати правильний шлях до бібліотеки у class path аргументі лаунчера.

Ліба для версії

Деякі ліби доступні тільки для певних версій. Наприклад, ця ліба потрібна для всіх версій MacOS окрім 10.5.x

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

А ось ця ліба потрібна тільки для MacOS версій 10.5.x

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Тобто, механізм "правил" ("rules") дозволяє для різних версій викачувати різні версії різних біблотек. Наприклад, в цьому випадку у MacOS 10.5.x був якийсь баг, через який бібліотека LWJGL не працювала як треба, тому довелось скачувати пропатчену версію.

Ліба для системи

Деякі бібліотеки потрібна тільки для однієї з ОС. У цьому випадку структура виглядає трошки складнішою, але все що воно робить, це вибирає яку бібліотеку на якій операційній системі скачувати.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Завдання: дістати список назв бібліотек (ключ name) з пакетного індексу.

Завдання: скачати програмно будь-яку бібліотеку з цього списку. Лінк на закачку вказаний в ключі url.

Як скачувати файли через Python: https://www.tutorialspoint.com/downloading-files-from-web-using-python

Завдання: для складних варіантів (де є ключ downloads.natives) потрібно скачати бібліотеку для правильної операційної системи (windows якщо у вас вінда, osx якщо MacOS).

Індекс ассетів

Він вказаний як лінк на ассети в пакетному індексі, наприклад:

https://launchermeta.mojang.com/v1/packages/4759bad2824e419da9db32861fcdc3a274336532/pre-1.6.json

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Формат цього файлу доволі простий: ключ objects є словник об'єктів, де ключем є шлях до файлу на клієнті (куди треба скачати), а значенням є пара (hash, size):

  • hash вказує на хеш об'єкту, і по цьому хешу можна отримати лінк на закачку. Лінк будується так: https://resources.download.minecraft.net/XX/YYYYYYYYYYYYYYYYYYYY, де XX - це перші два символи хешу, а YYYYYYYYYYYYYYYYYYY - сам хеш.
  • size - розмір файлу для закачки. Це потрібно для плавного відображення прогрес-бару при закачці.

Завдання: Написати функцію, яка по хешу отримує лінк на закачку ресурса по правилу вище.

Завдання: Написати функцію, яка отримує шлях до файлу, і створює всі папки які потрібно для того, щоб цей файл можна було скачати.

Завдання: (якщо зробили попередні два) Написати функцію, яка по індексу ассетів викачає всі файли по черзі і збереже їх в правильну папку.

Завдання: Написати функцію, яка по індексу ассетів порахує розмір всіх файлів для закачки і виведе на екран (в мегабайтах).

Завдання: Написати функцію, яка отримує на вхід два лінки на два різних індекси ассетів і виводить

  • скільки файлів ассетів є спільні для обох індексів
  • розмір файлів даних для кожного індексу
  • розмір даних для спільних асетів
  • скільки байт можна зекономити на інтернет закачці другого індексу, якщо не скачувати файли які вже були скачані по першому індексу