Skip to content

Commit 2c82f67

Browse files
authored
Merge pull request #254 from SignatureBeef/net9-upgrade
Upgrade to .NET 9 and OTAPI Static Hooks for ARM64
2 parents d4bb7e3 + d712022 commit 2c82f67

File tree

15 files changed

+625
-602
lines changed

15 files changed

+625
-602
lines changed

.github/workflows/build.yml

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,37 @@ on:
1212
jobs:
1313
# This workflow contains a single job called "build"
1414
build:
15+
strategy:
16+
fail-fast: false
17+
matrix:
18+
os: [
19+
{
20+
name: Windows,
21+
runs-on: windows-latest,
22+
},
23+
{
24+
name: Ubuntu,
25+
runs-on: ubuntu-latest,
26+
},
27+
{
28+
name: MacOS,
29+
runs-on: macos-latest,
30+
}
31+
]
32+
1533
# The type of runner that the job will run on
16-
runs-on: windows-latest
34+
runs-on: ${{ matrix.os.runs-on }}
35+
36+
name: ${{ matrix.os.name }}
1737

1838
# Steps represent a sequence of tasks that will be executed as part of the job
1939
steps:
2040
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
21-
- uses: actions/checkout@v3
41+
- uses: actions/checkout@v4
2242

23-
- uses: actions/setup-dotnet@v3
43+
- uses: actions/setup-dotnet@v4
2444
with:
25-
dotnet-version: '6.0.100'
45+
dotnet-version: 9.0.x
2646

2747
- name: MonoMod dev build
2848
run: dotnet nuget add source https://pkgs.dev.azure.com/MonoMod/MonoMod/_packaging/DevBuilds%40Local/nuget/v3/index.json -n DevBuilds@Local
@@ -32,9 +52,3 @@ jobs:
3252

3353
- name: Run tests
3454
run: dotnet test --filter "FullyQualifiedName!~TerrariaServerAPI.Tests.Benchmarks"
35-
36-
# example task for the release CI
37-
# - name: "Releasing to NuGet: TSAPI"
38-
# env:
39-
# NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
40-
# run: dotnet nuget push ./TerrariaServerAPI/bin/Release/TerrariaServer.*.nupkg --source https://api.nuget.org/v3/index.json --api-key "$env:NUGET_API_KEY"

.github/workflows/nuget.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ jobs:
1111
environment: release
1212

1313
steps:
14-
- uses: actions/checkout@v3
14+
- uses: actions/checkout@v4
1515
- name: Setup .NET
16-
uses: actions/setup-dotnet@v3
16+
uses: actions/setup-dotnet@v4
1717
with:
18-
dotnet-version: 6.0.400
18+
dotnet-version: 9.0.x
1919
- name: Restore dependencies
2020
run: dotnet restore
2121
- name: Build
Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using NUnit.Framework;
2-
using System;
3-
using System.Threading;
2+
using System.Runtime.InteropServices;
43

54
namespace TerrariaServerAPI.Tests;
65

@@ -13,24 +12,26 @@ public void EnsureInitialised()
1312
{
1413
if (!_initialized)
1514
{
16-
var are = new AutoResetEvent(false);
17-
Exception? error = null;
18-
On.Terraria.Main.hook_DedServ cb = (On.Terraria.Main.orig_DedServ orig, Terraria.Main instance) =>
15+
TestContext.Out.WriteLine($"Test architecture {RuntimeInformation.ProcessArchitecture}");
16+
17+
bool invoked = false;
18+
HookEvents.HookDelegate<Terraria.Main, HookEvents.Terraria.Main.DedServEventArgs> cb = (instance, args) =>
1919
{
20+
invoked = true;
21+
// DedServ typically requires input, so no need to continue execution
22+
args.ContinueExecution = false;
23+
// DedServ calls the following, which is needed for subsequent tests
2024
instance.Initialize();
21-
are.Set();
22-
_initialized = true;
2325
};
24-
On.Terraria.Main.DedServ += cb;
26+
HookEvents.Terraria.Main.DedServ += cb;
2527

26-
global::TerrariaApi.Server.Program.Main(new string[] { });
28+
TerrariaApi.Server.Program.Main([]);
2729

28-
_initialized = are.WaitOne(TimeSpan.FromSeconds(30));
30+
HookEvents.Terraria.Main.DedServ -= cb;
2931

30-
On.Terraria.Main.DedServ -= cb;
32+
Assert.That(invoked, Is.True);
3133

32-
Assert.That(_initialized, Is.True);
33-
Assert.That(error, Is.Null);
34+
_initialized = true;
3435
}
3536
}
3637
}

TerrariaServerAPI.Tests/ServerInitTests.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using NUnit.Framework;
2+
using System.Runtime.InteropServices;
23

34
namespace TerrariaServerAPI.Tests;
45

