Compare commits
23 Commits
playtest-2
...
playtest-2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5c8db82da | ||
|
|
2a26ff6818 | ||
|
|
5a11d54956 | ||
|
|
26c5a8b76c | ||
|
|
efcfab78dc | ||
|
|
ac351f6e65 | ||
|
|
42bdc9e53e | ||
|
|
3097efc5b6 | ||
|
|
853422409f | ||
|
|
f097250394 | ||
|
|
96e0f96c12 | ||
|
|
0a4c4162be | ||
|
|
10ff24f24e | ||
|
|
aeb96d98f3 | ||
|
|
cf4bfdcdfb | ||
|
|
d55af8d75d | ||
|
|
dd9e75d017 | ||
|
|
1b6220962e | ||
|
|
f70f2acb39 | ||
|
|
32e2507bff | ||
|
|
22a42b7dc9 | ||
|
|
c01e4043e8 | ||
|
|
c8665c98a6 |
46
.github/workflows/packaging.yml
vendored
46
.github/workflows/packaging.yml
vendored
@@ -61,8 +61,8 @@ jobs:
|
||||
file_glob: true
|
||||
file: build/linux/*
|
||||
|
||||
macos:
|
||||
name: macOS Disk Images
|
||||
macos-net:
|
||||
name: macOS .NET
|
||||
runs-on: macos-11
|
||||
steps:
|
||||
- name: Clone Repository
|
||||
@@ -76,7 +76,7 @@ jobs:
|
||||
- name: Prepare Environment
|
||||
run: echo "GIT_TAG=${GITHUB_REF#refs/tags/}" >> ${GITHUB_ENV}
|
||||
|
||||
- name: Package Disk Images
|
||||
- name: Package Disk Image
|
||||
env:
|
||||
MACOS_DEVELOPER_IDENTITY: ${{ secrets.MACOS_DEVELOPER_IDENTITY }}
|
||||
MACOS_DEVELOPER_CERTIFICATE_BASE64: ${{ secrets.MACOS_DEVELOPER_CERTIFICATE_BASE64 }}
|
||||
@@ -85,9 +85,45 @@ jobs:
|
||||
MACOS_DEVELOPER_PASSWORD: ${{ secrets.MACOS_DEVELOPER_PASSWORD }}
|
||||
run: |
|
||||
mkdir -p build/macos
|
||||
./packaging/macos/buildpackage.sh "${GIT_TAG}" "${PWD}/build/macos"
|
||||
./packaging/macos/buildpackage.sh "${GIT_TAG}" "${PWD}/build/macos" "standard" "build.dmg"
|
||||
|
||||
- name: Upload Packages
|
||||
- name: Upload Package
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
||||
file_glob: true
|
||||
file: build/macos/*
|
||||
|
||||
macos-mono:
|
||||
name: macOS Mono
|
||||
runs-on: macos-11
|
||||
|
||||
steps:
|
||||
- name: Clone Repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install .NET 6
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '6.0.x'
|
||||
|
||||
- name: Prepare Environment
|
||||
run: echo "GIT_TAG=${GITHUB_REF#refs/tags/}" >> ${GITHUB_ENV}
|
||||
|
||||
- name: Package Disk Image
|
||||
env:
|
||||
MACOS_DEVELOPER_IDENTITY: ${{ secrets.MACOS_DEVELOPER_IDENTITY }}
|
||||
MACOS_DEVELOPER_CERTIFICATE_BASE64: ${{ secrets.MACOS_DEVELOPER_CERTIFICATE_BASE64 }}
|
||||
MACOS_DEVELOPER_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_DEVELOPER_CERTIFICATE_PASSWORD }}
|
||||
MACOS_DEVELOPER_USERNAME: ${{ secrets.MACOS_DEVELOPER_USERNAME }}
|
||||
MACOS_DEVELOPER_PASSWORD: ${{ secrets.MACOS_DEVELOPER_PASSWORD }}
|
||||
run: |
|
||||
mkdir -p build/macos
|
||||
./packaging/macos/buildpackage.sh "${GIT_TAG}" "${PWD}/build/macos" "mono" "build-mono.dmg"
|
||||
|
||||
- name: Upload Package
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -57,12 +57,12 @@ namespace OpenRA.Network
|
||||
|
||||
void IConnection.Send(int frame, IEnumerable<Order> o)
|
||||
{
|
||||
orders.Enqueue((frame, new OrderPacket(o.ToArray())));
|
||||
orders.Enqueue((frame, new OrderPacket(o)));
|
||||
}
|
||||
|
||||
void IConnection.SendImmediate(IEnumerable<Order> o)
|
||||
{
|
||||
immediateOrders.Enqueue(new OrderPacket(o.ToArray()));
|
||||
immediateOrders.Enqueue(new OrderPacket(o));
|
||||
}
|
||||
|
||||
void IConnection.SendSync(int frame, int syncHash, ulong defeatState)
|
||||
@@ -230,14 +230,14 @@ namespace OpenRA.Network
|
||||
|
||||
void IConnection.Send(int frame, IEnumerable<Order> orders)
|
||||
{
|
||||
var o = new OrderPacket(orders.ToArray());
|
||||
var o = new OrderPacket(orders);
|
||||
sentOrders.Enqueue((frame, o));
|
||||
Send(o.Serialize(frame));
|
||||
}
|
||||
|
||||
void IConnection.SendImmediate(IEnumerable<Order> orders)
|
||||
{
|
||||
var o = new OrderPacket(orders.ToArray());
|
||||
var o = new OrderPacket(orders);
|
||||
sentImmediateOrders.Enqueue(o);
|
||||
Send(o.Serialize(0));
|
||||
}
|
||||
|
||||
@@ -17,32 +17,32 @@ namespace OpenRA.Network
|
||||
{
|
||||
public class OrderPacket
|
||||
{
|
||||
readonly Order[] orders;
|
||||
readonly MemoryStream data;
|
||||
public OrderPacket(Order[] orders)
|
||||
public OrderPacket(IEnumerable<Order> orders)
|
||||
{
|
||||
this.orders = orders;
|
||||
data = null;
|
||||
// Orders may refer to actors that no longer exist by the time
|
||||
// that the order is resolved. In order to ensure consistent
|
||||
// behaviour between local and remote clients, it is simplest
|
||||
// to always serialize / deserialize orders, instead of storing
|
||||
// the Order objects directly on the local client.
|
||||
data = new MemoryStream();
|
||||
foreach (var o in orders)
|
||||
data.WriteArray(o.Serialize());
|
||||
}
|
||||
|
||||
public OrderPacket(MemoryStream data)
|
||||
{
|
||||
orders = null;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public IEnumerable<Order> GetOrders(World world)
|
||||
{
|
||||
return orders ?? ParseData(world);
|
||||
}
|
||||
|
||||
IEnumerable<Order> ParseData(World world)
|
||||
{
|
||||
if (data == null)
|
||||
if (data.Length == 0)
|
||||
yield break;
|
||||
|
||||
// Order deserialization depends on the current world state,
|
||||
// so must be deferred until we are ready to consume them.
|
||||
data.Position = 0;
|
||||
var reader = new BinaryReader(data);
|
||||
while (data.Position < data.Length)
|
||||
{
|
||||
@@ -54,28 +54,25 @@ namespace OpenRA.Network
|
||||
|
||||
public byte[] Serialize(int frame)
|
||||
{
|
||||
if (data != null)
|
||||
return data.ToArray();
|
||||
|
||||
var ms = new MemoryStream();
|
||||
var ms = new MemoryStream((int)data.Length + 4);
|
||||
ms.WriteArray(BitConverter.GetBytes(frame));
|
||||
foreach (var o in orders)
|
||||
ms.WriteArray(o.Serialize());
|
||||
return ms.ToArray();
|
||||
|
||||
data.Position = 0;
|
||||
data.CopyTo(ms);
|
||||
|
||||
return ms.GetBuffer();
|
||||
}
|
||||
|
||||
public static OrderPacket Combine(IEnumerable<OrderPacket> packets)
|
||||
{
|
||||
var orders = new List<Order>();
|
||||
var ms = new MemoryStream();
|
||||
foreach (var packet in packets)
|
||||
{
|
||||
if (packet.orders == null)
|
||||
throw new InvalidOperationException("OrderPacket.Combine can only be used with locally generated OrderPackets.");
|
||||
|
||||
orders.AddRange(packet.orders);
|
||||
packet.data.Position = 0;
|
||||
packet.data.CopyTo(ms);
|
||||
}
|
||||
|
||||
return new OrderPacket(orders.ToArray());
|
||||
return new OrderPacket(ms);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,9 +56,9 @@ namespace OpenRA
|
||||
return BuildExceptionReport(ex, new StringBuilder(), 0);
|
||||
}
|
||||
|
||||
static StringBuilder AppendIndentedFormatLine(this StringBuilder sb, int indent, string format, params object[] args)
|
||||
static StringBuilder AppendIndentedLine(this StringBuilder sb, int indent, string message)
|
||||
{
|
||||
return sb.Append(new string(' ', indent * 2)).AppendFormat(format, args).AppendLine();
|
||||
return sb.Append(new string(' ', indent * 2)).Append(message).AppendLine();
|
||||
}
|
||||
|
||||
static StringBuilder BuildExceptionReport(Exception ex, StringBuilder sb, int indent)
|
||||
@@ -66,11 +66,11 @@ namespace OpenRA
|
||||
if (ex == null)
|
||||
return sb;
|
||||
|
||||
sb.AppendIndentedFormatLine(indent, $"Exception of type `{ex.GetType().FullName}`: {ex.Message}");
|
||||
sb.AppendIndentedLine(indent, $"Exception of type `{ex.GetType().FullName}`: {ex.Message}");
|
||||
|
||||
if (ex is TypeLoadException tle)
|
||||
{
|
||||
sb.AppendIndentedFormatLine(indent, $"TypeName=`{tle.TypeName}`");
|
||||
sb.AppendIndentedLine(indent, $"TypeName=`{tle.TypeName}`");
|
||||
}
|
||||
else if (ex is OutOfMemoryException)
|
||||
{
|
||||
@@ -78,14 +78,14 @@ namespace OpenRA
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
GC.Collect();
|
||||
sb.AppendIndentedFormatLine(indent, $"GC Memory (post-collect)={GC.GetTotalMemory(false):N0}");
|
||||
sb.AppendIndentedFormatLine(indent, $"GC Memory (pre-collect)={gcMemoryBeforeCollect:N0}");
|
||||
sb.AppendIndentedLine(indent, $"GC Memory (post-collect)={GC.GetTotalMemory(false):N0}");
|
||||
sb.AppendIndentedLine(indent, $"GC Memory (pre-collect)={gcMemoryBeforeCollect:N0}");
|
||||
|
||||
using (var p = Process.GetCurrentProcess())
|
||||
{
|
||||
sb.AppendIndentedFormatLine(indent, $"Working Set={p.WorkingSet64:N0}");
|
||||
sb.AppendIndentedFormatLine(indent, $"Private Memory={p.PrivateMemorySize64:N0}");
|
||||
sb.AppendIndentedFormatLine(indent, $"Virtual Memory={p.VirtualMemorySize64:N0}");
|
||||
sb.AppendIndentedLine(indent, $"Working Set={p.WorkingSet64:N0}");
|
||||
sb.AppendIndentedLine(indent, $"Private Memory={p.PrivateMemorySize64:N0}");
|
||||
sb.AppendIndentedLine(indent, $"Virtual Memory={p.VirtualMemorySize64:N0}");
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -95,11 +95,11 @@ namespace OpenRA
|
||||
|
||||
if (ex.InnerException != null)
|
||||
{
|
||||
sb.AppendIndentedFormatLine(indent, "Inner");
|
||||
sb.AppendIndentedLine(indent, "Inner");
|
||||
BuildExceptionReport(ex.InnerException, sb, indent + 1);
|
||||
}
|
||||
|
||||
sb.AppendIndentedFormatLine(indent, ex.StackTrace);
|
||||
sb.AppendIndentedLine(indent, ex.StackTrace);
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
@@ -65,15 +65,12 @@ namespace OpenRA.Mods.Common.Activities
|
||||
|
||||
public override bool Tick(Actor self)
|
||||
{
|
||||
if (cargo != carryall.Carryable)
|
||||
return true;
|
||||
|
||||
if (IsCanceling)
|
||||
{
|
||||
if (carryall.State == Carryall.CarryallState.Reserved)
|
||||
carryall.UnreserveCarryable(self);
|
||||
|
||||
// Make sure we run the TakeOff activity if we are / have landed
|
||||
// Make sure we run the TakeOff activity if we are/have landed
|
||||
if (self.Trait<Aircraft>().HasInfluence())
|
||||
{
|
||||
ChildHasPriority = true;
|
||||
@@ -85,10 +82,11 @@ namespace OpenRA.Mods.Common.Activities
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cargo.IsDead || carryable.IsTraitDisabled || !cargo.AppearsFriendlyTo(self))
|
||||
if (cargo != carryall.Carryable || cargo.IsDead || carryable.IsTraitDisabled || !cargo.AppearsFriendlyTo(self))
|
||||
{
|
||||
carryall.UnreserveCarryable(self);
|
||||
return true;
|
||||
Cancel(self, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Wait until we are near the target before we try to lock it
|
||||
@@ -100,7 +98,10 @@ namespace OpenRA.Mods.Common.Activities
|
||||
{
|
||||
var lockResponse = carryable.LockForPickup(cargo, self);
|
||||
if (lockResponse == LockResponse.Failed)
|
||||
Cancel(self);
|
||||
{
|
||||
Cancel(self, true);
|
||||
return false;
|
||||
}
|
||||
else if (lockResponse == LockResponse.Success)
|
||||
{
|
||||
// Pickup position and facing are now known - swap the fly/wait activity with Land
|
||||
|
||||
@@ -32,6 +32,15 @@ namespace OpenRA.Mods.Common.Lint
|
||||
var language = "en";
|
||||
var translation = new Translation(language, modData.Manifest.Translations, modData.DefaultFileSystem);
|
||||
|
||||
var gameSpeeds = modData.Manifest.Get<GameSpeeds>();
|
||||
foreach (var speed in gameSpeeds.Speeds.Values)
|
||||
{
|
||||
if (!translation.HasMessage(speed.Name))
|
||||
emitError($"{speed.Name} not present in {language} translation.");
|
||||
|
||||
referencedKeys.Add(speed.Name);
|
||||
}
|
||||
|
||||
foreach (var modType in modData.ObjectCreator.GetTypes())
|
||||
{
|
||||
foreach (var fieldInfo in modType.GetFields(Binding).Where(m => m.HasAttribute<TranslationReferenceAttribute>()))
|
||||
|
||||
@@ -1132,7 +1132,7 @@ namespace OpenRA.Mods.Common.Pathfinder
|
||||
if (maybeAbstractCell == null)
|
||||
throw new Exception(
|
||||
"The abstract path should never be searched for an unreachable point. " +
|
||||
"This is a bug. Failed lookup for an abstract cell.");
|
||||
$"Cell {cell} failed lookup for an abstract cell.");
|
||||
}
|
||||
|
||||
var abstractCell = maybeAbstractCell.Value;
|
||||
@@ -1145,7 +1145,7 @@ namespace OpenRA.Mods.Common.Pathfinder
|
||||
if (!abstractSearch.ExpandToTarget())
|
||||
throw new Exception(
|
||||
"The abstract path should never be searched for an unreachable point. " +
|
||||
"This is a bug. Failed to route to abstract cell.");
|
||||
$"Abstract cell {abstractCell} failed to route to abstract cell.");
|
||||
info = graph[abstractCell];
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,9 @@ namespace OpenRA.Mods.Common.Projectiles
|
||||
[Desc("How far beyond the target the projectile keeps on travelling.")]
|
||||
public readonly WDist BeyondTargetRange = new WDist(0);
|
||||
|
||||
[Desc("The minimum distance the beam travels.")]
|
||||
public readonly WDist MinDistance = WDist.Zero;
|
||||
|
||||
[Desc("Damage modifier applied at each range step.")]
|
||||
public readonly int[] Falloff = { 100, 100 };
|
||||
|
||||
@@ -136,7 +139,19 @@ namespace OpenRA.Mods.Common.Projectiles
|
||||
// Update the target position with the range we shoot beyond the target by
|
||||
// I.e. we can deliberately overshoot, so aim for that position
|
||||
var dir = new WVec(0, -1024, 0).Rotate(WRot.FromYaw(towardsTargetFacing));
|
||||
target += dir * info.BeyondTargetRange.Length / 1024;
|
||||
var dist = (args.SourceActor.CenterPosition - target).Length;
|
||||
int extraDist;
|
||||
if (info.MinDistance.Length > dist)
|
||||
{
|
||||
if (info.MinDistance.Length - dist < info.BeyondTargetRange.Length)
|
||||
extraDist = info.BeyondTargetRange.Length;
|
||||
else
|
||||
extraDist = info.MinDistance.Length - dist;
|
||||
}
|
||||
else
|
||||
extraDist = info.BeyondTargetRange.Length;
|
||||
|
||||
target += dir * extraDist / 1024;
|
||||
|
||||
length = Math.Max((target - headPos).Length / speed.Length, 1);
|
||||
weaponRange = new WDist(Util.ApplyPercentageModifiers(args.Weapon.Range.Length, args.RangeModifiers));
|
||||
|
||||
@@ -868,8 +868,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public void AddInfluence((CPos, SubCell)[] landingCells)
|
||||
{
|
||||
if (HasInfluence())
|
||||
throw new InvalidOperationException(
|
||||
$"Cannot {nameof(AddInfluence)} until previous influence is removed with {nameof(RemoveInfluence)}");
|
||||
self.World.ActorMap.RemoveInfluence(self, this);
|
||||
|
||||
this.landingCells = landingCells;
|
||||
if (self.IsInWorld)
|
||||
|
||||
@@ -106,30 +106,33 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
readonly Actor cargo;
|
||||
readonly Carryable carryable;
|
||||
readonly CarryallInfo carryallInfo;
|
||||
readonly Carryall carryall;
|
||||
|
||||
public FerryUnit(Actor self, Actor cargo)
|
||||
{
|
||||
this.cargo = cargo;
|
||||
carryable = cargo.Trait<Carryable>();
|
||||
carryallInfo = self.Trait<Carryall>().Info;
|
||||
carryall = self.Trait<Carryall>();
|
||||
}
|
||||
|
||||
protected override void OnFirstRun(Actor self)
|
||||
{
|
||||
if (!cargo.IsDead)
|
||||
QueueChild(new PickupUnit(self, cargo, 0, carryallInfo.TargetLineColor));
|
||||
QueueChild(new PickupUnit(self, cargo, 0, carryall.Info.TargetLineColor));
|
||||
}
|
||||
|
||||
public override bool Tick(Actor self)
|
||||
{
|
||||
if (cargo.IsDead)
|
||||
{
|
||||
carryall.UnreserveCarryable(self);
|
||||
return true;
|
||||
}
|
||||
|
||||
var dropRange = carryallInfo.DropRange;
|
||||
var dropRange = carryall.Info.DropRange;
|
||||
var destination = carryable.Destination;
|
||||
if (destination != null)
|
||||
self.QueueActivity(true, new DeliverUnit(self, Target.FromCell(self.World, destination.Value), dropRange, carryallInfo.TargetLineColor));
|
||||
self.QueueActivity(true, new DeliverUnit(self, Target.FromCell(self.World, destination.Value), dropRange, carryall.Info.TargetLineColor));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
// Find new harvesters
|
||||
// TODO: Look for a more performance-friendly way to update this list
|
||||
var newHarvesters = world.ActorsHavingTrait<Harvester>().Where(a => a.Owner == player && !harvesters.ContainsKey(a));
|
||||
var newHarvesters = world.ActorsHavingTrait<Harvester>().Where(a => !unitCannotBeOrdered(a) && !harvesters.ContainsKey(a));
|
||||
foreach (var a in newHarvesters)
|
||||
harvesters[a] = new HarvesterTraitWrapper(a);
|
||||
|
||||
|
||||
@@ -256,7 +256,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public virtual void UnreserveCarryable(Actor self)
|
||||
{
|
||||
if (Carryable != null && Carryable.IsInWorld && !Carryable.IsDead)
|
||||
Carryable.Trait<Carryable>().UnReserve(Carryable);
|
||||
{
|
||||
var carryable = Carryable.Trait<Carryable>();
|
||||
if (carryable.Carrier == self)
|
||||
carryable.UnReserve(Carryable);
|
||||
}
|
||||
|
||||
Carryable = null;
|
||||
State = CarryallState.Idle;
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
var dataTotal = 0.0f;
|
||||
var mag = 0;
|
||||
var dataSuffix = "";
|
||||
var host = downloadHost ?? UnknownHost;
|
||||
var host = downloadHost ?? modData.Translation.GetString(UnknownHost);
|
||||
|
||||
if (total < 0)
|
||||
{
|
||||
@@ -139,11 +139,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
|
||||
Action<string> onError = s => Game.RunAfterTick(() =>
|
||||
{
|
||||
Log.Write("install", "Download failed: " + s);
|
||||
var host = downloadHost ?? modData.Translation.GetString(UnknownHost);
|
||||
Log.Write("install", $"Download from {host} failed: " + s);
|
||||
|
||||
progressBar.Indeterminate = false;
|
||||
progressBar.Percentage = 100;
|
||||
getStatusText = () => "Error: " + s;
|
||||
getStatusText = () => $"{host}: Error: {s}";
|
||||
retryButton.IsVisible = () => true;
|
||||
cancelButton.OnClick = Ui.CloseWindow;
|
||||
});
|
||||
|
||||
@@ -1549,7 +1549,7 @@ Container@PLAYER_WIDGETS:
|
||||
X: WINDOW_RIGHT - WIDTH - 5
|
||||
Y: 5
|
||||
Width: 230
|
||||
Height: 291
|
||||
Height: 314
|
||||
ImageCollection: sidebar
|
||||
ImageName: background-sidebar
|
||||
ClickThrough: false
|
||||
|
||||
@@ -13,6 +13,7 @@ Sound:
|
||||
Falloff: 0, 0, 100, 0
|
||||
Range: 0, 0c450, 4c0, 8c0
|
||||
BeyondTargetRange: 1c0
|
||||
MinDistance: 5c0
|
||||
Color: 00FFFFC8
|
||||
Warhead@1Dam: SpreadDamage
|
||||
Range: 0, 32
|
||||
|
||||
@@ -603,7 +603,7 @@ Container@PLAYER_WIDGETS:
|
||||
X: WINDOW_RIGHT - 250
|
||||
Y: 272
|
||||
Width: 238
|
||||
Height: 27
|
||||
Height: 28
|
||||
ImageCollection: sidebar
|
||||
ImageName: background-moneybin
|
||||
ClickThrough: false
|
||||
|
||||
@@ -3,4 +3,10 @@ set -o errexit || exit $?
|
||||
|
||||
cd "{GAME_INSTALL_DIR}"
|
||||
|
||||
mono {DEBUG} OpenRA.Server.dll Game.Mod={MODID} "$@"
|
||||
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
|
||||
|
||||
@@ -11,7 +11,13 @@ if [ "${1#${PROTOCOL_PREFIX}}" != "${1}" ]; then
|
||||
fi
|
||||
|
||||
# Run the game
|
||||
mono {DEBUG} OpenRA.dll Game.Mod={MODID} Engine.LaunchPath="{BIN_DIR}/openra-{MODID}" "${JOIN_SERVER}" "$@" && rc=0 || rc=$?
|
||||
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
|
||||
|
||||
# Show a crash dialog if something went wrong
|
||||
if [ "${rc}" != 0 ] && [ "${rc}" != 1 ]; then
|
||||
|
||||
@@ -48,5 +48,7 @@
|
||||
<string>{JOIN_SERVER_URL_SCHEME}</string>
|
||||
<key>NSRequiresAquaSystemAppearance</key>
|
||||
<false/>
|
||||
<key>NSPrefersDisplaySafeAreaCompatibilityMode</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -16,15 +16,13 @@
|
||||
|
||||
set -o errexit -o pipefail || exit $?
|
||||
|
||||
MONO_TAG="osx-launcher-20201222"
|
||||
|
||||
if [ $# -ne "2" ]; then
|
||||
echo "Usage: $(basename "$0") tag outputdir"
|
||||
if [[ "${OSTYPE}" != "darwin"* ]]; then
|
||||
echo >&2 "macOS packaging requires a macOS host"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${OSTYPE}" != "darwin"* ]]; then
|
||||
echo >&2 "macOS packaging requires a macOS host"
|
||||
if [ $# -ne "4" ]; then
|
||||
echo "Usage: $(basename "$0") tag outputdir platform dmg"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -108,7 +106,7 @@ build_app() {
|
||||
|
||||
# Sign binaries with developer certificate
|
||||
if [ -n "${MACOS_DEVELOPER_IDENTITY}" ]; then
|
||||
codesign -s "${MACOS_DEVELOPER_IDENTITY}" --timestamp --options runtime -f --entitlements entitlements.plist --deep "${LAUNCHER_DIR}"
|
||||
codesign --sign "${MACOS_DEVELOPER_IDENTITY}" --timestamp --options runtime -f --entitlements entitlements.plist --deep "${LAUNCHER_DIR}"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -218,43 +216,23 @@ notarize_package() {
|
||||
# Create a temporary read-only dmg for submission (notarization service rejects read/write images)
|
||||
hdiutil convert "${DMG_PATH}" -format ULFO -ov -o "${NOTARIZE_DMG_PATH}"
|
||||
|
||||
NOTARIZATION_UUID=$(xcrun altool --notarize-app --primary-bundle-id "net.openra.packaging" -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
|
||||
xcrun notarytool submit "${NOTARIZE_DMG_PATH}" --wait --apple-id "${MACOS_DEVELOPER_USERNAME}" --password "${MACOS_DEVELOPER_PASSWORD}" --team-id "${MACOS_DEVELOPER_IDENTITY}"
|
||||
|
||||
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}"
|
||||
echo "${DMG_PATH}: Stapling tickets"
|
||||
DMG_DEVICE=$(hdiutil attach -readwrite -noverify -noautoopen "${DMG_PATH}" | egrep '^/dev/' | sed 1q | awk '{print $1}')
|
||||
sleep 2
|
||||
|
||||
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
|
||||
xcrun stapler staple "/Volumes/OpenRA/OpenRA - Red Alert.app"
|
||||
xcrun stapler staple "/Volumes/OpenRA/OpenRA - Tiberian Dawn.app"
|
||||
xcrun stapler staple "/Volumes/OpenRA/OpenRA - Dune 2000.app"
|
||||
|
||||
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
|
||||
sync
|
||||
sync
|
||||
|
||||
xcrun stapler staple "/Volumes/OpenRA/OpenRA - Red Alert.app"
|
||||
xcrun stapler staple "/Volumes/OpenRA/OpenRA - Tiberian Dawn.app"
|
||||
xcrun stapler staple "/Volumes/OpenRA/OpenRA - Dune 2000.app"
|
||||
|
||||
sync
|
||||
sync
|
||||
|
||||
hdiutil detach "${DMG_DEVICE}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
hdiutil detach "${DMG_DEVICE}"
|
||||
break
|
||||
}
|
||||
|
||||
finalize_package() {
|
||||
@@ -263,33 +241,26 @@ finalize_package() {
|
||||
OUTPUT_PATH="${3}"
|
||||
|
||||
if [ "${PLATFORM}" = "mono" ]; then
|
||||
hdiutil convert "${INPUT_PATH}" -format UDZO -imagekey zlib-level=9 -ov -o "${OUTPUT_PATH}"
|
||||
hdiutil convert "${INPUT_PATH}" -format UDZO -imagekey zlib-level=9 -ov -o "${OUTPUT_PATH}-mono.dmg"
|
||||
else
|
||||
# ULFO offers better compression and faster decompression speeds, but is only supported by 10.11+
|
||||
hdiutil convert "${INPUT_PATH}" -format ULFO -ov -o "${OUTPUT_PATH}"
|
||||
hdiutil convert "${INPUT_PATH}" -format ULFO -ov -o "${OUTPUT_PATH}.dmg"
|
||||
fi
|
||||
|
||||
rm "${INPUT_PATH}"
|
||||
}
|
||||
|
||||
build_platform "standard" "build.dmg"
|
||||
build_platform "mono" "build-mono.dmg"
|
||||
PLATFORM="$3"
|
||||
DISK_IMAGE="$4"
|
||||
|
||||
build_platform "${PLATFORM}" "${DISK_IMAGE}"
|
||||
|
||||
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") || exit 1 &
|
||||
(notarize_package "build-mono.dmg") || exit 1 &
|
||||
while wait -n; rc=$?; [ "${rc}" != 127 ]; do
|
||||
if [ "${rc}" != 0 ]; then
|
||||
wait
|
||||
exit "${rc}"
|
||||
fi
|
||||
done
|
||||
if [ -n "${MACOS_DEVELOPER_USERNAME}" ] && [ -n "${MACOS_DEVELOPER_PASSWORD}" ] && [ -n "${MACOS_DEVELOPER_IDENTITY}" ]; then
|
||||
notarize_package "${DISK_IMAGE}"
|
||||
fi
|
||||
|
||||
finalize_package "standard" "build.dmg" "${OUTPUTDIR}/OpenRA-${TAG}.dmg"
|
||||
finalize_package "mono" "build-mono.dmg" "${OUTPUTDIR}/OpenRA-${TAG}-mono.dmg"
|
||||
finalize_package "${PLATFORM}" "${DISK_IMAGE}" "${OUTPUTDIR}/OpenRA-${TAG}"
|
||||
|
||||
Reference in New Issue
Block a user