servidor minetest + postgreSQL en linux (I)

Este año me he propuesto «llevar a otro nivel» los talleres de minetest para desarrollar todo tipo de proyectos educativos: introducción al modelado 3D, estudio de instalaciones en viviendas, reconstrucción de monumentos y arquitectura clásica, diseño de circuitos digitales, introducción a la programación, construir una réplica de nuestro colegio a escala, explorar un nuevo planeta, estudiar la influencia del ser humano sobre la colonización de un entorno, reproducir una batalla histórica, imaginar una ciudad del futuro, construir un mundo sin armas,… 

Y no sólo eso. La idea es crear tantos «mundos» como grupos de alumnos de los diferentes niveles educativos quieran participar, involucrar a los profesores de las asignaturas correspondientes e incluso permitir a los chicos disfrutar tanto en el centro como desde sus casas (incluidos periodos no lectivos).

Así que… ¿Cómo lo hacemos?

Situaciones posibles:

  • Disponer de un servidor capaz de manejar múltiples instancias (mundos) independientes de forma simultánea, cada uno de ellos con un número de jugadores entre 25 y 40 (para todos los alumnos de una clase más los profesores)
  • Disponer de un servidor único con un mundo particionado en áreas protegidas, asignadas a grupos de jugadores por cursos/grupos de alumnos, donde pudieran jugar entre 100 y 200 alumnos simultáneamente.

Recomendación desde Minetest:

Otras cuestiones a tener en cuenta:

  • Facilitar la administración del servidor y sus instancias (inicio, parada, reglas de cortafuego/nat, configuración, instalación y habilitación de “mods”…)
  • Facilitar la creación, mantenimiento, copias de seguridad y seguimiento de los “mundos” a utilizar por los alumnos.
  • Facilitar la gestión de cuentas de jugador/alumno asignadas a cada “mundo” (claves, permisos, asignación de áreas,…)

Primer problema a resolver:

Las versiones “oficiales” del juego no traen consigo el soporte para Postgresql, por lo que tendremos que reconstruirlo desde cero a partir de su código fuente.

 

[1] Instalación del software necesario (ubuntu):

Actualiza los repositorios… 

sudo apt update

… y luego instala todo los necesario para trabajar …

sudo apt install wget postgresql postgresql-contrib g++ make libc6-dev libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev libpq-dev libpqtypes-dev doxygen libluajit-5.1-dev libspatialindex-dev libncurses-dev

[2] Creación de un usuario específico para la ejecución de las instancias del servidor:

Por seguridad siempre es bueno asociar a los procesos del servidor una cuenta de usuario con privilegios limitados. Le llamaremos «minetest»:

sudo useradd -mU minetest

[3] Descarga del código fuente de MineTest y de su modo de juego principal:

Iniciaremos desde el terminal una sesión interactiva con el reciente usuario «minetest»:

sudo -i -u minetest

A continuación procederemos a descargar, desempaquetar y eliminar los archivos descargados una vez extraído su contenido en el sitio correcto:

wget https://github.com/minetest/minetest/archive/master.tar.gz
tar xf master.tar.gz
rm master.tar.gz
cd minetest-master/games/
wget https://github.com/minetest/minetest_game/archive/master.tar.gz 
tar xf master.tar.gz
rm master.tar.gz
mv minetest_game-master minetest_game
cd ..

[4] Compilación con soporte para PostgreSQL y ejecución en el directorio local (no necesita instalación posterior):

Configuraremos las opciones de construcción del programa servidor para que se genere un binario que pueda ejecutarse en el directorio local (tipo aplicativo «portable»), excluyendo las opciones del cliente gráfico (no nos interesa para nada) y añadiendo lo necesario para que pueda manejarse con PostgreSQL:

cmake . -DRUN_IN_PLACE=TRUE -DBUILD_CLIENT=FALSE -DBUILD_SERVER=TRUE -DCMAKE_BUILD_TYPE=Release -DBUILD_UNITTESTS=FALSE -DENABLE_POSTGRESQL=TRUE -DVERSION_EXTRA=postgresql -DPostgreSQL_INCLUDE_DIR=/usr/include/postgresql -DPostgreSQL_TYPE_INCLUDE_DIR=/usr/include/postgresql -DPostgreSQL_LIBRARY=/usr/lib/x86_64-linux-gnu/libpq.so

