Eradicate ☠ Mono ☠
Co-Authored-By: Gustas <37534529+punkpun@users.noreply.github.com>
This commit is contained in:
1
.github/ISSUE_TEMPLATE/crash-report.md
vendored
1
.github/ISSUE_TEMPLATE/crash-report.md
vendored
@@ -16,7 +16,6 @@ assignees: ''
|
||||
- OpenRA Version: ENGINE VERSION
|
||||
- OpenRA Mod: GAME MOD
|
||||
- Source: Official download package OR self-compiled OR third-party package
|
||||
- For self-compiled or third-party packages: Mono version
|
||||
|
||||
|
||||
## Exception log
|
||||
|
||||
18
.github/workflows/ci.yml
vendored
18
.github/workflows/ci.yml
vendored
@@ -33,24 +33,6 @@ jobs:
|
||||
make check-scripts
|
||||
make TREAT_WARNINGS_AS_ERRORS=true test
|
||||
|
||||
linux-mono:
|
||||
name: Linux (mono)
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- name: Clone Repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Check Code
|
||||
run: |
|
||||
mono --version
|
||||
make RUNTIME=mono check
|
||||
|
||||
- name: Check Mods
|
||||
run: |
|
||||
# check-scripts does not depend on .net/mono, so is not needed here
|
||||
make RUNTIME=mono TREAT_WARNINGS_AS_ERRORS=true test
|
||||
|
||||
windows:
|
||||
name: Windows (.NET 6.0)
|
||||
runs-on: windows-2019
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -25,10 +25,6 @@ IP2LOCATION-LITE-DB1.IPV6.BIN.ZIP
|
||||
\#*
|
||||
.*.sw?
|
||||
|
||||
# Monodevelop
|
||||
*.pidb
|
||||
*.userprefs
|
||||
|
||||
# Mac OS X
|
||||
.DS_Store
|
||||
|
||||
|
||||
@@ -18,8 +18,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework Condition="'$(MSBuildRuntimeType)'!='Mono'">net6.0</TargetFramework>
|
||||
<TargetFramework Condition="'$(MSBuildRuntimeType)'=='Mono'">netstandard2.1</TargetFramework>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
@@ -54,8 +53,7 @@
|
||||
<!-- StyleCop/Roslynator -->
|
||||
<ItemGroup>
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.435" PrivateAssets="All" />
|
||||
<!-- Roslynator analyzers fail to run under Mono (AD0001) -->
|
||||
<PackageReference Include="Roslynator.Analyzers" Version="4.2.0" PrivateAssets="All" Condition="'$(MSBuildRuntimeType)'!='Mono'" />
|
||||
<PackageReference Include="Roslynator.Formatting.Analyzers" Version="4.2.0" PrivateAssets="All" Condition="'$(MSBuildRuntimeType)'!='Mono'" />
|
||||
<PackageReference Include="Roslynator.Analyzers" Version="4.2.0" PrivateAssets="All" />
|
||||
<PackageReference Include="Roslynator.Formatting.Analyzers" Version="4.2.0" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
10
INSTALL.md
10
INSTALL.md
@@ -17,11 +17,9 @@ Run the game with `launch-game.cmd`. It can be handed arguments that specify the
|
||||
Linux
|
||||
=====
|
||||
|
||||
.NET 6 or Mono (version 6.12 or later) is required to compile OpenRA. We recommend using .NET 6 when possible, as Mono is poorly packaged by most Linux distributions (e.g. missing the required `msbuild` toolchain), and has been deprecated as a standalone project.
|
||||
.NET 6 is required to compile OpenRA. The [.NET 6 download page](https://dotnet.microsoft.com/download/dotnet/6.0) provides repositories for various package managers and binary releases for several architectures.
|
||||
|
||||
The [.NET 6 download page](https://dotnet.microsoft.com/download/dotnet/6.0) provides repositories for various package managers and binary releases for several architectures. If you prefer to use Mono, we suggest adding the [upstream repository](https://www.mono-project.com/download/stable/#download-lin) for your distro to obtain the latest version and the `msbuild` toolchain.
|
||||
|
||||
To compile OpenRA, run `make` from the command line (or `make RUNTIME=mono` if using Mono). After this one can run the game with `./launch-game.sh`. It is also possible to specify the mod you wish to run from the command line, e.g. with `./launch-game.sh Game.Mod=ts` if you wish to try the experimental Tiberian Sun mod.
|
||||
To compile OpenRA, run `make` from the command line. After this one can run the game with `./launch-game.sh`. It is also possible to specify the mod you wish to run from the command line, e.g. with `./launch-game.sh Game.Mod=ts` if you wish to try the experimental Tiberian Sun mod.
|
||||
|
||||
The default behaviour on the x86_64 architecture is to download several pre-compiled native libraries using the Nuget packaging manager. If you prefer to use system libraries, compile instead using `make TARGETPLATFORM=unix-generic`.
|
||||
|
||||
@@ -78,6 +76,6 @@ Type `sudo make install` for system-wide installation. Run `sudo make install-li
|
||||
macOS
|
||||
=====
|
||||
|
||||
[.NET 6](https://dotnet.microsoft.com/download/dotnet/6.0) or [Mono](https://www.mono-project.com/download/stable/#download-mac) (version 6.12 or later) is required to compile OpenRA. We recommend using .NET 6 unless you are running a very old version of macOS (10.9 through 10.14).
|
||||
[.NET 6](https://dotnet.microsoft.com/download/dotnet/6.0) is required to compile OpenRA.
|
||||
|
||||
To compile OpenRA, run `make` from the command line (or `make RUNTIME=mono` if using Mono). Run with `./launch-game.sh`.
|
||||
To compile OpenRA, run `make` from the command line. Run with `./launch-game.sh`.
|
||||
|
||||
38
Makefile
38
Makefile
@@ -3,20 +3,17 @@
|
||||
# to compile, run:
|
||||
# make
|
||||
#
|
||||
# to compile using Mono (version 6.12 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
|
||||
# make TARGETPLATFORM=unix-generic
|
||||
#
|
||||
# to check the official mods for erroneous yaml files, run:
|
||||
# make [RUNTIME=net6] test
|
||||
# make test
|
||||
#
|
||||
# to check the engine and official mod dlls for code style violations, run:
|
||||
# make [RUNTIME=net6] check
|
||||
# make check
|
||||
#
|
||||
# to compile and install Red Alert, Tiberian Dawn, and Dune 2000, run:
|
||||
# make [RUNTIME=net6] [prefix=/foo] [bindir=/bar/bin] install
|
||||
# make [prefix=/foo] [bindir=/bar/bin] install
|
||||
#
|
||||
# to compile and install Red Alert, Tiberian Dawn, and Dune 2000
|
||||
# using system libraries for native dependencies, run:
|
||||
@@ -50,13 +47,11 @@ gameinstalldir ?= $(libdir)/openra
|
||||
CWD = $(shell pwd)
|
||||
MSBUILD = msbuild -verbosity:m -nologo
|
||||
DOTNET = dotnet
|
||||
MONO = mono
|
||||
RM = rm
|
||||
RM_R = $(RM) -r
|
||||
RM_F = $(RM) -f
|
||||
RM_RF = $(RM) -rf
|
||||
|
||||
RUNTIME ?= net6
|
||||
CONFIGURATION ?= Release
|
||||
DOTNET_RID = $(shell ${DOTNET} --info | grep RID: | cut -w -f3)
|
||||
ARCH_X64 = $(shell echo ${DOTNET_RID} | grep x64)
|
||||
@@ -91,18 +86,12 @@ endif
|
||||
#
|
||||
all:
|
||||
@echo "Compiling in ${CONFIGURATION} mode..."
|
||||
ifeq ($(RUNTIME), mono)
|
||||
@command -v $(firstword $(MSBUILD)) >/dev/null || (echo "OpenRA requires the '$(MSBUILD)' tool provided by Mono >= 6.12."; exit 1)
|
||||
@$(MSBUILD) -t:Build -restore -p:Configuration=${CONFIGURATION} -p:TargetPlatform=$(TARGETPLATFORM)
|
||||
else
|
||||
@$(DOTNET) build -c ${CONFIGURATION} -nologo -p:TargetPlatform=$(TARGETPLATFORM)
|
||||
endif
|
||||
ifeq ($(TARGETPLATFORM), unix-generic)
|
||||
@./configure-system-libraries.sh
|
||||
endif
|
||||
@./fetch-geoip.sh
|
||||
|
||||
# dotnet clean and msbuild -t:Clean leave files that cause problems when switching between mono/dotnet
|
||||
# Deleting the intermediate / output directories ensures the build directory is actually clean
|
||||
clean:
|
||||
@-$(RM_RF) ./bin ./*/obj
|
||||
@@ -111,12 +100,8 @@ clean:
|
||||
check:
|
||||
@echo
|
||||
@echo "Compiling in Debug mode..."
|
||||
ifeq ($(RUNTIME), mono)
|
||||
@$(MSBUILD) -t:clean\;build -restore -p:Configuration=Debug -warnaserror -p:TargetPlatform=$(TARGETPLATFORM)
|
||||
else
|
||||
@$(DOTNET) clean -c Debug --nologo --verbosity minimal
|
||||
@$(DOTNET) build -c Debug -nologo -warnaserror -p:TargetPlatform=$(TARGETPLATFORM)
|
||||
endif
|
||||
ifeq ($(TARGETPLATFORM), unix-generic)
|
||||
@./configure-system-libraries.sh
|
||||
endif
|
||||
@@ -161,7 +146,7 @@ endif
|
||||
@sh -c '. ./packaging/functions.sh; set_mod_version "$(VERSION)" mods/*/mod.yaml'
|
||||
|
||||
install:
|
||||
@sh -c '. ./packaging/functions.sh; install_assemblies $(CWD) $(DESTDIR)$(gameinstalldir) $(TARGETPLATFORM) $(RUNTIME) True True True'
|
||||
@sh -c '. ./packaging/functions.sh; install_assemblies $(CWD) $(DESTDIR)$(gameinstalldir) $(TARGETPLATFORM) True True True'
|
||||
@sh -c '. ./packaging/functions.sh; install_data $(CWD) $(DESTDIR)$(gameinstalldir) cnc d2k ra'
|
||||
|
||||
install-linux-shortcuts:
|
||||
@@ -178,24 +163,21 @@ help:
|
||||
@echo 'to compile, run:'
|
||||
@echo ' make'
|
||||
@echo
|
||||
@echo 'to compile using Mono (version 6.12 or greater) instead of .NET 6, run:'
|
||||
@echo ' make RUNTIME=mono'
|
||||
@echo
|
||||
@echo 'to compile using system libraries for native dependencies, run:'
|
||||
@echo ' make [RUNTIME=net6] TARGETPLATFORM=unix-generic'
|
||||
@echo ' make TARGETPLATFORM=unix-generic'
|
||||
@echo
|
||||
@echo 'to check the official mods for erroneous yaml files, run:'
|
||||
@echo ' make [RUNTIME=net6] [TREAT_WARNINGS_AS_ERRORS=false] test'
|
||||
@echo ' make [TREAT_WARNINGS_AS_ERRORS=false] test'
|
||||
@echo
|
||||
@echo 'to check the engine and official mod dlls for code style violations, run:'
|
||||
@echo ' make [RUNTIME=net6] check'
|
||||
@echo ' make check'
|
||||
@echo
|
||||
@echo 'to compile and install Red Alert, Tiberian Dawn, and Dune 2000 run:'
|
||||
@echo ' make [RUNTIME=net6] [prefix=/foo] [TARGETPLATFORM=unix-generic] install'
|
||||
@echo ' make [prefix=/foo] [TARGETPLATFORM=unix-generic] install'
|
||||
@echo
|
||||
@echo 'to compile and install Red Alert, Tiberian Dawn, and Dune 2000'
|
||||
@echo 'using system libraries for native dependencies, run:'
|
||||
@echo ' make [RUNTIME=net6] [prefix=/foo] [bindir=/bar/bin] TARGETPLATFORM=unix-generic install'
|
||||
@echo ' make [prefix=/foo] [bindir=/bar/bin] TARGETPLATFORM=unix-generic install'
|
||||
@echo
|
||||
@echo 'to install FreeDesktop startup scripts, desktop files, icons, and MIME metadata'
|
||||
@echo ' make install-linux-shortcuts'
|
||||
|
||||
@@ -14,6 +14,7 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Support;
|
||||
@@ -119,17 +120,11 @@ namespace OpenRA
|
||||
|
||||
public static V GetOrAdd<K, V>(this Dictionary<K, V> d, K k, V v)
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
// SAFETY: Dictionary cannot be modified whilst the ref is alive.
|
||||
ref var value = ref System.Runtime.InteropServices.CollectionsMarshal.GetValueRefOrAddDefault(d, k, out var exists);
|
||||
ref var value = ref CollectionsMarshal.GetValueRefOrAddDefault(d, k, out var exists);
|
||||
if (!exists)
|
||||
value = v;
|
||||
return value;
|
||||
#else
|
||||
if (!d.TryGetValue(k, out var ret))
|
||||
d.Add(k, ret = v);
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static V GetOrAdd<K, V>(this Dictionary<K, V> d, K k, Func<K, V> createFn)
|
||||
@@ -510,39 +505,6 @@ namespace OpenRA
|
||||
return result;
|
||||
}
|
||||
|
||||
public static T[,] ResizeArray<T>(T[,] ts, T t, int width, int height)
|
||||
{
|
||||
var result = new T[width, height];
|
||||
for (var i = 0; i < width; i++)
|
||||
{
|
||||
for (var j = 0; j < height; j++)
|
||||
{
|
||||
// Workaround for broken ternary operators in certain versions of mono
|
||||
// (3.10 and certain versions of the 3.8 series): https://bugzilla.xamarin.com/show_bug.cgi?id=23319
|
||||
if (i <= ts.GetUpperBound(0) && j <= ts.GetUpperBound(1))
|
||||
result[i, j] = ts[i, j];
|
||||
else
|
||||
result[i, j] = t;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int ToBits(this IEnumerable<bool> bits)
|
||||
{
|
||||
var i = 0;
|
||||
var result = 0;
|
||||
foreach (var b in bits)
|
||||
if (b)
|
||||
result |= 1 << i++;
|
||||
else
|
||||
i++;
|
||||
if (i > 33)
|
||||
throw new InvalidOperationException("ToBits only accepts up to 32 values.");
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte ParseByteInvariant(string s)
|
||||
{
|
||||
return byte.Parse(s, NumberStyles.Integer, NumberFormatInfo.InvariantInfo);
|
||||
|
||||
@@ -429,16 +429,9 @@ namespace OpenRA
|
||||
{
|
||||
var rendererPath = Path.Combine(Platform.BinDir, "OpenRA.Platforms." + platformName + ".dll");
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
var loader = new AssemblyLoader(rendererPath);
|
||||
var platformType = loader.LoadDefaultAssembly().GetTypes().SingleOrDefault(t => typeof(IPlatform).IsAssignableFrom(t));
|
||||
|
||||
#else
|
||||
// NOTE: This is currently the only use of System.Reflection in this file, so would give an unused using error if we import it above
|
||||
var assembly = System.Reflection.Assembly.LoadFile(rendererPath);
|
||||
var platformType = assembly.GetTypes().SingleOrDefault(t => typeof(IPlatform).IsAssignableFrom(t));
|
||||
#endif
|
||||
|
||||
if (platformType == null)
|
||||
throw new InvalidOperationException("Platform dll must include exactly one IPlatform implementation.");
|
||||
|
||||
|
||||
@@ -26,11 +26,7 @@ namespace OpenRA
|
||||
var total = response.Content.Headers.ContentLength ?? -1;
|
||||
var canReportProgress = total > 0;
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
using (var contentStream = await response.Content.ReadAsStreamAsync(token))
|
||||
#else
|
||||
using (var contentStream = await response.Content.ReadAsStreamAsync())
|
||||
#endif
|
||||
{
|
||||
var totalRead = 0L;
|
||||
var buffer = new byte[8192];
|
||||
|
||||
@@ -55,26 +55,9 @@ namespace OpenRA
|
||||
|
||||
if (!ResolvedAssemblies.TryGetValue(hash, out var assembly))
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
var loader = new Support.AssemblyLoader(resolvedPath);
|
||||
assembly = loader.LoadDefaultAssembly();
|
||||
ResolvedAssemblies.Add(hash, assembly);
|
||||
#else
|
||||
assembly = Assembly.LoadFile(resolvedPath);
|
||||
ResolvedAssemblies.Add(hash, assembly);
|
||||
|
||||
// Allow mods to use libraries.
|
||||
var assemblyPath = Path.GetDirectoryName(resolvedPath);
|
||||
if (assemblyPath != null)
|
||||
{
|
||||
foreach (var referencedAssembly in assembly.GetReferencedAssemblies())
|
||||
{
|
||||
var depedencyPath = Path.Combine(assemblyPath, referencedAssembly.Name + ".dll");
|
||||
if (File.Exists(depedencyPath))
|
||||
LoadAssembly(assemblyList, depedencyPath);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
assemblyList.Add(assembly);
|
||||
|
||||
@@ -2,14 +2,9 @@
|
||||
<PropertyGroup>
|
||||
<RootNamespace>OpenRA</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition="'$(MSBuildRuntimeType)'!='Mono'">
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="6.0.2" />
|
||||
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(MSBuildRuntimeType)'=='Mono'">
|
||||
<PackageReference Include="System.Collections.Immutable" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Linguini.Bundle" Version="0.8.1" />
|
||||
<PackageReference Include="OpenRA-Eluant" Version="1.0.22" />
|
||||
<PackageReference Include="Mono.NAT" Version="3.0.4" />
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OpenRA
|
||||
@@ -63,21 +62,7 @@ namespace OpenRA
|
||||
return PlatformType.Unknown;
|
||||
}
|
||||
|
||||
public static string RuntimeVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
var mono = Type.GetType("Mono.Runtime");
|
||||
if (mono == null)
|
||||
return $".NET CLR {Environment.Version}";
|
||||
|
||||
var version = mono.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
if (version == null)
|
||||
return $"Mono (unknown version) CLR {Environment.Version}";
|
||||
|
||||
return $"Mono {version.Invoke(null, null)} CLR {Environment.Version}";
|
||||
}
|
||||
}
|
||||
public static string RuntimeVersion => $".NET CLR {Environment.Version}";
|
||||
|
||||
public static string OperatingSystem
|
||||
{
|
||||
|
||||
@@ -24,10 +24,6 @@ namespace OpenRA.Scripting
|
||||
protected readonly ScriptContext Context;
|
||||
readonly Dictionary<string, ScriptMemberWrapper> members = new();
|
||||
|
||||
#if !NET5_0_OR_GREATER
|
||||
readonly List<string> membersToRemove = new List<string>();
|
||||
#endif
|
||||
|
||||
protected ScriptObjectWrapper(ScriptContext context)
|
||||
{
|
||||
Context = context;
|
||||
@@ -67,22 +63,10 @@ namespace OpenRA.Scripting
|
||||
|
||||
protected void Unbind(Type targetType)
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
// NOTE: In newer versions of .NET modifying the collection by calling Remove while iterating over it is valid
|
||||
foreach (var m in members)
|
||||
if (targetType == m.Value.Target.GetType())
|
||||
members.Remove(m.Key);
|
||||
#else
|
||||
// PERF: Re-use instead of allocating a new list on each unbind
|
||||
membersToRemove.Clear();
|
||||
|
||||
foreach (var m in members)
|
||||
if (targetType == m.Value.Target.GetType())
|
||||
membersToRemove.Add(m.Key);
|
||||
|
||||
foreach (var m in membersToRemove)
|
||||
members.Remove(m);
|
||||
#endif
|
||||
}
|
||||
|
||||
public bool ContainsKey(string key) { return members.ContainsKey(key); }
|
||||
|
||||
@@ -14,6 +14,7 @@ using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenRA
|
||||
@@ -160,11 +161,7 @@ namespace OpenRA
|
||||
while ((b = s.ReadUInt8()) != 0)
|
||||
bytes.Add(b);
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
return Encoding.ASCII.GetString(System.Runtime.InteropServices.CollectionsMarshal.AsSpan(bytes));
|
||||
#else
|
||||
return Encoding.ASCII.GetString(bytes.ToArray());
|
||||
#endif
|
||||
return Encoding.ASCII.GetString(CollectionsMarshal.AsSpan(bytes));
|
||||
}
|
||||
|
||||
public static string ReadAllText(this Stream s)
|
||||
|
||||
@@ -9,9 +9,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
// Not used/usable on Mono. Only used for Dotnet Core.
|
||||
// Based on https://github.com/natemcmaster/DotNetCorePlugins and used under the terms of the Apache 2.0 license
|
||||
#if NET5_0_OR_GREATER
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@@ -362,4 +360,3 @@ namespace OpenRA.Support
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -16,10 +16,8 @@ namespace OpenRA.Support
|
||||
{
|
||||
public static class HttpClientFactory
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
const int MaxConnectionPerServer = 20;
|
||||
static readonly TimeSpan ConnectionLifeTime = TimeSpan.FromMinutes(1);
|
||||
#endif
|
||||
|
||||
static readonly Lazy<HttpMessageHandler> Handler = new(GetHandler);
|
||||
|
||||
@@ -30,7 +28,6 @@ namespace OpenRA.Support
|
||||
|
||||
static HttpMessageHandler GetHandler()
|
||||
{
|
||||
#if NET5_0_OR_GREATER
|
||||
return new SocketsHttpHandler
|
||||
{
|
||||
// https://github.com/dotnet/corefx/issues/26895
|
||||
@@ -40,9 +37,6 @@ namespace OpenRA.Support
|
||||
PooledConnectionIdleTimeout = ConnectionLifeTime,
|
||||
MaxConnectionsPerServer = MaxConnectionPerServer
|
||||
};
|
||||
#else
|
||||
return new HttpClientHandler();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,13 +98,10 @@ namespace OpenRA.Mods.Cnc.SpriteLoaders
|
||||
if (metaStream != null)
|
||||
{
|
||||
string metaText;
|
||||
#if NET5_0_OR_GREATER
|
||||
using (metaStream)
|
||||
using (var metaReader = new StreamReader(metaStream, bufferSize: 64))
|
||||
metaText = metaReader.ReadToEnd();
|
||||
#else
|
||||
metaText = metaStream.ReadAllText();
|
||||
#endif
|
||||
|
||||
var meta = MetaRegex.Match(metaText);
|
||||
var crop = Rectangle.FromLTRB(
|
||||
ParseGroup(meta, "left"), ParseGroup(meta, "top"),
|
||||
|
||||
@@ -497,22 +497,4 @@ namespace OpenRA.Mods.Cnc.UtilityCommands
|
||||
Map.ActorDefinitions = Map.ActorDefinitions.Concat(nodes).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
#if !NET6_0_OR_GREATER
|
||||
public static class Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Only used for Mono builds. .NET 6 added the exact same thing.
|
||||
/// </summary>
|
||||
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
|
||||
{
|
||||
var knownKeys = new HashSet<TKey>();
|
||||
foreach (var element in source)
|
||||
{
|
||||
if (knownKeys.Add(keySelector(element)))
|
||||
yield return element;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -159,15 +159,8 @@ namespace OpenRA.Mods.Common.Orders
|
||||
if (mi.Modifiers.HasModifier(Modifiers.Alt))
|
||||
modifiers |= TargetModifiers.ForceMove;
|
||||
|
||||
// The Select(x => x) is required to work around an issue on mono 5.0
|
||||
// where calling OrderBy* on SelectManySingleSelectorIterator can in some
|
||||
// circumstances (which we were unable to identify) replace entries in the
|
||||
// enumeration with duplicates of other entries.
|
||||
// Other action that replace the SelectManySingleSelectorIterator with a
|
||||
// different enumerator type (e.g. .Where(true) or .ToList()) also work.
|
||||
var orders = self.TraitsImplementing<IIssueOrder>()
|
||||
.SelectMany(trait => trait.Orders.Select(x => new { Trait = trait, Order = x }))
|
||||
.Select(x => x)
|
||||
.OrderByDescending(x => x.Order.OrderPriority)
|
||||
.ToList();
|
||||
|
||||
|
||||
@@ -48,14 +48,9 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
public static Exit NearestExitOrDefault(this Actor actor, WPos pos, string productionType = null, Func<Exit, bool> p = null)
|
||||
{
|
||||
// The .ToList() is required to work around a bug/unexpected behaviour in mono, where
|
||||
// the ThenBy clause makes the FirstOrDefault behave differently than under .NET.
|
||||
// This is important because p may have side-effects that trigger a desync if not
|
||||
// called on the same exits in the same order!
|
||||
var all = Exits(actor, productionType)
|
||||
.OrderByDescending(e => e.Info.Priority)
|
||||
.ThenBy(e => (actor.World.Map.CenterOfCell(actor.Location + e.Info.ExitCell) - pos).LengthSquared)
|
||||
.ToList();
|
||||
.ThenBy(e => (actor.World.Map.CenterOfCell(actor.Location + e.Info.ExitCell) - pos).LengthSquared);
|
||||
|
||||
#pragma warning disable RCS1077 // Optimize LINQ method call.
|
||||
return p != null ? all.FirstOrDefault(p) : all.FirstOrDefault();
|
||||
|
||||
@@ -72,11 +72,4 @@ Global
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {9E2FAACA-DADB-4EEB-9898-2B0269F45E69}
|
||||
EndGlobalSection
|
||||
GlobalSection(MonoDevelopProperties) = preSolution
|
||||
StartupItem = OpenRA.Game\OpenRA.Game.csproj
|
||||
Policies = $0
|
||||
$0.DotNetNamingPolicy = $1
|
||||
$0.TextStylePolicy = $7
|
||||
outputpath = .
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -8,48 +8,29 @@
|
||||
|
||||
set -o errexit || exit $?
|
||||
|
||||
patch_config()
|
||||
create_symlinks()
|
||||
{
|
||||
LABEL=$1
|
||||
SEARCHDIRS=$2
|
||||
CONFIG=$3
|
||||
REPLACE=$4
|
||||
SEARCH=$5
|
||||
REPLACE=$3
|
||||
SEARCH=$4
|
||||
|
||||
if command -v mono >/dev/null 2>&1 && [ "$(grep -c .NETCoreApp,Version= bin/OpenRA.dll)" = "0" ]; then
|
||||
# Exit early if the file has already been patched
|
||||
grep -q "target=\"${REPLACE}\"" "${CONFIG}" || return 0
|
||||
|
||||
printf "Searching for %s... " "${LABEL}"
|
||||
for DIR in ${SEARCHDIRS} ; do
|
||||
for LIB in ${SEARCH}; do
|
||||
if [ -f "${DIR}/${LIB}" ]; then
|
||||
echo "${LIB}"
|
||||
sed "s|target=\"${REPLACE}\"|target=\"${DIR}/${LIB}\"|" "${CONFIG}" > "${CONFIG}.temp"
|
||||
mv "${CONFIG}.temp" "${CONFIG}"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
done
|
||||
else
|
||||
# .NET 6 does not support .config files, so we must use symlinks instead
|
||||
# Exit early if the symlink already exists
|
||||
if [ -L "bin/${REPLACE}" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
printf "Searching for %s... " "${LABEL}"
|
||||
for DIR in ${SEARCHDIRS} ; do
|
||||
for LIB in ${SEARCH}; do
|
||||
if [ -f "${DIR}/${LIB}" ]; then
|
||||
echo "${LIB}"
|
||||
ln -s "${DIR}/${LIB}" "bin/${REPLACE}"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
done
|
||||
# Exit early if the symlink already exists
|
||||
if [ -L "bin/${REPLACE}" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
printf "Searching for %s... " "${LABEL}"
|
||||
for DIR in ${SEARCHDIRS} ; do
|
||||
for LIB in ${SEARCH}; do
|
||||
if [ -f "${DIR}/${LIB}" ]; then
|
||||
echo "${LIB}"
|
||||
ln -s "${DIR}/${LIB}" "bin/${REPLACE}"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
echo "FAILED"
|
||||
|
||||
echo "OpenRA expects to find a file matching \"${SEARCH}\" in one of the following locations:"
|
||||
@@ -63,14 +44,14 @@ if [ "$(uname -s)" = "Darwin" ]; then
|
||||
else
|
||||
SEARCHDIRS="/usr/local/lib /usr/local/opt/openal-soft/lib"
|
||||
fi
|
||||
patch_config "Lua 5.1" "${SEARCHDIRS}" bin/Eluant.dll.config lua51.dylib liblua5.1.dylib
|
||||
patch_config SDL2 "${SEARCHDIRS}" bin/SDL2-CS.dll.config SDL2.dylib libSDL2-2.0.0.dylib
|
||||
patch_config OpenAL "${SEARCHDIRS}" bin/OpenAL-CS.dll.config soft_oal.dylib libopenal.1.dylib
|
||||
patch_config FreeType "${SEARCHDIRS}" bin/OpenRA.Platforms.Default.dll.config freetype6.dylib libfreetype.6.dylib
|
||||
create_symlinks "Lua 5.1" "${SEARCHDIRS}" lua51.dylib liblua5.1.dylib
|
||||
create_symlinks SDL2 "${SEARCHDIRS}" SDL2.dylib libSDL2-2.0.0.dylib
|
||||
create_symlinks OpenAL "${SEARCHDIRS}" soft_oal.dylib libopenal.1.dylib
|
||||
create_symlinks FreeType "${SEARCHDIRS}" freetype6.dylib libfreetype.6.dylib
|
||||
else
|
||||
SEARCHDIRS="/lib /lib64 /usr/lib /usr/lib64 /usr/lib/x86_64-linux-gnu /usr/lib/i386-linux-gnu /usr/lib/arm-linux-gnueabihf /usr/lib/aarch64-linux-gnu /usr/lib/powerpc64le-linux-gnu /usr/lib/mipsel-linux-gnu /usr/local/lib /opt/lib /opt/local/lib /app/lib"
|
||||
patch_config "Lua 5.1" "${SEARCHDIRS}" bin/Eluant.dll.config lua51.so "liblua.so.5.1.5 liblua5.1.so.5.1 liblua5.1.so.0 liblua.so.5.1 liblua-5.1.so liblua5.1.so"
|
||||
patch_config SDL2 "${SEARCHDIRS}" bin/SDL2-CS.dll.config SDL2.so "libSDL2-2.0.so.0 libSDL2-2.0.so libSDL2.so"
|
||||
patch_config OpenAL "${SEARCHDIRS}" bin/OpenAL-CS.dll.config soft_oal.so "libopenal.so.1 libopenal.so"
|
||||
patch_config FreeType "${SEARCHDIRS}" bin/OpenRA.Platforms.Default.dll.config freetype6.so "libfreetype.so.6 libfreetype.so"
|
||||
create_symlinks "Lua 5.1" "${SEARCHDIRS}" lua51.so "liblua.so.5.1.5 liblua5.1.so.5.1 liblua5.1.so.0 liblua.so.5.1 liblua-5.1.so liblua5.1.so"
|
||||
create_symlinks SDL2 "${SEARCHDIRS}" SDL2.so "libSDL2-2.0.so.0 libSDL2-2.0.so libSDL2.so"
|
||||
create_symlinks OpenAL "${SEARCHDIRS}" soft_oal.so "libopenal.so.1 libopenal.so"
|
||||
create_symlinks FreeType "${SEARCHDIRS}" freetype6.so "libfreetype.so.6 libfreetype.so"
|
||||
fi
|
||||
|
||||
@@ -9,11 +9,6 @@
|
||||
set -o errexit || exit $?
|
||||
|
||||
ENGINEDIR=$(dirname "$0")
|
||||
if command -v mono >/dev/null 2>&1 && [ "$(grep -c .NETCoreApp,Version= "${ENGINEDIR}/bin/OpenRA.Server.dll")" = "0" ]; then
|
||||
RUNTIME_LAUNCHER="mono --debug"
|
||||
else
|
||||
RUNTIME_LAUNCHER="dotnet"
|
||||
fi
|
||||
|
||||
Name="${Name:-"Dedicated Server"}"
|
||||
Mod="${Mod:-"ra"}"
|
||||
@@ -38,7 +33,7 @@ FloodLimitJoinCooldown="${FloodLimitJoinCooldown:-"5000"}"
|
||||
SupportDir="${SupportDir:-""}"
|
||||
|
||||
while true; do
|
||||
${RUNTIME_LAUNCHER} "${ENGINEDIR}/bin/OpenRA.Server.dll" Engine.EngineDir=".." Game.Mod="$Mod" \
|
||||
dotnet "${ENGINEDIR}/bin/OpenRA.Server.dll" Engine.EngineDir=".." Game.Mod="$Mod" \
|
||||
Server.Name="$Name" \
|
||||
Server.Map="$Map" \
|
||||
Server.ListenPort="$ListenPort" \
|
||||
|
||||
@@ -2,11 +2,6 @@
|
||||
set -o errexit || exit $?
|
||||
|
||||
ENGINEDIR=$(dirname "$0")
|
||||
if command -v mono >/dev/null 2>&1 && [ "$(grep -c .NETCoreApp,Version= "${ENGINEDIR}/bin/OpenRA.dll")" = "0" ]; then
|
||||
RUNTIME_LAUNCHER="mono --debug"
|
||||
else
|
||||
RUNTIME_LAUNCHER="dotnet"
|
||||
fi
|
||||
|
||||
if command -v python3 >/dev/null 2>&1; then
|
||||
LAUNCHPATH=$(python3 -c 'import os,sys; print(os.path.realpath(sys.argv[1]))' "$0")
|
||||
@@ -34,7 +29,7 @@ then
|
||||
fi
|
||||
|
||||
# Launch the engine with the appropriate arguments
|
||||
${RUNTIME_LAUNCHER} "${ENGINEDIR}/bin/OpenRA.dll" Engine.EngineDir=".." Engine.LaunchPath="${LAUNCHPATH}" ${MODARG} "$@" && rc=0 || rc=$?
|
||||
dotnet "${ENGINEDIR}/bin/OpenRA.dll" Engine.EngineDir=".." Engine.LaunchPath="${LAUNCHPATH}" ${MODARG} "$@" && rc=0 || rc=$?
|
||||
|
||||
# Show a crash dialog if something went wrong
|
||||
if [ "${rc}" != 0 ] && [ "${rc}" != 1 ]; then
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
# SRC_PATH: Path to the root OpenRA 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)
|
||||
# COPY_GENERIC_LAUNCHER: If set to True the OpenRA.exe will also be copied (True, False)
|
||||
# COPY_CNC_DLL: If set to True the OpenRA.Mods.Cnc.dll will also be copied (True, False)
|
||||
# COPY_D2K_DLL: If set to True the OpenRA.Mods.D2k.dll will also be copied (True, False)
|
||||
@@ -29,59 +28,14 @@ install_assemblies() (
|
||||
SRC_PATH="${1}"
|
||||
DEST_PATH="${2}"
|
||||
TARGETPLATFORM="${3}"
|
||||
RUNTIME="${4}"
|
||||
COPY_GENERIC_LAUNCHER="${5}"
|
||||
COPY_CNC_DLL="${6}"
|
||||
COPY_D2K_DLL="${7}"
|
||||
COPY_GENERIC_LAUNCHER="${4}"
|
||||
COPY_CNC_DLL="${5}"
|
||||
COPY_D2K_DLL="${6}"
|
||||
|
||||
ORIG_PWD=$(pwd)
|
||||
cd "${SRC_PATH}"
|
||||
|
||||
if [ "${RUNTIME}" = "mono" ]; then
|
||||
echo "Building assemblies"
|
||||
rm -rf "${SRC_PATH}/OpenRA."*/obj || :
|
||||
rm -rf "${SRC_PATH:?}/bin" || :
|
||||
|
||||
msbuild -verbosity:m -nologo -t:Build -restore -p:Configuration=Release -p:TargetPlatform="${TARGETPLATFORM}"
|
||||
if [ "${TARGETPLATFORM}" = "unix-generic" ]; then
|
||||
./configure-system-libraries.sh
|
||||
fi
|
||||
|
||||
if [ "${COPY_GENERIC_LAUNCHER}" != "True" ]; then
|
||||
rm "${SRC_PATH}/bin/OpenRA.dll"
|
||||
fi
|
||||
|
||||
if [ "${COPY_CNC_DLL}" != "True" ]; then
|
||||
rm "${SRC_PATH}/bin/OpenRA.Mods.Cnc.dll"
|
||||
fi
|
||||
|
||||
if [ "${COPY_D2K_DLL}" != "True" ]; then
|
||||
rm "${SRC_PATH}/bin/OpenRA.Mods.D2k.dll"
|
||||
fi
|
||||
|
||||
cd "${ORIG_PWD}"
|
||||
|
||||
echo "Installing engine to ${DEST_PATH}"
|
||||
install -d "${DEST_PATH}"
|
||||
|
||||
for LIB in "${SRC_PATH}/bin/"*.dll "${SRC_PATH}/bin/"*.dll.config; do
|
||||
install -m644 "${LIB}" "${DEST_PATH}"
|
||||
done
|
||||
|
||||
if [ "${TARGETPLATFORM}" = "linux-x64" ] || [ "${TARGETPLATFORM}" = "linux-arm64" ]; then
|
||||
for LIB in "${SRC_PATH}/bin/"*.so; do
|
||||
install -m755 "${LIB}" "${DEST_PATH}"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ "${TARGETPLATFORM}" = "osx-x64" ] || [ "${TARGETPLATFORM}" = "osx-arm64" ]; then
|
||||
for LIB in "${SRC_PATH}/bin/"*.dylib; do
|
||||
install -m755 "${LIB}" "${DEST_PATH}"
|
||||
done
|
||||
fi
|
||||
else
|
||||
dotnet publish -c Release -p:TargetPlatform="${TARGETPLATFORM}" -p:CopyGenericLauncher="${COPY_GENERIC_LAUNCHER}" -p:CopyCncDll="${COPY_CNC_DLL}" -p:CopyD2kDll="${COPY_D2K_DLL}" -r "${TARGETPLATFORM}" -p:PublishDir="${DEST_PATH}" --self-contained true
|
||||
fi
|
||||
dotnet publish -c Release -p:TargetPlatform="${TARGETPLATFORM}" -p:CopyGenericLauncher="${COPY_GENERIC_LAUNCHER}" -p:CopyCncDll="${COPY_CNC_DLL}" -p:CopyD2kDll="${COPY_D2K_DLL}" -r "${TARGETPLATFORM}" -p:PublishDir="${DEST_PATH}" --self-contained true
|
||||
cd "${ORIG_PWD}"
|
||||
)
|
||||
|
||||
@@ -131,7 +85,7 @@ install_data() (
|
||||
done
|
||||
)
|
||||
|
||||
# Compile and publish (using Mono) a windows launcher with the specified mod details to the target directory
|
||||
# Compile and publish a windows launcher with the specified mod details to the target directory
|
||||
# Arguments:
|
||||
# SRC_PATH: Path to the root OpenRA directory
|
||||
# DEST_PATH: Path to the root of the install destination (will be created if necessary)
|
||||
|
||||
@@ -67,7 +67,7 @@ build_appimage() {
|
||||
IS_D2K="True"
|
||||
fi
|
||||
|
||||
install_assemblies "${SRCDIR}" "${APPDIR}/usr/lib/openra" "linux-x64" "net6" "True" "True" "${IS_D2K}"
|
||||
install_assemblies "${SRCDIR}" "${APPDIR}/usr/lib/openra" "linux-x64" "True" "True" "${IS_D2K}"
|
||||
install_data "${SRCDIR}" "${APPDIR}/usr/lib/openra" "${MOD_ID}"
|
||||
set_engine_version "${TAG}" "${APPDIR}/usr/lib/openra"
|
||||
set_mod_version "${TAG}" "${APPDIR}/usr/lib/openra/mods/${MOD_ID}/mod.yaml" "${APPDIR}/usr/lib/openra/mods/${MOD_ID}-content/mod.yaml"
|
||||
|
||||
@@ -5,8 +5,6 @@ cd "{GAME_INSTALL_DIR}"
|
||||
|
||||
if test -f "OpenRA.Server"; then
|
||||
./OpenRA.Server Game.Mod={MODID} "$@"
|
||||
elif command -v mono >/dev/null 2>&1 && [ "$(grep -c .NETCoreApp,Version= OpenRA.Server.dll)" = "0" ]; then
|
||||
mono {DEBUG} OpenRA.Server.dll Game.Mod={MODID} "$@"
|
||||
else
|
||||
dotnet OpenRA.Server.dll Game.Mod={MODID} "$@"
|
||||
fi
|
||||
|
||||
@@ -13,8 +13,6 @@ fi
|
||||
# Run the game
|
||||
if test -f "OpenRA"; then
|
||||
./OpenRA Game.Mod={MODID} Engine.LaunchPath="{BIN_DIR}/openra-{MODID}" "${JOIN_SERVER}" "$@" && rc=0 || rc=$?
|
||||
elif command -v mono >/dev/null 2>&1 && [ "$(grep -c .NETCoreApp,Version= OpenRA.dll)" = "0" ]; then
|
||||
mono {DEBUG} OpenRA.dll Game.Mod={MODID} Engine.LaunchPath="{BIN_DIR}/openra-{MODID}" "${JOIN_SERVER}" "$@" && rc=0 || rc=$?
|
||||
else
|
||||
dotnet OpenRA.dll Game.Mod={MODID} Engine.LaunchPath="{BIN_DIR}/openra-{MODID}" "${JOIN_SERVER}" "$@" && rc=0 || rc=$?
|
||||
fi
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
|
||||
//
|
||||
// A custom apphost is required (instead of just invoking `mono OpenRA.dll ...` directly)
|
||||
// because macOS will only properly associate dock icons and tooltips to windows that are
|
||||
// created by a process in the Contents/MacOS directory (not subdirectories).
|
||||
//
|
||||
// Based on https://github.com/mono/monodevelop/blob/main/main/build/MacOSX/monostub.mm
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
typedef int (* mono_main)(int argc, char **argv);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// TODO: This snippet increasing the open file limit was copied from
|
||||
// the monodevelop launcher stub. It may not be needed for OpenRA.
|
||||
struct rlimit limit;
|
||||
if (getrlimit(RLIMIT_NOFILE, &limit) == 0 && limit.rlim_cur < 1024)
|
||||
{
|
||||
limit.rlim_cur = limit.rlim_max < 1024 ? limit.rlim_max : 1024;
|
||||
setrlimit(RLIMIT_NOFILE, &limit);
|
||||
}
|
||||
|
||||
void *libmono = dlopen(argv[1], RTLD_LAZY);
|
||||
if (libmono == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to load libmonosgen-2.0.dylib: %s\n", dlerror());
|
||||
return 1;
|
||||
}
|
||||
|
||||
mono_main _mono_main = (mono_main)dlsym(libmono, "mono_main");
|
||||
if (!_mono_main)
|
||||
{
|
||||
fprintf(stderr, "Could not load mono_main(): %s\n", dlerror());
|
||||
return 1;
|
||||
}
|
||||
|
||||
return _mono_main(argc - 1, &argv[1]);
|
||||
}
|
||||
@@ -75,9 +75,8 @@ build_app() {
|
||||
fi
|
||||
|
||||
# Install engine and mod files
|
||||
install_assemblies "${SRCDIR}" "${LAUNCHER_CONTENTS_DIR}/MacOS/x86_64" "osx-x64" "net6" "True" "True" "${IS_D2K}"
|
||||
install_assemblies "${SRCDIR}" "${LAUNCHER_CONTENTS_DIR}/MacOS/arm64" "osx-arm64" "net6" "True" "True" "${IS_D2K}"
|
||||
install_assemblies "${SRCDIR}" "${LAUNCHER_CONTENTS_DIR}/MacOS/mono" "osx-x64" "mono" "True" "True" "${IS_D2K}"
|
||||
install_assemblies "${SRCDIR}" "${LAUNCHER_CONTENTS_DIR}/MacOS/x86_64" "osx-x64" "True" "True" "${IS_D2K}"
|
||||
install_assemblies "${SRCDIR}" "${LAUNCHER_CONTENTS_DIR}/MacOS/arm64" "osx-arm64" "True" "True" "${IS_D2K}"
|
||||
|
||||
install_data "${SRCDIR}" "${LAUNCHER_RESOURCES_DIR}" "${MOD_ID}"
|
||||
set_engine_version "${TAG}" "${LAUNCHER_RESOURCES_DIR}"
|
||||
@@ -114,7 +113,6 @@ echo "Building launchers"
|
||||
# Prepare generic template for the mods to duplicate and customize
|
||||
TEMPLATE_DIR="${BUILTDIR}/template.app"
|
||||
mkdir -p "${TEMPLATE_DIR}/Contents/Resources"
|
||||
mkdir -p "${TEMPLATE_DIR}/Contents/MacOS/mono"
|
||||
mkdir -p "${TEMPLATE_DIR}/Contents/MacOS/x86_64"
|
||||
mkdir -p "${TEMPLATE_DIR}/Contents/MacOS/arm64"
|
||||
|
||||
@@ -122,22 +120,20 @@ echo "APPL????" > "${TEMPLATE_DIR}/Contents/PkgInfo"
|
||||
cp Info.plist.in "${TEMPLATE_DIR}/Contents/Info.plist"
|
||||
modify_plist "{DEV_VERSION}" "${TAG}" "${TEMPLATE_DIR}/Contents/Info.plist"
|
||||
modify_plist "{FAQ_URL}" "https://wiki.openra.net/FAQ" "${TEMPLATE_DIR}/Contents/Info.plist"
|
||||
modify_plist "{MINIMUM_SYSTEM_VERSION}" "10.11" "${TEMPLATE_DIR}/Contents/Info.plist"
|
||||
modify_plist "{MINIMUM_SYSTEM_VERSION}" "10.15" "${TEMPLATE_DIR}/Contents/Info.plist"
|
||||
|
||||
# Compile universal (x86_64 + arm64) arch-specific apphosts
|
||||
clang apphost.c -o "${TEMPLATE_DIR}/Contents/MacOS/apphost-x86_64" -framework AppKit -target x86_64-apple-macos10.15
|
||||
clang apphost.c -o "${TEMPLATE_DIR}/Contents/MacOS/apphost-arm64" -framework AppKit -target arm64-apple-macos10.15
|
||||
clang apphost-mono.c -o "${TEMPLATE_DIR}/Contents/MacOS/apphost-mono" -framework AppKit -target x86_64-apple-macos10.11
|
||||
clang checkmono.c -o "${TEMPLATE_DIR}/Contents/MacOS/checkmono" -framework AppKit -target x86_64-apple-macos10.11
|
||||
|
||||
# Compile universal (x86_64 + arm64) Launcher
|
||||
clang launcher.m -o "${TEMPLATE_DIR}/Contents/MacOS/Launcher-x86_64" -framework AppKit -target x86_64-apple-macos10.11
|
||||
clang launcher.m -o "${TEMPLATE_DIR}/Contents/MacOS/Launcher-x86_64" -framework AppKit -target x86_64-apple-macos10.15
|
||||
clang launcher.m -o "${TEMPLATE_DIR}/Contents/MacOS/Launcher-arm64" -framework AppKit -target arm64-apple-macos10.15
|
||||
lipo -create -output "${TEMPLATE_DIR}/Contents/MacOS/Launcher" "${TEMPLATE_DIR}/Contents/MacOS/Launcher-x86_64" "${TEMPLATE_DIR}/Contents/MacOS/Launcher-arm64"
|
||||
rm "${TEMPLATE_DIR}/Contents/MacOS/Launcher-x86_64" "${TEMPLATE_DIR}/Contents/MacOS/Launcher-arm64"
|
||||
|
||||
# Compile universal (x86_64 + arm64) Utility
|
||||
clang utility.m -o "${TEMPLATE_DIR}/Contents/MacOS/Utility-x86_64" -framework AppKit -target x86_64-apple-macos10.11
|
||||
clang utility.m -o "${TEMPLATE_DIR}/Contents/MacOS/Utility-x86_64" -framework AppKit -target x86_64-apple-macos10.15
|
||||
clang utility.m -o "${TEMPLATE_DIR}/Contents/MacOS/Utility-arm64" -framework AppKit -target arm64-apple-macos10.15
|
||||
lipo -create -output "${TEMPLATE_DIR}/Contents/MacOS/Utility" "${TEMPLATE_DIR}/Contents/MacOS/Utility-x86_64" "${TEMPLATE_DIR}/Contents/MacOS/Utility-arm64"
|
||||
rm "${TEMPLATE_DIR}/Contents/MacOS/Utility-x86_64" "${TEMPLATE_DIR}/Contents/MacOS/Utility-arm64"
|
||||
@@ -197,7 +193,7 @@ SetFile -a C "/Volumes/OpenRA"
|
||||
|
||||
# Replace duplicate .NET runtime files with hard links to improve compression
|
||||
for MOD in "Red Alert" "Tiberian Dawn"; do
|
||||
for p in "x86_64" "arm64" "mono"; do
|
||||
for p in "x86_64" "arm64"; do
|
||||
for f in "/Volumes/OpenRA/OpenRA - ${MOD}.app/Contents/MacOS/${p}"/*; do
|
||||
g="/Volumes/OpenRA/OpenRA - Dune 2000.app/Contents/MacOS/${p}/"$(basename "${f}")
|
||||
hashf=$(shasum "${f}" | awk '{ print $1 }') || :
|
||||
@@ -212,19 +208,17 @@ for MOD in "Red Alert" "Tiberian Dawn"; do
|
||||
done
|
||||
|
||||
for MOD in "Red Alert" "Tiberian Dawn" "Dune 2000"; do
|
||||
for p in "arm64" "mono"; do
|
||||
for f in "/Volumes/OpenRA/OpenRA - ${MOD}.app/Contents/MacOS/x86_64"/*; do
|
||||
g="/Volumes/OpenRA/OpenRA - ${MOD}.app/Contents/MacOS/${p}/"$(basename "${f}")
|
||||
if [ -e "${g}" ]; then
|
||||
hashf=$(shasum "${f}" | awk '{ print $1 }') || :
|
||||
hashg=$(shasum "${g}" | awk '{ print $1 }') || :
|
||||
if [ -n "${hashf}" ] && [ "${hashf}" = "${hashg}" ]; then
|
||||
echo "Deduplicating ${f}"
|
||||
rm "${f}"
|
||||
ln "${g}" "${f}"
|
||||
fi
|
||||
for f in "/Volumes/OpenRA/OpenRA - ${MOD}.app/Contents/MacOS/x86_64"/*; do
|
||||
g="/Volumes/OpenRA/OpenRA - ${MOD}.app/Contents/MacOS/arm64/"$(basename "${f}")
|
||||
if [ -e "${g}" ]; then
|
||||
hashf=$(shasum "${f}" | awk '{ print $1 }') || :
|
||||
hashg=$(shasum "${g}" | awk '{ print $1 }') || :
|
||||
if [ -n "${hashf}" ] && [ "${hashf}" = "${hashg}" ]; then
|
||||
echo "Deduplicating ${f}"
|
||||
rm "${f}"
|
||||
ln "${g}" "${f}"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) The OpenRA Developers and Contributors
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
|
||||
//
|
||||
// NOTE: Mono.framework only ships intel dylibs, so cannot be loaded by the arm64 slice of the Launcher utility.
|
||||
// Splitting checkmono into its own intel-only utility allows it to be called through rosetta if the user
|
||||
// wants to force the game to run under mono-through-rosetta.
|
||||
//
|
||||
// Based on https://github.com/mono/monodevelop/blob/main/main/build/MacOSX/monostub.mm and https://github.com/mono/monodevelop/blob/main/main/build/MacOSX/monostub-utils.h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#define SYSTEM_MONO_PATH "/Library/Frameworks/Mono.framework/Versions/Current/"
|
||||
#define SYSTEM_MONO_MIN_VERSION "6.12"
|
||||
|
||||
typedef char *(* mono_get_runtime_build_info)(void);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
void *libmono = dlopen(SYSTEM_MONO_PATH "lib/libmonosgen-2.0.dylib", RTLD_LAZY);
|
||||
if (libmono == NULL)
|
||||
{
|
||||
fprintf (stderr, "Failed to load libmonosgen-2.0.dylib: %s\n", dlerror());
|
||||
return 1;
|
||||
}
|
||||
|
||||
mono_get_runtime_build_info _mono_get_runtime_build_info = (mono_get_runtime_build_info)dlsym(libmono, "mono_get_runtime_build_info");
|
||||
if (!_mono_get_runtime_build_info)
|
||||
{
|
||||
fprintf(stderr, "Could not load mono_get_runtime_build_info(): %s\n", dlerror());
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *version = _mono_get_runtime_build_info();
|
||||
char *req_end, *end;
|
||||
long req_val, val;
|
||||
char *req_version = SYSTEM_MONO_MIN_VERSION;
|
||||
|
||||
while (*req_version && *version)
|
||||
{
|
||||
req_val = strtol(req_version, &req_end, 10);
|
||||
if (req_version == req_end || (*req_end && *req_end != '.'))
|
||||
{
|
||||
fprintf(stderr, "Bad version requirement string '%s'\n", req_end);
|
||||
return 1;
|
||||
}
|
||||
|
||||
val = strtol(version, &end, 10);
|
||||
if (version == end || val < req_val)
|
||||
return 1;
|
||||
|
||||
if (val > req_val)
|
||||
return 0;
|
||||
|
||||
if (*req_end == '.' && *end != '.')
|
||||
return 1;
|
||||
|
||||
req_version = req_end;
|
||||
if (*req_version)
|
||||
req_version++;
|
||||
|
||||
version = end + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -12,8 +12,6 @@
|
||||
#include <sys/sysctl.h>
|
||||
#include <mach/machine.h>
|
||||
|
||||
#define SYSTEM_MONO_PATH @"/Library/Frameworks/Mono.framework/Versions/Current/"
|
||||
#define SYSTEM_MONO_MIN_VERSION @"6.12"
|
||||
#define DOTNET_MIN_MACOS_VERSION 10.15
|
||||
|
||||
@interface OpenRALauncher : NSObject <NSApplicationDelegate>
|
||||
@@ -38,29 +36,6 @@ NSTask *gameTask;
|
||||
return @"OpenRA";
|
||||
}
|
||||
|
||||
- (void)exitWithMonoPrompt
|
||||
{
|
||||
[NSApp setActivationPolicy: NSApplicationActivationPolicyRegular];
|
||||
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
|
||||
|
||||
NSString *modName = [self modName];
|
||||
NSString *title = [NSString stringWithFormat: @"Cannot launch %@", modName];
|
||||
NSString *message = [NSString stringWithFormat: @"%@ requires Mono %@ or later. Please install Mono and try again.", modName, SYSTEM_MONO_MIN_VERSION];
|
||||
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert setMessageText:title];
|
||||
[alert setInformativeText:message];
|
||||
[alert addButtonWithTitle:@"Download Mono"];
|
||||
[alert addButtonWithTitle:@"Quit"];
|
||||
NSInteger answer = [alert runModal];
|
||||
[alert release];
|
||||
|
||||
if (answer == NSAlertFirstButtonReturn)
|
||||
[[NSWorkspace sharedWorkspace] openURL: [NSURL URLWithString:@"https://www.mono-project.com/download/"]];
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
- (void)exitWithCrashPrompt
|
||||
{
|
||||
[NSApp setActivationPolicy: NSApplicationActivationPolicyRegular];
|
||||
@@ -126,7 +101,7 @@ NSTask *gameTask;
|
||||
}
|
||||
|
||||
[self launchGameWithArgs: gameArgs];
|
||||
[gameArgs release];
|
||||
[gameArgs release];
|
||||
}
|
||||
|
||||
- (void)applicationWillFinishLaunching:(NSNotification *)aNotification
|
||||
@@ -155,15 +130,6 @@ NSTask *gameTask;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (int)hasValidMono
|
||||
{
|
||||
NSTask *task = [[NSTask alloc] init];
|
||||
[task setLaunchPath: [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent: @"Contents/MacOS/checkmono"]];
|
||||
[task launch];
|
||||
[task waitUntilExit];
|
||||
|
||||
return [task terminationStatus] == 0;
|
||||
}
|
||||
|
||||
- (void)launchGameWithArgs: (NSArray *)gameArgs
|
||||
{
|
||||
@@ -175,16 +141,6 @@ NSTask *gameTask;
|
||||
|
||||
launched = YES;
|
||||
|
||||
BOOL useMono = NO;
|
||||
|
||||
if (@available(macOS 10.15, *))
|
||||
useMono = [[[NSProcessInfo processInfo] environment]objectForKey:@"OPENRA_PREFER_MONO"] != nil;
|
||||
else
|
||||
useMono = YES;
|
||||
|
||||
if (useMono && ![self hasValidMono])
|
||||
[self exitWithMonoPrompt];
|
||||
|
||||
// Default values - can be overriden by setting certain keys Info.plist
|
||||
NSString *modId = nil;
|
||||
|
||||
@@ -203,30 +159,21 @@ NSTask *gameTask;
|
||||
NSString *dllPath;
|
||||
NSString *hostPath;
|
||||
|
||||
if (useMono)
|
||||
size_t size;
|
||||
cpu_type_t type;
|
||||
size = sizeof(type);
|
||||
|
||||
if (sysctlbyname("hw.cputype", &type, &size, NULL, 0) == 0 && (type & 0xFF) == CPU_TYPE_ARM)
|
||||
{
|
||||
launchPath = [exePath stringByAppendingPathComponent: @"apphost-mono"];
|
||||
hostPath = [SYSTEM_MONO_PATH stringByAppendingPathComponent: @"lib/libmonosgen-2.0.dylib"];;
|
||||
dllPath = [exePath stringByAppendingPathComponent: @"mono/OpenRA.dll"];
|
||||
launchPath = [exePath stringByAppendingPathComponent: @"apphost-arm64"];
|
||||
hostPath = [exePath stringByAppendingPathComponent: @"arm64/libhostfxr.dylib"];;
|
||||
dllPath = [exePath stringByAppendingPathComponent: @"arm64/OpenRA.dll"];
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t size;
|
||||
cpu_type_t type;
|
||||
size = sizeof(type);
|
||||
|
||||
if (sysctlbyname("hw.cputype", &type, &size, NULL, 0) == 0 && (type & 0xFF) == CPU_TYPE_ARM)
|
||||
{
|
||||
launchPath = [exePath stringByAppendingPathComponent: @"apphost-arm64"];
|
||||
hostPath = [exePath stringByAppendingPathComponent: @"arm64/libhostfxr.dylib"];;
|
||||
dllPath = [exePath stringByAppendingPathComponent: @"arm64/OpenRA.dll"];
|
||||
}
|
||||
else
|
||||
{
|
||||
launchPath = [exePath stringByAppendingPathComponent: @"apphost-x86_64"];
|
||||
hostPath = [exePath stringByAppendingPathComponent: @"x86_64/libhostfxr.dylib"];;
|
||||
dllPath = [exePath stringByAppendingPathComponent: @"x86_64/OpenRA.dll"];
|
||||
}
|
||||
launchPath = [exePath stringByAppendingPathComponent: @"apphost-x86_64"];
|
||||
hostPath = [exePath stringByAppendingPathComponent: @"x86_64/libhostfxr.dylib"];;
|
||||
dllPath = [exePath stringByAppendingPathComponent: @"x86_64/OpenRA.dll"];
|
||||
}
|
||||
|
||||
NSString *appPath = [exePath stringByAppendingPathComponent: @"Launcher"];
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
#include <sys/resource.h>
|
||||
#include <mach/machine.h>
|
||||
|
||||
#define SYSTEM_MONO_PATH @"/Library/Frameworks/Mono.framework/Versions/Current/"
|
||||
#define SYSTEM_MONO_MIN_VERSION @"6.12"
|
||||
#define DOTNET_MIN_MACOS_VERSION 10.15
|
||||
|
||||
typedef void* hostfxr_handle;
|
||||
@@ -35,56 +33,6 @@ typedef int32_t(*hostfxr_initialize_for_dotnet_command_line_fn)(
|
||||
|
||||
typedef int32_t(*hostfxr_run_app_fn)(const hostfxr_handle host_context_handle);
|
||||
typedef int32_t(*hostfxr_close_fn)(const hostfxr_handle host_context_handle);
|
||||
typedef int (*mono_main)(int argc, char **argv);
|
||||
|
||||
int launch_mono(int argc, char **argv, char *modId)
|
||||
{
|
||||
NSString *exePath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent: @"Contents/MacOS/"];
|
||||
NSString *hostPath = [SYSTEM_MONO_PATH stringByAppendingPathComponent: @"lib/libmonosgen-2.0.dylib"];
|
||||
NSString *dllPath = [exePath stringByAppendingPathComponent: @"mono/OpenRA.Utility.dll"];
|
||||
|
||||
// TODO: This snippet increasing the open file limit was copied from
|
||||
// the monodevelop launcher stub. It may not be needed for OpenRA.
|
||||
struct rlimit limit;
|
||||
if (getrlimit(RLIMIT_NOFILE, &limit) == 0 && limit.rlim_cur < 1024)
|
||||
{
|
||||
limit.rlim_cur = limit.rlim_max < 1024 ? limit.rlim_max : 1024;
|
||||
setrlimit(RLIMIT_NOFILE, &limit);
|
||||
}
|
||||
|
||||
void *libmono = dlopen([hostPath UTF8String], RTLD_LAZY);
|
||||
if (!libmono)
|
||||
{
|
||||
NSLog(@"Failed to load libmonosgen-2.0.dylib: %s\n", dlerror());
|
||||
return 1;
|
||||
}
|
||||
|
||||
mono_main _mono_main = (mono_main)dlsym(libmono, "mono_main");
|
||||
if (!_mono_main)
|
||||
{
|
||||
NSLog(@"Could not load mono_main(): %s\n", dlerror());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Insert hostpath, dll and modId as arguments. Overwrite the first argument which was used to launch this application.
|
||||
char **newv = malloc((argc + 2) * sizeof(char*));
|
||||
if (!newv)
|
||||
{
|
||||
NSLog(@"Failed to allocate memory for args array.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
newv[0] = (char*)[hostPath UTF8String];
|
||||
newv[1] = (char*)[dllPath UTF8String];
|
||||
newv[2] = modId;
|
||||
for (int i = 1; i < argc; i++)
|
||||
newv[i + 2] = argv[i];
|
||||
|
||||
int ret = _mono_main(argc + 2, newv);
|
||||
free(newv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int launch_dotnet(int argc, char **argv, char *modId, bool isArmArchitecture)
|
||||
{
|
||||
@@ -173,32 +121,6 @@ int main(int argc, char **argv)
|
||||
size = sizeof(type);
|
||||
bool isArmArchitecture = sysctlbyname("hw.cputype", &type, &size, NULL, 0) == 0 && (type & 0xFF) == CPU_TYPE_ARM;
|
||||
|
||||
BOOL useMono = NO;
|
||||
|
||||
// Before 10.15 macOS didn't support arm.
|
||||
// Mono is compiled for intel only.
|
||||
if (!isArmArchitecture)
|
||||
{
|
||||
if (@available(macOS 10.15, *))
|
||||
useMono = [[[NSProcessInfo processInfo] environment]objectForKey:@"OPENRA_PREFER_MONO"] != nil;
|
||||
else
|
||||
useMono = YES;
|
||||
}
|
||||
|
||||
if (useMono)
|
||||
{
|
||||
NSTask *task = [[NSTask alloc] init];
|
||||
[task setLaunchPath: [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent: @"Contents/MacOS/checkmono"]];
|
||||
[task launch];
|
||||
[task waitUntilExit];
|
||||
|
||||
if ([task terminationStatus] != 0)
|
||||
{
|
||||
NSLog(@"Utility requires Mono %@ or later. Please install Mono and try again.\n", SYSTEM_MONO_MIN_VERSION);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
NSDictionary *plist = [[NSBundle mainBundle] infoDictionary];
|
||||
char *modId;
|
||||
if (plist)
|
||||
@@ -216,11 +138,7 @@ int main(int argc, char **argv)
|
||||
|
||||
setenv("ENGINE_DIR", (char*)[[[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent: @"Contents/Resources/"] UTF8String], 1);
|
||||
|
||||
int ret;
|
||||
if (useMono)
|
||||
ret = launch_mono(argc, argv, modId);
|
||||
else
|
||||
ret = launch_dotnet(argc, argv, modId, isArmArchitecture);
|
||||
int ret = launch_dotnet(argc, argv, modId, isArmArchitecture);
|
||||
|
||||
[pool release];
|
||||
return ret;
|
||||
|
||||
@@ -75,7 +75,7 @@ function build_platform()
|
||||
USE_PROGRAMFILES32=""
|
||||
fi
|
||||
|
||||
install_assemblies "${SRCDIR}" "${BUILTDIR}" "win-${PLATFORM}" "net6" "False" "True" "True"
|
||||
install_assemblies "${SRCDIR}" "${BUILTDIR}" "win-${PLATFORM}" "False" "True" "True"
|
||||
install_data "${SRCDIR}" "${BUILTDIR}" "cnc" "d2k" "ra"
|
||||
set_engine_version "${TAG}" "${BUILTDIR}"
|
||||
set_mod_version "${TAG}" "${BUILTDIR}/mods/cnc/mod.yaml" "${BUILTDIR}/mods/d2k/mod.yaml" "${BUILTDIR}/mods/ra/mod.yaml" "${BUILTDIR}/mods/cnc-content/mod.yaml" "${BUILTDIR}/mods/d2k-content/mod.yaml" "${BUILTDIR}/mods/ra-content/mod.yaml"
|
||||
|
||||
@@ -2,10 +2,5 @@
|
||||
set -o errexit || exit $?
|
||||
|
||||
ENGINEDIR=$(dirname "$0")
|
||||
if command -v mono >/dev/null 2>&1 && [ "$(grep -c .NETCoreApp,Version= "${ENGINEDIR}/bin/OpenRA.Utility.dll")" = "0" ]; then
|
||||
RUNTIME_LAUNCHER="mono --debug"
|
||||
else
|
||||
RUNTIME_LAUNCHER="dotnet"
|
||||
fi
|
||||
|
||||
ENGINE_DIR=.. ${RUNTIME_LAUNCHER} "${ENGINEDIR}/bin/OpenRA.Utility.dll" "$@"
|
||||
ENGINE_DIR=.. dotnet "${ENGINEDIR}/bin/OpenRA.Utility.dll" "$@"
|
||||
|
||||
Reference in New Issue
Block a user