# Личный проект по IT ###### tags: `IT` `Minecraft` `Аттестаты` > Проект полностью выполнен своими силами и призван произвести хайп вокруг школы :video_game: > Быстрый доступ ко всему: > [ToC] ## :memo: Что за проект? Поскольку во время карантина нельзя было собираться толпами людей, проводить мероприятия по вручению аттестатов в 9 классе - стало проблематичным. Вся учебная жизнь в этом году у них - закончилась. Было принято решение провести вручение в игре майнкрафт. В данном документе расписано подробно все новые IT фишки, которые я смог применить в реализации данного соц/IT проекта. ## Задачи - [ ] Создать переносной сервер для быстрого развёртывания на любой ОС - [ ] Найти строителей в Майнкрафт для создании копии здания школы в игре - [ ] Привлечь людей к серверу и начать рекламную компанию (в одной школе) - [ ] Найти платформу проведения мероприятия в онлайн с использованием голосового чата (или видео) - [ ] Выдать игровые аттестаты перед этим каким-то образом сгенерировав их ### Шаг 0: С чего всё началось? Первое, с чего стоит начать, что простой компьютер не всегда можно вывести в открытую сеть. Сделать так, чтобы любой человек по какому-то уникальному запросу (IP) подключился именно к вашему компьютеру Я нашёл три пути решения, и использовал одно, для начала: - Использовать виртуальный мост между всеми компьютерами (VPN) ![](https://help.keenetic.com/hc/article_attachments/360000670920/vpn-site-to-site.png) - Купить у провайдера белый(статический) IP и стать компьютером, доступным в интернете из любой точки сети ![](https://zametkinapolyah.ru/wp-content/uploads/2018/09/4.7.1-%D0%A1%D1%85%D0%B5%D0%BC%D0%B0-%D0%BF%D0%BE%D1%8F%D1%81%D0%BD%D1%8F%D1%8E%D1%89%D0%B0%D1%8F-%D0%BF%D1%80%D0%BE-%D1%81%D0%B5%D1%80%D1%8B%D0%B5-%D0%B8-%D0%B1%D0%B5%D0%BB%D1%8B%D0%B5-IP-%D0%B0%D0%B4%D1%80%D0%B5%D1%81%D0%B0.png) - Использовать утилиту, которая проводит трафик через компьютер, доступный в интернете (к примеру [Ngrok](https://ngrok.com/)) ![](https://i.imgur.com/7RnIEZP.png) **Итог шага:** Естественно, самым простым решением было использовать Ngrok, для создания сервера в Майнкрафт, оставалось только его запустить, но так, чтобы можно было его перенести затем на любую другую машину. :rocket: ### Шаг 1: Настраиваем первый сервер #### Пишем свой Docker-Compose Самое удобное, что придумало человечество - виртуализация. Установка одной системы - в другую. Самой простой мини виртуализацией - является Docker > **Docker** — программное обеспечение для автоматизации развёртывания и управления приложениями в средах с поддержкой контейнеризации. [Википедия](https://ru.wikipedia.org/wiki/Docker) Для начала, необходимо было решить, что вообще использовать для сервера в Minecraft. Так как аудитория - 9 класс. Было принято решение работать с пиратскими клиентами майнкрафт, а значит в 2020 году - это называется издание майнкрафт Java Edition. И гугл подсказал несколько вариантов. Обзор: - Официальная сборка сервера для Minecraft - Простая, лёгкая в установке - Один JAR File - Нет никаких плагинов, поддерживается всеми разработчиками - CraftBukkit - Удобная платформа - Есть дополнения - плагины - Уменьшенная нагрузка на память сервера - Куча настроек, загрузка из Jar File - Spigot - Legacy поддержка CraftBukkit - Так-же имеются плагины - Многопоточные вычисления - Оптимизация и поддержка Java 11 версии - Paper - Плагины, которые раюотают только на одной версии Paper - Подробный гайд для установки - Нет Legacy, зато есть место на жёстком диске после 3ёх часов игры на сервере! :::info Самым простым решением был Spigot, поскольку у него есть поддержка всех новых версий, а так же он экономит оперативную память. От этого критерия будет зависеть максимальное колличество игроков на сервере. ::: Опустим самые сложные вычисления, которые могли возникнуть, но после несокльких гугл запросов, я нашёл интересные Docker контейнеры для запуска сервера [Docker Minecraft](https://hub.docker.com/r/itzg/minecraft-server/) Было принято решение использовать Майнкрафт версии 1.15.2. Под данные контейнеры был написан простенький скрипт, который можно запустить из директории командой `sudo docker-compose up -d` ```yaml=1 version: '3' services: minecraft: image: itzg/minecraft-server ports: - "25565:25565" - "25575:25575" environment: EULA: 'TRUE' TYPE: SPIGOT VERSION: 1.15.2 OPS: Admin MEMORY: '1536M' volumes: - './datas:/data' restart: always ``` После запуска появляется сервер майнкрафт досутпный по адресу `127.0.0.1:25565` #### Настраиваем плагины для входа на сервер Далее необходимо было настроить плагины авторизации/регистрации и быстрого изменения территории в майнкрафт. AutoBackup и AutoSave Поскольку версия майнкрафта - 1.15.2, хороших, переведённых плагинов - ещё не существовало. Пришлось гуглить не только на российских сайтах. - Плагин авторизации - nLogin - Португальская поддержка - Имеется своя капча от ботов на сервере - Умеет хранить данные в базе данных MariaDB (MySQL) - Умеет сохранять сессию и определять местоположение по входу и IP Плагин этот пришлось немного дописать, чтобы он начал обращаться к другому сервису капчи. И после этого, он начал работать - лучше. Сейчас - плагин мы полностью перевели и используем на сервере. - WorldEdit - плагин для быстрого возведения стен, трансофрмации пространства в Minecraft - LuckyPerms - успер удобный плагин для установки прав пользователям, создании групп и прочего. С помощью него мы настроили аккаунты строителей, зрителей (игроков) и двух администраторов. Уже на данном этапе наш сервер работал просто на виживании, и пришлось думать, как теперь искать людей для постройки копии школы. ![](https://sun9-67.userapi.com/YYzDq8O0yAqipzMS3pDmecw4jJ5DAGh-NlNW-A/1P8AzsJV0CQ.jpg) #### BungeeCord. Бьём сервер на потоки Теперь мы думали о том, как создать на одном сервере - несколько подсерверов, в которые можно было бы перейти из Lobby Для этого нужно было понять, чем проксировать такие запросы. И, теперь назову главный плюс сборки сервера от Spigot - у него есть отдельный сервис для Proxy - [BungeeCord](https://www.spigotmc.org/wiki/about-bungeecord/) > BungeeCord is a useful software written in-house by the team at SpigotMC. It acts as a proxy between the player's client and the connected Minecraft servers. End-users of BungeeCord see no difference between it and a normal Minecraft server. Теперь схема подключения выглядела таким образом: 1. Схема авторизации ```sequence Клиент->Bung: Я хочу подключиться к серверу. Bung->Auth: Произведи авторизацю данного пользователя. Auth-->Клиент: Зарегестрируйся или авторизируйся! Клиент->Auth: Ввожу свои данные авторизации Auth-->Bung: Пользователь авторизирован Bung->Lobby: Этот пользователь хочет присоедениться к игре! Lobby-->Bung: Окей, принято! Клиент->Lobby: Join the Game ``` 2. Схема перехода на игровой сервер и сервер для школы (в примере просто сервер N): ```sequence Клиент->Lobby: Хочу перейти на игровой сервер N Lobby->Bung: Есть подключение к серверу N? Bung->N: Ты здесь? N-->Bung: Да, я здесь! Bung-->Lobby: Сервер N в сети! Lobby-->Клиент: Данные для подключения к серверу N Клиент->Bung: У меня есть данные для подключения к серверу N! Bung->N: Ты здесь? N-->Bung: Да, я здесь! Клиент->N: Join the Game ``` Теперь три файла Docker-compose: 1. Bung (Proxy) + Lobby + Auth. Для шаговой доступности всё в одном Docker compose файле ```yaml=1 version: '3' services: bung: image: itzg/minecraft-server ports: - "25565:25565" - "25575:25575" environment: EULA: 'TRUE' TYPE: SPIGOT SPIGOT_DOWNLOAD_URL: "https://ci.md-5.net/job/BungeeCord/lastSuccessfulBuild/artifact/bootstrap/target/BungeeCord.jar" OPS: Admin MEMORY: '1G' volumes: - './bungeecoord:/data' depends_on: - "auth" - "lobby" auth: image: itzg/minecraft-server environment: EULA: 'TRUE' TYPE: SPIGOT VERSION: 1.15.2 OPS: Admin MEMORY: '1G' volumes: - './auth:/data' lobby: image: itzg/minecraft-server environment: EULA: 'TRUE' TYPE: SPIGOT VERSION: 1.15.2 OPS: Admin MEMORY: '1G' volumes: - './lobby:/data' ``` 2. Сервер игровой, для привличения людей (Выживание) ```yaml=1 version: '3' services: minecraft: image: itzg/minecraft-server ports: - "25565:25565" - "25575:25575" environment: EULA: 'TRUE' TYPE: SPIGOT VERSION: 1.15.2 OPS: 68miner MEMORY: '1536M' volumes: - './datas:/data' restart: always ``` 3. Сервер игровой, школа (Режим приключений) ```yaml=1 version: '3' services: minecraft: image: itzg/minecraft-server ports: - "25565:25565" - "25575:25575" environment: EULA: 'TRUE' TYPE: SPIGOT VERSION: 1.15.2 OPS: Admin MEMORY: '13G' volumes: - './datas:/data' restart: always ``` 4. Настраиваем файл с проксированием: ```yaml=1 listeners: - query_port: 25565 # порт с прослушиванием motd: '&eGaben &aServer Minecraft' tab_list: GLOBAL_PING query_enabled: false proxy_protocol: false forced_hosts: pvp.md-5.net: pvp ping_passthrough: false priorities: - auth bind_local_address: true host: 0.0.0.0:25565 max_players: 5452 tab_size: 60 force_default_server: true remote_ping_cache: -1 network_compression_threshold: 256 permissions: default: null admin: null log_pings: true connection_throttle_limit: 3 server_connect_timeout: 5000 timeout: 30000 stats: d970fa7a-9aca-412e-a019-d13afc685c35 player_limit: -1 ip_forward: true groups: md_5: - default remote_ping_timeout: 5000 connection_throttle: 4000 log_commands: false prevent_proxy_connections: false online_mode: false forge_support: false disabled_commands: - god servers: # Здесь настраиваются сервера и подключения к ним lobby: motd: '&eGaben &aServer Minecraft' address: lobby:25565 restricted: false auth: motd: '&eGaben &aServer Minecraft' address: auth:25565 restricted: false survivalone: motd: '&eGaben &aServer SurvivalOne' address: 10.154.0.2:25565 restricted: false school: motd: '&eGaben &aServer School' address: 10.154.0.100:25565 restricted: false ``` :::info :bulb: После настройки сервера, все протестировали на Ngrok и после этого перенесли в Google Cloud (Compute Engine) ![](https://sun9-71.userapi.com/bTKhnD6TnhqtugM_4bTZpEIpiaJ18XHbXTEnYQ/7eag-GUfEe8.jpg) ::: ### Шаг 2: Создаём школу с нуля На этом шаге можно посмотреть фотографии [фасада здания](https://drive.google.com/drive/folders/1zkoT4GY2b1uB8y0P5UpK3myyixkRsMnW) нашей в реальном мире и в [мире Minecraft](https://drive.google.com/file/d/1_85t_cSMoGsvjFs6izKvEPjLSG7fT7lc/view?usp=sharing Фото: :::spoiler >![](https://i.imgur.com/1cPRjWZ.jpg) ![](https://i.imgur.com/q7PfOeM.jpg) ![](https://i.imgur.com/69XrrFu.jpg) ::: Здесь добавлю только одно, то, что была написана программа для генерации сундуков для языка командного блока, с помещением внутрь всяких декораций, но она никак не использовалась. ``` /setblock ~ ~1 ~ minecraft:chest[]{Items:[{Slot: 0b, id: "minecraft:written_book", Count: 1b, tag: {pages:['["",{"text":"\\u041a\\u043d\\u0438\\u0433\\u0430 \\u0441 Minecraft Tools *\\u0437\\u0434\\u0435\\u041\\u044c \\u0431\\u044b\\u043b Azerus Team*dasdasdasdasdsad"},{"text":"dasdasdsadasd","color":"green"},{"text":"adsdsadsad","color":"light_purple"},{"text":"dasdasdasd","color":"dark_purple"},{"text":"dsadasdsasd","color":"white"},{"text":"dasdasdasdsdasdsad \\u0020 ","color":"dark_red"}]'],title:"Книга",author:sema_kol123,display:{Lore:["lolkek"]}}}]} ``` К примеру эта команда генерировала сундук с книгой внутри. ### Шаг 3: Генерация Аттестатов Вот здесь нам понадобились глубокие знания и программирования и механики Майнкрафт. Не будем же мы проставлять все оценки вручную! #### Гугл формы творят чудеса Для начала - создали форму для регистрации на мероприятие. Пока решали вопрос с администрацией, поняли, что проще всего в этой форме и создать генератор своего аттестата. Ребята сами вписывали свои оценки, а, если чего-то не хватало, просто генерировалась оценка сначала рандомно, а затем, по текущему среднему баллу. Таикм образом все получили аттестаты - какие хотели. [Ссылка на форму](https://forms.gle/yU2u5Kcptf2BxvJ87) - Скрин формы: ![](https://i.imgur.com/Wr2sZZN.png) - Получившаяся таблица Google Sheet (скрыты реальные ФИО) ![](https://i.imgur.com/c3PsHb5.png) #### Создаём шаблон для генерации Одни раз и навсегда мы решили создаь простой шаблон для генерации Аттестата. ``` /give $nick written_book{pages:['["",{"text":"\\n\\n"},{"text":"ATTECTAT","bold":true},{"text":"\\n\\n\\n\\u041e\\u0431 \\u043e\\u0441\\u043d\\u043e\\u0432\\u043d\\u043e\\u043c \\u043e\\u0431\\u0449\\u0435\\u043c \\u043e\\u0431\\u0440\\u0430\\u0437\\u043e\\u0432\\u0430\\u043d\\u0438\\u0438\\n ","color":"reset"}]','["",{"text":"\\u0418\\u0433\\u0440\\u043e\\u0432\\u043e\\u0439 \\u0430\\u0442\\u0442\\u0435\\u0441\\u0442\\u0430\\u0442 \\u0441\\u0432\\u0438\\u0434\\u0435\\u0442\\u0435\\u043b\\u044c\\u0441\\u0442\\u0432\\u0443\\u0435\\u0442 \\u043e \\u0442\\u043e\\u043c, \\u0447\\u0442\\u043e\\n\\n"},{"text":"$names","bold":true},{"text":"\\n\\n\\u0432 2020 \\u0433\\u043e\\u0434\\u0443 \\u043d\\u0430\\u043a\\u043e\\u043d\\u0435\\u0446-\\u0442\\u043e \\u043e\\u043a\\u043e\\u043d\\u0447\\u0438\\u043b(\\u0430) \\u0441\\u0432\\u043e\\u044e \\u043b\\u044e\\u0431\\u0438\\u043c\\u0443\\u044e \\u0448\\u043a\\u043e\\u043b\\u0443 \\u0438 \\u043f\\u043e\\u043b\\u0443\\u0447\\u0438\\u043b(\\u0430) \\u043e\\u0431\\u0449\\u0435\\u0435 \\u043e\\u0431\\u0440\\u0430\\u0437\\u043e\\u0432\\u0430\\u043d\\u0438\\u0435","color":"reset"}]','{"text":"\\u041f\\u0440\\u0435\\u0434\\u043c\\u0435\\u0442\\u044b \\u0020| \\u041e\\u0446\\u0435\\u043d\\u043a\\u0430\\n\\n\\u0410\\u043d\\u0433\\u043b\\u0438\\u0439\\u0441\\u043a\\u0438\\u0439 \\u044f\\u0437\\u044b\\u043a \\u0020 $a\\n\\u0411\\u0438\\u043e\\u043b\\u043e\\u0433\\u0438\\u044f \\u0020 \\u0020 \\u0020 \\u0020 \\u0020 $b\\n\\u0413\\u0435\\u043e\\u0433\\u0440\\u0430\\u0444\\u0438\\u044f \\u0020 \\u0020 \\u0020 \\u0020 \\u0020$c\\n\\u0418\\u043d\\u0444\\u043e\\u0440\\u043c\\u0430\\u0442\\u0438\\u043a\\u0430 \\u0020 \\u0020 \\u0020 $d\\n\\u0418\\u0441\\u0442\\u043e\\u0440\\u0438\\u044f \\u0020 \\u0020 \\u0020 \\u0020 \\u0020 \\u0020$e\\n\\u041b\\u0438\\u0442\\u0435\\u0440\\u0430\\u0442\\u0443\\u0440\\u0430 \\u0020 \\u0020 \\u0020 \\u0020$f\\n\\u041c\\u0430\\u0442\\u0435\\u043c\\u0430\\u0442\\u0438\\u043a\\u0430 \\u0020 \\u0020 \\u0020 \\u0020$g\\n\\u041e\\u0411\\u0416 \\u0020 \\u0020 \\u0020 \\u0020 \\u0020 \\u0020 \\u0020 $h"}','{"text":"\\u041f\\u0440\\u0435\\u0434\\u043c\\u0435\\u0442\\u044b \\u0020| \\u041e\\u0446\\u0435\\u043d\\u043a\\u0430\\n\\n\\u041e\\u0431\\u0449\\u0435\\u0441\\u0442\\u0432\\u043e\\u0437\\u043d\\u0430\\u043d\\u0438\\u0435 \\u0020 $i\\n\\u0420\\u0443\\u0441\\u0441\\u043a\\u0438\\u0439 \\u044f\\u0437\\u044b\\u043a \\u0020 \\u0020 \\u0020 $g\\n\\u0424\\u0438\\u0437\\u0438\\u043a\\u0430 \\u0020 \\u0020 \\u0020 \\u0020 \\u0020 \\u0020 \\u0020$k\\n\\u0424\\u0438\\u0437\\u043a\\u0443\\u043b\\u044c\\u0442\\u0443\\u0440\\u0430 \\u0020 \\u0020 \\u0020 $l\\n\\u0425\\u0438\\u043c\\u0438\\u044f \\u0020 \\u0020 \\u0020 \\u0020 \\u0020 \\u0020 \\u0020 $m\\n\\u041c\\u0443\\u0437\\u044b\\u043a\\u0430 \\u0020 \\u0020 \\u0020 \\u0020 \\u0020 \\u0020 \\u0020$n\\n\\u0418\\u0417\\u041e \\u0020 \\u0020 \\u0020 \\u0020 \\u0020 \\u0020 \\u0020 \\u0020 $o\\n\\u0422\\u0435\\u0445\\u043d\\u043e\\u043b\\u043e\\u0433\\u0438\\u044f \\u0020 \\u0020 \\u0020 \\u0020$p"}','{"text":"***\\n\\u0414\\u0430\\u043d\\u043d\\u044b\\u0439 \\u0430\\u0442\\u0442\\u0435\\u0441\\u0442\\u0430\\u0442 \\u043d\\u0435\\u0441\\u0451\\u0442 \\u0438\\u0441\\u043a\\u043b\\u044e\\u0447\\u0438\\u0442\\u0435\\u043b\\u044c\\u043d\\u043e \\u0440\\u0430\\u0437\\u0432\\u043b\\u0435\\u043a\\u0430\\u0442\\u0435\\u043b\\u044c\\u043d\\u044b\\u0439 \\u0445\\u0430\\u0440\\u0430\\u043a\\u0442\\u0435\\u0440\\n\\n\\u041d\\u0435 \\u0438\\u043c\\u0435\\u0435\\u0442 \\u044e\\u0440\\u0438\\u0434\\u0438\\u0447\\u0435\\u0441\\u043a\\u043e\\u0439 \\u0441\\u0438\\u043b\\u044b\\n\\n\\u0421\\u043e\\u0437\\u0434\\u0430\\u0442\\u0435\\u043b\\u044c \\u043d\\u0435 \\u043d\\u0435\\u0441\\u0451\\u0442 \\u043e\\u0442\\u0432\\u0435\\u0441\\u0442\\u0432\\u0435\\u043d\\u043d\\u043e\\u0441\\u0442\\u0438 \\u0437\\u0430 \\u0441\\u043e\\u0434\\u0435\\u0440\\u0436\\u0438\\u043c\\u043e\\u0435 \\u0432 \\u043d\\u0451\\u043c\\n\\n***\\n "}','{"text":"***\\n\\n\\u041a\\u0443\\u0440\\u0435\\u043d\\u0438\\u0435 \\u0432\\u0440\\u0435\\u0434\\u0438\\u0442 \\u0432\\u0430\\u0448\\u0435\\u043c\\u0443 \\u0437\\u0434\\u043e\\u0440\\u043e\\u0432\\u044c\\u044e.\\n\\n***"}'],title:"Аттестат",author:"Лицей ВЕКТОРиЯ"} ``` Поддержка UTF-8 в Minecraft завезли не так уж и рано, поэтому пришлось весь текст переводить в набор байт и экранировать (вместо одного слеша ставить двойной) Если введём эту команду - увидим следующую книгу в своих руках: ![](https://i.imgur.com/7M7nUGL.gif) #### Скрипт? Не слышали! Теперь приступим уже к конкретному действию - запускаем скрипт, который создаст команду для каждого игрока из Google таблиц. ![](https://i.imgur.com/c8vz5dh.gif) Проверим аттестат одного из игроков: ![](https://vk.com/doc174899453_554567342?hash=67b84c61abeaf39460&dl=bea5a02b367b69d568&wnd=1&module=im) [:accept: Код можно посмотреть тут](https://drive.google.com/file/d/1AHrkB0XWkrxwbzFUU1PrRlw6Gjfan8mr/view?usp=sharing) ### Шаг 4: Платформа проведения #### Discord :unamused: Во время карантина уже некоторые люди поняли, что Zoom - супер штука, которой можно даже пользоваться. Мы хотели использовать платформу **Discord** для проведения мероприятия, но, так получилось, что на территорию Пермского края пришло письмо от губернатора с сожержимым: :::spoiler > Тема: О запрете исплоьзования Discord > Здравствуйте. Направляю письмо министерства образования в работу. > [Ссылка на документ](https://vk.com/doc26350930_553314681?hash=eac517343c6907a0dc&dl=70bea006d58528f8ba) > ![](https://i.imgur.com/k7cemYV.png) :::info P.s Мне просто нельзя было его использовать конкретно на данном мероприятии. :::success ::: Поэтому пришлось быстро перестраиваться и решать что-то. Нашёл одну интересную вещь, которую успели настроить но не протестировали. #### BigBlueButton и конференции https://bigbluebutton.org/ Это простая платформа, которая устанавливается за 15 минут (не всегда), и полезна тем, что устанавливается на компьютер Ubuntu 16.04 LTS Полезно знать Nginx и после установки - настроить его. Она очень простая, но нам хватило её, чтобы поговорить с участниками! Фото ниже: :::spoiler > ![](https://i.imgur.com/J2XKSqP.gif) > ![](https://i.imgur.com/tyHMg9B.png) > ![](https://i.imgur.com/pIbkyRE.png) > Тестовая ссылка: https://webinar.vycheslavrussu.ru/ > P.s Она сейчас может не рабоать, поскольку сервер - не самый дешёвый. ::: ### Шаг 5: Посты в ВК и проведение Чтобы было всё красиво - необходимы красивые, понятные посты для привличения внимания! Вот и они: :::spoiler >![](https://i.imgur.com/pDMDZMN.png) >![](https://i.imgur.com/RX9iiaJ.png) >![](https://i.imgur.com/tO9ZxHE.png) ::: ### Шаг 6: А поиграть то можно? Да, конечно можно! :::success **☑** Сервер доступен, вы можете прогуляться по точной копии здания Лицея № 1 **♨** IP сервера: 34.89.7.213 / Minecraft 1.15.2 ::: Прикладываю [видео](https://drive.google.com/file/d/1Go1I68Fz9BRk3IWe3chqUbvEMZpjagkL/view?usp=sharing) с обзором сервера. Как он сейчас работает. ## Вывод Проект успешно завершён, но осталась только одна маленькая деталь. Мне предстоит монтировать видео, отрендерить красивое здание лицея, а после этого сказать, насколько простая идея может принести столько "хайпа" одной школе. Начиналось всё просто с того, что сервер сделали для одной игры - отдохнуть. А теперь настроили его так, чтобы его можно было использовать любому человеку. [Чистый проект отправляю на GitLab](https://gitlab.com/gabenD/easyminecraftinstall)