@@ -9,4 +10,25 @@ public void EnsureBoots()
910
{
1011
EnsureInitialised();
1112
}
13+
14+
[Test]
15+
public void EnsureRuntimeDetours()
16+
{
17+
// Platform exclude doesnt support arm64, so manual check it is...
18+
if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
19+
Assert.Ignore("Test is not supported on ARM64 architecture.");
20+
21+
TestContext.Out.WriteLine($"Test architecture {RuntimeInformation.ProcessArchitecture}");
22+
23+
bool invoked = false;
24+
25+
On.Terraria.Program.hook_RunGame callback = (orig) => invoked = true;
26+
On.Terraria.Program.RunGame += callback;
27+
28+
Terraria.Program.RunGame();
29+
30+
On.Terraria.Program.RunGame -= callback;
31+
32+
Assert.That(invoked, Is.True);
33+
}
1234
}

TerrariaServerAPI.Tests/TerrariaServerAPI.Tests.csproj

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net6.0</TargetFramework>
4+
<TargetFramework>net9.0</TargetFramework>
55
<Nullable>enable</Nullable>
66

77
<IsPackable>false</IsPackable>
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="BenchmarkDotNet" Version="0.13.2" />
12-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
13-
<PackageReference Include="NUnit" Version="3.13.3" />
14-
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
15-
<PackageReference Include="NUnit.Analyzers" Version="3.3.0" />
16-
<PackageReference Include="coverlet.collector" Version="3.1.2">
11+
<PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
12+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
13+
<PackageReference Include="NUnit" Version="4.3.2" />
14+
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
15+
<PackageReference Include="NUnit.Analyzers" Version="4.5.0">
16+
<PrivateAssets>all</PrivateAssets>
17+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
18+
</PackageReference>
19+
<PackageReference Include="coverlet.collector" Version="6.0.3">
1720
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1821
<PrivateAssets>all</PrivateAssets>
1922
</PackageReference>

TerrariaServerAPI/TerrariaApi.Server/HookManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public static void InitialiseAPI()
2424
ServerApi.ApiVersion,
2525
Main.versionNumber2,
2626
Main.curRelease,
27-
typeof(OTAPI.Hooks).Assembly.GetName().Version
27+
OTAPI.Common.VersionShort
2828
);
2929
ServerApi.Initialize(Environment.GetCommandLineArgs(), Main.instance);
3030
}
Lines changed: 70 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,96 @@
1-
using Microsoft.Xna.Framework;
2-
using OTAPI;
1+
using OTAPI;
32

