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