Закрыть
Идея создания Minecraft Classic сервера на Bash с GNU-утилитами, без использования какого либо языка программирования:
Сервер для классических версий, так просто меньше заморочек.
Есть главная проблема: Bash не умеет работать с null-байтами в строках, они обрезают данные. Поэтому вся архитектура будет строиться вокруг непрерывной конвертации бинарного трафика в текст (hex) и обратно.
Следующие утилиты пригодятся:
Использование socat или xinetd для прослушивания порта 25565.
При каждом входящем подключении socat запускает отдельный экземпляр bash-скрипта, пробрасывая сокет клиента в стандартные потоки stdin и stdout скрипта.
Сырые байты из stdin немедленно пайпятся в "xxd -p", превращаясь в сплошную hex-строку (0x0...), которую bash может безопасно читать и сохранять в переменные.
В самом скрипте формируется ответный пакет как текстовую hex-строку, прогоняет её через "xxd -r -p" для обратной конвертации в сырые байты и пишет в stdout (т.е. прямо в сокет клиента).

Так как в классических версиях сервера пакеты имеют строгую длину, входящий hex-поток нарезается с помощью текстовых утилит cut, "head -c" или awk (чтение определенных символов строки). ID пакета (первые два hex-символа) передается в конструкцию скрипта "case ... esac", которая вызывает соответствующую функцию в bash (рукопожатие, авторизация, установка блока, движение).
Мир будет хранится в "/dev/shm" (tmpfs), для повышения скрости. При старте/завершении работы мир загружать/выгружать. Сам мир будет небольшим, плоским, один слой какого-то блока. Запись будет в текстовом файле или через ассоциативные массивы bash, где блоки записаны в виде символов.
При первом старте сервера утилита yes (да, тупо спамит какими-то символам) генерирует простой файл нужного размера.
При входе игрока сервер не собирает чанки динамически, а просто читает файл плоского мира (через утилиту cat), оборачивает в заголовки пакетов и отправляет клиенту. Серверу также нужна многопоточность. Внутри обработчика клиента запускается фоновый процесс ("while true; do ... sleep 0.05; done &"), имитирующий 20 TPS. Изменения, как упоминал, пишутся в "/dev/shm", чтобы другие фоновые процессы могли их прочитать. Фоновый цикл регулярно формирует hex-пакет Keep-Alive и отправляет его через xxd, чтобы клиент не отвалился по таймауту.
Показать больше
Пожаловаться  |  Поделиться

Комментарии (3)

хотя не, хуйня, тут ещё много нюансов нужно соблюсти
Harrier Du-Bois, да и многопоточность для такого простого мира и небольшого числа игроков ни к чему, лишняя проблема
лучше на lua потому что тогда будет гораздо легче писать серверные моды (на сколько я знаю там есть корутины)

Действия