A continuación lanzaremos el proceso de construcción (compilación):

make -j$(nproc)

OPCIONAL – Crea un paquete “.tar.gz” para su distribución como aplicativo “portable”:

make package

NOTAS: El paquete generado sólo incluye textos en inglés. Si quieres traducciones debes incluir también la carpeta “locale” (adapta el nombre del fichero con el que tú hayas generado):

tar -zcf minetest-locale.tar.gz local

Puedes descargarte desde este enlace el paquete completo con las traducciones integradas: minetest-5.5.0-postgresql-linux.tar.gz

Finalmente regresa al directorio base del usuario «minetest»:

cd ..

[5] Primera ejecución y parada del servidor de minetest:

Esta primera acción servirá para comprobar que es posible ejecutar el programa recién compilado.

./minetest-master/bin/minetestserver

… y pulsa luego “Ctrl” + “C” para finalizar y cerrar el servicio.

Si todo ha funcionado correctamente se habrá generado dentro de “minetest-master/” un archivo llamado “debug.txt” y una carpeta llamada “worlds/”, y a su vez dentro de ella un primer “mundo” con su carpeta correspondiente llamado “world/”. Los archivos de esta última representan el estado actual de ese mundo, su configuración y cómo ha de generarse el mundo según lo vayan descubriendo los jugadores (faltan algunos archivos que no se crean hasta que se requieren por primera vez): 

debug.txt
worlds/
└── world/
   ├── env_meta.txt
   ├── force_loaded.txt
   ├── ipban.txt
   ├── map_meta.txt
   ├── map.sqlite
   └── world.mt

Por ahora nos interesa especialmente el fichero “world.mt” cuyo contenido se muestra a continuación:

enable_damage = true
creative_mode = false
auth_backend = sqlite3
player_backend = sqlite3
backend = sqlite3
gameid = minetest
world_name = world

En él podemos observar que por defecto el servidor MineTest utiliza el método “sqlite3” como almacenamiento para los datos del mapa, jugadores y autenticación. ¡NO CAMBIES NADA TODAVÍA

[6] Configuración de PostgreSQL como almacenamiento para MineTest

Abre un nuevo terminal (o cierra la sesión del usuario “minetest” si sigues con ella).

Edita el archivo “postgresql.conf” (en mi caso es “/etc/postgresql/12/main/postgresql.conf”) y cambia el valor del parámetro “shared_buffer” al valor de la mitad de la RAM instalada en el equipo, con un mínimo de 512MB (con 4GB en el mío yo pondría 2048MB).

Reinicia el servicio para que los cambios tengan efecto:

sudo systemctl restart postgresql.service

Ejecuta la herramienta “psql” con el usuario “postgres” para generar un nuevo rol (credenciales de acceso) específico para el servidor de MineTest y asociarlo a una base de datos particular:

sudo -u postgres psql
  • Escribe las siguientes sentencias (incluyendo el “;” final). Puedes cambiar el nombre del usuario “mtuser” y la clave “mtpass” por los valores que quieras, así como el nombre de la base de datos “mtworld”.
CREATE USER mtuser WITH PASSWORD 'mtpass';
CREATE DATABASE mtworld OWNER mtuser;
GRANT ALL PRIVILEGES ON DATABASE mtworld TO mtuser;
  • Puedes comprobar que se han creado correctamente escribiendo el comando “\l” (“ele» minúscula)
\l

                                 List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
------------+----------+----------+-------------+-------------+-----------------------
mtworld    | mtuser   | UTF8     | es_ES.UTF-8 | es_ES.UTF-8 | =Tc/mtuser           +
           |          |          |             |             | mtuser=CTc/mtuser
postgres   | postgres | UTF8     | es_ES.UTF-8 | es_ES.UTF-8 | 
template0  | postgres | UTF8     | es_ES.UTF-8 | es_ES.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
template1  | postgres | UTF8     | es_ES.UTF-8 | es_ES.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
(4 rows)
  • Para salir de este entorno pulsa “\q” y luego escribe “exit” para cerrar la sesión.