4-
namespace TerrariaApi.Server.Hooking
3+
namespace TerrariaApi.Server.Hooking;
4+
5+
internal static class GameHooks
56
{
6-
internal static class GameHooks
7+
private static HookManager _hookManager;
8+
9+
/// <summary>
10+
/// Attaches any of the OTAPI Game hooks to the existing <see cref="HookManager"/> implementation
11+
/// </summary>
12+
/// <param name="hookManager">HookManager instance which will receive the events</param>
13+
public static void AttachTo(HookManager hookManager)
714
{
8-
private static HookManager _hookManager;
15+
_hookManager = hookManager;
916

10-
/// <summary>
11-
/// Attaches any of the OTAPI Game hooks to the existing <see cref="HookManager"/> implementation
12-
/// </summary>
13-
/// <param name="hookManager">HookManager instance which will receive the events</param>
14-
public static void AttachTo(HookManager hookManager)
15-
{
16-
_hookManager = hookManager;
17+
HookEvents.Terraria.Main.Update += OnUpdate;
18+
HookEvents.Terraria.Main.Initialize += OnInitialize;
19+
HookEvents.Terraria.Netplay.StartServer += OnStartServer;
1720

18-
On.Terraria.Main.Update += OnUpdate;
19-
On.Terraria.Main.Initialize += OnInitialize;
20-
On.Terraria.Netplay.StartServer += OnStartServer;
21+
Hooks.WorldGen.HardmodeTilePlace += OnHardmodeTilePlace;
22+
Hooks.WorldGen.HardmodeTileUpdate += OnHardmodeTileUpdate;
23+
Hooks.Item.MechSpawn += OnItemMechSpawn;
24+
Hooks.NPC.MechSpawn += OnNpcMechSpawn;
25+
}
2126

22-
Hooks.WorldGen.HardmodeTilePlace += OnHardmodeTilePlace;
23-
Hooks.WorldGen.HardmodeTileUpdate += OnHardmodeTileUpdate;
24-
Hooks.Item.MechSpawn += OnItemMechSpawn;
25-
Hooks.NPC.MechSpawn += OnNpcMechSpawn;
26-
}
27+
private static void OnUpdate(Terraria.Main instance, HookEvents.Terraria.Main.UpdateEventArgs args)
28+
{
29+
if (!args.ContinueExecution) return;
30+
args.ContinueExecution = false;
31+
_hookManager.InvokeGameUpdate();
32+
args.OriginalMethod(args.gameTime);
33+
_hookManager.InvokeGamePostUpdate();
34+
}
2735

28-
private static void OnUpdate(On.Terraria.Main.orig_Update orig, Terraria.Main instance, GameTime gameTime)
36+
private static void OnHardmodeTileUpdate(object sender, Hooks.WorldGen.HardmodeTileUpdateEventArgs e)
37+
{
38+
if (e.Result == HookResult.Cancel)
2939
{
30-
_hookManager.InvokeGameUpdate();
31-
orig(instance, gameTime);
32-
_hookManager.InvokeGamePostUpdate();
40+
return;
3341
}
34-
35-
private static void OnHardmodeTileUpdate(object sender, Hooks.WorldGen.HardmodeTileUpdateEventArgs e)
42+
if (_hookManager.InvokeGameHardmodeTileUpdate(e.X, e.Y, e.Type))
3643
{
37-
if (e.Result == HookResult.Cancel)
38-
{
39-
return;
40-
}
41-
if (_hookManager.InvokeGameHardmodeTileUpdate(e.X, e.Y, e.Type))
42-
{
43-
e.Result = HookResult.Cancel;
44-
}
44+
e.Result = HookResult.Cancel;
4545
}
46+
}
4647

47-
private static void OnHardmodeTilePlace(object sender, Hooks.WorldGen.HardmodeTilePlaceEventArgs e)
48+
private static void OnHardmodeTilePlace(object sender, Hooks.WorldGen.HardmodeTilePlaceEventArgs e)
49+
{
50+
if (e.Result == HardmodeTileUpdateResult.Cancel)
4851
{
49-
if (e.Result == HardmodeTileUpdateResult.Cancel)
50-
{
51-
return;
52-
}
53-
if (_hookManager.InvokeGameHardmodeTileUpdate(e.X, e.Y, e.Type))
54-
{
55-
e.Result = HardmodeTileUpdateResult.Cancel;
56-
}
52+
return;
5753
}
58-
59-
private static void OnInitialize(On.Terraria.Main.orig_Initialize orig, Terraria.Main instance)
54+
if (_hookManager.InvokeGameHardmodeTileUpdate(e.X, e.Y, e.Type))
6055
{
61-
HookManager.InitialiseAPI();
62-
_hookManager.InvokeGameInitialize();
63-
orig(instance);
56+
e.Result = HardmodeTileUpdateResult.Cancel;
6457
}
58+
}
6559

66-
private static void OnStartServer(On.Terraria.Netplay.orig_StartServer orig)
60+
private static void OnInitialize(Terraria.Main instance, HookEvents.Terraria.Main.InitializeEventArgs args)
61+
{
62+
if (!args.ContinueExecution) return;
63+
HookManager.InitialiseAPI();
64+
_hookManager.InvokeGameInitialize();
65+
}
66+
67+
private static void OnStartServer(object? sender, HookEvents.Terraria.Netplay.StartServerEventArgs args)
68+
{
69+
if (!args.ContinueExecution) return;
70+
_hookManager.InvokeGamePostInitialize();
71+
}
72+
73+
private static void OnItemMechSpawn(object sender, Hooks.Item.MechSpawnEventArgs e)
74+
{
75+
if (e.Result == HookResult.Cancel)
6776
{
68-
_hookManager.InvokeGamePostInitialize();
69-
orig();
77+
return;
7078
}
71-
72-
private static void OnItemMechSpawn(object sender, Hooks.Item.MechSpawnEventArgs e)
79+
if (!_hookManager.InvokeGameStatueSpawn(e.Num2, e.Num3, e.Num, (int)(e.X / 16f), (int)(e.Y / 16f), e.Type, false))
7380
{
74-
if (e.Result == HookResult.Cancel)
75-
{
76-
return;
77-
}
78-
if (!_hookManager.InvokeGameStatueSpawn(e.Num2, e.Num3, e.Num, (int)(e.X / 16f), (int)(e.Y / 16f), e.Type, false))
79-
{
80-
e.Result = HookResult.Cancel;
81-
}
81+
e.Result = HookResult.Cancel;
8282
}
83+
}
8384

84-
private static void OnNpcMechSpawn(object sender, Hooks.NPC.MechSpawnEventArgs e)
85+
private static void OnNpcMechSpawn(object sender, Hooks.NPC.MechSpawnEventArgs e)
86+
{
87+
if (e.Result == HookResult.Cancel)
88+
{
89+
return;
90+
}
91+
if (!_hookManager.InvokeGameStatueSpawn(e.Num2, e.Num3, e.Num, (int)(e.X / 16f), (int)(e.Y / 16f), e.Type, true))
8592
{
86-
if (e.Result == HookResult.Cancel)
87-
{
88-
return;
89-
}
90-
if (!_hookManager.InvokeGameStatueSpawn(e.Num2, e.Num3, e.Num, (int)(e.X / 16f), (int)(e.Y / 16f), e.Type, true))
91-
{
92-
e.Result = HookResult.Cancel;
93-
}
93+
e.Result = HookResult.Cancel;
9494
}
9595
}
9696
}

0 commit comments

Comments
 (0)