diff --git a/Makefile b/Makefile index 5a9dcb6..2b25059 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,12 @@ # to compile, run: # make # +# to compile using Mono (version 6.4 or greater) instead of .NET 6, run: +# make RUNTIME=mono +# +# to compile using system libraries for native dependencies, run: +# make [RUNTIME=net6] TARGETPLATFORM=unix-generic +# # to remove the files created by compiling, run: # make clean # @@ -13,7 +19,10 @@ # make check-scripts # # to check the engine and your mod dlls for StyleCop violations, run: -# make check +# make [RUNTIME=net6] check +# +# to check your mod yaml for errors, run: +# make [RUNTIME=net6] test # # the following are internal sdk helpers that are not intended to be run directly: # make check-variables @@ -36,31 +45,39 @@ MOD_ID = $(shell cat user.config mod.config 2> /dev/null | awk -F= '/MOD_ID/ { p ENGINE_DIRECTORY = $(shell cat user.config mod.config 2> /dev/null | awk -F= '/ENGINE_DIRECTORY/ { print $$2; exit }') MOD_SEARCH_PATHS = "$(shell $(PYTHON) -c "import os; print(os.path.realpath('.'))")/mods,./mods" -WHITELISTED_OPENRA_ASSEMBLIES = "$(shell cat user.config mod.config 2> /dev/null | awk -F= '/WHITELISTED_OPENRA_ASSEMBLIES/ { print $$2; exit }')" -WHITELISTED_THIRDPARTY_ASSEMBLIES = "$(shell cat user.config mod.config 2> /dev/null | awk -F= '/WHITELISTED_THIRDPARTY_ASSEMBLIES/ { print $$2; exit }')" -WHITELISTED_CORE_ASSEMBLIES = "$(shell cat user.config mod.config 2> /dev/null | awk -F= '/WHITELISTED_CORE_ASSEMBLIES/ { print $$2; exit }')" -WHITELISTED_MOD_ASSEMBLIES = "$(shell cat user.config mod.config 2> /dev/null | awk -F= '/WHITELISTED_MOD_ASSEMBLIES/ { print $$2; exit }')" - MANIFEST_PATH = "mods/$(MOD_ID)/mod.yaml" HAS_LUAC = $(shell command -v luac 2> /dev/null) LUA_FILES = $(shell find mods/*/maps/* -iname '*.lua' 2> /dev/null) MOD_SOLUTION_FILES = $(shell find . -maxdepth 1 -iname '*.sln' 2> /dev/null) MSBUILD = msbuild -verbosity:m -nologo +DOTNET = dotnet + +RUNTIME ?= net6 +CONFIGURATION ?= Release +DOTNET_RID = $(shell ${DOTNET} --info | grep RID: | cut -w -f3) ifndef TARGETPLATFORM UNAME_S := $(shell uname -s) UNAME_M := $(shell uname -m) ifeq ($(UNAME_S),Darwin) +ifeq ($(RUNTIME)-$(DOTNET_RID),net6-osx-arm64) +TARGETPLATFORM = osx-arm64 +else TARGETPLATFORM = osx-x64 +endif else ifeq ($(UNAME_M),x86_64) TARGETPLATFORM = linux-x64 else +ifeq ($(UNAME_M),aarch64) +TARGETPLATFORM = linux-arm64 +else TARGETPLATFORM = unix-generic endif endif endif +endif check-sdk-scripts: @awk '/\r$$/ { exit(1); }' mod.config || (printf "Invalid mod.config format: file must be saved using unix-style (CR, not CRLF) line endings.\n"; exit 1) @@ -123,18 +140,25 @@ check-variables: engine: check-variables check-sdk-scripts @./fetch-engine.sh || (printf "Unable to continue without engine files\n"; exit 1) - @cd $(ENGINE_DIRECTORY) && make TARGETPLATFORM=$(TARGETPLATFORM) all + @cd $(ENGINE_DIRECTORY) && make RUNTIME=$(RUNTIME) TARGETPLATFORM=$(TARGETPLATFORM) all all: engine - @command -v $(MSBUILD) >/dev/null || (echo "OpenRA requires the '$(MSBUILD)' tool provided by Mono >= 5.18."; exit 1) +ifeq ($(RUNTIME), mono) + @command -v $(MSBUILD) >/dev/null || (echo "OpenRA requires the '$(MSBUILD)' tool provided by Mono >= 6.4."; exit 1) ifneq ("$(MOD_SOLUTION_FILES)","") - @find . -maxdepth 1 -name '*.sln' -exec $(MSBUILD) -t:Build -restore -p:Configuration=Release -p:TargetPlatform=$(TARGETPLATFORM) \; + @find . -maxdepth 1 -name '*.sln' -exec $(MSBUILD) -t:Build -restore -p:Configuration=${CONFIGURATION} -p:TargetPlatform=$(TARGETPLATFORM) -p:Mono=true \; +endif +else + @find . -maxdepth 1 -name '*.sln' -exec $(DOTNET) build -c ${CONFIGURATION} -p:TargetPlatform=$(TARGETPLATFORM) \; endif clean: engine - @command -v $(MSBUILD) >/dev/null || (echo "OpenRA requires the '$(MSBUILD)' tool provided by Mono >= 5.18."; exit 1) ifneq ("$(MOD_SOLUTION_FILES)","") +ifeq ($(RUNTIME), mono) @find . -maxdepth 1 -name '*.sln' -exec $(MSBUILD) -t:clean \; +else + @find . -maxdepth 1 -name '*.sln' -exec $(DOTNET) clean \; +endif endif @cd $(ENGINE_DIRECTORY) && make clean @@ -154,11 +178,15 @@ endif check: engine ifneq ("$(MOD_SOLUTION_FILES)","") - @echo "Compiling in debug mode..." - @find . -maxdepth 1 -name '*.sln' -exec $(MSBUILD) -t:Build -restore -p:Configuration=Debug -p:TargetPlatform=$(TARGETPLATFORM) \; + @echo "Compiling in Debug mode..." +ifeq ($(RUNTIME), mono) +# Enabling EnforceCodeStyleInBuild and GenerateDocumentationFile as a workaround for some code style rules (in particular IDE0005) being bugged and not reporting warnings/errors otherwise. + @$(MSBUILD) -t:build -restore -p:Configuration=Debug -warnaserror -p:TargetPlatform=$(TARGETPLATFORM) -p:Mono=true -p:EnforceCodeStyleInBuild=true -p:GenerateDocumentationFile=true +else +# Enabling EnforceCodeStyleInBuild and GenerateDocumentationFile as a workaround for some code style rules (in particular IDE0005) being bugged and not reporting warnings/errors otherwise. + @$(DOTNET) build -c Debug -nologo -warnaserror -p:TargetPlatform=$(TARGETPLATFORM) -p:EnforceCodeStyleInBuild=true -p:GenerateDocumentationFile=true +endif endif - @echo "Checking runtime assemblies..." - @./utility.sh --check-runtime-assemblies $(WHITELISTED_OPENRA_ASSEMBLIES) $(WHITELISTED_THIRDPARTY_ASSEMBLIES) $(WHITELISTED_CORE_ASSEMBLIES) $(WHITELISTED_MOD_ASSEMBLIES) @echo "Checking for explicit interface violations..." @./utility.sh --check-explicit-interfaces @echo "Checking for incorrect conditional trait interface overrides..." diff --git a/launch-dedicated.cmd b/launch-dedicated.cmd index c78a427..58dca9a 100644 --- a/launch-dedicated.cmd +++ b/launch-dedicated.cmd @@ -6,6 +6,7 @@ set Name="Dedicated Server" set ListenPort=1234 set AdvertiseOnline=True set Password="" +set RecordReplays=False set RequireAuthentication=False set ProfileIDBlacklist="" @@ -14,8 +15,11 @@ set ProfileIDWhitelist="" set EnableSingleplayer=False set EnableSyncReports=False set EnableGeoIP=True +set EnableLintChecks=True set ShareAnonymizedIPs=True +set JoinChatDelay=5000 + @echo off setlocal EnableDelayedExpansion @@ -33,7 +37,7 @@ if not exist %ENGINE_DIRECTORY%\bin\OpenRA.exe goto noengine cd %ENGINE_DIRECTORY% :loop -bin\OpenRA.Server.exe Game.Mod=%MOD_ID% Engine.EngineDir=".." Server.Name=%Name% Server.ListenPort=%ListenPort% Server.AdvertiseOnline=%AdvertiseOnline% Server.EnableSingleplayer=%EnableSingleplayer% Server.Password=%Password% Server.RequireAuthentication=%RequireAuthentication% Server.ProfileIDBlacklist=%ProfileIDBlacklist% Server.ProfileIDWhitelist=%ProfileIDWhitelist% Server.EnableSyncReports=%EnableSyncReports% Server.EnableGeoIP=%EnableGeoIP% Server.ShareAnonymizedIPs=%ShareAnonymizedIPs% Engine.SupportDir=%SupportDir% +bin\OpenRA.Server.exe Game.Mod=%MOD_ID% Engine.EngineDir=".." Server.Name=%Name% Server.ListenPort=%ListenPort% Server.AdvertiseOnline=%AdvertiseOnline% Server.EnableSingleplayer=%EnableSingleplayer% Server.Password=%Password% Server.RequireAuthentication=%RequireAuthentication% Server.RecordReplays=%RecordReplays% Server.ProfileIDBlacklist=%ProfileIDBlacklist% Server.ProfileIDWhitelist=%ProfileIDWhitelist% Server.EnableSyncReports=%EnableSyncReports% Server.EnableGeoIP=%EnableGeoIP% Server.ShareAnonymizedIPs=%ShareAnonymizedIPs% Server.EnableLintChecks=%EnableLintChecks% Engine.SupportDir=%SupportDir% Server.JoinChatDelay=%JoinChatDelay% goto loop :noengine diff --git a/launch-dedicated.sh b/launch-dedicated.sh index 97201e8..ae52ac8 100755 --- a/launch-dedicated.sh +++ b/launch-dedicated.sh @@ -5,7 +5,10 @@ # Read the file to see which settings you can override set -e -command -v mono >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK requires mono."; exit 1; } +if ! command -v mono >/dev/null 2>&1; then + command -v dotnet >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK requires dotnet or mono."; exit 1; } +fi + if command -v python3 >/dev/null 2>&1; then PYTHON="python3" else @@ -39,11 +42,18 @@ fi require_variables "MOD_ID" "ENGINE_VERSION" "ENGINE_DIRECTORY" +if command -v mono >/dev/null 2>&1 && [ "$(grep -c .NETCoreApp,Version= ${ENGINE_DIRECTORY}/bin/OpenRA.Server.dll)" = "0" ]; then + RUNTIME_LAUNCHER="mono --debug" +else + RUNTIME_LAUNCHER="dotnet" +fi + NAME="${Name:-"Dedicated Server"}" LAUNCH_MOD="${Mod:-"${MOD_ID}"}" LISTEN_PORT="${ListenPort:-"1234"}" ADVERTISE_ONLINE="${AdvertiseOnline:-"True"}" PASSWORD="${Password:-""}" +RECORD_REPLAYS="${RecordReplays:-"False"}" REQUIRE_AUTHENTICATION="${RequireAuthentication:-"False"}" PROFILE_ID_BLACKLIST="${ProfileIDBlacklist:-""}" @@ -52,12 +62,15 @@ PROFILE_ID_WHITELIST="${ProfileIDWhitelist:-""}" ENABLE_SINGLE_PLAYER="${EnableSingleplayer:-"False"}" ENABLE_SYNC_REPORTS="${EnableSyncReports:-"False"}" ENABLE_GEOIP="${EnableGeoIP:-"True"}" +ENABLE_LINT_CHECKS="${EnableLintChecks:-"True"}" SHARE_ANONYMISED_IPS="${ShareAnonymizedIPs:-"True"}" +JOIN_CHAT_DELAY="${JoinChatDelay:-"5000"}" + SUPPORT_DIR="${SupportDir:-""}" cd "${TEMPLATE_ROOT}" -if [ ! -f "${ENGINE_DIRECTORY}/bin/OpenRA.Server.exe" ] || [ "$(cat "${ENGINE_DIRECTORY}/VERSION")" != "${ENGINE_VERSION}" ]; then +if [ ! -f "${ENGINE_DIRECTORY}/bin/OpenRA.Server.dll" ] || [ "$(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 @@ -66,16 +79,21 @@ fi cd "${ENGINE_DIRECTORY}" while true; do - MOD_SEARCH_PATHS="${MOD_SEARCH_PATHS}" mono --debug bin/OpenRA.Server.exe Engine.EngineDir=".." Game.Mod="${LAUNCH_MOD}" \ - Server.Name="${NAME}" Server.ListenPort="${LISTEN_PORT}" \ + MOD_SEARCH_PATHS="${MOD_SEARCH_PATHS}" + ${RUNTIME_LAUNCHER} bin/OpenRA.Server.dll Engine.EngineDir=".." Game.Mod="${LAUNCH_MOD}" \ + Server.Name="${NAME}" \ + Server.ListenPort="${LISTEN_PORT}" \ Server.AdvertiseOnline="${ADVERTISE_ONLINE}" \ Server.Password="${PASSWORD}" \ + Server.RecordReplays="${RECORD_REPLAYS}" \ Server.RequireAuthentication="${REQUIRE_AUTHENTICATION}" \ Server.ProfileIDBlacklist="${PROFILE_ID_BLACKLIST}" \ Server.ProfileIDWhitelist="${PROFILE_ID_WHITELIST}" \ Server.EnableSingleplayer="${ENABLE_SINGLE_PLAYER}" \ Server.EnableSyncReports="${ENABLE_SYNC_REPORTS}" \ Server.EnableGeoIP="${ENABLE_GEOIP}" \ + Server.EnableLintChecks="${ENABLE_LINT_CHECKS}" \ Server.ShareAnonymizedIPs="${SHARE_ANONYMISED_IPS}" \ + Server.JoinChatDelay="${JOIN_CHAT_DELAY}" \ Engine.SupportDir="${SUPPORT_DIR}" done diff --git a/launch-game.cmd b/launch-game.cmd index b3cd456..b9479d6 100644 --- a/launch-game.cmd +++ b/launch-game.cmd @@ -16,7 +16,7 @@ if not exist %ENGINE_DIRECTORY%\bin\OpenRA.exe goto noengine >nul find %ENGINE_VERSION% %ENGINE_DIRECTORY%\VERSION || goto noengine cd %ENGINE_DIRECTORY% -bin\OpenRA.exe Game.Mod=%MOD_ID% Engine.EngineDir=".." Engine.LaunchPath="%TEMPLATE_LAUNCHER%" "Engine.ModSearchPaths=%MOD_SEARCH_PATHS%" "%*" +bin\OpenRA.exe Game.Mod=%MOD_ID% Engine.EngineDir=".." Engine.LaunchPath="%TEMPLATE_LAUNCHER%" Engine.ModSearchPaths="%MOD_SEARCH_PATHS%" "%*" set ERROR=%errorlevel% cd %TEMPLATE_DIR% diff --git a/launch-game.sh b/launch-game.sh index 1d2586f..e618427 100755 --- a/launch-game.sh +++ b/launch-game.sh @@ -1,7 +1,10 @@ #!/bin/sh set -e -command -v mono >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK requires mono."; exit 1; } +if ! command -v mono >/dev/null 2>&1; then + command -v dotnet >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK requires dotnet or mono."; exit 1; } +fi + if command -v python3 >/dev/null 2>&1; then PYTHON="python3" else @@ -36,11 +39,17 @@ fi require_variables "MOD_ID" "ENGINE_VERSION" "ENGINE_DIRECTORY" cd "${TEMPLATE_ROOT}" -if [ ! -f "${ENGINE_DIRECTORY}/bin/OpenRA.exe" ] || [ "$(cat "${ENGINE_DIRECTORY}/VERSION")" != "${ENGINE_VERSION}" ]; then +if [ ! -f "${ENGINE_DIRECTORY}/bin/OpenRA.dll" ] || [ "$(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 fi +if command -v mono >/dev/null 2>&1 && [ "$(grep -c .NETCoreApp,Version= ${ENGINE_DIRECTORY}/bin/OpenRA.dll)" = "0" ]; then + RUNTIME_LAUNCHER="mono --debug" +else + RUNTIME_LAUNCHER="dotnet" +fi + cd "${ENGINE_DIRECTORY}" -mono --debug bin/OpenRA.exe Engine.EngineDir=".." Engine.LaunchPath="${TEMPLATE_LAUNCHER}" "Engine.ModSearchPaths=${MOD_SEARCH_PATHS}" Game.Mod="${MOD_ID}" "$@" +${RUNTIME_LAUNCHER} bin/OpenRA.dll Game.Mod="${MOD_ID}" Engine.EngineDir=".." Engine.LaunchPath="${TEMPLATE_LAUNCHER}" Engine.ModSearchPaths="${MOD_SEARCH_PATHS}" "$@" diff --git a/make.ps1 b/make.ps1 index 4101b14..8bbdd37 100644 --- a/make.ps1 +++ b/make.ps1 @@ -7,6 +7,7 @@ function All-Command { If (!(Test-Path "*.sln")) { + Write-Host "No custom solution file found. Aborting." -ForegroundColor Red return } @@ -15,7 +16,9 @@ function All-Command return } - dotnet build /p:Configuration=Release /nologo + Write-Host "Building in" $configuration "configuration..." -ForegroundColor Cyan + dotnet build -c $configuration --nologo -p:TargetPlatform=win-x64 + if ($lastexitcode -ne 0) { Write-Host "Build failed. If just the development tools failed to build, try installing Visual Studio. You may also still be able to run the game." -ForegroundColor Red @@ -30,6 +33,7 @@ function Clean-Command { If (!(Test-Path "*.sln")) { + Write-Host "No custom solution file found - nothing to clean. Aborting." -ForegroundColor Red return } @@ -110,8 +114,10 @@ function Check-Command return } - Write-Host "Compiling in debug configuration..." -ForegroundColor Cyan - dotnet build /p:Configuration=Debug /nologo + Write-Host "Compiling in Debug configuration..." -ForegroundColor Cyan + + # Enabling EnforceCodeStyleInBuild and GenerateDocumentationFile as a workaround for some code style rules (in particular IDE0005) being bugged and not reporting warnings/errors otherwise. + dotnet build -c Debug --nologo -warnaserror -p:TargetPlatform=win-x64 -p:EnforceCodeStyleInBuild=true -p:GenerateDocumentationFile=true if ($lastexitcode -ne 0) { Write-Host "Build failed." -ForegroundColor Red @@ -119,9 +125,6 @@ function Check-Command if ((CheckForUtility) -eq 0) { - Write-Host "Checking runtime assemblies..." -ForegroundColor Cyan - InvokeCommand "$utilityPath $modID --check-runtime-assemblies $env:WHITELISTED_OPENRA_ASSEMBLIES $env:WHITELISTED_THIRDPARTY_ASSEMBLIES $env:WHITELISTED_CORE_ASSEMBLIES $env:WHITELISTED_MOD_ASSEMBLIES" - Write-Host "Checking for explicit interface violations..." -ForegroundColor Cyan InvokeCommand "$utilityPath $modID --check-explicit-interfaces" @@ -160,9 +163,9 @@ function CheckForUtility function CheckForDotnet { - if ((Get-Command "dotnet" -ErrorAction SilentlyContinue) -eq $null) + if ((Get-Command "dotnet" -ErrorAction SilentlyContinue) -eq $null) { - Write-Host "The 'dotnet' tool is required to compile OpenRA. Please install the .NET Core SDK or Visual Studio and try again. https://dotnet.microsoft.com/download" -ForegroundColor Red + Write-Host "The 'dotnet' tool is required to compile OpenRA. Please install the .NET 6.0 SDK and try again. https://dotnet.microsoft.com/download/dotnet/6.0" -ForegroundColor Red return 1 } @@ -171,7 +174,7 @@ function CheckForDotnet function WaitForInput { - echo "Press enter to continue." + Write-Host "Press enter to continue." while ($true) { if ([System.Console]::KeyAvailable) @@ -194,9 +197,7 @@ function ReadConfigLine($line, $name) function ParseConfigFile($fileName) { $names = @("MOD_ID", "ENGINE_VERSION", "AUTOMATIC_ENGINE_MANAGEMENT", "AUTOMATIC_ENGINE_SOURCE", - "AUTOMATIC_ENGINE_EXTRACT_DIRECTORY", "AUTOMATIC_ENGINE_TEMP_ARCHIVE_NAME", "ENGINE_DIRECTORY", - "WHITELISTED_OPENRA_ASSEMBLIES", "WHITELISTED_THIRDPARTY_ASSEMBLIES", "WHITELISTED_CORE_ASSEMBLIES", - "WHITELISTED_MOD_ASSEMBLIES") + "AUTOMATIC_ENGINE_EXTRACT_DIRECTORY", "AUTOMATIC_ENGINE_TEMP_ARCHIVE_NAME", "ENGINE_DIRECTORY") $reader = [System.IO.File]::OpenText($fileName) while($null -ne ($line = $reader.ReadLine())) @@ -219,12 +220,12 @@ function ParseConfigFile($fileName) if ($missing) { - echo "Required mod.config variables are missing:" + Write-Host "Required mod.config variables are missing:" foreach ($m in $missing) { - echo " $m" + Write-Host " $m" } - echo "Repair your mod.config (or user.config) and try again." + Write-Host "Repair your mod.config (or user.config) and try again." WaitForInput exit } @@ -249,24 +250,24 @@ function InvokeCommand ############################################################### if ($PSVersionTable.PSVersion.Major -clt 3) { - echo "The makefile requires PowerShell version 3 or higher." - echo "Please download and install the latest Windows Management Framework version from Microsoft." + Write-Host "The makefile requires PowerShell version 3 or higher." -ForegroundColor Red + Write-Host "Please download and install the latest Windows Management Framework version from Microsoft." -ForegroundColor Red WaitForInput } if ($args.Length -eq 0) { - echo "Command list:" - echo "" - echo " all Builds the game, its development tools and the mod dlls." - echo " version Sets the version strings for all mods to the latest" - echo " version for the current Git branch." - echo " clean Removes all built and copied files." - echo " from the mods and the engine directories." - echo " test Tests the mod's MiniYAML for errors." - echo " check Checks .cs files for StyleCop violations." - echo " check-scripts Checks .lua files for syntax errors." - echo "" + Write-Host "Command list:" + Write-Host "" + Write-Host " all Builds the game, its development tools and the mod dlls." + Write-Host " version Sets the version strings for all mods to the latest" + Write-Host " version for the current Git branch." + Write-Host " clean Removes all built and copied files." + Write-Host " from the mods and the engine directories." + Write-Host " test Tests the mod's MiniYAML for errors." + Write-Host " check Checks .cs files for StyleCop violations." + Write-Host " check-scripts Checks .lua files for syntax errors." + Write-Host "" $command = (Read-Host "Enter command").Split(' ', 2) } else @@ -308,34 +309,34 @@ if ($command -eq "all" -or $command -eq "clean" -or $command -eq "check") { cd $env:ENGINE_DIRECTORY Invoke-Expression ".\make.cmd $command" - echo "" + Write-Host "" cd $templateDir } elseif ($env:AUTOMATIC_ENGINE_MANAGEMENT -ne "True") { - echo "Automatic engine management is disabled." - echo "Please manually update the engine to version $env:ENGINE_VERSION." + Write-Host "Automatic engine management is disabled." + Write-Host "Please manually update the engine to version $env:ENGINE_VERSION." WaitForInput } else { - echo "OpenRA engine version $env:ENGINE_VERSION is required." + Write-Host "OpenRA engine version $env:ENGINE_VERSION is required." if (Test-Path $env:ENGINE_DIRECTORY) { if ($currentEngine -ne "") { - echo "Deleting engine version $currentEngine." + Write-Host "Deleting engine version $currentEngine." } else { - echo "Deleting existing engine (unknown version)." + Write-Host "Deleting existing engine (unknown version)." } rm $env:ENGINE_DIRECTORY -r } - echo "Downloading engine..." + Write-Host "Downloading engine..." if (Test-Path $env:AUTOMATIC_ENGINE_EXTRACT_DIRECTORY) { @@ -366,13 +367,19 @@ if ($command -eq "all" -or $command -eq "clean" -or $command -eq "check") cd $env:ENGINE_DIRECTORY Invoke-Expression ".\make.cmd version $env:ENGINE_VERSION" Invoke-Expression ".\make.cmd $command" - echo "" + Write-Host "" cd $templateDir } } $utilityPath = $env:ENGINE_DIRECTORY + "/bin/OpenRA.Utility.exe" +$configuration = "Release" +if ($args.Contains("CONFIGURATION=Debug")) +{ + $configuration = "Debug" +} + $execute = $command if ($command.Length -gt 1) { @@ -387,7 +394,7 @@ switch ($execute) "test" { Test-Command } "check" { Check-Command } "check-scripts" { Check-Scripts-Command } - Default { echo ("Invalid command '{0}'" -f $command) } + Default { Write-Host ("Invalid command '{0}'" -f $command) } } # In case the script was called without any parameters we keep the window open diff --git a/mod.config b/mod.config index 566e91c..2dc906f 100644 --- a/mod.config +++ b/mod.config @@ -11,9 +11,6 @@ MOD_ID="example" # The OpenRA engine version to use for this project. ENGINE_VERSION="release-20210321" -# .dll filenames compiled by the mod solution for use by the runtime assembly check -WHITELISTED_MOD_ASSEMBLIES="OpenRA.Mods.Example.dll" - ############################################################################## # Packaging # @@ -53,10 +50,6 @@ PACKAGING_FAQ_URL="http://wiki.openra.net/FAQ" # - Windows "Add/Remove Programs" list PACKAGING_AUTHORS="Example Mod authors" -# Space delimited list of dll files compiled by the mod, which -# should be copied from the bin directory into your installers -PACKAGING_COPY_MOD_BINARIES="OpenRA.Mods.Example.dll" - # If your mod depends on OpenRA.Mods.Cnc.dll from the engine set # this to "True" to package the dll in your installers. # Accepts values "True" or "False". @@ -72,9 +65,6 @@ PACKAGING_COPY_D2K_DLL="False" # and define the client id here and in your mod.yaml PACKAGING_DISCORD_APPID="" -# The git tag to use for the macOS Launcher files. -PACKAGING_OSX_MONO_TAG="osx-launcher-20200830" - # The macOS disk image icon positions, matched to the background artwork PACKAGING_OSX_DMG_MOD_ICON_POSITION="190, 210" PACKAGING_OSX_DMG_APPLICATION_ICON_POSITION="410, 210" @@ -93,9 +83,6 @@ PACKAGING_WINDOWS_REGISTRY_KEY="OpenRAExampleMod" # Path to the file containing the text to show in the Windows installer license dialog PACKAGING_WINDOWS_LICENSE_FILE="./COPYING" -# The git tag to use for the AppImage dependencies. -PACKAGING_APPIMAGE_DEPENDENCIES_TAG="20200328" - # Space delimited list of additional files/directories to copy from the engine directory # when packaging your mod. e.g. "./mods/modcontent" PACKAGING_COPY_ENGINE_FILES="" @@ -122,25 +109,3 @@ AUTOMATIC_ENGINE_SOURCE="https://github.com/OpenRA/OpenRA/archive/${ENGINE_VERSI AUTOMATIC_ENGINE_EXTRACT_DIRECTORY="./engine_temp" AUTOMATIC_ENGINE_TEMP_ARCHIVE_NAME="engine.zip" ENGINE_DIRECTORY="./engine" - -# The url to download the OpenRA macOS mono runtime. -PACKAGING_OSX_MONO_SOURCE="https://github.com/OpenRA/OpenRALauncherOSX/releases/download/${PACKAGING_OSX_MONO_TAG}/mono.zip" - -# Temporary file name used when downloading the OpenRA macOS launcher files. -PACKAGING_OSX_MONO_TEMP_ARCHIVE_NAME="mono.zip" - -# The url to download the OpenRA AppImage dependencies. -PACKAGING_APPIMAGE_DEPENDENCIES_SOURCE="https://github.com/OpenRA/AppImageSupport/releases/download/${PACKAGING_APPIMAGE_DEPENDENCIES_TAG}/mono.tar.bz2" - -# Temporary file name used when downloading the OpenRA AppImage dependencies. -PACKAGING_APPIMAGE_DEPENDENCIES_TEMP_ARCHIVE_NAME="mono.tar.bz2" - -# List of .NET assemblies that we can guarantee exist -WHITELISTED_OPENRA_ASSEMBLIES="OpenRA.exe OpenRA.Utility.exe OpenRA.Server.exe OpenRA.Platforms.Default.dll OpenRA.Game.dll OpenRA.Mods.Common.dll OpenRA.Mods.Cnc.dll OpenRA.Mods.D2k.dll" - -# These are explicitly shipped alongside our core files by the packaging script -WHITELISTED_THIRDPARTY_ASSEMBLIES="ICSharpCode.SharpZipLib.dll FuzzyLogicLibrary.dll Eluant.dll BeaconLib.dll Open.Nat.dll SDL2-CS.dll OpenAL-CS.Core.dll DiscordRPC.dll Newtonsoft.Json.dll" - -# These are shipped in our custom minimal mono runtime and also available in the full system-installed .NET/mono stack -# This list *must* be kept in sync with the files packaged by the AppImageSupport and OpenRALauncherOSX repositories -WHITELISTED_CORE_ASSEMBLIES="mscorlib.dll System.dll System.Configuration.dll System.Core.dll System.Numerics.dll System.Security.dll System.Xml.dll Mono.Security.dll netstandard.dll" diff --git a/packaging/functions.sh b/packaging/functions.sh new file mode 100644 index 0000000..514c98f --- /dev/null +++ b/packaging/functions.sh @@ -0,0 +1,53 @@ +#!/bin/sh +# Helper functions for packaging and installing projects using the OpenRA Mod SDK + +#### +# This file must stay /bin/sh and POSIX compliant for macOS and BSD portability. +# Copy-paste the entire script into http://shellcheck.net to check. +#### + +# Compile and publish any mod assemblies to the target directory +# Arguments: +# SRC_PATH: Path to the root SDK directory +# DEST_PATH: Path to the root of the install destination (will be created if necessary) +# TARGETPLATFORM: Platform type (win-x86, win-x64, osx-x64, osx-arm64, linux-x64, linux-arm64, unix-generic) +# RUNTIME: Runtime type (net6, mono) +# ENGINE_PATH: Path to the engine root directory +install_mod_assemblies() { + SRC_PATH="${1}" + DEST_PATH="${2}" + TARGETPLATFORM="${3}" + RUNTIME="${4}" + ENGINE_PATH="${5}" + + ORIG_PWD=$(pwd) + cd "${SRC_PATH}" || exit 1 + + if [ "${RUNTIME}" = "mono" ]; then + echo "Building assemblies" + + rm -rf "${ENGINE_PATH:?}/bin" + + find . -maxdepth 1 -name '*.sln' -exec msbuild -verbosity:m -nologo -t:Build -restore -p:Configuration=Release -p:TargetPlatform="${TARGETPLATFORM}" -p:Mono=true \; + + cd "${ORIG_PWD}" || exit 1 + for LIB in "${ENGINE_PATH}/bin/"*.dll "${ENGINE_PATH}/bin/"*.dll.config; do + install -m644 "${LIB}" "${DEST_PATH}" + done + + if [ "${TARGETPLATFORM}" = "linux-x64" ] || [ "${TARGETPLATFORM}" = "linux-arm64" ]; then + for LIB in "${ENGINE_PATH}/bin/"*.so; do + install -m755 "${LIB}" "${DEST_PATH}" + done + fi + + if [ "${TARGETPLATFORM}" = "osx-x64" ] || [ "${TARGETPLATFORM}" = "osx-arm64" ]; then + for LIB in "${ENGINE_PATH}/bin/"*.dylib; do + install -m755 "${LIB}" "${DEST_PATH}" + done + fi + else + find . -maxdepth 1 -name '*.sln' -exec dotnet publish -c Release -p:TargetPlatform="${TARGETPLATFORM}" -r "${TARGETPLATFORM}" -o "${DEST_PATH}" --self-contained true \; + cd "${ORIG_PWD}" || exit 1 + fi +} diff --git a/packaging/linux/buildpackage.sh b/packaging/linux/buildpackage.sh index bc9d559..be9fb19 100755 --- a/packaging/linux/buildpackage.sh +++ b/packaging/linux/buildpackage.sh @@ -4,7 +4,6 @@ set -e command -v make >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Linux packaging requires make."; exit 1; } command -v python3 >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Linux packaging requires python 3."; exit 1; } -command -v tar >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Linux packaging requires tar."; exit 1; } command -v curl >/dev/null 2>&1 || command -v wget > /dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Linux packaging requires curl or wget."; exit 1; } require_variables() { @@ -37,7 +36,6 @@ if [ -f "${TEMPLATE_ROOT}/user.config" ]; then fi require_variables "MOD_ID" "ENGINE_DIRECTORY" "PACKAGING_DISPLAY_NAME" "PACKAGING_INSTALLER_NAME" "PACKAGING_COPY_CNC_DLL" "PACKAGING_COPY_D2K_DLL" \ - "PACKAGING_APPIMAGE_DEPENDENCIES_TAG" "PACKAGING_APPIMAGE_DEPENDENCIES_SOURCE" "PACKAGING_APPIMAGE_DEPENDENCIES_TEMP_ARCHIVE_NAME" \ "PACKAGING_FAQ_URL" "PACKAGING_OVERWRITE_MOD_VERSION" TAG="$1" @@ -59,6 +57,7 @@ if [ ! -f "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/Makefile" ]; then fi . "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/functions.sh" +. "${TEMPLATE_ROOT}/packaging/functions.sh" if [ ! -d "${OUTPUTDIR}" ]; then echo "Output directory '${OUTPUTDIR}' does not exist."; @@ -66,7 +65,7 @@ if [ ! -d "${OUTPUTDIR}" ]; then fi echo "Building core files" -install_assemblies_mono "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${APPDIR}/usr/lib/openra" "linux-x64" "True" "${PACKAGING_COPY_CNC_DLL}" "${PACKAGING_COPY_D2K_DLL}" +install_assemblies "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${APPDIR}/usr/lib/openra" "linux-x64" "net6" "True" "${PACKAGING_COPY_CNC_DLL}" "${PACKAGING_COPY_D2K_DLL}" install_data "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${APPDIR}/usr/lib/openra" for f in ${PACKAGING_COPY_ENGINE_FILES}; do @@ -75,17 +74,10 @@ for f in ${PACKAGING_COPY_ENGINE_FILES}; do done echo "Building mod files" -pushd "${TEMPLATE_ROOT}" > /dev/null -make all -popd > /dev/null +install_mod_assemblies "${TEMPLATE_ROOT}" "${APPDIR}/usr/lib/openra" "linux-x64" "net6" "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" cp -Lr "${TEMPLATE_ROOT}/mods/"* "${APPDIR}/usr/lib/openra/mods" -for f in ${PACKAGING_COPY_MOD_BINARIES}; do - mkdir -p "${APPDIR}/usr/lib/openra/$(dirname "${f}")" - cp "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/bin/${f}" "${APPDIR}/usr/lib/openra/${f}" -done - set_engine_version "${ENGINE_VERSION}" "${APPDIR}/usr/lib/openra" if [ "${PACKAGING_OVERWRITE_MOD_VERSION}" == "True" ]; then set_mod_version "${TAG}" "${APPDIR}/usr/lib/openra/mods/${MOD_ID}/mod.yaml" @@ -95,27 +87,15 @@ else fi # Add native libraries -echo "Downloading dependencies" +echo "Downloading appimagetool" if command -v curl >/dev/null 2>&1; then - curl -s -L -o "${PACKAGING_APPIMAGE_DEPENDENCIES_TEMP_ARCHIVE_NAME}" -O "${PACKAGING_APPIMAGE_DEPENDENCIES_SOURCE}" || exit 3 curl -s -L -O https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage || exit 3 else - wget -cq "${PACKAGING_APPIMAGE_DEPENDENCIES_SOURCE}" -O "${PACKAGING_APPIMAGE_DEPENDENCIES_TEMP_ARCHIVE_NAME}" || exit 3 wget -cq https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage || exit 3 fi echo "Building AppImage" -tar xf "${PACKAGING_APPIMAGE_DEPENDENCIES_TEMP_ARCHIVE_NAME}" -C "${APPDIR}" -chmod 0755 "${APPDIR}/usr/bin/mono" -chmod 0644 "${APPDIR}/etc/mono/config" -chmod 0644 "${APPDIR}/etc/mono/4.5/machine.config" -chmod 0644 "${APPDIR}/usr/lib/mono/4.5/Facades/"*.dll -chmod 0644 "${APPDIR}/usr/lib/mono/4.5/"*.dll "${APPDIR}/usr/lib/mono/4.5/"*.exe -chmod 0755 "${APPDIR}/usr/lib/"*.so - -rm -rf "${PACKAGING_APPIMAGE_DEPENDENCIES_SOURCE}" - # Add launcher and icons sed "s/{MODID}/${MOD_ID}/g" "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/linux/AppRun.in" | sed "s/{MODNAME}/${PACKAGING_DISPLAY_NAME}/g" > "${APPDIR}/AppRun" chmod 0755 "${APPDIR}/AppRun" @@ -162,7 +142,6 @@ sed "s/{MODID}/${MOD_ID}/g" "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/linu chmod 0755 "${APPDIR}/usr/bin/openra-${MOD_ID}-utility" install -m 0755 "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/linux/gtk-dialog.py" "${APPDIR}/usr/bin/gtk-dialog.py" -install -m 0755 "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/linux/restore-environment.sh" "${APPDIR}/usr/bin/restore-environment.sh" chmod a+x appimagetool-x86_64.AppImage ARCH=x86_64 ./appimagetool-x86_64.AppImage "${APPDIR}" "${OUTPUTDIR}/${PACKAGING_INSTALLER_NAME}-${TAG}-x86_64.AppImage" diff --git a/packaging/macos/buildpackage.sh b/packaging/macos/buildpackage.sh index 59aa360..864fbc4 100755 --- a/packaging/macos/buildpackage.sh +++ b/packaging/macos/buildpackage.sh @@ -13,7 +13,7 @@ # MACOS_DEVELOPER_USERNAME: Email address for the developer account # MACOS_DEVELOPER_PASSWORD: App-specific password for the developer account # -set -e +set -o errexit -o pipefail || exit $? if [[ "$OSTYPE" != "darwin"* ]]; then echo >&2 "macOS packaging requires a macOS host" @@ -22,6 +22,7 @@ fi command -v make >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK macOS packaging requires make."; exit 1; } command -v python3 >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK macOS packaging requires python 3."; exit 1; } +command -v clang >/dev/null 2>&1 || { echo >&2 "macOS packaging requires clang."; exit 1; } require_variables() { missing="" @@ -35,8 +36,8 @@ require_variables() { fi } -if [ $# -eq "0" ]; then - echo "Usage: $(basename "$0") version [outputdir]" +if [ $# -ne "2" ]; then + echo "Usage: $(basename "$0") tag outputdir" exit 1 fi @@ -53,7 +54,6 @@ if [ -f "${TEMPLATE_ROOT}/user.config" ]; then fi require_variables "MOD_ID" "ENGINE_DIRECTORY" "PACKAGING_DISPLAY_NAME" "PACKAGING_INSTALLER_NAME" "PACKAGING_COPY_CNC_DLL" "PACKAGING_COPY_D2K_DLL" \ - "PACKAGING_OSX_MONO_TAG" "PACKAGING_OSX_MONO_SOURCE" "PACKAGING_OSX_MONO_TEMP_ARCHIVE_NAME" \ "PACKAGING_OSX_DMG_MOD_ICON_POSITION" "PACKAGING_OSX_DMG_APPLICATION_ICON_POSITION" "PACKAGING_OSX_DMG_HIDDEN_ICON_POSITION" \ "PACKAGING_FAQ_URL" "PACKAGING_OVERWRITE_MOD_VERSION" @@ -64,6 +64,7 @@ if [ ! -f "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/Makefile" ]; then fi . "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/functions.sh" +. "${TEMPLATE_ROOT}/packaging/functions.sh" # Import code signing certificate if [ -n "${MACOS_DEVELOPER_CERTIFICATE_BASE64}" ] && [ -n "${MACOS_DEVELOPER_CERTIFICATE_PASSWORD}" ] && [ -n "${MACOS_DEVELOPER_IDENTITY}" ]; then @@ -99,215 +100,161 @@ modify_plist() { sed "s|$1|$2|g" "$3" > "$3.tmp" && mv "$3.tmp" "$3" } -build_platform() { - PLATFORM="${1}" - DMG_NAME="${2}" - LAUNCHER_DIR="${BUILTDIR}/${PACKAGING_OSX_APP_NAME}" - LAUNCHER_CONTENTS_DIR="${LAUNCHER_DIR}/Contents" - LAUNCHER_MACOS_DIR="${LAUNCHER_CONTENTS_DIR}/MacOS" - LAUNCHER_RESOURCES_DIR="${LAUNCHER_CONTENTS_DIR}/Resources" +LAUNCHER_DIR="${BUILTDIR}/${PACKAGING_OSX_APP_NAME}" +LAUNCHER_CONTENTS_DIR="${LAUNCHER_DIR}/Contents" +LAUNCHER_ASSEMBLY_DIR="${LAUNCHER_CONTENTS_DIR}/MacOS" +LAUNCHER_RESOURCES_DIR="${LAUNCHER_CONTENTS_DIR}/Resources" - echo "Building launcher (${PLATFORM})" +echo "Building launcher" - mkdir -p "${LAUNCHER_RESOURCES_DIR}" - mkdir -p "${LAUNCHER_CONTENTS_DIR}/MacOS" - echo "APPL????" > "${LAUNCHER_CONTENTS_DIR}/PkgInfo" - cp "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/Info.plist.in" "${LAUNCHER_CONTENTS_DIR}/Info.plist" +mkdir -p "${LAUNCHER_RESOURCES_DIR}" +mkdir -p "${LAUNCHER_ASSEMBLY_DIR}/x86_64" +mkdir -p "${LAUNCHER_ASSEMBLY_DIR}/arm64" +mkdir -p "${LAUNCHER_ASSEMBLY_DIR}/mono" +echo "APPL????" > "${LAUNCHER_CONTENTS_DIR}/PkgInfo" +cp "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/Info.plist.in" "${LAUNCHER_CONTENTS_DIR}/Info.plist" - modify_plist "{DEV_VERSION}" "${TAG}" "${LAUNCHER_CONTENTS_DIR}/Info.plist" - modify_plist "{FAQ_URL}" "${PACKAGING_FAQ_URL}" "${LAUNCHER_CONTENTS_DIR}/Info.plist" - modify_plist "{MOD_ID}" "${MOD_ID}" "${LAUNCHER_CONTENTS_DIR}/Info.plist" - modify_plist "{MOD_NAME}" "${PACKAGING_DISPLAY_NAME}" "${LAUNCHER_CONTENTS_DIR}/Info.plist" - modify_plist "{JOIN_SERVER_URL_SCHEME}" "openra-${MOD_ID}-${TAG}" "${LAUNCHER_CONTENTS_DIR}/Info.plist" +modify_plist "{DEV_VERSION}" "${TAG}" "${LAUNCHER_CONTENTS_DIR}/Info.plist" +modify_plist "{FAQ_URL}" "${PACKAGING_FAQ_URL}" "${LAUNCHER_CONTENTS_DIR}/Info.plist" +modify_plist "{MOD_ID}" "${MOD_ID}" "${LAUNCHER_CONTENTS_DIR}/Info.plist" +modify_plist "{MINIMUM_SYSTEM_VERSION}" "10.11" "${LAUNCHER_CONTENTS_DIR}/Info.plist" +modify_plist "{MOD_NAME}" "${PACKAGING_DISPLAY_NAME}" "${LAUNCHER_CONTENTS_DIR}/Info.plist" +modify_plist "{JOIN_SERVER_URL_SCHEME}" "openra-${MOD_ID}-${TAG}" "${LAUNCHER_CONTENTS_DIR}/Info.plist" +if [ -n "${DISCORD_APPID}" ]; then + modify_plist "{DISCORD_URL_SCHEME}" "discord-${DISCORD_APPID}" "${LAUNCHER_CONTENTS_DIR}/Info.plist" +else + modify_plist "{DISCORD_URL_SCHEME}" "" "${LAUNCHER_CONTENTS_DIR}/Info.plist" +fi - if [ -n "${DISCORD_APPID}" ]; then - modify_plist "{DISCORD_URL_SCHEME}" "discord-${DISCORD_APPID}" "${LAUNCHER_CONTENTS_DIR}/Info.plist" - else - modify_plist "{DISCORD_URL_SCHEME}" "" "${LAUNCHER_CONTENTS_DIR}/Info.plist" - fi +# Compile universal (x86_64 + arm64) Launcher and arch-specific apphosts +clang "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/apphost.c" -o "${LAUNCHER_ASSEMBLY_DIR}/apphost-x86_64" -framework AppKit -target x86_64-apple-macos10.15 +clang "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/apphost.c" -o "${LAUNCHER_ASSEMBLY_DIR}/apphost-arm64" -framework AppKit -target arm64-apple-macos10.15 +clang "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/apphost-mono.c" -o "${LAUNCHER_ASSEMBLY_DIR}/apphost-mono" -framework AppKit -target x86_64-apple-macos10.11 +clang "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/checkmono.c" -o "${LAUNCHER_ASSEMBLY_DIR}/checkmono" -framework AppKit -target x86_64-apple-macos10.11 +clang "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/launcher.m" -o "${LAUNCHER_ASSEMBLY_DIR}/Launcher-x86_64" -framework AppKit -target x86_64-apple-macos10.11 +clang "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/launcher.m" -o "${LAUNCHER_ASSEMBLY_DIR}/Launcher-arm64" -framework AppKit -target arm64-apple-macos10.15 +lipo -create -output "${LAUNCHER_ASSEMBLY_DIR}/Launcher" "${LAUNCHER_ASSEMBLY_DIR}/Launcher-x86_64" "${LAUNCHER_ASSEMBLY_DIR}/Launcher-arm64" +rm "${LAUNCHER_ASSEMBLY_DIR}/Launcher-x86_64" "${LAUNCHER_ASSEMBLY_DIR}/Launcher-arm64" - if [ "${PLATFORM}" = "compat" ]; then - modify_plist "{MINIMUM_SYSTEM_VERSION}" "10.9" "${LAUNCHER_CONTENTS_DIR}/Info.plist" - clang -m64 "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/launcher-mono.m" -o "${LAUNCHER_MACOS_DIR}/OpenRA" -framework AppKit -mmacosx-version-min=10.9 - else - modify_plist "{MINIMUM_SYSTEM_VERSION}" "10.13" "${LAUNCHER_CONTENTS_DIR}/Info.plist" - clang -m64 "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/launcher.m" -o "${LAUNCHER_MACOS_DIR}/OpenRA" -framework AppKit -mmacosx-version-min=10.13 +install_assemblies "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${LAUNCHER_ASSEMBLY_DIR}/x86_64" "osx-x64" "net6" "True" "${PACKAGING_COPY_CNC_DLL}" "${PACKAGING_COPY_D2K_DLL}" +install_assemblies "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${LAUNCHER_ASSEMBLY_DIR}/arm64" "osx-arm64" "net6" "True" "${PACKAGING_COPY_CNC_DLL}" "${PACKAGING_COPY_D2K_DLL}" +install_assemblies "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${LAUNCHER_ASSEMBLY_DIR}/mono" "osx-x64" "mono" "True" "${PACKAGING_COPY_CNC_DLL}" "${PACKAGING_COPY_D2K_DLL}" +install_data "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${LAUNCHER_RESOURCES_DIR}" - curl -s -L -o "${PACKAGING_OSX_MONO_TEMP_ARCHIVE_NAME}" -O "${PACKAGING_OSX_MONO_SOURCE}" || exit 3 - unzip -qq -d "${BUILTDIR}" "${PACKAGING_OSX_MONO_TEMP_ARCHIVE_NAME}" - rm "${PACKAGING_OSX_MONO_TEMP_ARCHIVE_NAME}" +for f in ${PACKAGING_COPY_ENGINE_FILES}; do + mkdir -p "${LAUNCHER_RESOURCES_DIR}/$(dirname "${f}")" + cp -r "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/${f}" "${LAUNCHER_RESOURCES_DIR}/${f}" +done - mv "${BUILTDIR}/mono" "${LAUNCHER_MACOS_DIR}" - mv "${BUILTDIR}/etc" "${LAUNCHER_RESOURCES_DIR}" - mv "${BUILTDIR}/lib" "${LAUNCHER_RESOURCES_DIR}" - fi +echo "Building mod files" +install_mod_assemblies "${TEMPLATE_ROOT}" "${LAUNCHER_ASSEMBLY_DIR}/x86_64" "osx-x64" "net6" "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" +install_mod_assemblies "${TEMPLATE_ROOT}" "${LAUNCHER_ASSEMBLY_DIR}/arm64" "osx-arm64" "net6" "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" +install_mod_assemblies "${TEMPLATE_ROOT}" "${LAUNCHER_ASSEMBLY_DIR}/mono" "osx-x64" "mono" "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" - echo "Building core files" - install_assemblies_mono "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${LAUNCHER_RESOURCES_DIR}" "osx-x64" "True" "${PACKAGING_COPY_CNC_DLL}" "${PACKAGING_COPY_D2K_DLL}" - install_data "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${LAUNCHER_RESOURCES_DIR}" +cp -LR "${TEMPLATE_ROOT}mods/"* "${LAUNCHER_RESOURCES_DIR}/mods" - for f in ${PACKAGING_COPY_ENGINE_FILES}; do - mkdir -p "${LAUNCHER_RESOURCES_DIR}/$(dirname "${f}")" - cp -r "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/${f}" "${LAUNCHER_RESOURCES_DIR}/${f}" - done +set_engine_version "${ENGINE_VERSION}" "${LAUNCHER_RESOURCES_DIR}" +if [ "${PACKAGING_OVERWRITE_MOD_VERSION}" == "True" ]; then + set_mod_version "${TAG}" "${LAUNCHER_RESOURCES_DIR}/mods/${MOD_ID}/mod.yaml" +else + MOD_VERSION=$(grep 'Version:' "${LAUNCHER_RESOURCES_DIR}/mods/${MOD_ID}/mod.yaml" | awk '{print $2}') + echo "Mod version ${MOD_VERSION} will remain unchanged."; +fi - echo "Building mod files" - pushd "${TEMPLATE_ROOT}" > /dev/null - make all - popd > /dev/null +# Assemble multi-resolution icon +mkdir "${BUILTDIR}/mod.iconset" +cp "${ARTWORK_DIR}/icon_16x16.png" "${BUILTDIR}/mod.iconset/icon_16x16.png" +cp "${ARTWORK_DIR}/icon_32x32.png" "${BUILTDIR}/mod.iconset/icon_16x16@2.png" +cp "${ARTWORK_DIR}/icon_32x32.png" "${BUILTDIR}/mod.iconset/icon_32x32.png" +cp "${ARTWORK_DIR}/icon_64x64.png" "${BUILTDIR}/mod.iconset/icon_32x32@2x.png" +cp "${ARTWORK_DIR}/icon_128x128.png" "${BUILTDIR}/mod.iconset/icon_128x128.png" +cp "${ARTWORK_DIR}/icon_256x256.png" "${BUILTDIR}/mod.iconset/icon_128x128@2x.png" +cp "${ARTWORK_DIR}/icon_256x256.png" "${BUILTDIR}/mod.iconset/icon_256x256.png" +cp "${ARTWORK_DIR}/icon_512x512.png" "${BUILTDIR}/mod.iconset/icon_256x256@2x.png" +iconutil --convert icns "${BUILTDIR}/mod.iconset" -o "${LAUNCHER_RESOURCES_DIR}/${MOD_ID}.icns" +rm -rf "${BUILTDIR}/mod.iconset" - cp -LR "${TEMPLATE_ROOT}mods/"* "${LAUNCHER_RESOURCES_DIR}/mods" +# Sign binaries with developer certificate +if [ -n "${MACOS_DEVELOPER_IDENTITY}" ]; then + codesign -s "${MACOS_DEVELOPER_IDENTITY}" --timestamp --options runtime -f --entitlements "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/entitlements.plist" --deep "${LAUNCHER_DIR}" +fi - for f in ${PACKAGING_COPY_MOD_BINARIES}; do - mkdir -p "${LAUNCHER_RESOURCES_DIR}/$(dirname "${f}")" - cp "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/bin/${f}" "${LAUNCHER_RESOURCES_DIR}/${f}" - done +echo "Packaging disk image" +hdiutil create "build.dmg" -format UDRW -volname "${PACKAGING_DISPLAY_NAME}" -fs HFS+ -srcfolder "${BUILTDIR}" +DMG_DEVICE=$(hdiutil attach -readwrite -noverify -noautoopen "${PACKAGING_DIR}/build.dmg" | egrep '^/dev/' | sed 1q | awk '{print $1}') +sleep 2 - set_engine_version "${ENGINE_VERSION}" "${LAUNCHER_RESOURCES_DIR}" - if [ "${PACKAGING_OVERWRITE_MOD_VERSION}" == "True" ]; then - set_mod_version "${TAG}" "${LAUNCHER_RESOURCES_DIR}/mods/${MOD_ID}/mod.yaml" - else - MOD_VERSION=$(grep 'Version:' "${LAUNCHER_RESOURCES_DIR}/mods/${MOD_ID}/mod.yaml" | awk '{print $2}') - echo "Mod version ${MOD_VERSION} will remain unchanged."; - fi +# Background image is created from source svg in artsrc repository +mkdir "/Volumes/${PACKAGING_DISPLAY_NAME}/.background/" +tiffutil -cathidpicheck "${ARTWORK_DIR}/macos-background.png" "${ARTWORK_DIR}/macos-background-2x.png" -out "/Volumes/${PACKAGING_DISPLAY_NAME}/.background/background.tiff" - # Assemble multi-resolution icon - mkdir "${BUILTDIR}/mod.iconset" - cp "${ARTWORK_DIR}/icon_16x16.png" "${BUILTDIR}/mod.iconset/icon_16x16.png" - cp "${ARTWORK_DIR}/icon_32x32.png" "${BUILTDIR}/mod.iconset/icon_16x16@2.png" - cp "${ARTWORK_DIR}/icon_32x32.png" "${BUILTDIR}/mod.iconset/icon_32x32.png" - cp "${ARTWORK_DIR}/icon_64x64.png" "${BUILTDIR}/mod.iconset/icon_32x32@2x.png" - cp "${ARTWORK_DIR}/icon_128x128.png" "${BUILTDIR}/mod.iconset/icon_128x128.png" - cp "${ARTWORK_DIR}/icon_256x256.png" "${BUILTDIR}/mod.iconset/icon_128x128@2x.png" - cp "${ARTWORK_DIR}/icon_256x256.png" "${BUILTDIR}/mod.iconset/icon_256x256.png" - cp "${ARTWORK_DIR}/icon_512x512.png" "${BUILTDIR}/mod.iconset/icon_256x256@2x.png" - iconutil --convert icns "${BUILTDIR}/mod.iconset" -o "${LAUNCHER_RESOURCES_DIR}/${MOD_ID}.icns" - rm -rf "${BUILTDIR}/mod.iconset" +cp "${LAUNCHER_DIR}/Contents/Resources/${MOD_ID}.icns" "/Volumes/${PACKAGING_DISPLAY_NAME}/.VolumeIcon.icns" - # Sign binaries with developer certificate - if [ -n "${MACOS_DEVELOPER_IDENTITY}" ]; then - codesign -s "${MACOS_DEVELOPER_IDENTITY}" --timestamp --options runtime -f --entitlements "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/entitlements.plist" "${LAUNCHER_RESOURCES_DIR}/"*.dylib - codesign -s "${MACOS_DEVELOPER_IDENTITY}" --timestamp --options runtime -f --entitlements "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/macos/entitlements.plist" --deep "${LAUNCHER_DIR}" - fi +echo ' + tell application "Finder" + tell disk "'${PACKAGING_DISPLAY_NAME}'" + open + set current view of container window to icon view + set toolbar visible of container window to false + set statusbar visible of container window to false + set the bounds of container window to {400, 100, 1000, 550} + set theViewOptions to the icon view options of container window + set arrangement of theViewOptions to not arranged + set icon size of theViewOptions to 72 + set background picture of theViewOptions to file ".background:background.tiff" + make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"} + set position of item "'${PACKAGING_OSX_APP_NAME}'" of container window to {'${PACKAGING_OSX_DMG_MOD_ICON_POSITION}'} + set position of item "Applications" of container window to {'${PACKAGING_OSX_DMG_APPLICATION_ICON_POSITION}'} + set position of item ".background" of container window to {'${PACKAGING_OSX_DMG_HIDDEN_ICON_POSITION}'} + set position of item ".fseventsd" of container window to {'${PACKAGING_OSX_DMG_HIDDEN_ICON_POSITION}'} + set position of item ".VolumeIcon.icns" of container window to {'${PACKAGING_OSX_DMG_HIDDEN_ICON_POSITION}'} + update without registering applications + delay 5 + close + end tell + end tell +' | osascript - echo "Packaging disk image" - hdiutil create "${PACKAGING_DIR}/${DMG_NAME}" -format UDRW -volname "${PACKAGING_DISPLAY_NAME}" -fs HFS+ -srcfolder "${BUILTDIR}" - DMG_DEVICE=$(hdiutil attach -readwrite -noverify -noautoopen "${PACKAGING_DIR}/${DMG_NAME}" | egrep '^/dev/' | sed 1q | awk '{print $1}') - sleep 2 +# HACK: Copy the volume icon again - something in the previous step seems to delete it...? +cp "${LAUNCHER_DIR}/Contents/Resources/${MOD_ID}.icns" "/Volumes/${PACKAGING_DISPLAY_NAME}/.VolumeIcon.icns" +SetFile -c icnC "/Volumes/${PACKAGING_DISPLAY_NAME}/.VolumeIcon.icns" +SetFile -a C "/Volumes/${PACKAGING_DISPLAY_NAME}" - # Background image is created from source svg in artsrc repository - mkdir "/Volumes/${PACKAGING_DISPLAY_NAME}/.background/" - tiffutil -cathidpicheck "${ARTWORK_DIR}/macos-background.png" "${ARTWORK_DIR}/macos-background-2x.png" -out "/Volumes/${PACKAGING_DISPLAY_NAME}/.background/background.tiff" +chmod -Rf go-w "/Volumes/${PACKAGING_DISPLAY_NAME}" +sync +sync - cp "${LAUNCHER_DIR}/Contents/Resources/${MOD_ID}.icns" "/Volumes/${PACKAGING_DISPLAY_NAME}/.VolumeIcon.icns" - - echo ' - tell application "Finder" - tell disk "'${PACKAGING_DISPLAY_NAME}'" - open - set current view of container window to icon view - set toolbar visible of container window to false - set statusbar visible of container window to false - set the bounds of container window to {400, 100, 1000, 550} - set theViewOptions to the icon view options of container window - set arrangement of theViewOptions to not arranged - set icon size of theViewOptions to 72 - set background picture of theViewOptions to file ".background:background.tiff" - make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"} - set position of item "'${PACKAGING_OSX_APP_NAME}'" of container window to {'${PACKAGING_OSX_DMG_MOD_ICON_POSITION}'} - set position of item "Applications" of container window to {'${PACKAGING_OSX_DMG_APPLICATION_ICON_POSITION}'} - set position of item ".background" of container window to {'${PACKAGING_OSX_DMG_HIDDEN_ICON_POSITION}'} - set position of item ".fseventsd" of container window to {'${PACKAGING_OSX_DMG_HIDDEN_ICON_POSITION}'} - set position of item ".VolumeIcon.icns" of container window to {'${PACKAGING_OSX_DMG_HIDDEN_ICON_POSITION}'} - update without registering applications - delay 5 - close - end tell - end tell - ' | osascript - - # HACK: Copy the volume icon again - something in the previous step seems to delete it...? - cp "${LAUNCHER_DIR}/Contents/Resources/${MOD_ID}.icns" "/Volumes/${PACKAGING_DISPLAY_NAME}/.VolumeIcon.icns" - SetFile -c icnC "/Volumes/${PACKAGING_DISPLAY_NAME}/.VolumeIcon.icns" - SetFile -a C "/Volumes/${PACKAGING_DISPLAY_NAME}" - - chmod -Rf go-w "/Volumes/${PACKAGING_DISPLAY_NAME}" - sync - sync - - hdiutil detach "${DMG_DEVICE}" - rm -rf "${BUILTDIR}" -} - -notarize_package() { - DMG_PATH="${1}" - NOTARIZE_DMG_PATH="${DMG_PATH%.*}"-notarization.dmg - echo "Submitting ${DMG_PATH} for notarization" - - # Reset xcode search path to fix xcrun not finding altool - sudo xcode-select -r - - # Create a temporary read-only dmg for submission (notarization service rejects read/write images) - hdiutil convert "${DMG_PATH}" -format UDZO -imagekey zlib-level=9 -ov -o "${NOTARIZE_DMG_PATH}" - - NOTARIZATION_UUID=$(xcrun altool --notarize-app --primary-bundle-id "net.openra.modsdk" -u "${MACOS_DEVELOPER_USERNAME}" -p "${MACOS_DEVELOPER_PASSWORD}" --file "${NOTARIZE_DMG_PATH}" 2>&1 | awk -F' = ' '/RequestUUID/ { print $2; exit }') - if [ -z "${NOTARIZATION_UUID}" ]; then - echo "Submission failed" - exit 1 - fi - - echo "${DMG_PATH} submission UUID is ${NOTARIZATION_UUID}" - rm "${NOTARIZE_DMG_PATH}" - - while :; do - sleep 30 - NOTARIZATION_RESULT=$(xcrun altool --notarization-info "${NOTARIZATION_UUID}" -u "${MACOS_DEVELOPER_USERNAME}" -p "${MACOS_DEVELOPER_PASSWORD}" 2>&1 | awk -F': ' '/Status/ { print $2; exit }') - echo "${DMG_PATH}: ${NOTARIZATION_RESULT}" - - if [ "${NOTARIZATION_RESULT}" == "invalid" ]; then - NOTARIZATION_LOG_URL=$(xcrun altool --notarization-info "${NOTARIZATION_UUID}" -u "${MACOS_DEVELOPER_USERNAME}" -p "${MACOS_DEVELOPER_PASSWORD}" 2>&1 | awk -F': ' '/LogFileURL/ { print $2; exit }') - echo "${NOTARIZATION_UUID} failed notarization with error:" - curl -s "${NOTARIZATION_LOG_URL}" -w "\n" - exit 1 - fi - - if [ "${NOTARIZATION_RESULT}" == "success" ]; then - echo "${DMG_PATH}: Stapling tickets" - DMG_DEVICE=$(hdiutil attach -readwrite -noverify -noautoopen "${DMG_PATH}" | egrep '^/dev/' | sed 1q | awk '{print $1}') - sleep 2 - - xcrun stapler staple "/Volumes/${PACKAGING_DISPLAY_NAME}/${PACKAGING_OSX_APP_NAME}" - - sync - sync - - hdiutil detach "${DMG_DEVICE}" - break - fi - done -} - -finalize_package() { - DMG_PATH="${1}" - OUTPUT_PATH="${2}" - - hdiutil convert "${DMG_PATH}" -format UDZO -imagekey zlib-level=9 -ov -o "${OUTPUT_PATH}" - rm "${DMG_PATH}" -} - -build_platform "standard" "build.dmg" -build_platform "compat" "build-compat.dmg" +hdiutil detach "${DMG_DEVICE}" +rm -rf "${BUILTDIR}" if [ -n "${MACOS_DEVELOPER_CERTIFICATE_BASE64}" ] && [ -n "${MACOS_DEVELOPER_CERTIFICATE_PASSWORD}" ] && [ -n "${MACOS_DEVELOPER_IDENTITY}" ]; then security delete-keychain build.keychain fi -if [ -n "${MACOS_DEVELOPER_USERNAME}" ] && [ -n "${MACOS_DEVELOPER_PASSWORD}" ]; then - # Parallelize processing - (notarize_package "build.dmg") & - (notarize_package "build-compat.dmg") & - wait +if [ -n "${MACOS_DEVELOPER_USERNAME}" ] && [ -n "${MACOS_DEVELOPER_PASSWORD}" ] && [ -n "${MACOS_DEVELOPER_IDENTITY}" ]; then + echo "Submitting build for notarization" + + # Reset xcode search path to fix xcrun not finding altool + sudo xcode-select -r + + # Create a temporary read-only dmg for submission (notarization service rejects read/write images) + hdiutil convert "build.dmg" -format ULFO -ov -o "build-notarization.dmg" + + xcrun notarytool submit "build-notarization.dmg" --wait --apple-id "${MACOS_DEVELOPER_USERNAME}" --password "${MACOS_DEVELOPER_PASSWORD}" --team-id "${MACOS_DEVELOPER_IDENTITY}" + + rm "build-notarization.dmg" + + echo "Stapling tickets" + DMG_DEVICE=$(hdiutil attach -readwrite -noverify -noautoopen "build.dmg" | egrep '^/dev/' | sed 1q | awk '{print $1}') + sleep 2 + + xcrun stapler staple "/Volumes/${PACKAGING_DISPLAY_NAME}/${PACKAGING_OSX_APP_NAME}" + + sync + sync + + hdiutil detach "${DMG_DEVICE}" fi -finalize_package "build.dmg" "${OUTPUTDIR}/${PACKAGING_INSTALLER_NAME}-${TAG}.dmg" -finalize_package "build-compat.dmg" "${OUTPUTDIR}/${PACKAGING_INSTALLER_NAME}-${TAG}-compat.dmg" +hdiutil convert "build.dmg" -format ULFO -ov -o "${OUTPUTDIR}/${PACKAGING_INSTALLER_NAME}-${TAG}.dmg" +rm "build.dmg" \ No newline at end of file diff --git a/packaging/windows/buildpackage.nsi b/packaging/windows/buildpackage.nsi index 67dd433..1f7de30 100644 --- a/packaging/windows/buildpackage.nsi +++ b/packaging/windows/buildpackage.nsi @@ -93,14 +93,16 @@ Section "Game" GAME SetOutPath "$INSTDIR" File "${SRCDIR}\*.exe" - File "${SRCDIR}\*.exe.config" + File "${SRCDIR}\*.dll.config" File "${SRCDIR}\*.dll" File "${SRCDIR}\*.ico" + File "${SRCDIR}\*.deps.json" + File "${SRCDIR}\*.runtimeconfig.json" + File "${SRCDIR}\global mix database.dat" + File "${SRCDIR}\IP2LOCATION-LITE-DB1.IPV6.BIN.ZIP" File "${SRCDIR}\VERSION" File "${SRCDIR}\AUTHORS" File "${SRCDIR}\COPYING" - File "${SRCDIR}\global mix database.dat" - File "${SRCDIR}\IP2LOCATION-LITE-DB1.IPV6.BIN.ZIP" File /r "${SRCDIR}\mods" !insertmacro MUI_STARTMENU_WRITE_BEGIN Application @@ -123,6 +125,7 @@ Section "Game" GAME SetShellVarContext all CreateDirectory "$APPDATA\OpenRA\ModMetadata" + SetOutPath "$INSTDIR" nsExec::ExecToLog '"$INSTDIR\OpenRA.Utility.exe" ${MOD_ID} --register-mod "$INSTDIR\${PACKAGING_WINDOWS_LAUNCHER_NAME}.exe" system' nsExec::ExecToLog '"$INSTDIR\OpenRA.Utility.exe" ${MOD_ID} --clear-invalid-mod-registrations system' SetShellVarContext current @@ -135,21 +138,6 @@ Section "Desktop Shortcut" DESKTOPSHORTCUT "$INSTDIR\${PACKAGING_WINDOWS_LAUNCHER_NAME}.exe" "" "" "" "" SectionEnd -;*************************** -;Dependency Sections -;*************************** -Section "-DotNet" DotNet - ClearErrors - ; https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed - ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" "Release" - IfErrors error 0 - IntCmp $0 461808 done error done - error: - MessageBox MB_OK ".NET Framework v4.7.2 or later is required to run OpenRA." - Abort - done: -SectionEnd - ;*************************** ;Uninstaller Sections ;*************************** @@ -176,14 +164,17 @@ Function ${UN}Clean RMDir /r $INSTDIR\glsl RMDir /r $INSTDIR\lua Delete $INSTDIR\*.exe - Delete $INSTDIR\*.exe.config Delete $INSTDIR\*.dll Delete $INSTDIR\*.ico + Delete $INSTDIR\*.dll.config + Delete $INSTDIR\*.deps.json + Delete $INSTDIR\*.runtimeconfig.json Delete $INSTDIR\VERSION Delete $INSTDIR\AUTHORS Delete $INSTDIR\COPYING Delete "$INSTDIR\global mix database.dat" Delete $INSTDIR\IP2LOCATION-LITE-DB1.IPV6.BIN.ZIP + RMDir /r $INSTDIR\Support !ifndef USE_PROGRAMFILES32 @@ -194,7 +185,7 @@ Function ${UN}Clean DeleteRegKey HKLM "Software\Classes\openra-${MOD_ID}-${TAG}" !ifdef USE_DISCORDID - DeleteRegKey HKLM "Software\Classes\discord-${DISCORD_APP_ID}" + DeleteRegKey HKLM "Software\Classes\discord-${USE_DISCORDID}" !endif Delete $INSTDIR\uninstaller.exe diff --git a/packaging/windows/buildpackage.sh b/packaging/windows/buildpackage.sh index 548bd65..a5fbcee 100755 --- a/packaging/windows/buildpackage.sh +++ b/packaging/windows/buildpackage.sh @@ -1,8 +1,10 @@ #!/bin/bash set -e +command -v curl >/dev/null 2>&1 || command -v wget > /dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Windows packaging requires curl or wget."; exit 1; } command -v makensis >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Windows packaging requires makensis."; exit 1; } command -v convert >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Windows packaging requires ImageMagick."; exit 1; } command -v python3 >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Windows packaging requires python 3."; exit 1; } +command -v wine64 >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK Windows packaging requires wine64."; exit 1; } require_variables() { missing="" @@ -56,12 +58,19 @@ if [ ! -f "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/Makefile" ]; then fi . "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/packaging/functions.sh" +. "${TEMPLATE_ROOT}/packaging/functions.sh" if [ ! -d "${OUTPUTDIR}" ]; then echo "Output directory '${OUTPUTDIR}' does not exist."; exit 1 fi +if command -v curl >/dev/null 2>&1; then + curl -s -L -O https://github.com/electron/rcedit/releases/download/v1.1.1/rcedit-x64.exe || exit 3 +else + wget -cq https://github.com/electron/rcedit/releases/download/v1.1.1/rcedit-x64.exe || exit 3 +fi + function build_platform() { PLATFORM="${1}" @@ -78,7 +87,7 @@ function build_platform() fi echo "Building core files (${PLATFORM})" - install_assemblies_mono "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${BUILTDIR}" "win-${PLATFORM}" "False" "${PACKAGING_COPY_CNC_DLL}" "${PACKAGING_COPY_D2K_DLL}" + install_assemblies "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${BUILTDIR}" "win-${PLATFORM}" "net6" "False" "${PACKAGING_COPY_CNC_DLL}" "${PACKAGING_COPY_D2K_DLL}" install_data "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${BUILTDIR}" for f in ${PACKAGING_COPY_ENGINE_FILES}; do @@ -87,17 +96,10 @@ function build_platform() done echo "Building mod files (${PLATFORM})" - pushd "${TEMPLATE_ROOT}" > /dev/null - make all - popd > /dev/null + install_mod_assemblies "${TEMPLATE_ROOT}" "${BUILTDIR}" "win-${PLATFORM}" "net6" "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" cp -Lr "${TEMPLATE_ROOT}/mods/"* "${BUILTDIR}/mods" - for f in ${PACKAGING_COPY_MOD_BINARIES}; do - mkdir -p "${BUILTDIR}/$(dirname "${f}")" - cp "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}/bin/${f}" "${BUILTDIR}/${f}" - done - set_engine_version "${ENGINE_VERSION}" "${BUILTDIR}" if [ "${PACKAGING_OVERWRITE_MOD_VERSION}" == "True" ]; then set_mod_version "${TAG}" "${BUILTDIR}/mods/${MOD_ID}/mod.yaml" @@ -110,7 +112,9 @@ function build_platform() convert "${ARTWORK_DIR}/icon_16x16.png" "${ARTWORK_DIR}/icon_24x24.png" "${ARTWORK_DIR}/icon_32x32.png" "${ARTWORK_DIR}/icon_48x48.png" "${ARTWORK_DIR}/icon_256x256.png" "${BUILTDIR}/${MOD_ID}.ico" echo "Compiling Windows launcher (${PLATFORM})" - install_windows_launcher "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${BUILTDIR}" "win-${PLATFORM}" "${MOD_ID}" "${PACKAGING_WINDOWS_LAUNCHER_NAME}" "${PACKAGING_DISPLAY_NAME}" "${BUILTDIR}/${MOD_ID}.ico" "${PACKAGING_FAQ_URL}" + install_windows_launcher "${TEMPLATE_ROOT}/${ENGINE_DIRECTORY}" "${BUILTDIR}" "win-${PLATFORM}" "${MOD_ID}" "${PACKAGING_WINDOWS_LAUNCHER_NAME}" "${PACKAGING_DISPLAY_NAME}" "${PACKAGING_FAQ_URL}" + + wine64 rcedit-x64.exe "${BUILTDIR}/${PACKAGING_WINDOWS_LAUNCHER_NAME}.exe" --set-icon "${BUILTDIR}/${MOD_ID}.ico" echo "Building Windows setup.exe (${PLATFORM})" pushd "${PACKAGING_DIR}" > /dev/null diff --git a/utility.sh b/utility.sh index 1f7b38d..34af2ae 100755 --- a/utility.sh +++ b/utility.sh @@ -5,7 +5,10 @@ set -e command -v make >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK requires make."; exit 1; } -command -v mono >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK requires mono."; exit 1; } + +if ! command -v mono >/dev/null 2>&1; then + command -v dotnet >/dev/null 2>&1 || { echo >&2 "The OpenRA mod SDK requires dotnet or mono."; exit 1; } +fi if command -v python3 >/dev/null 2>&1; then PYTHON="python3" @@ -43,11 +46,17 @@ require_variables "MOD_ID" "ENGINE_VERSION" "ENGINE_DIRECTORY" LAUNCH_MOD="${Mod:-"${MOD_ID}"}" cd "${TEMPLATE_ROOT}" -if [ ! -f "${ENGINE_DIRECTORY}/bin/OpenRA.Utility.exe" ] || [ "$(cat "${ENGINE_DIRECTORY}/VERSION")" != "${ENGINE_VERSION}" ]; then +if [ ! -f "${ENGINE_DIRECTORY}/bin/OpenRA.Utility.dll" ] || [ "$(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 fi +if command -v mono >/dev/null 2>&1 && [ "$(grep -c .NETCoreApp,Version= ${ENGINE_DIRECTORY}/bin/OpenRA.Utility.dll)" = "0" ]; then + RUNTIME_LAUNCHER="mono --debug" +else + RUNTIME_LAUNCHER="dotnet" +fi + cd "${ENGINE_DIRECTORY}" -MOD_SEARCH_PATHS="${MOD_SEARCH_PATHS}" ENGINE_DIR=".." mono --debug bin/OpenRA.Utility.exe "${LAUNCH_MOD}" "$@" +MOD_SEARCH_PATHS="${MOD_SEARCH_PATHS}" ENGINE_DIR=".." ${RUNTIME_LAUNCHER} bin/OpenRA.Utility.dll "${LAUNCH_MOD}" "$@"