diff --git a/.gitignore b/.gitignore index e43da52..95fbfd2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ cmangos-docker.wiki mangosd_data/* +database/* diff --git a/README.md b/README.md index 7027dcf..173489d 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,25 @@ # wow private server -## Versions prises en charge - - ## Pre requis +- Linux 🐧 +- Docker :whale: - Clients: -| Game name | Game version | Keyword | -|--------------------------------------------|--------------|-----------| -| World of WarcraftÂź | **v1.12.x** | `classic` | -| World of Warcraft: The Burning CrusadeÂź | **v2.4.3** | `tbc` | -| World of Warcraft: Wrath of the Link KingÂź | **v3.3.5a** | `wotlk` | -- Docker +## Versions prises en charge + +| Game name | Game version | Keyword | client download | +|--------------------------------------------|--------------|-----------|-------------------| +| World of WarcraftÂź | **v1.12.x** | `classic` | https://archive.org/download/World_of_Warcraft_Client_and_Installation_Archive/ISO/WoW-1.12.1_install.rar | +| World of Warcraft: The Burning CrusadeÂź | **v2.4.3** | `tbc` | https://archive.org/download/World_of_Warcraft_Client_and_Installation_Archive/ISO/WoW-2.4.3_install.rar | +| World of Warcraft: Wrath of the Link KingÂź | **v3.3.5a** | `wotlk` | | + ## Configuration -- .env path to wow client +- Renseigner dans le fichier `.env` : + - Le chemin absolue vers le client WOW (Classic, tbc ou wotlk) + - La version de WOW correspondante au client ## Installation @@ -25,7 +28,7 @@ ./builder/run.sh extract ``` -> Choisir l'import en HD avec le plus de CPU possible car c'est long +> Choisir l'import en HD avec le plus de CPU possible car c'est long ☕ - Lançer la base de donnĂ©es: ```bash @@ -37,5 +40,5 @@ docker compose up wow-db ./builder/run.sh init-db ``` -> Patienter le temps de la mise en place de la base de donnĂ©es +> Patienter le temps de la mise en place de la base de donnĂ©es ☕ diff --git a/compose.yml b/compose.yml index 7f413c7..ad2da32 100644 --- a/compose.yml +++ b/compose.yml @@ -12,7 +12,7 @@ services: - wow mangosd: - image: "ghcr.io/byloth/cmangos/${WOW_VERSION}:latest" + image: dockerregistry.legaragenumerique.fr/wow-server-wotlk:runner container_name: wow-mangosd depends_on: - database @@ -33,7 +33,7 @@ services: - wow realmd: - image: "ghcr.io/byloth/cmangos/${WOW_VERSION}:latest" + image: dockerregistry.legaragenumerique.fr/wow-server-wotlk:runner container_name: wow-realmd depends_on: - database diff --git a/docker/Dockerfile b/docker/Dockerfile index 2f7fd2d..6a55add 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -134,8 +134,8 @@ ENV MANGOS_CHARACTERS_DBNAME="${EXPANSION}characters" ENV MANGOS_LOGS_DBNAME="${EXPANSION}logs" ENV MANGOS_REALMD_DBNAME="${EXPANSION}realmd" -COPY builder/entrypoint.sh / -COPY builder/InstallFullDB.config "${DATABASE_DIR}/" +COPY entrypoint-builder.sh /entrypoint.sh +COPY InstallFullDB.config "${DATABASE_DIR}/" ENTRYPOINT ["/entrypoint.sh"] CMD ["bash"] @@ -179,7 +179,7 @@ WORKDIR "${MANGOS_DIR}" ARG EXPANSION COPY --from=builder "${HOME_DIR}/run" "${MANGOS_DIR}" -COPY runner/entrypoint.sh / +COPY entrypoint-runner.sh /entrypoint.sh ENV VOLUME_DIR="/var/lib/mangos" ENV TMPDIR="${VOLUME_DIR}/tmp" @@ -202,15 +202,11 @@ CMD ["bash"] EXPOSE 3443 3724 7878 8085 8086 VOLUME ["${VOLUME_DIR}"] -ARG COMMIT_SHA -ARG CREATE_DATE ARG VERSION LABEL org.opencontainers.image.title="CMaNGOS Runner \"${EXPANSION}\" version" LABEL org.opencontainers.image.description="A CMaNGOS \"${EXPANSION}\" version Docker image ready-to-use to host your emulated private server for WoW wherever you want." LABEL org.opencontainers.image.licenses="GPL-2.0" LABEL org.opencontainers.image.version="${VERSION}" -LABEL org.opencontainers.image.revision="${COMMIT_SHA}" -LABEL org.opencontainers.image.created="${CREATE_DATE}" ARG MANGOS_SHA1 LABEL "net.cmangos.mangos-${EXPANSION}.revision"="${MANGOS_SHA1}" diff --git a/docker/InstallFullDB.config b/docker/InstallFullDB.config new file mode 100644 index 0000000..5bf9bb2 --- /dev/null +++ b/docker/InstallFullDB.config @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +# + +#################################################################################################### +# This is the config file for the 'InstallFullDB.sh' script +# +# You need to customize +# MYSQL_HOST: Host on which the database resides +# MYSQL_PORT: Port on which the database is running +# MYSQL_USERNAME: Your a valid mysql username +# MYSQL_PASSWORD: Your corresponding mysql password +# MYSQL_PATH: Your mysql command (usually mysql) +# WORLD_DB_NAME: Your content database +# CORE_PATH: Your path to core's directory +# +#################################################################################################### + +## Define the host on which the mangos database resides (typically localhost) +MYSQL_HOST="${MANGOS_DBHOST}" + +## Define the port on which the mangos database is running (typically 3306) +MYSQL_PORT="${MANGOS_DBPORT}" + +## Define your username +MYSQL_USERNAME="${MANGOS_DBUSER}" + +## Define your password (It is suggested to restrict read access to this file!) +MYSQL_PASSWORD="${MANGOS_DBPASS}" + +## Define default mysql address binding(you can set "%" to be able to connect from any computer) +MYSQL_USERIP="%" + +## Define the databases names (let them empty for default name '') +WORLD_DB_NAME="${MANGOS_WORLD_DBNAME}" +REALM_DB_NAME="${MANGOS_REALMD_DBNAME}" +CHAR_DB_NAME="${MANGOS_CHARACTERS_DBNAME}" +LOGS_DB_NAME="${MANGOS_LOGS_DBNAME}" + +## Define your mysql programm if this differs +MYSQL_PATH="/usr/bin/mariadb" + +## Define the path to your mysql dump binary folder +MYSQL_DUMP_PATH="/usr/bin/mariadb-dump" + +## Define the path to your core's folder +CORE_PATH="${MANGOS_DIR}" + +## Define if the 'locales' directory for processing localization/multi-language SQL files needs to be used +## Set the variable to "YES" to use the locales directory +LOCALES="YES" + +## Define if you want to wait a bit before applying the full database +FORCE_WAIT="NO" + +## Define if the 'dev' directory for processing development SQL files needs to be used +## Set the variable to "YES" to use the dev directory +DEV_UPDATES="NO" + +## Define if AHBot SQL updates need to be applied (by default, assume the core is built without AHBot) +## Set the variable to "YES" to import AHBot sql. +AHBOT="NO" + +## Define if the 'src/modules/PlayerBots/sql' directory for processing development SQL files needs to be used +## Set the variable to "YES" to use the playerbots directory +PLAYERBOTS_DB="NO" + +# Enjoy using the tool diff --git a/docker/entrypoint-builder.sh b/docker/entrypoint-builder.sh new file mode 100755 index 0000000..7f08e5e --- /dev/null +++ b/docker/entrypoint-builder.sh @@ -0,0 +1,430 @@ +#!/usr/bin/env bash +# + +readonly SCRIPT_VERSION="1.0.0" + +set -e + +# Utils: +# +function echoerr() +{ + echo ${@} >&2 +} + +function success() +{ + echo -e "\e[32m${1}\e[0m" +} +function info() +{ + echo -e "\e[36m${1}\e[0m" +} +function warning() +{ + if [[ "${2}" == "--underline" ]] + then + echo -e "\e[4;33m${1}\e[0m" + else + echo -e "\e[33m${1}\e[0m" + fi +} +function error() +{ + if [[ "${2}" == "--underline" ]] + then + echo -e "\e[4;31m${1}\e[0m" + else + echo -e "\e[31m${1}\e[0m" + fi +} + +function mysql_execute() +{ + mariadb "-h${MANGOS_DBHOST}" "-P${MANGOS_DBPORT}" "-u${MYSQL_SUPERUSER}" "-p${MYSQL_SUPERPASS}" ${@} +} +function mysql_dump() +{ + local DATABASE_NAME="${1}" + local OUTPUT_FILE="${2}" + + mariadb-dump "-h${MANGOS_DBHOST}" "-P${MANGOS_DBPORT}" "-u${MYSQL_SUPERUSER}" "-p${MYSQL_SUPERPASS}" \ + "${DATABASE_NAME}" --opt --result-file="${OUTPUT_FILE}" +} + +# Sub-functions: +# +function install_updates() +{ + cd "${DATABASE_DIR}" + + ./InstallFullDB.sh -UpdateCore + + if [[ "${1}" == "--world" ]] + then + ./InstallFullDB.sh -World + fi +} + +# Main functions: +# +function extract_resources_from_client() +{ + cd "${VOLUME_DIR}" + + if [[ -f ".resext" ]] || [[ $(ls | grep -c -E "Cameras|dbc|maps|mmaps|vmaps") -gt 0 ]] + then + echo "" + echo -e " $(warning "WARNING!" --underline)" + echo -e " $(warning "└") It seems that you've already extracted the resources from the client before." + echo -e " If you continue, existing resources will be overwritten by the new ones." + echo "" + read -p "Are you sure to continue? [Y/n]: " ANSWER + + if [[ "${ANSWER}" != "y" ]] && [[ "${ANSWER}" != "Y" ]] + then + echo -e " └ Ok, no problem! Resources have been left untouched." + + return + fi + + rm -rf Cameras/ \ + dbc/ \ + maps/ \ + mmaps/ \ + vmaps/ + fi + + cd "${HOME_DIR}/run/bin/tools" + + cp * "${HOME_DIR}/wow-client/" + cd "${HOME_DIR}/wow-client" + + ./ExtractResources.sh ${@} + + mv Cameras "${VOLUME_DIR}/Cameras" + mv dbc "${VOLUME_DIR}/dbc" + mv maps "${VOLUME_DIR}/maps" + mv mmaps "${VOLUME_DIR}/mmaps" + mv vmaps "${VOLUME_DIR}/vmaps" + + mkdir -p "${VOLUME_DIR}/logs" + mv *.log "${VOLUME_DIR}/logs/" + + rm -rf Buildings/ \ + \ + ExtractResources.sh \ + MoveMapGen \ + MoveMapGen.sh \ + ad \ + offmesh.txt \ + vmap_assembler \ + vmap_extractor + + echo "${SCRIPT_VERSION}" > "${VOLUME_DIR}/.resext" +} +function init_db() +{ + cd "${DATABASE_DIR}" + + echo "" + echo "This procedure will create all the databases required by the server" + echo " to run properly and will initialize them with the default data." + echo "" + echo -e " $(warning "WARNING!" --underline)" + echo -e " $(warning "└") Please note that, if you have already initialized the databases before," + echo -e " this procedure will prune $(info "ALL") of your data and" + echo -e " they will be lost $(info "FOREVER") (it's a very long time)!" + echo "" + read -p "Are you sure to continue? [Y/n]: " ANSWER + + if [[ "${ANSWER}" != "y" ]] && [[ "${ANSWER}" != "Y" ]] + then + echo -e " └ Ok, no problem! Databases have been left untouched." + + return + fi + + echo -e " └ Please, wait... Initializing databases..." + echo "" + echo -e " --------------------------------------" + + ./InstallFullDB.sh -InstallAll "${MYSQL_SUPERUSER}" "${MYSQL_SUPERPASS}" DeleteAll +} +function backup_db() +{ + readonly HELP_MSG=" +Backups the specified database(s) and then returns the + result as a single \"tar.gz\" file via standard output. + +Usage: + backup-db [OPTIONS...] + +Options: + -a | --all + Backups all databases. + + -w | --world + Backups the world database: \"$(info "${MANGOS_WORLD_DBNAME}")\". + + -c | --characters + Backups the characters database: \"$(info "${MANGOS_CHARACTERS_DBNAME}")\". + + -l | --logs + Backups the logs database: \"$(info "${MANGOS_LOGS_DBNAME}")\". + + -r | --realmd + Backups the realmd database: \"$(info "${MANGOS_REALMD_DBNAME}")\". + + -h | -? | --help + Displays this help message. +" + + declare -A DATABASES + + while [[ ${#} -gt 0 ]] + do + case "${1}" in + -a | --all) + readonly BACKUPS_ALL="true" + ;; + -w | --world) + DATABASES+=(["world"]="${MANGOS_WORLD_DBNAME}") + ;; + -c | --characters) + DATABASES+=(["characters"]="${MANGOS_CHARACTERS_DBNAME}") + ;; + -l | --logs) + DATABASES+=(["logs"]="${MANGOS_LOGS_DBNAME}") + ;; + -r | --realmd) + DATABASES+=(["realmd"]="${MANGOS_REALMD_DBNAME}") + ;; + -h | -? | --help) + echo -e "${HELP_MSG}" + + exit 0 + ;; + *) + echoerr "" + echoerr -e " $(error "ERROR!" --underline)" + echoerr -e " $(error "└") Unknown option: \"$(info "${1}")\"" + echoerr "" + echoerr " Run \"$(info "backup-db --help")\" for more information." + + exit 1 + ;; + esac + + shift + done + + if [[ "${BACKUPS_ALL}" == "true" ]] + then + if [[ -n ${DATABASES[@]} ]] + then + echoerr "" + echoerr -e " $(error "ERROR!" --underline)" + echoerr -e " $(error "└") You cannot specify both \"$(info "--all")\" and any other" + echoerr -e " specific database options at the same time." + echoerr "" + echoerr " Run \"$(info "backup-db --help")\" for more information." + + exit 2 + fi + + DATABASES=(["world"]="${MANGOS_WORLD_DBNAME}" \ + ["characters"]="${MANGOS_CHARACTERS_DBNAME}" \ + ["logs"]="${MANGOS_LOGS_DBNAME}" \ + ["realmd"]="${MANGOS_REALMD_DBNAME}") + fi + if [[ -z ${DATABASES[@]} ]] + then + echoerr "" + echoerr -e " $(error "ERROR!" --underline)" + echoerr -e " $(error "└") You must specify at least one database to backup." + echoerr "" + echoerr " Run \"$(info "backup-db --help")\" for more information." + + exit 3 + fi + + local TIMESTAMP="$(date +"%Y-%m-%d_%H-%M-%S")" + local BACKUP_DIR="/home/mangos/data/backups/${TIMESTAMP}" + local BACKUP_FILE="${BACKUP_DIR}/backup_${TIMESTAMP}.tar.gz" + + mkdir -p "${BACKUP_DIR}" + + for DATABASE in ${!DATABASES[@]} + do + local DATABASE_NAME="${DATABASES["${DATABASE}"]}" + local OUTPUT_FILENAME="${DATABASE}.sql" + + mysql_dump "${DATABASE_NAME}" "${BACKUP_DIR}/${OUTPUT_FILENAME}" + done + + cd "${BACKUP_DIR}" + + echo "${SCRIPT_VERSION}" > .version + tar -czvf "${BACKUP_FILE}" .version $(ls *.sql | xargs -n 1) > /dev/null + + cat "${BACKUP_FILE}" +} +function manage_db() +{ + cd "${DATABASE_DIR}" + + ./InstallFullDB.sh +} +function restore_db() +{ + local TIMESTAMP="$(date +"%Y-%m-%d_%H-%M-%S")" + local TEMP_DIR="${TMPDIR}/${TIMESTAMP}" + local BACKUP_FILE="${TEMP_DIR}/backup_${TIMESTAMP}.tar.gz" + + mkdir -p "${TEMP_DIR}" + cat - > "${BACKUP_FILE}" + + cd "${TEMP_DIR}" + + tar -xzvf "${BACKUP_FILE}" -C . > /dev/null + + local BACKUP_FILES=($(ls *.sql | xargs -n 1)) + + for BACKUP_FILE in ${BACKUP_FILES[@]} + do + local DATABASE="${BACKUP_FILE%.sql}" + + if [[ "${DATABASE}" == "world" ]] + then + local DATABASE_NAME="${MANGOS_WORLD_DBNAME}" + elif [[ "${DATABASE}" == "characters" ]] + then + local DATABASE_NAME="${MANGOS_CHARACTERS_DBNAME}" + elif [[ "${DATABASE}" == "logs" ]] + then + local DATABASE_NAME="${MANGOS_LOGS_DBNAME}" + elif [[ "${DATABASE}" == "realmd" ]] + then + local DATABASE_NAME="${MANGOS_REALMD_DBNAME}" + fi + + mysql_execute "${DATABASE_NAME}" < "${TEMP_DIR}/${BACKUP_FILE}" + done +} +function update_db() +{ + readonly HELP_MSG=" +Updates databases by applying the latest changes + to the database structure and default data. +Dy default, this is a non-destructive procedure, + so any custom data you may have loaded into + your \"$(info "${MANGOS_WORLD_DBNAME}")\" database will remain intact. + +Unfortunately, however, sometimes this plain update procedure + isn't enough to apply all the changes required by + the new version of the server to run properly. +In these cases, you can use the \"$(info "--world")\" option to + perform a \"deeper\" update procedure to solve the issue. + +Please note that this more \"aggressive\" update procedure + will prune any custom data from the \"$(info "${MANGOS_WORLD_DBNAME}")\" database + and will restore the default data shipped with the server. +If, however, you use an original version of the database + and have never customized any data, you can safely use + this option without any fear. No data will be lost. + +Usage: + update-db [OPTIONS...] + +Options: + -w | --world + Updates the world database: \"$(info "${MANGOS_WORLD_DBNAME}")\". + + -h | -? | --help + Displays this help message. +" + if [[ -n "${1}" ]] + then + case "${1}" in + -w | --world) + echo "" + echo -e " $(warning "WARNING!" --underline)" + echo -e " $(warning "└") This procedure will prune all custom data you" + echo -e " may have loaded into your \"$(info "${MANGOS_WORLD_DBNAME}")\" database." + echo "" + read -p "Are you sure to continue? [Y/n]: " ANSWER + + if [[ "${ANSWER}" != "y" ]] && [[ "${ANSWER}" != "Y" ]] + then + echo -e " └ Ok, no problem! Database have been left untouched." + + return + fi + + echo -e " └ Please, wait... Updating database..." + echo "" + echo -e " --------------------------------------" + + install_updates --world + + ;; + -h | -? | --help) + echo -e "${HELP_MSG}" + + exit 0 + ;; + *) + echoerr "" + echoerr -e " $(error "ERROR!" --underline)" + echoerr -e " $(error "└") Unknown option: \"$(info "${1}")\"" + echoerr "" + echoerr " Run \"$(info "update-db --help")\" for more information." + + exit 1 + ;; + esac + else + install_updates + fi +} + +# Execution: +# +case "${1}" in + extract) + shift + + extract_resources_from_client ${@} + ;; + init-db) + shift + + init_db + ;; + backup-db) + shift + + backup_db ${@} + ;; + restore-db) + shift + + restore_db ${@} + ;; + manage-db) + shift + + manage_db + ;; + update-db) + shift + + update_db ${@} + ;; + *) + cd "${HOME_DIR}" + + exec ${@} + ;; +esac diff --git a/docker/entrypoint.sh b/docker/entrypoint-runner.sh similarity index 100% rename from docker/entrypoint.sh rename to docker/entrypoint-runner.sh diff --git a/docker/run.sh b/docker/run.sh index 7976b65..1140f0b 100755 --- a/docker/run.sh +++ b/docker/run.sh @@ -6,12 +6,12 @@ set -e readonly BASE_DIR="$(realpath "$(dirname "${0}")/..")" source "${BASE_DIR}/.env" -readonly NAME="cmangos-runner" -readonly IMAGE="ghcr.io/byloth/cmangos/${WOW_VERSION}" +readonly NAME="cmangos-builder" +readonly IMAGE="ghcr.io/byloth/cmangos/${WOW_VERSION}/builder" readonly VERSION="latest" -readonly DATA_VOLUME="cmangos_mangosd_data" -readonly NETWORK="cmangos_default" +readonly DATA_VOLUME="./mangosd_data" +readonly NETWORK="wow" if [[ -t 0 ]] && [[ -t 1 ]] then @@ -24,15 +24,12 @@ docker run ${TTY} \ --name "${NAME}" \ --network "${NETWORK}" \ --rm \ - -e MANGOS_DBHOST="mariadb" \ + -e MYSQL_SUPERUSER="root" \ + -e MYSQL_SUPERPASS="${MYSQL_SUPERPASS}" \ + -e MANGOS_DBHOST="database" \ -e MANGOS_DBUSER="${MANGOS_DBUSER}" \ -e MANGOS_DBPASS="${MANGOS_DBPASS}" \ - -p 3443:3443 \ - -p 3724:3724 \ - -p 7878:7878 \ - -p 8085:8085 \ - -p 8086:8086 \ - -v "${PWD}/config":/opt/mangos/conf:ro \ - -v "${DATA_VOLUME}":/var/lib/mangos:ro \ + -v "${DATA_VOLUME}":/home/mangos/data \ + -v "${WOW_CLIENT_DIR}":/home/mangos/wow-client \ \ "${IMAGE}:${VERSION}" ${@}