Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 24 additions & 10 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,37 @@ on:
jobs:
# This workflow contains a single job called "build"
build:
strategy:
fail-fast: false
matrix:
os: [
{
name: Windows,
runs-on: windows-latest,
},
{
name: Ubuntu,
runs-on: ubuntu-latest,
},
{
name: MacOS,
runs-on: macos-latest,
}
]

# The type of runner that the job will run on
runs-on: windows-latest
runs-on: ${{ matrix.os.runs-on }}

name: ${{ matrix.os.name }}

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

- uses: actions/setup-dotnet@v3
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '6.0.100'
dotnet-version: 9.0.x

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

- name: Run tests
run: dotnet test --filter "FullyQualifiedName!~TerrariaServerAPI.Tests.Benchmarks"

# example task for the release CI
# - name: "Releasing to NuGet: TSAPI"
# env:
# NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
# run: dotnet nuget push ./TerrariaServerAPI/bin/Release/TerrariaServer.*.nupkg --source https://api.nuget.org/v3/index.json --api-key "$env:NUGET_API_KEY"
6 changes: 3 additions & 3 deletions .github/workflows/nuget.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ jobs:
environment: release

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
with:
dotnet-version: 6.0.400
dotnet-version: 9.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
Expand Down
13 changes: 8 additions & 5 deletions TerrariaServerAPI.Tests/BaseTest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using NUnit.Framework;
using System;
using System.Runtime.InteropServices;
using System.Threading;