\q
exit

NOTAS:

  • Tanto si queremos un mundo grande “compartido” o “varios mundos individuales (uno por curso/grupo, p.ej.) es necesario crear una base de datos independiente para cada uno de ellos.
  • El usuario y su clave pueden ser el mismo para todas las bases de datos utilizadas por Minetest

[7] Configurar el archivo “world.mt” de nuestro “mundo“ para que trabaje con Postgresql

Abre una sesión interactiva con el usuario “minetest” (o vuelve a ella si estabas en otro terminal)

sudo -i -u minetest

Edita el archivo “minetest-master/worlds/world/world.mt” y añade las siguientes líneas adaptando los valores de usuario/clave/base si los cambiaste al crearlos:

enable_damage = true
creative_mode = false
auth_backend = sqlite3
player_backend = sqlite3
backend = sqlite3
gameid = minetest
world_name = world
pgsql_connection = host=127.0.0.1 port=5432 user=mtuser password=mtpass dbname=mtworld
pgsql_auth_connection = host=127.0.0.1 port=5432 user=mtuser password=mtpass dbname=mtworld
pgsql_player_connection = host=127.0.0.1 port=5432 user=mtuser password=mtpass dbname=mtworld

IMPORTANTE!

NO cambies los métodos “sqlite3” manualmente. Se adaptarán automáticamente con las acciones del siguiente paso.

Cierra el archivo y desde la consola ejecuta los siguientes comandos para convertir los métodos de “sqlite3” a “postgresql”

./minetest-master/bin/minetestserver --migrate postgresql --world minetest-master/worlds/world

./minetest-master/bin/minetestserver --migrate-auth postgresql --world minetest-master/worlds/world

./minetest-master/bin/minetestserver --migrate-players postgresql --world minetest-master/worlds/world

NOTA:

No te preocupes si en los mensajes de resultado aparecen “0 blocks”, “0 auth” o “0 players” migrados. El mundo de ejemplo que estamos utilizando esta virgen y aun no se ha guardado nada.

Si observamos ahora el contenido del archivo de configuración “minetest-master/worlds/world/world.mt” comprobaremos que se ha adaptado al nuevo modelo de almacenamiento:

enable_damage = true
creative_mode = false
auth_backend = postgresql
player_backend = postgresql
backend = postgresql
gameid = minetest
world_name = world
pgsql_connection = host=127.0.0.1 port=5432 user=mtuser password=mtpass dbname=mtworld
pgsql_auth_connection = host=127.0.0.1 port=5432 user=mtuser password=mtpass dbname=mtworld
pgsql_player_connection = host=127.0.0.1 port=5432 user=mtuser password=mtpass dbname=mtworld

IMPORTANTE!

Aguanta un minuto más las ganas de probar el servidor. Antes vamos a salvaguardar lo que hemos hecho para poder reutilizarlo y crear de una forma más sencilla nuevos “mundos”!

Ejecuta el siguiente comando para hacer un volcado de la base de datos tal como se encuentra en la actualidad (te pedirá la contraseña del usuario “mtuser”)

pg_dump -U mtuser -h 127.0.0.1 -p 5432 mtworld >> mtworld.sql

[8] Prueba final del servidor

Ejecuta el binario del servidor tal como hicimos nada más compilarlo:

./minetest-master/bin/minetestserver

y desde un cliente (en mi caso ejecutado para la prueba en el mismo ordenador) nos conectamos al servidor 127.0.0.1, puerto 30000, con el nombre del jugador que queramos:

En los siguientes artículos trataré entre otros temas:

  • Configuración personalizada para una instancia y su mundo. 
  • Instalación y gestión de “mods” globales y dedicados por mundo.
  • Automatización de inicio/parada de una o varias instancias del servidor MineTest.
  • Automatización de copias de seguridad de los mundos.
  • Configuración del cortafuegos (si éste estuviese habilitado). 
  • Permitir el acceso desde cualquier lugar (internet).
  • Herramientas y útiles de administración / monitorización.
  • Gestión de alumnos.
  • Protección y asignación de áreas.