diff --git a/.travis.yml b/.travis.yml index 1b9efa0..61ea43c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,6 +30,7 @@ deploy: - build/${PACKAGING_INSTALLER_NAME}-${TRAVIS_TAG}.exe - build/${PACKAGING_INSTALLER_NAME}-${TRAVIS_TAG}-macOS.zip - build/${PACKAGING_INSTALLER_NAME}-${TRAVIS_TAG}-winportable.zip + - build/${PACKAGING_INSTALLER_NAME}-${TRAVIS_TAG}.AppImage skip_cleanup: true on: tags: true diff --git a/Makefile b/Makefile index e637d82..4ecdb4b 100644 --- a/Makefile +++ b/Makefile @@ -25,12 +25,7 @@ VERSION = $(shell git name-rev --name-only --tags --no-undefined HEAD 2>/dev/null || echo git-`git rev-parse --short HEAD`) MOD_ID = $(shell cat user.config mod.config 2> /dev/null | awk -F= '/MOD_ID/ { print $$2; exit }') ENGINE_DIRECTORY = $(shell cat user.config mod.config 2> /dev/null | awk -F= '/ENGINE_DIRECTORY/ { print $$2; exit }') -INCLUDE_DEFAULT_MODS = $(shell cat user.config mod.config 2> /dev/null | awk -F= '/INCLUDE_DEFAULT_MODS/ { print $$2; exit }') - -MOD_SEARCH_PATHS = "$(shell python -c "import os; print(os.path.realpath('.'))")/mods" -ifeq ($(INCLUDE_DEFAULT_MODS),"True") - MOD_SEARCH_PATHS := "$(MOD_SEARCH_PATHS),./mods" -endif +MOD_SEARCH_PATHS = "$(shell python -c "import os; print(os.path.realpath('.'))")/mods,./mods" MANIFEST_PATH = "mods/$(MOD_ID)/mod.yaml" @@ -39,7 +34,20 @@ HAS_LUAC = $(shell command -v luac 2> /dev/null) LUA_FILES = $(shell find mods/*/maps/* -iname '*.lua') PROJECT_DIRS = $(shell dirname $$(find . -iname "*.csproj" -not -path "$(ENGINE_DIRECTORY)/*")) -engine: +variables: + @if [ -z "$(MOD_ID)" ] || [ -z "$(ENGINE_DIRECTORY)" ];then \ + echo "Required mod.config variables are missing:"; \ + if [ -z "$(MOD_ID)" ]; then \ + echo " MOD_ID"; \ + fi; \ + if [ -z "$(ENGINE_DIRECTORY)" ]; then \ + echo " ENGINE_DIRECTORY"; \ + fi; \ + echo "Repair your mod.config (or user.config) and try again."; \ + exit 1; \ + fi + +engine: variables @./fetch-engine.sh || (printf "Unable to continue without engine files\n"; exit 1) @cd $(ENGINE_DIRECTORY) && make core @@ -65,13 +73,13 @@ endif @cd $(ENGINE_DIRECTORY) && make clean @printf "The engine has been cleaned.\n" -version: +version: variables @awk '{sub("Version:.*$$","Version: $(VERSION)"); print $0}' $(MANIFEST_PATH) > $(MANIFEST_PATH).tmp && \ awk '{sub("/[^/]*: User$$", "/$(VERSION): User"); print $0}' $(MANIFEST_PATH).tmp > $(MANIFEST_PATH) && \ rm $(MANIFEST_PATH).tmp @printf "Version changed to $(VERSION).\n" -check-scripts: +check-scripts: variables ifeq ("$(HAS_LUAC)","") @printf "'luac' not found.\n" && exit 1 endif diff --git a/fetch-engine.sh b/fetch-engine.sh index 0e53acd..1cbd3ee 100755 --- a/fetch-engine.sh +++ b/fetch-engine.sh @@ -5,6 +5,19 @@ command -v curl >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires curl."; exit 1; } command -v python >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires python."; exit 1; } +require_variables() { + missing="" + for i in "$@"; do + eval check="\$$i" + [ -z "${check}" ] && missing="${missing} ${i}\n" + done + if [ ! -z "${missing}" ]; then + echo "Required mod.config variables are missing:\n${missing}Repair your mod.config (or user.config) and try again." + exit 1 + fi +} + + TEMPLATE_LAUNCHER=$(python -c "import os; print(os.path.realpath('$0'))") TEMPLATE_ROOT=$(dirname "${TEMPLATE_LAUNCHER}") @@ -16,6 +29,8 @@ if [ -f "${TEMPLATE_ROOT}/user.config" ]; then . "${TEMPLATE_ROOT}/user.config" fi +require_variables "MOD_ID" "ENGINE_VERSION" "ENGINE_DIRECTORY" + CURRENT_ENGINE_VERSION=$(cat "${ENGINE_DIRECTORY}/VERSION" 2> /dev/null) if [ -f "${ENGINE_DIRECTORY}/VERSION" ] && [ "${CURRENT_ENGINE_VERSION}" = "${ENGINE_VERSION}" ]; then @@ -23,6 +38,8 @@ if [ -f "${ENGINE_DIRECTORY}/VERSION" ] && [ "${CURRENT_ENGINE_VERSION}" = "${EN fi if [ "${AUTOMATIC_ENGINE_MANAGEMENT}" = "True" ]; then + require_variables "AUTOMATIC_ENGINE_SOURCE" "AUTOMATIC_ENGINE_EXTRACT_DIRECTORY" "AUTOMATIC_ENGINE_TEMP_ARCHIVE_NAME" + echo "OpenRA engine version ${ENGINE_VERSION} is required." if [ -d "${ENGINE_DIRECTORY}" ]; then diff --git a/launch-dedicated.cmd b/launch-dedicated.cmd index f5f07cc..19cd5cc 100644 --- a/launch-dedicated.cmd +++ b/launch-dedicated.cmd @@ -10,17 +10,19 @@ set EnableSingleplayer=False set Password="" @echo off +setlocal EnableDelayedExpansion title %Name% FOR /F "tokens=1,2 delims==" %%A IN (mod.config) DO (set %%A=%%B) if exist user.config (FOR /F "tokens=1,2 delims==" %%A IN (user.config) DO (set %%A=%%B)) +set MOD_SEARCH_PATHS=%~dp0mods,./mods -set MOD_SEARCH_PATHS=%~dp0mods -if %INCLUDE_DEFAULT_MODS% neq "True" goto start -set MOD_SEARCH_PATHS=%MOD_SEARCH_PATHS%,./mods +if "!MOD_ID!" == "" goto badconfig +if "!ENGINE_VERSION!" == "" goto badconfig +if "!ENGINE_DIRECTORY!" == "" goto badconfig -:start if not exist %ENGINE_DIRECTORY%\OpenRA.Game.exe goto noengine +>nul find %ENGINE_VERSION% %ENGINE_DIRECTORY%\VERSION || goto noengine cd %ENGINE_DIRECTORY% :loop @@ -31,4 +33,11 @@ goto loop echo Required engine files not found. echo Run `make all` in the mod directory to fetch and build the required files, then try again. pause +exit /b + +:badconfig +echo Required mod.config variables are missing. +echo Ensure that MOD_ID ENGINE_VERSION and ENGINE_DIRECTORY are +echo defined in your mod.config (or user.config) and try again. +pause exit /b \ No newline at end of file diff --git a/launch-dedicated.sh b/launch-dedicated.sh index 407befc..3feac05 100755 --- a/launch-dedicated.sh +++ b/launch-dedicated.sh @@ -8,8 +8,21 @@ set -e command -v python >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires python."; exit 1; } command -v mono >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires mono."; exit 1; } +require_variables() { + missing="" + for i in "$@"; do + eval check="\$$i" + [ -z "${check}" ] && missing="${missing} ${i}\n" + done + if [ ! -z "${missing}" ]; then + echo "Required mod.config variables are missing:\n${missing}Repair your mod.config (or user.config) and try again." + exit 1 + fi +} + TEMPLATE_LAUNCHER=$(python -c "import os; print(os.path.realpath('$0'))") TEMPLATE_ROOT=$(dirname "${TEMPLATE_LAUNCHER}") +MOD_SEARCH_PATHS="${TEMPLATE_ROOT}/mods,./mods" # shellcheck source=mod.config . "${TEMPLATE_ROOT}/mod.config" @@ -19,10 +32,7 @@ if [ -f "${TEMPLATE_ROOT}/user.config" ]; then . "${TEMPLATE_ROOT}/user.config" fi -MOD_SEARCH_PATHS="${TEMPLATE_ROOT}/mods" -if [ "${INCLUDE_DEFAULT_MODS}" = "True" ]; then - MOD_SEARCH_PATHS="${MOD_SEARCH_PATHS},./mods" -fi +require_variables "MOD_ID" "ENGINE_VERSION" "ENGINE_DIRECTORY" NAME="${Name:-"Dedicated Server"}" LAUNCH_MOD="${Mod:-"${MOD_ID}"}" @@ -33,7 +43,7 @@ ENABLE_SINGLE_PLAYER="${EnableSingleplayer:-"False"}" PASSWORD="${Password:-""}" cd "${TEMPLATE_ROOT}" -if [ ! -f "${ENGINE_DIRECTORY}/OpenRA.Game.exe" ]; then +if [ ! -f "${ENGINE_DIRECTORY}/OpenRA.Game.exe" ] || [ "$(cat "${ENGINE_DIRECTORY}/VERSION")" != "${ENGINE_VERSION}" ]; then echo "Required engine files not found." echo "Run \`make\` in the mod directory to fetch and build the required files, then try again."; exit 1 diff --git a/launch-game.cmd b/launch-game.cmd index 56a982a..2c98fda 100644 --- a/launch-game.cmd +++ b/launch-game.cmd @@ -1,18 +1,21 @@ @echo off +setlocal EnableDelayedExpansion title OpenRA + FOR /F "tokens=1,2 delims==" %%A IN (mod.config) DO (set %%A=%%B) if exist user.config (FOR /F "tokens=1,2 delims==" %%A IN (user.config) DO (set %%A=%%B)) - set TEMPLATE_LAUNCHER=%0 -set MOD_SEARCH_PATHS=%~dp0mods -if %INCLUDE_DEFAULT_MODS% neq "True" goto launch -set MOD_SEARCH_PATHS=%MOD_SEARCH_PATHS%,./mods +set MOD_SEARCH_PATHS=%~dp0mods,./mods + +if "!MOD_ID!" == "" goto badconfig +if "!ENGINE_VERSION!" == "" goto badconfig +if "!ENGINE_DIRECTORY!" == "" goto badconfig -:launch set TEMPLATE_DIR=%CD% if not exist %ENGINE_DIRECTORY%\OpenRA.Game.exe goto noengine - +>nul find %ENGINE_VERSION% %ENGINE_DIRECTORY%\VERSION || goto noengine cd %ENGINE_DIRECTORY% + OpenRA.Game.exe Game.Mod=%MOD_ID% Engine.LaunchPath="%TEMPLATE_LAUNCHER%" "Engine.ModSearchPaths=%MOD_SEARCH_PATHS%" "%*" set ERROR=%errorlevel% cd %TEMPLATE_DIR% @@ -26,6 +29,13 @@ echo Run `make all` in the mod directory to fetch and build the required files, pause exit /b +:badconfig +echo Required mod.config variables are missing. +echo Ensure that MOD_ID ENGINE_VERSION and ENGINE_DIRECTORY are +echo defined in your mod.config (or user.config) and try again. +pause +exit /b + :crashdialog echo ---------------------------------------- echo OpenRA has encountered a fatal error. diff --git a/launch-game.sh b/launch-game.sh index 3094b39..86381e1 100755 --- a/launch-game.sh +++ b/launch-game.sh @@ -4,8 +4,21 @@ set -e command -v python >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires python."; exit 1; } command -v mono >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires mono."; exit 1; } +require_variables() { + missing="" + for i in "$@"; do + eval check="\$$i" + [ -z "${check}" ] && missing="${missing} ${i}\n" + done + if [ ! -z "${missing}" ]; then + echo "Required mod.config variables are missing:\n${missing}Repair your mod.config (or user.config) and try again." + exit 1 + fi +} + TEMPLATE_LAUNCHER=$(python -c "import os; print(os.path.realpath('$0'))") TEMPLATE_ROOT=$(dirname "${TEMPLATE_LAUNCHER}") +MOD_SEARCH_PATHS="${TEMPLATE_ROOT}/mods,./mods" # shellcheck source=mod.config . "${TEMPLATE_ROOT}/mod.config" @@ -15,13 +28,10 @@ if [ -f "${TEMPLATE_ROOT}/user.config" ]; then . "${TEMPLATE_ROOT}/user.config" fi -MOD_SEARCH_PATHS="${TEMPLATE_ROOT}/mods" -if [ "${INCLUDE_DEFAULT_MODS}" = "True" ]; then - MOD_SEARCH_PATHS="${MOD_SEARCH_PATHS},./mods" -fi +require_variables "MOD_ID" "ENGINE_VERSION" "ENGINE_DIRECTORY" cd "${TEMPLATE_ROOT}" -if [ ! -f "${ENGINE_DIRECTORY}/OpenRA.Game.exe" ]; then +if [ ! -f "${ENGINE_DIRECTORY}/OpenRA.Game.exe" ] || [ "$(cat "${ENGINE_DIRECTORY}/VERSION")" != "${ENGINE_VERSION}" ]; then echo "Required engine files not found." echo "Run \`make\` in the mod directory to fetch and build the required files, then try again."; exit 1 diff --git a/make.ps1 b/make.ps1 index 58ed470..e279c62 100644 --- a/make.ps1 +++ b/make.ps1 @@ -217,7 +217,7 @@ function ReadConfigLine($line, $name) function ParseConfigFile($fileName) { - $names = @("MOD_ID", "INCLUDE_DEFAULT_MODS", "ENGINE_VERSION", "AUTOMATIC_ENGINE_MANAGEMENT", "AUTOMATIC_ENGINE_SOURCE", + $names = @("MOD_ID", "ENGINE_VERSION", "AUTOMATIC_ENGINE_MANAGEMENT", "AUTOMATIC_ENGINE_SOURCE", "AUTOMATIC_ENGINE_EXTRACT_DIRECTORY", "AUTOMATIC_ENGINE_TEMP_ARCHIVE_NAME", "ENGINE_DIRECTORY") $reader = [System.IO.File]::OpenText($fileName) @@ -228,6 +228,27 @@ function ParseConfigFile($fileName) ReadConfigLine $line $name } } + + $missing = @() + foreach ($name in $names) + { + if (!([System.Environment]::GetEnvironmentVariable($name))) + { + $missing += $name + } + } + + if ($missing) + { + echo "Required mod.config variables are missing:" + foreach ($m in $missing) + { + echo " $m" + } + echo "Repair your mod.config (or user.config) and try again." + WaitForInput + exit + } } ############################################################### @@ -272,11 +293,7 @@ if (Test-Path "user.config") $modID = $env:MOD_ID -$env:MOD_SEARCH_PATHS = (Get-Item -Path ".\" -Verbose).FullName + "\mods" -if ($env:INCLUDE_DEFAULT_MODS -eq "True") -{ - $env:MOD_SEARCH_PATHS = $env:MOD_SEARCH_PATHS + ",./mods" -} +$env:MOD_SEARCH_PATHS = (Get-Item -Path ".\" -Verbose).FullName + "\mods,./mods" # Run the same command on the engine's make file if ($command -eq "all" -or $command -eq "clean") diff --git a/mod.config b/mod.config index 6e77a3e..91fc512 100644 --- a/mod.config +++ b/mod.config @@ -9,13 +9,7 @@ MOD_ID="ura" # The OpenRA engine version to use for this project. -ENGINE_VERSION="39aa1a9" - -# Enable this to make the default OpenRA mods available for use in your mod.yaml -# Packages list (via $mod references). Accepts values "True" or "False". -# WARNING: This setting is provided to simplify early project development, -# and must be disabled before you can package installers for your project! -INCLUDE_DEFAULT_MODS="False" +ENGINE_VERSION="3febae1" ############################################################################## # Continuous Integration @@ -30,7 +24,7 @@ TRAVIS_TEST_MOD="True" # Perform a dry run of the installer generation when a new commit is pushed to the GitHub repository # Accepts values "True" or "False". -TRAVIS_TEST_PACKAGING="False" +TRAVIS_TEST_PACKAGING="True" ############################################################################## # Packaging @@ -41,6 +35,7 @@ TRAVIS_TEST_PACKAGING="False" # The prefix used for the installer filenames. # - Windows installers will be named as {PACKAGING_INSTALLER_NAME}-{TAG}.exe # - macOS installers will be named as {PACKAGING_INSTALLER_NAME}-{TAG}.zip +# - Linux .appimages will be named as {PACKAGING_INSTALLER_NAME}-${TAG}.AppImage PACKAGING_INSTALLER_NAME="RedAlertUnplugged" # The human-readable name for this project. @@ -53,6 +48,7 @@ PACKAGING_INSTALLER_NAME="RedAlertUnplugged" # - Windows start menu # - Windows desktop shortcut # - Windows "Programs and Features" list +# - Linux launcher shortcut PACKAGING_DISPLAY_NAME="Red Alert Unplugged" # The URL for the project homepage. @@ -60,7 +56,7 @@ PACKAGING_DISPLAY_NAME="Red Alert Unplugged" # - Windows "Add/Remove Programs" list PACKAGING_WEBSITE_URL="https://github.com/RAunplugged/uRA/wiki" -# The URL that is opened when a player presses the "FAQ" button in the crash dialog. +# The URL that is displayed in the crash dialog. PACKAGING_FAQ_URL="http://wiki.openra.net/FAQ" # The human-readable project authors. @@ -81,6 +77,13 @@ PACKAGING_WINDOWS_INSTALL_DIR_NAME="Red Alert Unplugged" # This should not contain spaces or special characters. PACKAGING_WINDOWS_REGISTRY_KEY="RedAlertUnplugged" +# The git tag to use for the AppImage dependencies. +PACKAGING_APPIMAGE_DEPENDENCIES_TAG="20180408" + +# Space delimited list of additional files/directories to copy from the engine directory +# when packaging your mod. e.g. "./mods/modcontent" or "./mods/d2k/OpenRA.Mods.D2k.dll" +PACKAGING_COPY_ENGINE_FILES="./mods/modcontent" + ############################################################################## # Advanced Configuration # @@ -105,3 +108,9 @@ PACKAGING_OSX_LAUNCHER_SOURCE="https://github.com/OpenRA/OpenRALauncherOSX/relea # Temporary file name used when downloading the OpenRA macOS launcher files. PACKAGING_OSX_LAUNCHER_TEMP_ARCHIVE_NAME="launcher.zip" + +# The url to download the OpenRA AppImage dependencies. +PACKAGING_APPIMAGE_DEPENDENCIES_SOURCE="https://github.com/OpenRA/AppImageSupport/releases/download/${PACKAGING_APPIMAGE_DEPENDENCIES_TAG}/libs.tar.bz2" + +# Temporary file name used when downloading the OpenRA AppImage dependencies. +PACKAGING_APPIMAGE_DEPENDENCIES_TEMP_ARCHIVE_NAME="libs.tar.bz2" \ No newline at end of file diff --git a/packaging/linux/buildpackage.sh b/packaging/linux/buildpackage.sh new file mode 100644 index 0000000..57b4674 --- /dev/null +++ b/packaging/linux/buildpackage.sh @@ -0,0 +1,140 @@ +#!/bin/bash +# OpenRA packaging script for Linux (AppImage) +set -e + +command -v make >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires make."; exit 1; } +command -v python >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires python."; exit 1; } +command -v tar >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires tar."; exit 1; } +command -v curl >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires curl."; exit 1; } + +require_variables() { + missing="" + for i in "$@"; do + eval check="\$$i" + [ -z "${check}" ] && missing="${missing} ${i}\n" + done + if [ ! -z "${missing}" ]; then + echo "Required mod.config variables are missing:\n${missing}Repair your mod.config (or user.config) and try again." + exit 1 + fi +} + +if [ $# -eq "0" ]; then + echo "Usage: `basename $0` version [outputdir]" + exit 1 +fi + +PACKAGING_DIR=$(python -c "import os; print(os.path.dirname(os.path.realpath('$0')))") +TEMPLATE_ROOT="${PACKAGING_DIR}/../../" + +# shellcheck source=mod.config +. "${TEMPLATE_ROOT}/mod.config" + +if [ -f "${TEMPLATE_ROOT}/user.config" ]; then + # shellcheck source=user.config + . "${TEMPLATE_ROOT}/user.config" +fi + +require_variables "MOD_ID" "ENGINE_DIRECTORY" "PACKAGING_DISPLAY_NAME" "PACKAGING_INSTALLER_NAME" \ + "PACKAGING_APPIMAGE_DEPENDENCIES_TAG" "PACKAGING_APPIMAGE_DEPENDENCIES_SOURCE" "PACKAGING_APPIMAGE_DEPENDENCIES_TEMP_ARCHIVE_NAME" \ + "PACKAGING_FAQ_URL" + +TAG="$1" +if [ $# -eq "1" ]; then + OUTPUTDIR=$(python -c "import os; print(os.path.realpath('.'))") +else + OUTPUTDIR=$(python -c "import os; print(os.path.realpath('$2'))") +fi + +BUILTDIR="${PACKAGING_DIR}/${PACKAGING_INSTALLER_NAME}.appdir" + +# Set the working dir to the location of this script +cd "${PACKAGING_DIR}" + +pushd "${TEMPLATE_ROOT}" > /dev/null + +if [ ! -f "${ENGINE_DIRECTORY}/Makefile" ]; then + echo "Required engine files not found." + echo "Run \`make\` in the mod directory to fetch and build the required files, then try again."; + exit 1 +fi + +if [ ! -d "${OUTPUTDIR}" ]; then + echo "Output directory '${OUTPUTDIR}' does not exist."; + exit 1 +fi + +echo "Building core files" + +make version VERSION="${TAG}" + +pushd "${ENGINE_DIRECTORY}" > /dev/null +make linux-dependencies +make core SDK="-sdk:4.5" +make install-engine prefix="usr" DESTDIR="${BUILTDIR}/" +make install-common-mod-files prefix="usr" DESTDIR="${BUILTDIR}/" + +for f in ${PACKAGING_COPY_ENGINE_FILES}; do + mkdir -p "${BUILTDIR}/usr/lib/openra/$(dirname "${f}")" + cp -r "${f}" "${BUILTDIR}/usr/lib/openra/${f}" +done + +popd > /dev/null +popd > /dev/null + +# Add native libraries +echo "Downloading dependencies" +curl -s -L -o "${PACKAGING_APPIMAGE_DEPENDENCIES_TEMP_ARCHIVE_NAME}" -O "${PACKAGING_APPIMAGE_DEPENDENCIES_SOURCE}" || exit 3 +tar xf "${PACKAGING_APPIMAGE_DEPENDENCIES_TEMP_ARCHIVE_NAME}" + +curl -s -L -O https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage +chmod a+x appimagetool-x86_64.AppImage + +echo "Building AppImage" + +# Add mod files +cp -Lr "${TEMPLATE_ROOT}/mods/"* "${BUILTDIR}/usr/lib/openra/mods" + +install -Dm 0755 libSDL2.so "${BUILTDIR}/usr/lib/openra/" +install -Dm 0644 include/SDL2-CS.dll.config "${BUILTDIR}/usr/lib/openra/" +install -Dm 0755 libopenal.so "${BUILTDIR}/usr/lib/openra/" +install -Dm 0644 include/OpenAL-CS.dll.config "${BUILTDIR}/usr/lib/openra/" +install -Dm 0755 liblua.so "${BUILTDIR}/usr/lib/openra/" +install -Dm 0644 include/Eluant.dll.config "${BUILTDIR}/usr/lib/openra/" + +# Add launcher and icons +sed "s/{MODID}/${MOD_ID}/g" include/AppRun.in | sed "s/{MODNAME}/${PACKAGING_DISPLAY_NAME}/g" > AppRun.temp +install -m 0755 AppRun.temp "${BUILTDIR}/AppRun" + +sed "s/{MODID}/${MOD_ID}/g" include/mod.desktop.in | sed "s/{MODNAME}/${PACKAGING_DISPLAY_NAME}/g" | sed "s/{TAG}/${TAG}/g" > temp.desktop +install -Dm 0755 temp.desktop "${BUILTDIR}/usr/share/applications/openra-${MOD_ID}.desktop" +install -m 0755 temp.desktop "${BUILTDIR}/openra-${MOD_ID}.desktop" + +sed "s/{MODID}/${MOD_ID}/g" include/mod-mimeinfo.xml.in | sed "s/{TAG}/${TAG}/g" > temp.xml +install -Dm 0755 temp.xml "${BUILTDIR}/usr/share/mime/packages/openra-${MOD_ID}.xml" + +if [ -f "${PACKAGING_DIR}/mod_scalable.svg" ]; then + install -Dm644 "${PACKAGING_DIR}/mod_scalable.svg" "${BUILTDIR}/usr/share/icons/hicolor/scalable/apps/openra-${MOD_ID}.svg" +fi + +for i in 16x16 32x32 48x48 64x64 128x128 256x256 512x512 1024x1024; do + if [ -f "${PACKAGING_DIR}/mod_${i}.png" ]; then + install -Dm644 "${PACKAGING_DIR}/mod_${i}.png" "${BUILTDIR}/usr/share/icons/hicolor/${i}/apps/openra-${MOD_ID}.png" + install -m644 "${PACKAGING_DIR}/mod_${i}.png" "${BUILTDIR}/openra-${MOD_ID}.png" + fi +done + +install -d "${BUILTDIR}/usr/bin" + +sed "s/{MODID}/${MOD_ID}/g" include/mod.in | sed "s/{TAG}/${TAG}/g" | sed "s/{MODNAME}/${PACKAGING_DISPLAY_NAME}/g" | sed "s/{MODINSTALLERNAME}/${PACKAGING_INSTALLER_NAME}/g" | sed "s|{MODFAQURL}|${PACKAGING_FAQ_URL}|g" > openra-mod.temp +install -m 0755 openra-mod.temp "${BUILTDIR}/usr/bin/openra-${MOD_ID}" + +sed "s/{MODID}/${MOD_ID}/g" include/mod-server.in > openra-mod-server.temp +install -m 0755 openra-mod-server.temp "${BUILTDIR}/usr/bin/openra-${MOD_ID}-server" + +# travis-ci doesn't support mounting FUSE filesystems so extract and run the contents manually +./appimagetool-x86_64.AppImage --appimage-extract +ARCH=x86_64 ./squashfs-root/AppRun "${BUILTDIR}" "${OUTPUTDIR}/${PACKAGING_INSTALLER_NAME}-${TAG}.AppImage" + +# Clean up +rm -rf openra-mod.temp openra-mod-server.temp temp.desktop temp.xml AppRun.temp libSDL2.so libopenal.so liblua.so appimagetool-x86_64.AppImage squashfs-root "${PACKAGING_APPIMAGE_DEPENDENCIES_TEMP_ARCHIVE_NAME}" "${BUILTDIR}" diff --git a/packaging/linux/include/AppRun.in b/packaging/linux/include/AppRun.in new file mode 100644 index 0000000..353e9de --- /dev/null +++ b/packaging/linux/include/AppRun.in @@ -0,0 +1,38 @@ +#!/bin/sh + +# Make sure the user has a sufficiently recent version of mono on the PATH +MINIMUM_MONO_VERSION="4.2" + +make_version() { + echo "$1" | tr '.' '\n' | head -n 4 | xargs printf "%03d%03d%03d%03d"; +} + +mono_missing_or_old() { + command -v mono >/dev/null 2>&1 || return 0 + MONO_VERSION=$(mono --version | head -n1 | cut -d' ' -f5) + [ "$(make_version "${MONO_VERSION}")" -lt "$(make_version "${MINIMUM_MONO_VERSION}")" ] && return 0 + return 1 +} + +if mono_missing_or_old; then + ERROR_MESSAGE="{MODNAME} requires Mono ${MINIMUM_MONO_VERSION} or greater.\nPlease install Mono using your system package manager." + if command -v zenity > /dev/null; then + zenity --no-wrap --error --title "{MODNAME}" --text "${ERROR_MESSAGE}" 2> /dev/null + elif command -v kdialog > /dev/null; then + kdialog --title "{MODNAME}" --error "${ERROR_MESSAGE}" + else + printf "${ERROR_MESSAGE}" + fi + exit 1 +fi + +# Run the game or server +HERE="$(dirname "$(readlink -f "${0}")")" +export PATH="${HERE}"/usr/bin/:"${PATH}" +export XDG_DATA_DIRS="${HERE}"/usr/share/:"${XDG_DATA_DIRS}" + +if [ -n "$1" ] && [ "$1" = "--server" ]; then + exec "openra-{MODID}-server" "$@" +else + exec "openra-{MODID}" "$@" +fi diff --git a/packaging/linux/include/Eluant.dll.config b/packaging/linux/include/Eluant.dll.config new file mode 100644 index 0000000..561d8e9 --- /dev/null +++ b/packaging/linux/include/Eluant.dll.config @@ -0,0 +1,3 @@ + + + diff --git a/packaging/linux/include/OpenAL-CS.dll.config b/packaging/linux/include/OpenAL-CS.dll.config new file mode 100644 index 0000000..43cedc7 --- /dev/null +++ b/packaging/linux/include/OpenAL-CS.dll.config @@ -0,0 +1,4 @@ + + + + diff --git a/packaging/linux/include/SDL2-CS.dll.config b/packaging/linux/include/SDL2-CS.dll.config new file mode 100644 index 0000000..a2aa928 --- /dev/null +++ b/packaging/linux/include/SDL2-CS.dll.config @@ -0,0 +1,4 @@ + + + + diff --git a/packaging/linux/include/mod-mimeinfo.xml.in b/packaging/linux/include/mod-mimeinfo.xml.in new file mode 100644 index 0000000..a1e8c19 --- /dev/null +++ b/packaging/linux/include/mod-mimeinfo.xml.in @@ -0,0 +1,8 @@ + + + + + Join OpenRA server + + + diff --git a/packaging/linux/include/mod-server.in b/packaging/linux/include/mod-server.in new file mode 100644 index 0000000..a2798c2 --- /dev/null +++ b/packaging/linux/include/mod-server.in @@ -0,0 +1,6 @@ +#!/bin/sh + +HERE="$(dirname "$(readlink -f "${0}")")" +cd "${HERE}/../lib/openra" || exit 1 + +mono --debug OpenRA.Server.exe Game.Mod={MODID} "$@" diff --git a/packaging/linux/include/mod.desktop.in b/packaging/linux/include/mod.desktop.in new file mode 100644 index 0000000..bb4c2a4 --- /dev/null +++ b/packaging/linux/include/mod.desktop.in @@ -0,0 +1,11 @@ +[Desktop Entry] +Type=Application +Version=1.0 +Name=OpenRA - {MODNAME} +GenericName=Real Time Strategy Game +Icon=openra-{MODID} +Exec=openra-{MODID} %u +Terminal=false +Categories=Game;StrategyGame; +StartupWMClass=openra-{MODID}-{TAG} +MimeType=x-scheme-handler/openra-{MODID}-{TAG}; diff --git a/packaging/linux/include/mod.in b/packaging/linux/include/mod.in new file mode 100644 index 0000000..45bf353 --- /dev/null +++ b/packaging/linux/include/mod.in @@ -0,0 +1,52 @@ +#!/bin/sh + +LAUNCHER=$(readlink -f "${0}") +HERE="$(dirname "${LAUNCHER}")" +cd "${HERE}/../lib/openra" || exit 1 + +# APPIMAGE is an environment variable set by the runtime +# defining the absolute path to the .AppImage file +if [ ! -z "${APPIMAGE}" ]; then + LAUNCHER=${APPIMAGE} + + # appimaged doesn't update the mime or icon caches when registering AppImages. + # Run update-desktop-database and gtk-update-icon-cache ourselves if we detect + # that the desktop file has been installed but the handler is not cached + if command -v update-desktop-database > /dev/null; then + APPIMAGEID=$(printf "file://%s" "${APPIMAGE}" | md5sum | cut -d' ' -f1) + LAUNCHER_NAME="appimagekit_${APPIMAGEID}-openra-{MODID}.desktop" + LAUNCHER_PATH="${HOME}/.local/share/applications/${LAUNCHER_NAME}" + MIMECACHE_PATH="${HOME}/.local/share/applications/mimeinfo.cache" + SCHEME="x-scheme-handler/openra-{MODID}-{TAG}" + if [ -f "${LAUNCHER_PATH}" ] && ! grep -qs "${SCHEME}=" "${MIMECACHE_PATH}"; then + update-desktop-database "${HOME}/.local/share/applications" + if command -v gtk-update-icon-cache > /dev/null; then + gtk-update-icon-cache ~/.local/share/icons/hicolor/ -t + fi + fi + fi +fi + +# Search for server connection +PROTOCOL_PREFIX="openra-{MODID}-{TAG}://" +JOIN_SERVER="" +if [ "${1#${PROTOCOL_PREFIX}}" != "${1}" ]; then + JOIN_SERVER="Launch.Connect=${1#${PROTOCOL_PREFIX}}" +fi + +# Run the game +export SDL_VIDEO_X11_WMCLASS="openra-{MODID}-{TAG}" +mono --debug OpenRA.Game.exe Game.Mod={MODID} Engine.LaunchPath="${LAUNCHER}" "${JOIN_SERVER}" "$@" + +# Show a crash dialog if something went wrong +if [ $? != 0 ] && [ $? != 1 ]; then + ERROR_MESSAGE="{MODNAME} has encountered a fatal error.\nPlease refer to the crash logs and FAQ for more information.\n\nLog files are located in ~/.openra/Logs\nThe FAQ is available at {MODFAQURL}" + if command -v zenity > /dev/null; then + zenity --no-wrap --error --title "{MODNAME}" --text "${ERROR_MESSAGE}" 2> /dev/null + elif command -v kdialog > /dev/null; then + kdialog --title "{MODNAME}" --error "${ERROR_MESSAGE}" + else + printf "${ERROR_MESSAGE}\n" + fi + exit 1 +fi diff --git a/packaging/linux/mod_128x128.png b/packaging/linux/mod_128x128.png new file mode 100644 index 0000000..ed1b458 Binary files /dev/null and b/packaging/linux/mod_128x128.png differ diff --git a/packaging/linux/mod_16x16.png b/packaging/linux/mod_16x16.png new file mode 100644 index 0000000..c31b0fc Binary files /dev/null and b/packaging/linux/mod_16x16.png differ diff --git a/packaging/linux/mod_256x256.png b/packaging/linux/mod_256x256.png new file mode 100644 index 0000000..e05a6f8 Binary files /dev/null and b/packaging/linux/mod_256x256.png differ diff --git a/packaging/linux/mod_32x32.png b/packaging/linux/mod_32x32.png new file mode 100644 index 0000000..155dafd Binary files /dev/null and b/packaging/linux/mod_32x32.png differ diff --git a/packaging/linux/mod_48x48.png b/packaging/linux/mod_48x48.png new file mode 100644 index 0000000..e5cc191 Binary files /dev/null and b/packaging/linux/mod_48x48.png differ diff --git a/packaging/linux/mod_64x64.png b/packaging/linux/mod_64x64.png new file mode 100644 index 0000000..d780c5a Binary files /dev/null and b/packaging/linux/mod_64x64.png differ diff --git a/packaging/osx/buildpackage.sh b/packaging/osx/buildpackage.sh index 08a9a09..7c8a623 100755 --- a/packaging/osx/buildpackage.sh +++ b/packaging/osx/buildpackage.sh @@ -6,6 +6,18 @@ command -v make >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires command -v python >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires python."; exit 1; } command -v curl >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires curl."; exit 1; } +require_variables() { + missing="" + for i in "$@"; do + eval check="\$$i" + [ -z "${check}" ] && missing="${missing} ${i}\n" + done + if [ ! -z "${missing}" ]; then + echo "Required mod.config variables are missing:\n${missing}Repair your mod.config (or user.config) and try again." + exit 1 + fi +} + if [ $# -eq "0" ]; then echo "Usage: `basename $0` version [outputdir]" exit 1 @@ -22,11 +34,9 @@ if [ -f "${TEMPLATE_ROOT}/user.config" ]; then . "${TEMPLATE_ROOT}/user.config" fi -if [ "${INCLUDE_DEFAULT_MODS}" = "True" ]; then - echo "Cannot generate installers while INCLUDE_DEFAULT_MODS is enabled." - echo "Make sure that this setting is disabled in both your mod.config and user.config." - exit 1 -fi +require_variables "MOD_ID" "ENGINE_DIRECTORY" "PACKAGING_DISPLAY_NAME" "PACKAGING_INSTALLER_NAME" \ + "PACKAGING_OSX_LAUNCHER_TAG" "PACKAGING_OSX_LAUNCHER_SOURCE" "PACKAGING_OSX_LAUNCHER_TEMP_ARCHIVE_NAME" \ + "PACKAGING_FAQ_URL" TAG="$1" if [ $# -eq "1" ]; then @@ -75,11 +85,17 @@ make osx-dependencies make core SDK="-sdk:4.5" make install-engine gameinstalldir="/Contents/Resources/" DESTDIR="${BUILTDIR}/OpenRA.app" make install-common-mod-files gameinstalldir="/Contents/Resources/" DESTDIR="${BUILTDIR}/OpenRA.app" + +for f in ${PACKAGING_COPY_ENGINE_FILES}; do + mkdir -p "${BUILTDIR}/OpenRA.app/Contents/Resources/$(dirname "${f}")" + cp -r "${f}" "${BUILTDIR}/OpenRA.app/Contents/Resources/${f}" +done + popd > /dev/null popd > /dev/null # Add mod files -cp -r "${TEMPLATE_ROOT}/mods/"* "${BUILTDIR}/OpenRA.app/Contents/Resources/mods" +cp -Lr "${TEMPLATE_ROOT}/mods/"* "${BUILTDIR}/OpenRA.app/Contents/Resources/mods" cp "mod.icns" "${BUILTDIR}/OpenRA.app/Contents/Resources/${MOD_ID}.icns" pushd "${BUILTDIR}" > /dev/null @@ -92,7 +108,7 @@ modify_plist "{JOIN_SERVER_URL_SCHEME}" "openra-${MOD_ID}-${TAG}" "${PACKAGING_O echo "Packaging zip archive" -zip "${PACKAGING_INSTALLER_NAME}-${TAG}-macOS.zip" -r -9 "${PACKAGING_OSX_APP_NAME}" --quiet --symlinks +zip "${PACKAGING_INSTALLER_NAME}-${TAG}-macOS.zip" -r -9 "${PACKAGING_OSX_APP_NAME}" --quiet mv "${PACKAGING_INSTALLER_NAME}-${TAG}-macOS.zip" "${OUTPUTDIR}" popd > /dev/null diff --git a/packaging/windows/buildpackage.sh b/packaging/windows/buildpackage.sh index 52b8eae..9ff3489 100755 --- a/packaging/windows/buildpackage.sh +++ b/packaging/windows/buildpackage.sh @@ -4,6 +4,18 @@ set -e command -v curl >/dev/null 2>&1 || { echo >&2 "Windows packaging requires curl."; exit 1; } command -v makensis >/dev/null 2>&1 || { echo >&2 "Windows packaging requires makensis."; exit 1; } +require_variables() { + missing="" + for i in "$@"; do + eval check="\$$i" + [ -z "${check}" ] && missing="${missing} ${i}\n" + done + if [ ! -z "${missing}" ]; then + echo "Required mod.config variables are missing:\n${missing}Repair your mod.config (or user.config) and try again." + exit 1 + fi +} + if [ $# -eq "0" ]; then echo "Usage: `basename $0` version [outputdir]" exit 1 @@ -20,11 +32,9 @@ if [ -f "${TEMPLATE_ROOT}/user.config" ]; then . "${TEMPLATE_ROOT}/user.config" fi -if [ "${INCLUDE_DEFAULT_MODS}" = "True" ]; then - echo "Cannot generate installers while INCLUDE_DEFAULT_MODS is enabled." - echo "Make sure that this setting is disabled in both your mod.config and user.config." - exit 1 -fi +require_variables "MOD_ID" "ENGINE_DIRECTORY" "PACKAGING_DISPLAY_NAME" "PACKAGING_INSTALLER_NAME" \ + "PACKAGING_WINDOWS_LAUNCHER_NAME" "PACKAGING_WINDOWS_REGISTRY_KEY" "PACKAGING_WINDOWS_INSTALL_DIR_NAME" \ + "PACKAGING_FAQ_URL" "PACKAGING_WEBSITE_URL" "PACKAGING_AUTHORS" TAG="$1" if [ $# -eq "1" ]; then @@ -63,11 +73,17 @@ make windows-dependencies make core SDK="-sdk:4.5" make install-engine gameinstalldir="" DESTDIR="${BUILTDIR}" make install-common-mod-files gameinstalldir="" DESTDIR="${BUILTDIR}" + +for f in ${PACKAGING_COPY_ENGINE_FILES}; do + mkdir -p "${BUILTDIR}/$(dirname "${f}")" + cp -r "${f}" "${BUILTDIR}/${f}" +done + popd > /dev/null popd > /dev/null # Add mod files -cp -r "${TEMPLATE_ROOT}/mods/"* "${BUILTDIR}/mods" +cp -Lr "${TEMPLATE_ROOT}/mods/"* "${BUILTDIR}/mods" cp "mod.ico" "${BUILTDIR}/${MOD_ID}.ico" cp "${SRC_DIR}/OpenRA.Game.exe.config" "${BUILTDIR}" @@ -88,7 +104,7 @@ popd > /dev/null echo "Packaging zip archive" pushd "${BUILTDIR}" > /dev/null find "${SRC_DIR}/thirdparty/download/windows/" -name '*.dll' -exec cp '{}' '.' ';' -zip "${PACKAGING_INSTALLER_NAME}-${TAG}-winportable" -r -9 * --quiet --symlinks +zip "${PACKAGING_INSTALLER_NAME}-${TAG}-winportable" -r -9 * --quiet mv "${PACKAGING_INSTALLER_NAME}-${TAG}-winportable.zip" "${OUTPUTDIR}" popd > /dev/null diff --git a/utility.cmd b/utility.cmd index 500e2e2..2fd46b6 100644 --- a/utility.cmd +++ b/utility.cmd @@ -1,17 +1,19 @@ @echo off +setlocal EnableDelayedExpansion FOR /F "tokens=1,2 delims==" %%A IN (mod.config) DO (set %%A=%%B) if exist user.config (FOR /F "tokens=1,2 delims==" %%A IN (user.config) DO (set %%A=%%B)) +set MOD_SEARCH_PATHS=%~dp0mods,./mods -title OpenRA.Utility.exe %MOD_ID% +if "!MOD_ID!" == "" goto badconfig +if "!ENGINE_VERSION!" == "" goto badconfig +if "!ENGINE_DIRECTORY!" == "" goto badconfig -set MOD_SEARCH_PATHS=%~dp0mods -if %INCLUDE_DEFAULT_MODS% neq "True" goto start -set MOD_SEARCH_PATHS=%MOD_SEARCH_PATHS%,./mods +title OpenRA.Utility.exe %MOD_ID% -:start set TEMPLATE_DIR=%CD% if not exist %ENGINE_DIRECTORY%\OpenRA.Game.exe goto noengine +>nul find %ENGINE_VERSION% %ENGINE_DIRECTORY%\VERSION || goto noengine cd %ENGINE_DIRECTORY% :loop @@ -35,4 +37,11 @@ goto loop echo Required engine files not found. echo Run `make all` in the mod directory to fetch and build the required files, then try again. pause -exit /b \ No newline at end of file +exit /b + +:badconfig +echo Required mod.config variables are missing. +echo Ensure that MOD_ID ENGINE_VERSION and ENGINE_DIRECTORY are +echo defined in your mod.config (or user.config) and try again. +pause +exit /b diff --git a/utility.sh b/utility.sh index ac35531..b649e7b 100755 --- a/utility.sh +++ b/utility.sh @@ -8,8 +8,21 @@ command -v make >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires command -v python >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires python."; exit 1; } command -v mono >/dev/null 2>&1 || { echo >&2 "The OpenRA mod template requires mono."; exit 1; } +require_variables() { + missing="" + for i in "$@"; do + eval check="\$$i" + [ -z "${check}" ] && missing="${missing} ${i}\n" + done + if [ ! -z "${missing}" ]; then + echo "Required mod.config variables are missing:\n${missing}Repair your mod.config (or user.config) and try again." + exit 1 + fi +} + TEMPLATE_LAUNCHER=$(python -c "import os; print(os.path.realpath('$0'))") TEMPLATE_ROOT=$(dirname "${TEMPLATE_LAUNCHER}") +MOD_SEARCH_PATHS="${TEMPLATE_ROOT}/mods,./mods" # shellcheck source=mod.config . "${TEMPLATE_ROOT}/mod.config" @@ -19,15 +32,12 @@ if [ -f "${TEMPLATE_ROOT}/user.config" ]; then . "${TEMPLATE_ROOT}/user.config" fi -MOD_SEARCH_PATHS="${TEMPLATE_ROOT}/mods" -if [ "${INCLUDE_DEFAULT_MODS}" = "True" ]; then - MOD_SEARCH_PATHS="${MOD_SEARCH_PATHS},./mods" -fi +require_variables "MOD_ID" "ENGINE_VERSION" "ENGINE_DIRECTORY" LAUNCH_MOD="${Mod:-"${MOD_ID}"}" cd "${TEMPLATE_ROOT}" -if [ ! -f "${ENGINE_DIRECTORY}/OpenRA.Game.exe" ]; then +if [ ! -f "${ENGINE_DIRECTORY}/OpenRA.Game.exe" ] || [ "$(cat "${ENGINE_DIRECTORY}/VERSION")" != "${ENGINE_VERSION}" ]; then echo "Required engine files not found." echo "Run \`make\` in the mod directory to fetch and build the required files, then try again."; exit 1