namespace TerrariaServerAPI.Tests;
Expand All @@ -11,23 +12,25 @@ public class BaseTest
[OneTimeSetUp]
public void EnsureInitialised()
{
TestContext.Out.WriteLine($"Test architecture {RuntimeInformation.ProcessArchitecture}");

if (!_initialized)
{
var are = new AutoResetEvent(false);
AutoResetEvent are = new(false);
Exception? error = null;
On.Terraria.Main.hook_DedServ cb = (On.Terraria.Main.orig_DedServ orig, Terraria.Main instance) =>
HookEvents.HookDelegate<global::Terraria.Main, HookEvents.Terraria.Main.DedServEventArgs> cb = (instance, args) =>
{
instance.Initialize();
are.Set();
_initialized = true;
};
On.Terraria.Main.DedServ += cb;
HookEvents.Terraria.Main.DedServ += cb;

global::TerrariaApi.Server.Program.Main(new string[] { });
global::TerrariaApi.Server.Program.Main([]);

_initialized = are.WaitOne(TimeSpan.FromSeconds(30));

On.Terraria.Main.DedServ -= cb;
HookEvents.Terraria.Main.DedServ -= cb;

Assert.That(_initialized, Is.True);
Assert.That(error, Is.Null);
Expand Down
17 changes: 10 additions & 7 deletions TerrariaServerAPI.Tests/TerrariaServerAPI.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
<PackageReference Include="NUnit.Analyzers" Version="3.3.0" />
<PackageReference Include="coverlet.collector" Version="3.1.2">
<PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="NUnit" Version="4.3.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
<PackageReference Include="NUnit.Analyzers" Version="4.5.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
140 changes: 70 additions & 70 deletions TerrariaServerAPI/TerrariaApi.Server/Hooking/GameHooks.cs
Original file line number Diff line number Diff line change
@@ -1,96 +1,96 @@
using Microsoft.Xna.Framework;
using OTAPI;
using OTAPI;

namespace TerrariaApi.Server.Hooking
namespace TerrariaApi.Server.Hooking;

internal static class GameHooks
{
internal static class GameHooks
private static HookManager _hookManager;

/// <summary>
/// Attaches any of the OTAPI Game hooks to the existing <see cref="HookManager"/> implementation
/// </summary>
/// <param name="hookManager">HookManager instance which will receive the events</param>
public static void AttachTo(HookManager hookManager)
{
private static HookManager _hookManager;
_hookManager = hookManager;

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

On.Terraria.Main.Update += OnUpdate;
On.Terraria.Main.Initialize += OnInitialize;
On.Terraria.Netplay.StartServer += OnStartServer;
Hooks.WorldGen.HardmodeTilePlace += OnHardmodeTilePlace;
Hooks.WorldGen.HardmodeTileUpdate += OnHardmodeTileUpdate;
Hooks.Item.MechSpawn += OnItemMechSpawn;
Hooks.NPC.MechSpawn += OnNpcMechSpawn;
}

Hooks.WorldGen.HardmodeTilePlace += OnHardmodeTilePlace;
Hooks.WorldGen.HardmodeTileUpdate += OnHardmodeTileUpdate;
Hooks.Item.MechSpawn += OnItemMechSpawn;
Hooks.NPC.MechSpawn += OnNpcMechSpawn;
}
private static void OnUpdate(Terraria.Main instance, HookEvents.Terraria.Main.UpdateEventArgs args)
{
if (!args.ContinueExecution) return;
args.ContinueExecution = false;
_hookManager.InvokeGameUpdate();
args.OriginalMethod(args.gameTime);
_hookManager.InvokeGamePostUpdate();
}

private static void OnUpdate(On.Terraria.Main.orig_Update orig, Terraria.Main instance, GameTime gameTime)
private static void OnHardmodeTileUpdate(object sender, Hooks.WorldGen.HardmodeTileUpdateEventArgs e)
{
if (e.Result == HookResult.Cancel)
{
_hookManager.InvokeGameUpdate();
orig(instance, gameTime);
_hookManager.InvokeGamePostUpdate();
return;
}

private static void OnHardmodeTileUpdate(object sender, Hooks.WorldGen.HardmodeTileUpdateEventArgs e)
if (_hookManager.InvokeGameHardmodeTileUpdate(e.X, e.Y, e.Type))
{
if (e.Result == HookResult.Cancel)
{
return;
}
if (_hookManager.InvokeGameHardmodeTileUpdate(e.X, e.Y, e.Type))
{
e.Result = HookResult.Cancel;
}
e.Result = HookResult.Cancel;
}
}

private static void OnHardmodeTilePlace(object sender, Hooks.WorldGen.HardmodeTilePlaceEventArgs e)
private static void OnHardmodeTilePlace(object sender, Hooks.WorldGen.HardmodeTilePlaceEventArgs e)
{
if (e.Result == HardmodeTileUpdateResult.Cancel)
{
if (e.Result == HardmodeTileUpdateResult.Cancel)
{
return;
}
if (_hookManager.InvokeGameHardmodeTileUpdate(e.X, e.Y, e.Type))
{
e.Result = HardmodeTileUpdateResult.Cancel;
}
return;
}

private static void OnInitialize(On.Terraria.Main.orig_Initialize orig, Terraria.Main instance)
if (_hookManager.InvokeGameHardmodeTileUpdate(e.X, e.Y, e.Type))
{
HookManager.InitialiseAPI();
_hookManager.InvokeGameInitialize();
orig(instance);
e.Result = HardmodeTileUpdateResult.Cancel;
}
}

private static void OnStartServer(On.Terraria.Netplay.orig_StartServer orig)
private static void OnInitialize(Terraria.Main instance, HookEvents.Terraria.Main.InitializeEventArgs args)
{
if (!args.ContinueExecution) return;
HookManager.InitialiseAPI();
_hookManager.InvokeGameInitialize();
}

private static void OnStartServer(object? sender, HookEvents.Terraria.Netplay.StartServerEventArgs args)
{
if (!args.ContinueExecution) return;
_hookManager.InvokeGamePostInitialize();
}

private static void OnItemMechSpawn(object sender, Hooks.Item.MechSpawnEventArgs e)
{
if (e.Result == HookResult.Cancel)
{
_hookManager.InvokeGamePostInitialize();
orig();
return;
}

private static void OnItemMechSpawn(object sender, Hooks.Item.MechSpawnEventArgs e)
if (!_hookManager.InvokeGameStatueSpawn(e.Num2, e.Num3, e.Num, (int)(e.X / 16f), (int)(e.Y / 16f), e.Type, false))
{
if (e.Result == HookResult.Cancel)
{
return;
}
if (!_hookManager.InvokeGameStatueSpawn(e.Num2, e.Num3, e.Num, (int)(e.X / 16f), (int)(e.Y / 16f), e.Type, false))
{
e.Result = HookResult.Cancel;
}
e.Result = HookResult.Cancel;
}
}

private static void OnNpcMechSpawn(object sender, Hooks.NPC.MechSpawnEventArgs e)
private static void OnNpcMechSpawn(object sender, Hooks.NPC.MechSpawnEventArgs e)
{
if (e.Result == HookResult.Cancel)
{
return;
}
if (!_hookManager.InvokeGameStatueSpawn(e.Num2, e.Num3, e.Num, (int)(e.X / 16f), (int)(e.Y / 16f), e.Type, true))
{
if (e.Result == HookResult.Cancel)
{
return;
}
if (!_hookManager.InvokeGameStatueSpawn(e.Num2, e.Num3, e.Num, (int)(e.X / 16f), (int)(e.Y / 16f), e.Type, true))
{
e.Result = HookResult.Cancel;
}
e.Result = HookResult.Cancel;
}
}
}
70 changes: 33 additions & 37 deletions TerrariaServerAPI/TerrariaApi.Server/Hooking/ItemHooks.cs
Original file line number Diff line number Diff line change
@@ -1,53 +1,49 @@
using OTAPI;
using Terraria;
using Terraria.GameContent.Items;

namespace TerrariaApi.Server.Hooking
namespace TerrariaApi.Server.Hooking;

internal static class ItemHooks
{
internal static class ItemHooks
{
private static HookManager _hookManager;
private static HookManager _hookManager;

/// <summary>
/// Attaches any of the OTAPI Item hooks to the existing <see cref="HookManager"/> implementation
/// </summary>
/// <param name="hookManager">HookManager instance which will receive the events</param>
public static void AttachTo(HookManager hookManager)
{
_hookManager = hookManager;
/// <summary>
/// Attaches any of the OTAPI Item hooks to the existing <see cref="HookManager"/> implementation
/// </summary>
/// <param name="hookManager">HookManager instance which will receive the events</param>
public static void AttachTo(HookManager hookManager)
{
_hookManager = hookManager;

On.Terraria.Item.SetDefaults_int_bool_ItemVariant += OnSetDefaults;
On.Terraria.Item.netDefaults += OnNetDefaults;
HookEvents.Terraria.Item.SetDefaults_Int32_Boolean_ItemVariant += OnSetDefaults;
HookEvents.Terraria.Item.netDefaults += OnNetDefaults;

Hooks.Chest.QuickStack += OnQuickStack;
}
Hooks.Chest.QuickStack += OnQuickStack;
}

private static void OnNetDefaults(On.Terraria.Item.orig_netDefaults orig, Item item, int type)
{
if (_hookManager.InvokeItemNetDefaults(ref type, item))
return;
private static void OnNetDefaults(Item item, HookEvents.Terraria.Item.netDefaultsEventArgs args)
{
if (!args.ContinueExecution) return;
if (_hookManager.InvokeItemNetDefaults(ref args.type, item))
args.ContinueExecution = false;
}

orig(item, type);
}
private static void OnSetDefaults(Item item, HookEvents.Terraria.Item.SetDefaults_Int32_Boolean_ItemVariantEventArgs args)
{
if (!args.ContinueExecution) return;
if (_hookManager.InvokeItemSetDefaultsInt(ref args.Type, item, args.variant))
args.ContinueExecution = false;
}

private static void OnSetDefaults(On.Terraria.Item.orig_SetDefaults_int_bool_ItemVariant orig, Item item, int type, bool noMatCheck, ItemVariant? variant = null)
private static void OnQuickStack(object sender, Hooks.Chest.QuickStackEventArgs e)
{
if (e.Result == HookResult.Cancel)
{
if (_hookManager.InvokeItemSetDefaultsInt(ref type, item, variant))
return;

orig(item, type, noMatCheck, variant);
return;
}

private static void OnQuickStack(object sender, Hooks.Chest.QuickStackEventArgs e)
if (_hookManager.InvokeItemForceIntoChest(Main.chest[e.ChestIndex], e.Item, Main.player[e.PlayerId]))
{
if (e.Result == HookResult.Cancel)
{
return;
}
if (_hookManager.InvokeItemForceIntoChest(Main.chest[e.ChestIndex], e.Item, Main.player[e.PlayerId]))
{
e.Result = HookResult.Cancel;
}
e.Result = HookResult.Cancel;
}
}
}
Loading