# Личный проект по IT
###### tags: `IT` `Minecraft` `Аттестаты`
> Проект полностью выполнен своими силами и призван произвести хайп вокруг школы :video_game:
> Быстрый доступ ко всему:
> [ToC]
## :memo: Что за проект?
Поскольку во время карантина нельзя было собираться толпами людей, проводить мероприятия по вручению аттестатов в 9 классе - стало проблематичным. Вся учебная жизнь в этом году у них - закончилась. Было принято решение провести вручение в игре майнкрафт. В данном документе расписано подробно все новые IT фишки, которые я смог применить в реализации данного соц/IT проекта.
## Задачи
- [ ] Создать переносной сервер для быстрого развёртывания на любой ОС
- [ ] Найти строителей в Майнкрафт для создании копии здания школы в игре
- [ ] Привлечь людей к серверу и начать рекламную компанию (в одной школе)
- [ ] Найти платформу проведения мероприятия в онлайн с использованием голосового чата (или видео)
- [ ] Выдать игровые аттестаты перед этим каким-то образом сгенерировав их
### Шаг 0: С чего всё началось?
Первое, с чего стоит начать, что простой компьютер не всегда можно вывести в открытую сеть. Сделать так, чтобы любой человек по какому-то уникальному запросу (IP) подключился именно к вашему компьютеру
Я нашёл три пути решения, и использовал одно, для начала:
- Использовать виртуальный мост между всеми компьютерами (VPN)

- Купить у провайдера белый(статический) IP и стать компьютером, доступным в интернете из любой точки сети

- Использовать утилиту, которая проводит трафик через компьютер, доступный в интернете (к примеру [Ngrok](https://ngrok.com/))

**Итог шага:**
Естественно, самым простым решением было использовать 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 - успер удобный плагин для установки прав пользователям, создании групп и прочего. С помощью него мы настроили аккаунты строителей, зрителей (игроков) и двух администраторов.
Уже на данном этапе наш сервер работал просто на виживании, и пришлось думать, как теперь искать людей для постройки копии школы.

#### 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)

:::
### Шаг 2: Создаём школу с нуля
На этом шаге можно посмотреть фотографии [фасада здания](https://drive.google.com/drive/folders/1zkoT4GY2b1uB8y0P5UpK3myyixkRsMnW) нашей в реальном мире и в [мире Minecraft](https://drive.google.com/file/d/1_85t_cSMoGsvjFs6izKvEPjLSG7fT7lc/view?usp=sharing
Фото:
:::spoiler
>


:::
Здесь добавлю только одно, то, что была написана программа для генерации сундуков для языка командного блока, с помещением внутрь всяких декораций, но она никак не использовалась.
```
/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)
- Скрин формы:

- Получившаяся таблица Google Sheet (скрыты реальные ФИО)

#### Создаём шаблон для генерации
Одни раз и навсегда мы решили создаь простой шаблон для генерации Аттестата.
```
/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 завезли не так уж и рано, поэтому пришлось весь текст переводить в набор байт и экранировать (вместо одного слеша ставить двойной)
Если введём эту команду - увидим следующую книгу в своих руках:

#### Скрипт? Не слышали!
Теперь приступим уже к конкретному действию - запускаем скрипт, который создаст команду для каждого игрока из Google таблиц.

Проверим аттестат одного из игроков:

[: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)
> 
:::info
P.s Мне просто нельзя было его использовать конкретно на данном мероприятии.
:::success
:::
Поэтому пришлось быстро перестраиваться и решать что-то.
Нашёл одну интересную вещь, которую успели настроить но не протестировали.
#### BigBlueButton и конференции
https://bigbluebutton.org/
Это простая платформа, которая устанавливается за 15 минут (не всегда), и полезна тем, что устанавливается на компьютер Ubuntu 16.04 LTS
Полезно знать Nginx и после установки - настроить его.
Она очень простая, но нам хватило её, чтобы поговорить с участниками!
Фото ниже:
:::spoiler
> 
> 
> 
> Тестовая ссылка: https://webinar.vycheslavrussu.ru/
> P.s Она сейчас может не рабоать, поскольку сервер - не самый дешёвый.
:::
### Шаг 5: Посты в ВК и проведение
Чтобы было всё красиво - необходимы красивые, понятные посты для привличения внимания!
Вот и они:
:::spoiler
>
>
>
:::
### Шаг 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)