From 6114a1b519e84bba7f18904dfef2c9d5bdaae910 Mon Sep 17 00:00:00 2001 From: Luke Date: Sat, 28 Dec 2024 17:58:25 +1000 Subject: [PATCH] WIP shift to net9 and static hooks This includes package updates, including steamworks upgrades --- .github/workflows/ci-launcher.yml | 12 +- .github/workflows/ci-nuget.yml | 24 +-- .github/workflows/ci.yml | 22 +-- .vscode/launch.json | 12 +- OTAPI.Client.Launcher/App.axaml | 7 +- OTAPI.Client.Launcher/MainWindow.axaml | 6 +- OTAPI.Client.Launcher/MainWindow.axaml.cs | 2 +- .../OTAPI.Client.Launcher.csproj | 40 ++-- OTAPI.Client.Launcher/Program.cs | 5 +- .../Targets/InstallTarget.Extensions.cs | 33 +--- OTAPI.Common/OTAPI.Common.csproj | 10 +- OTAPI.Patcher/NugetPackageBuilder.cs | 2 +- OTAPI.Patcher/OTAPI.Patcher.csproj | 19 +- OTAPI.Patcher/Targets/PCServerTarget.cs | 96 +++++++--- OTAPI.Scripts/Mods/OnPacketWrite.Server.cs | 6 +- OTAPI.Scripts/Mods/PatchSteamworks.cs | 39 +++- OTAPI.Scripts/OTAPI.Scripts.csproj | 84 ++++---- .../ModifyCollisionSwitchTiles.Server.cs | 127 +++++++------ .../Patches/PatchNpcStrikeArgs.Server.cs | 129 +++++++------ .../OTAPI.Server.Launcher.csproj | 179 +++++++++--------- OTAPI.Server.Launcher/Program.cs | 63 +++++- build.sh | 18 +- examples/RuntimeExample.Server/MyClass.cs | 9 +- .../RuntimeExample.Server.csproj | 36 ++-- 24 files changed, 548 insertions(+), 432 deletions(-) diff --git a/.github/workflows/ci-launcher.yml b/.github/workflows/ci-launcher.yml index 17d187aad..6745df9c1 100644 --- a/.github/workflows/ci-launcher.yml +++ b/.github/workflows/ci-launcher.yml @@ -56,13 +56,13 @@ jobs: # 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 with: submodules: 'recursive' - uses: actions/setup-dotnet@v2 with: - dotnet-version: '6.0.x' # SDK Version to use; x will use the latest version of the 3.1 channel + dotnet-version: '9.0.x' # SDK Version to use; x will use the latest version of the 3.1 channel # - 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 @@ -70,12 +70,12 @@ jobs: - name: Build run: | cd OTAPI.Client.Launcher - dotnet publish -r ${{ matrix.profile.runtime_identifier }} --framework net6.0 -p:PublishReadyToRun=true --self-contained false -c Release + dotnet publish -r ${{ matrix.profile.runtime_identifier }} --framework net9.0 -p:PublishReadyToRun=true --self-contained false -c Release if ${{ matrix.profile.runs_on != 'macos-latest' }} ; then - 7z a ../${{ matrix.profile.archive_name }} './bin/Release/net6.0/${{ matrix.profile.runtime_identifier }}/publish/*' + 7z a ../${{ matrix.profile.archive_name }} './bin/Release/net9.0/${{ matrix.profile.runtime_identifier }}/publish/*' else mkdir -p OTAPI.app/Contents/Resources - mv bin/Release/net6.0/osx-x64/publish OTAPI.app/Contents/MacOS + mv bin/Release/net9.0/osx-x64/publish OTAPI.app/Contents/MacOS cp ../docs/MacOS.Info.plist OTAPI.app/Contents/Info.plist cp OTAPI.osx.sh OTAPI.app/Contents/MacOS/OTAPI chmod +x OTAPI.app/Contents/MacOS/OTAPI @@ -85,7 +85,7 @@ jobs: # - uses: actions/upload-artifact@v2 # with: # name: ${{ matrix.profile.name }} Launcher - # path: OTAPI.Client.Launcher/bin/Release/net6.0/${{ matrix.profile.runtime_identifier }}/publish + # path: OTAPI.Client.Launcher/bin/Release/net9.0/${{ matrix.profile.runtime_identifier }}/publish - uses: "marvinpinto/action-automatic-releases@latest" with: diff --git a/.github/workflows/ci-nuget.yml b/.github/workflows/ci-nuget.yml index a0dc01118..641cc4303 100644 --- a/.github/workflows/ci-nuget.yml +++ b/.github/workflows/ci-nuget.yml @@ -36,38 +36,38 @@ jobs: name: ${{ matrix.profile.name }} Server steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: 'recursive' - - uses: actions/setup-dotnet@v3 + - uses: actions/setup-dotnet@v4 with: - dotnet-version: '6.0.x' + dotnet-version: '9.0.x' - name: Build the project run: | dotnet build OTAPI.Mods.slnf - (cd OTAPI.Patcher/bin/Debug/net6.0 && exec dotnet run --project ../../../OTAPI.Patcher.csproj -patchTarget=${{ matrix.profile.patch_target }} -latest=n --framework net6.0) + (cd OTAPI.Patcher/bin/Debug/net9.0 && exec dotnet run --project ../../../OTAPI.Patcher.csproj -patchTarget=${{ matrix.profile.patch_target }} -latest=n --framework net9.0) dotnet build OTAPI.Server.Launcher.slnf - (cd OTAPI.Server.Launcher/bin/Debug/net6.0 && exec dotnet OTAPI.Server.Launcher.dll -test-init) + (cd OTAPI.Server.Launcher/bin/Debug/net9.0 && exec dotnet OTAPI.Server.Launcher.dll -test-init) - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: ${{ matrix.profile.name }} NuGet Package - path: OTAPI.Patcher/bin/Debug/net6.0/${{ matrix.profile.package_path }} + path: OTAPI.Patcher/bin/Debug/net9.0/${{ matrix.profile.package_path }} - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: ${{ matrix.profile.name }} Binaries path: | - OTAPI.Patcher/bin/Debug/net6.0/artifact-*/* + OTAPI.Patcher/bin/Debug/net9.0/artifact-*/* - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: ${{ matrix.profile.name }} Wiki MD files - path: OTAPI.Patcher/bin/Debug/net6.0/*.mfw.md + path: OTAPI.Patcher/bin/Debug/net9.0/*.mfw.md - name: "Releasing to NuGet: ${{ matrix.profile.name }}" env: NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} - run: dotnet nuget push OTAPI.Patcher/bin/Debug/net6.0/${{ matrix.profile.package_path }} --source https://api.nuget.org/v3/index.json --api-key "$NUGET_API_KEY" + run: dotnet nuget push OTAPI.Patcher/bin/Debug/net9.0/${{ matrix.profile.package_path }} --source https://api.nuget.org/v3/index.json --api-key "$NUGET_API_KEY" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5912ab5a8..4874a083a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,33 +41,33 @@ jobs: name: ${{ matrix.profile.name }} Server steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: 'recursive' - - uses: actions/setup-dotnet@v3 + - uses: actions/setup-dotnet@v4 with: - dotnet-version: '6.0.x' + dotnet-version: '9.0.x' - name: Build the project run: | dotnet build OTAPI.Mods.slnf - (cd OTAPI.Patcher/bin/Debug/net6.0 && exec dotnet run --project ../../../OTAPI.Patcher.csproj -patchTarget=${{ matrix.profile.patch_target }} -latest=n --framework net6.0) + (cd OTAPI.Patcher/bin/Debug/net9.0 && exec dotnet run --project ../../../OTAPI.Patcher.csproj -patchTarget=${{ matrix.profile.patch_target }} -latest=n --framework net9.0) dotnet build OTAPI.Server.Launcher.slnf - (cd OTAPI.Server.Launcher/bin/Debug/net6.0 && exec dotnet OTAPI.Server.Launcher.dll -test-init) + (cd OTAPI.Server.Launcher/bin/Debug/net9.0 && exec dotnet OTAPI.Server.Launcher.dll -test-init) - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: ${{ matrix.profile.name }} NuGet Package - path: OTAPI.Patcher/bin/Debug/net6.0/${{ matrix.profile.package_path }} + path: OTAPI.Patcher/bin/Debug/net9.0/${{ matrix.profile.package_path }} - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: ${{ matrix.profile.name }} Binaries path: | - OTAPI.Patcher/bin/Debug/net6.0/artifact-*/* + OTAPI.Patcher/bin/Debug/net9.0/artifact-*/* - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: ${{ matrix.profile.name }} Wiki MD files - path: OTAPI.Patcher/bin/Debug/net6.0/*.mfw.md + path: OTAPI.Patcher/bin/Debug/net9.0/*.mfw.md diff --git a/.vscode/launch.json b/.vscode/launch.json index 2875a6c4e..92b128490 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,9 +10,9 @@ "request": "launch", "preLaunchTask": "build-setup", // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/OTAPI.Setup/bin/Debug/net6.0/OTAPI.Setup.dll", + "program": "${workspaceFolder}/OTAPI.Setup/bin/Debug/net9.0/OTAPI.Setup.dll", "args": ["-patchTarget=v", "-latestVanilla=n"], - "cwd": "${workspaceFolder}/OTAPI.Setup/bin/Debug/net6.0/", + "cwd": "${workspaceFolder}/OTAPI.Setup/bin/Debug/net9.0/", // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console "console": "internalConsole", "stopAtEntry": false @@ -23,9 +23,9 @@ "request": "launch", "preLaunchTask": "build-mods", // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/OTAPI.Patcher/bin/Debug/net6.0/OTAPI.Patcher.dll", + "program": "${workspaceFolder}/OTAPI.Patcher/bin/Debug/net9.0/OTAPI.Patcher.dll", "args": ["-patchTarget=v", "-latestVanilla=n"], - "cwd": "${workspaceFolder}/OTAPI.Patcher/bin/Debug/net6.0/", + "cwd": "${workspaceFolder}/OTAPI.Patcher/bin/Debug/net9.0/", // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console "console": "internalConsole", "stopAtEntry": false @@ -36,9 +36,9 @@ "request": "launch", "preLaunchTask": "build-launcher", // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/OTAPI.Launcher/bin/Debug/net6.0/OTAPI.Launcher.dll", + "program": "${workspaceFolder}/OTAPI.Launcher/bin/Debug/net9.0/OTAPI.Launcher.dll", "args": ["-patchTarget=v", "-latestVanilla=n"], - "cwd": "${workspaceFolder}/OTAPI.Launcher/bin/Debug/net6.0/", // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console + "cwd": "${workspaceFolder}/OTAPI.Launcher/bin/Debug/net9.0/", // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console "console": "externalTerminal", "stopAtEntry": false }, diff --git a/OTAPI.Client.Launcher/App.axaml b/OTAPI.Client.Launcher/App.axaml index 82860bb36..d7a96c19c 100644 --- a/OTAPI.Client.Launcher/App.axaml +++ b/OTAPI.Client.Launcher/App.axaml @@ -8,9 +8,12 @@ - + + + + diff --git a/OTAPI.Client.Launcher/MainWindow.axaml b/OTAPI.Client.Launcher/MainWindow.axaml index 7542ad181..b47eaf06f 100644 --- a/OTAPI.Client.Launcher/MainWindow.axaml +++ b/OTAPI.Client.Launcher/MainWindow.axaml @@ -169,7 +169,7 @@ Plugins - + - - + diff --git a/OTAPI.Client.Launcher/MainWindow.axaml.cs b/OTAPI.Client.Launcher/MainWindow.axaml.cs index e2400eadb..7fd47a6e7 100644 --- a/OTAPI.Client.Launcher/MainWindow.axaml.cs +++ b/OTAPI.Client.Launcher/MainWindow.axaml.cs @@ -87,7 +87,7 @@ private void OnConsoleLineReceived(string line) Context.Console.Insert(0, $"[{DateTime.Now:yyyyMMdd HH:mm:ss}] {line}"); } - protected override void OnClosing(CancelEventArgs e) + protected override void OnClosing(WindowClosingEventArgs e) { base.OnClosing(e); _watcher?.Dispose(); diff --git a/OTAPI.Client.Launcher/OTAPI.Client.Launcher.csproj b/OTAPI.Client.Launcher/OTAPI.Client.Launcher.csproj index 1d34acd40..6a902a460 100644 --- a/OTAPI.Client.Launcher/OTAPI.Client.Launcher.csproj +++ b/OTAPI.Client.Launcher/OTAPI.Client.Launcher.csproj @@ -1,7 +1,7 @@  WinExe - net6.0 + net9.0 enable embedded Always @@ -27,15 +27,17 @@ - - - - - - - - - + + + + + + + + + + + @@ -48,12 +50,12 @@ - - - - - - + + + + + + @@ -121,7 +123,7 @@ - + @@ -215,7 +217,7 @@ - - + + diff --git a/OTAPI.Client.Launcher/Program.cs b/OTAPI.Client.Launcher/Program.cs index b9b1b97e3..4a5267c86 100644 --- a/OTAPI.Client.Launcher/Program.cs +++ b/OTAPI.Client.Launcher/Program.cs @@ -170,6 +170,7 @@ static void Start(string[] args) plg.OnEnabledChanged += OnPluginChanged; // start the launcher, then OTAPI if requested + IconProvider.Current.Register(new FontAwesomeIconProvider()); BuildAvaloniaApp() .StartWithClassicDesktopLifetime(args); @@ -189,7 +190,5 @@ private static void OnPluginChanged(object? sender, EventArgs e) public static AppBuilder BuildAvaloniaApp() => AppBuilder.Configure() .UsePlatformDetect() - .LogToTrace() - .WithIcons(container => container - .Register()); + .LogToTrace(); } diff --git a/OTAPI.Client.Launcher/Targets/InstallTarget.Extensions.cs b/OTAPI.Client.Launcher/Targets/InstallTarget.Extensions.cs index c5396b8c7..19f8508ba 100644 --- a/OTAPI.Client.Launcher/Targets/InstallTarget.Extensions.cs +++ b/OTAPI.Client.Launcher/Targets/InstallTarget.Extensions.cs @@ -49,7 +49,7 @@ public static void CopyOTAPI(this IPlatformTarget target, string otapiFolder, IE File.WriteAllText(Path.Combine(otapiFolder, "Terraria.runtimeconfig.json"), @"{ ""runtimeOptions"": { - ""tfm"": ""net6.0"", + ""tfm"": ""net9.0"", ""framework"": { ""name"": ""Microsoft.NETCore.App"", ""version"": ""5.0.0"" @@ -241,8 +241,6 @@ public static IEnumerable PublishHostGame(this IPlatformTarget target) compilation = compilation.AddReferences(MetadataReference.CreateFromFile("ImGui.NET.dll")); compilation = compilation.AddReferences(MetadataReference.CreateFromFile("OTAPI.exe")); compilation = compilation.AddReferences(MetadataReference.CreateFromFile("OTAPI.Runtime.dll")); - //compilation = compilation.AddReferences(MetadataReference.CreateFromFile(Path.Combine(hostDir, @"..\OTAPI.Client.Installer\bin\Debug\net6.0\OTAPI.exe"))); - //compilation = compilation.AddReferences(MetadataReference.CreateFromFile(Path.Combine(hostDir, @"..\OTAPI.Client.Installer\bin\Debug\net6.0\OTAPI.Runtime.dll"))); var outPdbPath = Path.Combine(output, "OTAPI.Client.Installer.pdb"); var emitOptions = new EmitOptions( @@ -341,31 +339,6 @@ public static string PublishHostLauncher(this IPlatformTarget target) return Path.GetDirectoryName(files.Single(x => Path.GetFileName(x).Equals("Terraria.exe", StringComparison.CurrentCultureIgnoreCase))); else // linux+osx return Path.GetDirectoryName(files.Single(x => Path.GetFileName(x).Equals("Terraria", StringComparison.CurrentCultureIgnoreCase))); - - //Console.WriteLine(target.Status = "Building launcher, this may take a long time..."); - //var hostDir = "../../../../OTAPI.Client.Launcher/"; - - //var package = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) - // ? "win-x64" : ( - // RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "osx.10.11-x64" : "ubuntu.16.04-x64" - //); - - //using var process = new System.Diagnostics.Process() - //{ - // StartInfo = new System.Diagnostics.ProcessStartInfo() - // { - // FileName = "dotnet", - // Arguments = $"publish -r {package} --framework net6.0 -p:PublishTrimmed=true -p:PublishSingleFile=true -p:PublishReadyToRun=true --self-contained true -c Release", - // //Arguments = "msbuild -restore -t:PublishAllRids", - // WorkingDirectory = hostDir - // }, - //}; - //process.Start(); - //process.WaitForExit(); - - //Console.WriteLine("Published"); - - //return Path.Combine(hostDir, "bin", "Release", "net6.0", package, "publish"); } public static string DownloadZip(this IPlatformTarget target, string url, string name) @@ -436,8 +409,8 @@ public static void GenerateTypings(this IPlatformTarget target, string rootFolde if (File.Exists(dll)) return Assembly.LoadFile(dll); - exe = Path.Combine(patcherDir, "bin", "Debug", "net6.0", "EmbeddedResources", $"{asr.Name}.exe"); - dll = Path.Combine(patcherDir, "bin", "Debug", "net6.0", "EmbeddedResources", $"{asr.Name}.dll"); + exe = Path.Combine(patcherDir, "bin", "Debug", "net9.0", "EmbeddedResources", $"{asr.Name}.exe"); + dll = Path.Combine(patcherDir, "bin", "Debug", "net9.0", "EmbeddedResources", $"{asr.Name}.dll"); if (File.Exists(exe)) return Assembly.LoadFile(exe); diff --git a/OTAPI.Common/OTAPI.Common.csproj b/OTAPI.Common/OTAPI.Common.csproj index 1506adfd3..d758188f1 100644 --- a/OTAPI.Common/OTAPI.Common.csproj +++ b/OTAPI.Common/OTAPI.Common.csproj @@ -1,15 +1,15 @@ - net6.0 + net9.0 disable - - - + + + - + \ No newline at end of file diff --git a/OTAPI.Patcher/NugetPackageBuilder.cs b/OTAPI.Patcher/NugetPackageBuilder.cs index 9b0ec6031..bbfee2bd7 100644 --- a/OTAPI.Patcher/NugetPackageBuilder.cs +++ b/OTAPI.Patcher/NugetPackageBuilder.cs @@ -52,7 +52,7 @@ public void Build(ModFwModder modder) var commitSha = Common.GetGitCommitSha(); nuspec_xml = nuspec_xml.Replace("[INJECT_GIT_HASH]", String.IsNullOrWhiteSpace(commitSha) ? "" : $" git#{commitSha}"); - var platforms = new[] { "net6.0" }; // relinker only does net6 currently. until there is a reason to implement it... + var platforms = new[] { "net9.0" }; // relinker only does net6 currently. until there is a reason to implement it... var steamworks = modder.Module.AssemblyReferences.First(x => x.Name == "Steamworks.NET"); var newtonsoft = modder.Module.AssemblyReferences.First(x => x.Name == "Newtonsoft.Json"); var dependencies = new[] diff --git a/OTAPI.Patcher/OTAPI.Patcher.csproj b/OTAPI.Patcher/OTAPI.Patcher.csproj index 6e90ba13e..1636ea19e 100644 --- a/OTAPI.Patcher/OTAPI.Patcher.csproj +++ b/OTAPI.Patcher/OTAPI.Patcher.csproj @@ -2,22 +2,23 @@ Exe - net6.0 + net9.0 3.1.20 true x64 - win7-x64;osx.10.11-x64;ubuntu.16.04-x64 + win-x64;osx-x64;linux-x64 enable Initial 1.4.4.9 support - - - - - - - + + + + + + + + diff --git a/OTAPI.Patcher/Targets/PCServerTarget.cs b/OTAPI.Patcher/Targets/PCServerTarget.cs index 6e81af147..e336030ee 100644 --- a/OTAPI.Patcher/Targets/PCServerTarget.cs +++ b/OTAPI.Patcher/Targets/PCServerTarget.cs @@ -1,5 +1,6 @@ using ModFramework; using ModFramework.Modules.CSharp; +using MonoMod.Utils; using OTAPI.Patcher.Resolvers; using System; using System.Collections.Generic; @@ -85,18 +86,18 @@ public void Patch() { Common.AddMarkdownFormatter(); - var input = DownloadServer(); - var inputName = Path.GetFileNameWithoutExtension(input); + var vanillaDllPath = DownloadServer(); + var vanillaName = Path.GetFileNameWithoutExtension(vanillaDllPath); Console.WriteLine("[OTAPI] Extracting embedded binaries and packing into one binary..."); - var embeddedResources = this.ExtractResources(input); + var embeddedResources = this.ExtractResources(vanillaDllPath); - var basepath = Path.Combine(ModContext.BaseDirectory, "outputs"); - Directory.CreateDirectory(basepath); + var putputsPath = Path.Combine(ModContext.BaseDirectory, "outputs"); + Directory.CreateDirectory(putputsPath); - var refs = Path.Combine(basepath, "TerrariaServer.dll"); - var otapi = Path.Combine(ModContext.BaseDirectory, "OTAPI.dll"); - var hooks = Path.Combine(ModContext.BaseDirectory, "OTAPI.Runtime.dll"); + var terrariaServerDllDestination = Path.Combine(putputsPath, "TerrariaServer.dll"); + var otapiDllDestination = Path.Combine(ModContext.BaseDirectory, "OTAPI.dll"); + var otapiRuntimeDllDestination = Path.Combine(ModContext.BaseDirectory, "OTAPI.Runtime.dll"); ModContext.ReferenceFiles.AddRange(new[] { @@ -111,7 +112,7 @@ public void Patch() }); // expose types to be public, so private IL refs can be ref'd by compiling mods - this.Patch("Merging and pregenerating files", input, refs, PublicEverything, (modType, mm) => + this.Patch("Merging and pregenerating files", vanillaDllPath, terrariaServerDllDestination, PublicEverything, (modType, mm) => { if (mm is not null) { @@ -124,21 +125,55 @@ public void Patch() // merge in HookResult, HookEvent etc mm.ReadMod(typeof(HookEvent).Assembly.Location); + ////mm.Module.GetType("Terraria.Main").FindMethod("Update").CreateHook(mm); + //mm.Module.GetType("Terraria.Main").CreateHooks(mm); + //mm.Module.GetType("Terraria.Item").CreateHooks(mm); + //mm.Module.GetType("Terraria.NetMessage").CreateHooks(mm); + //mm.Module.GetType("Terraria.Netplay").CreateHooks(mm); + //mm.Module.GetType("Terraria.NPC").CreateHooks(mm); + //mm.Module.GetType("Terraria.WorldGen").CreateHooks(mm); + //mm.Module.GetType("Terraria.Chat.ChatHelper").CreateHooks(mm); + //mm.Module.GetType("Terraria.IO.WorldFile").CreateHooks(mm); + //mm.Module.GetType("Terraria.Net.NetManager").CreateHooks(mm); + //mm.Module.GetType("Terraria.Projectile").CreateHooks(mm); + mm.Module.GetType("Terraria.Liquid").CreateHooks(mm); + mm.Module.Write("test.dll"); + //HookEmitter.CreateHookDelegate(mm); + //mm.Module.Write("test.dll"); + + //// generate static hooks + //mm.Module.GetType("Terraria.Main").CreateHooks(mm); + //mm.Module.GetType("Terraria.Item").CreateHooks(mm); + //mm.Module.GetType("Terraria.NetMessage").CreateHooks(mm); + //mm.Module.GetType("Terraria.Netplay").CreateHooks(mm); + //mm.Module.GetType("Terraria.NPC").CreateHooks(mm); + //mm.Module.GetType("Terraria.WorldGen").CreateHooks(mm); + //mm.Module.GetType("Terraria.Chat.ChatHelper").CreateHooks(mm); + //mm.Module.GetType("Terraria.IO.WorldFile").CreateHooks(mm); + //mm.Module.GetType("Terraria.Net.NetManager").CreateHooks(mm); + //mm.Module.GetType("Terraria.Projectile").CreateHooks(mm); + //mm.Module.GetType("Terraria.RemoteClient").CreateHooks(mm); + Console.WriteLine($"[OTAPI] Changing to AnyCPU (x64 preferred)"); mm.SetAnyCPU(); CompileAndReadShims(mm); MergeReLogic(mm, embeddedResources); - this.AddPatchMetadata(mm, mm.Module.Name, input); + this.AddPatchMetadata(mm, mm.Module.Name, vanillaDllPath); } + //else if(modType == ModType.PreWrite) + //{ + // HookEmitter.CreateHookDelegate(mm); + // mm.Module.Write("test.dll"); + //} } return EApplyResult.Continue; }); - ModContext.ReferenceFiles.Add(refs); + ModContext.ReferenceFiles.Add(terrariaServerDllDestination); // load into the current app domain for patch refs - var asm = Assembly.LoadFile(refs); + var asm = Assembly.LoadFile(terrariaServerDllDestination); var cache = new Dictionary(); Assembly? ResolvingFile(AssemblyLoadContext arg1, AssemblyName args) @@ -177,36 +212,51 @@ public void Patch() AssemblyLoadContext.Default.Resolving += ResolvingFile; try { - this.Patch("Applying modifications", refs, otapi, false, (modType, modder) => + this.Patch("Applying modifications", terrariaServerDllDestination, otapiDllDestination, false, (modType, mm) => { - if (modder is not null) + if (mm is not null) { if (modType == ModType.PreRead) { - modder.AssemblyResolver.AddSearchDirectory(embeddedResources); + mm.AssemblyResolver.AddSearchDirectory(embeddedResources); } else if (modType == ModType.Read) { // assembly is loaded, can use it to add in constants // before the plugins are invoked - this.AddConstants(inputName, modder); + this.AddConstants(vanillaName, mm); LoadModifications(); } else if (modType == ModType.PreWrite) { - modder.ModContext.TargetAssemblyName = "OTAPI"; // change the target assembly since otapi is now valid for write events - AddVersion(modder); - this.AddPatchMetadata(modder); - modder.AddEnvMetadata(); + mm.ModContext.TargetAssemblyName = "OTAPI"; // change the target assembly since otapi is now valid for write events + AddVersion(mm); + this.AddPatchMetadata(mm); + mm.AddEnvMetadata(); + + // generate static hooks + Console.Write("[OTAPI] Generating static hooks..."); + mm.Module.GetType("Terraria.Main").CreateHooks(mm); + mm.Module.GetType("Terraria.Item").CreateHooks(mm); + mm.Module.GetType("Terraria.NetMessage").CreateHooks(mm); + mm.Module.GetType("Terraria.Netplay").CreateHooks(mm); + mm.Module.GetType("Terraria.NPC").CreateHooks(mm); + mm.Module.GetType("Terraria.WorldGen").CreateHooks(mm); + mm.Module.GetType("Terraria.Chat.ChatHelper").CreateHooks(mm); + mm.Module.GetType("Terraria.IO.WorldFile").CreateHooks(mm); + mm.Module.GetType("Terraria.Net.NetManager").CreateHooks(mm); + mm.Module.GetType("Terraria.Projectile").CreateHooks(mm); + mm.Module.GetType("Terraria.RemoteClient").CreateHooks(mm); + Console.WriteLine("Done"); } else if (modType == ModType.Write) { - modder.ModContext = new("OTAPI.Runtime"); // done with the context. they will be triggered again by runtime hooks if not for this - modder.CreateRuntimeHooks(hooks); + mm.ModContext = new("OTAPI.Runtime"); // done with the context. they will be triggered again by runtime hooks if not for this + mm.CreateRuntimeHooks(otapiRuntimeDllDestination); Console.WriteLine("[OTAPI] Building NuGet package..."); - NugetPackager.Build(modder); + NugetPackager.Build(mm); } } return EApplyResult.Continue; diff --git a/OTAPI.Scripts/Mods/OnPacketWrite.Server.cs b/OTAPI.Scripts/Mods/OnPacketWrite.Server.cs index 24f53ebed..2131338da 100644 --- a/OTAPI.Scripts/Mods/OnPacketWrite.Server.cs +++ b/OTAPI.Scripts/Mods/OnPacketWrite.Server.cs @@ -64,10 +64,10 @@ void OnPacketWrite(MonoModder modder) sendData.Emit(OpCodes.Ldloc, ms); sendData.Emit(OpCodes.Ldloc, bw); - foreach (var method in sendData.Method.Parameters) + foreach (var prm in sendData.Method.Parameters) { - callback.Parameters.Add(method.Clone()); - sendData.Emit(OpCodes.Ldarg, method); + callback.Parameters.Add(prm.Clone()); + sendData.Emit(OpCodes.Ldarg, prm); } sendData.Emit(OpCodes.Call, callback); diff --git a/OTAPI.Scripts/Mods/PatchSteamworks.cs b/OTAPI.Scripts/Mods/PatchSteamworks.cs index 9b6787bda..70d3f6f14 100644 --- a/OTAPI.Scripts/Mods/PatchSteamworks.cs +++ b/OTAPI.Scripts/Mods/PatchSteamworks.cs @@ -23,8 +23,8 @@ You should have received a copy of the GNU General Public License #else using ModFramework; using Mono.Cecil; +using Mono.Cecil.Cil; using MonoMod; -using System.IO; using System.Linq; /// @@ -32,16 +32,17 @@ You should have received a copy of the GNU General Public License /// [Modification(ModType.PreMerge, "Patching Steamworks.NET")] [MonoMod.MonoModIgnore] -void PatchSteam(MonoModder modder) +void PatchSteam(ModFwModder modder) { - var desired = typeof(Steamworks.SteamShutdown_t).Assembly.GetName().Version; + var steamworks = AssemblyDefinition.ReadAssembly("Steamworks.NET.dll"); // Avoid using type refs, as arm64 will die on this assembly. + var version = steamworks.Name.Version; // Avoid using type refs, as arm64 will die on this assembly. //Update the references to match what is installed foreach (var reference in modder.Module.AssemblyReferences) { if (reference.Name == "Steamworks.NET") { - reference.Version = desired; + reference.Version = version; break; } } @@ -50,5 +51,35 @@ void PatchSteam(MonoModder modder) modder.Module.Resources.Remove( modder.Module.Resources.Single(x => x.Name.EndsWith("Steamworks.NET.dll")) ); + + // Wire in changes since Terraria implemented this library - we are using the latest! + var steamNetworkingIdentity = modder.Module.ImportReference(steamworks.MainModule.Types.Single(x => x.FullName == "Steamworks.SteamNetworkingIdentity")); + modder.OnRewritingMethodBody += (MonoModder modder, MethodBody body, Instruction instr, int instri) => + { + if (instr.OpCode == OpCodes.Call && instr.Operand is MethodReference methodRef) + { + if (methodRef.DeclaringType.FullName == "Steamworks.SteamUGC" && + methodRef.Name == "SetItemTags" && + instr.Previous.OpCode != OpCodes.Ldc_I4_0) + { + // add bAllowAdminTags = false to the call + body.Instructions.Insert(instri, Instruction.Create(OpCodes.Ldc_I4_0)); + methodRef.Parameters.Add(new("bAllowAdminTags", ParameterAttributes.None, methodRef.Module.TypeSystem.Boolean)); + } + + if (methodRef.DeclaringType.FullName == "Steamworks.SteamUser" && + methodRef.Name == "GetAuthSessionTicket" && + instr.Previous.OpCode != OpCodes.Ldloca_S) + { + // create a new local variable to store SteamNetworkingIdentity + var steamNetworkingIdentityVar = new VariableDefinition(steamNetworkingIdentity); + body.Variables.Add(steamNetworkingIdentityVar); + body.InitLocals = true; + body.Instructions.Insert(instri, Instruction.Create(OpCodes.Ldloca_S, steamNetworkingIdentityVar)); + // add parameter: ref SteamNetworkingIdentity pSteamNetworkingIdentity + methodRef.Parameters.Add(new("pSteamNetworkingIdentity", ParameterAttributes.None, new ByReferenceType(steamNetworkingIdentity))); + } + } + }; } #endif \ No newline at end of file diff --git a/OTAPI.Scripts/OTAPI.Scripts.csproj b/OTAPI.Scripts/OTAPI.Scripts.csproj index 3aac0802e..8d1ebaed4 100644 --- a/OTAPI.Scripts/OTAPI.Scripts.csproj +++ b/OTAPI.Scripts/OTAPI.Scripts.csproj @@ -1,45 +1,45 @@ - - net6.0 - true - true - true - enable - - - - - - ..\OTAPI.Patcher\bin\Debug\net6.0\OTAPI.exe - - - ..\OTAPI.Patcher\bin\Debug\net6.0\OTAPI.dll - - - ..\OTAPI.Patcher\bin\Debug\net6.0\OTAPI.Runtime.dll - - - ..\OTAPI.Patcher\bin\Debug\net6.0\EmbeddedResources\Steamworks.NET.dll - - - ..\OTAPI.Client.Launcher\bin\x64\Debug\net6.0\client\OTAPI.exe - - - ..\OTAPI.Client.Launcher\bin\x64\Debug\net6.0\client\OTAPI.Runtime.dll - - - - - - - - - - - - - - - + + net9.0 + true + true + true + enable + + + + + + ..\OTAPI.Patcher\bin\Debug\net9.0\OTAPI.exe + + + ..\OTAPI.Patcher\bin\Debug\net9.0\OTAPI.dll + + + ..\OTAPI.Patcher\bin\Debug\net9.0\OTAPI.Runtime.dll + + + ..\OTAPI.Patcher\bin\Debug\net9.0\EmbeddedResources\Steamworks.NET.dll + + + ..\OTAPI.Client.Launcher\bin\x64\Debug\net9.0\client\OTAPI.exe + + + ..\OTAPI.Client.Launcher\bin\x64\Debug\net9.0\client\OTAPI.Runtime.dll + + + + + + + + + + + + + + + diff --git a/OTAPI.Scripts/Patches/ModifyCollisionSwitchTiles.Server.cs b/OTAPI.Scripts/Patches/ModifyCollisionSwitchTiles.Server.cs index 92fc30194..53d228372 100644 --- a/OTAPI.Scripts/Patches/ModifyCollisionSwitchTiles.Server.cs +++ b/OTAPI.Scripts/Patches/ModifyCollisionSwitchTiles.Server.cs @@ -33,84 +33,89 @@ You should have received a copy of the GNU General Public License [MonoModIgnore] partial class CollisionSwitchTiles { - static ParameterDefinition Entity { get; set; } - static MethodDefinition SwitchTiles { get; set; } + //static ParameterDefinition Entity { get; set; } + //static MethodDefinition SwitchTiles { get; set; } [Modification(ModType.PreMerge, "Patching Collision.SwitchTiles")] static void ModifyCollisionSwitchTiles(ModFramework.ModFwModder modder) { var csr = modder.GetILCursor(() => Terraria.Collision.SwitchTiles(default, 0, 0, default, 0)); - SwitchTiles = csr.Method; + var redirects = csr.Method.DeclaringType.Methods + .Where(x => (HookEmitter.HookMethodNamePrefix + x.Name) == csr.Method.Name || ("orig_" + x.Name) == csr.Method.Name) + .Select(x => x.GetILCursor()) + .ToArray(); + //SwitchTiles = csr.Method; - csr.Method.Parameters.Add(Entity = new ParameterDefinition("entity", - ParameterAttributes.HasDefault | ParameterAttributes.Optional, - - modder.Module.ImportReference(modder.GetDefinition()) - ) + foreach (var method in redirects.Append(csr)) { - Constant = null - }); - - modder.OnRewritingMethodBody += PatchCollisionSwitchTiles_OnRewritingMethodBody; - - // inject the callback - { - // find all the HitSwitch calls - // add a branch around them, until after the SendData call - - var calls = csr.Body.Instructions.Where(ins => ins.Operand is MethodReference mref && mref.Name == "HitSwitch").ToArray(); + ParameterDefinition entity; + method.Method.Parameters.Add(entity = new("entity", + ParameterAttributes.HasDefault | ParameterAttributes.Optional, - foreach (var hitswitch in calls) + modder.Module.ImportReference(modder.GetDefinition()) + ) { - var arg_x = hitswitch.Previous.Previous; - var arg_y = hitswitch.Previous; - - csr.Goto(hitswitch, MonoMod.Cil.MoveType.Before); - - //// find the continuation branch (via SendData) - //var continuation = hitswitch.Next(ins => ins.Operand is MethodReference mref && mref.Name == "SendData"); - - csr.Emit(OpCodes.Ldarg, Entity); - csr.EmitDelegate(OTAPI.Hooks.Collision.InvokePressurePlate); - var cancellation = csr.EmitAll( - new { OpCodes.Nop }, - new { OpCodes.Ldc_I4_0 }, - new { OpCodes.Ret } - ); - - // we consumed the stack with our callback, readd the x/y for the HitSwitch call to use - var continuation = csr.EmitAll( - new { arg_x.OpCode, arg_x.Operand }, - new { arg_y.OpCode, arg_y.Operand } - ); - - var nop = cancellation.First(); - nop.OpCode = OpCodes.Brtrue_S; - nop.Operand = continuation.First(); - } - } - } + Constant = null + }); - private static void PatchCollisionSwitchTiles_OnRewritingMethodBody(MonoModder modder, MethodBody body, Instruction instr, int instri) - { - if (instr.Operand is MethodReference methodReference) - { - if (methodReference.DeclaringType.Name == SwitchTiles.DeclaringType.Name - && methodReference.Name == SwitchTiles.Name) + modder.OnRewritingMethodBody += (MonoModder modder, MethodBody body, Instruction instr, int instri) => { - if (methodReference.Parameters.Any(x => x.Name == Entity.Name)) + if (instr.Operand is MethodReference methodReference && + methodReference.DeclaringType.Name == method.Method.DeclaringType.Name && + methodReference.Name == method.Method.Name + ) { - return; + if (methodReference.Parameters.Any(x => x.Name == entity.Name)) + return; + + methodReference.Parameters.Add(entity); + + if (body.Method.DeclaringType.BaseType.FullName == typeof(Terraria.Entity).FullName) + { + body.GetILProcessor().InsertBefore(instr, + new { OpCodes.Ldarg_0 } + ); + } + else throw new NotImplementedException($"{body.Method.Name} is not a supported caller for this modification"); } - methodReference.Parameters.Add(Entity); + }; - if (body.Method.DeclaringType.BaseType.FullName == typeof(Terraria.Entity).FullName) + // inject the callback if the target + if(method == csr) + { + // find all the HitSwitch calls + // add a branch around them, until after the SendData call + + var calls = csr.Body.Instructions.Where(ins => ins.Operand is MethodReference mref && mref.Name == "HitSwitch").ToArray(); + + foreach (var hitswitch in calls) { - body.GetILProcessor().InsertBefore(instr, - new { OpCodes.Ldarg_0 } + var arg_x = hitswitch.Previous.Previous; + var arg_y = hitswitch.Previous; + + csr.Goto(hitswitch, MonoMod.Cil.MoveType.Before); + + //// find the continuation branch (via SendData) + //var continuation = hitswitch.Next(ins => ins.Operand is MethodReference mref && mref.Name == "SendData"); + + csr.Emit(OpCodes.Ldarg, entity); + csr.EmitDelegate(OTAPI.Hooks.Collision.InvokePressurePlate); + var cancellation = csr.EmitAll( + new { OpCodes.Nop }, + new { OpCodes.Ldc_I4_0 }, + new { OpCodes.Ret } + ); + + // we consumed the stack with our callback, readd the x/y for the HitSwitch call to use + var continuation = csr.EmitAll( + new { arg_x.OpCode, arg_x.Operand }, + new { arg_y.OpCode, arg_y.Operand } ); + + var nop = cancellation.First(); + nop.OpCode = OpCodes.Brtrue_S; + nop.Operand = continuation.First(); } - else throw new NotImplementedException($"{body.Method.Name} is not a supported caller for this modification"); } } } diff --git a/OTAPI.Scripts/Patches/PatchNpcStrikeArgs.Server.cs b/OTAPI.Scripts/Patches/PatchNpcStrikeArgs.Server.cs index a92897ee9..4280e9ad9 100644 --- a/OTAPI.Scripts/Patches/PatchNpcStrikeArgs.Server.cs +++ b/OTAPI.Scripts/Patches/PatchNpcStrikeArgs.Server.cs @@ -30,72 +30,79 @@ You should have received a copy of the GNU General Public License [MonoModIgnore] partial class NpcStrikeArgs { - static ParameterDefinition Entity { get; set; } - static MethodDefinition StrikeNPC { get; set; } + //static ParameterDefinition Entity { get; set; } + //static MethodDefinition StrikeNPC { get; set; } [Modification(ModType.PreMerge, "Patching in entity source for NPC strike")] static void PatchNpcStrikeArgs(ModFwModder modder) { - var csr = modder.GetILCursor(() => (new Terraria.NPC()).StrikeNPC(0, 0, 0, false, false, false)); - StrikeNPC = csr.Method; - - csr.Method.Parameters.Add(Entity = new ParameterDefinition("entity", - ParameterAttributes.HasDefault | ParameterAttributes.Optional, - - modder.Module.ImportReference(modder.GetDefinition()) - ) - { - Constant = null - }); - - modder.OnRewritingMethodBody += Modder_OnRewritingMethodBody; - } - - private static void Modder_OnRewritingMethodBody(MonoModder modder, MethodBody body, Instruction instr, int instri) - { - if (instr.Operand is MethodReference methodReference) - { - if (methodReference.DeclaringType.Name == StrikeNPC.DeclaringType.Name - && methodReference.Name == StrikeNPC.Name) - { - if (methodReference.Parameters.Any(x => x.Name == Entity.Name)) - { - return; - } - methodReference.Parameters.Add(Entity); - - switch (body.Method.DeclaringType.Name + "." + body.Method.Name) - { - case "MessageBuffer.GetData": - body.GetILProcessor().InsertBefore(instr, - new { OpCodes.Ldsfld, Operand = modder.Module.ImportReference(modder.GetFieldDefinition(() => Terraria.Main.player)) }, - new { OpCodes.Ldarg_0 }, - new { OpCodes.Ldfld, Operand = modder.Module.ImportReference(modder.GetFieldDefinition(() => (new Terraria.MessageBuffer()).whoAmI)) }, - new { OpCodes.Ldelem_Ref } - ); - break; - - case "NPC.StrikeNPCNoInteraction": - // this is via world, so null is expected. - body.GetILProcessor().InsertBefore(instr, - new { OpCodes.Ldnull } - ); - break; - - case "Player.ApplyDamageToNPC": - case "Player.ItemCheck_MeleeHitNPCs": - case "Projectile.Damage": - case "Player.ProcessHitAgainstNPC": - body.GetILProcessor().InsertBefore(instr, - new { OpCodes.Ldarg_0 } - ); - break; + var csr = modder.GetILCursor(() => (new Terraria.NPC()).StrikeNPC(0, 0, 0, false, false, false)); + var redirects = csr.Method.DeclaringType.Methods + .Where(x => (HookEmitter.HookMethodNamePrefix + x.Name) == csr.Method.Name || ("orig_" + x.Name) == csr.Method.Name) + .Select(x => x.GetILCursor()) + .ToArray(); + + foreach (var method in redirects.Append(csr)) + { + ParameterDefinition Entity; + method.Method.Parameters.Add(Entity = new ("entity", + ParameterAttributes.HasDefault | ParameterAttributes.Optional, - default: - throw new NotImplementedException($"{body.Method.Name} is not a supported caller for this modification"); - } - } + modder.Module.ImportReference(modder.GetDefinition()) + ) + { + Constant = null + }); + + modder.OnRewritingMethodBody += (MonoModder modder, MethodBody body, Instruction instr, int instri) => + { + if (instr.Operand is MethodReference methodReference) + { + if (methodReference.DeclaringType.Name == method.Method.DeclaringType.Name + && methodReference.Name == method.Method.Name) + { + if (methodReference.Parameters.Any(x => x.Name == Entity.Name)) + { + return; + } + methodReference.Parameters.Add(Entity); + + var methodName = body.Method.DeclaringType.Name + "." + body.Method.Name; + switch (methodName.Replace(HookEmitter.HookMethodNamePrefix, "")) + { + case "MessageBuffer.GetData": + body.GetILProcessor().InsertBefore(instr, + new { OpCodes.Ldsfld, Operand = modder.Module.ImportReference(modder.GetFieldDefinition(() => Terraria.Main.player)) }, + new { OpCodes.Ldarg_0 }, + new { OpCodes.Ldfld, Operand = modder.Module.ImportReference(modder.GetFieldDefinition(() => (new Terraria.MessageBuffer()).whoAmI)) }, + new { OpCodes.Ldelem_Ref } + ); + break; + + case "NPC.StrikeNPCNoInteraction": + // this is via world, so null is expected. + body.GetILProcessor().InsertBefore(instr, + new { OpCodes.Ldnull } + ); + break; + + case "Player.ApplyDamageToNPC": + case "Player.ItemCheck_MeleeHitNPCs": + case "Projectile.Damage": + case "Player.ProcessHitAgainstNPC": + case "NPC.StrikeNPC": + body.GetILProcessor().InsertBefore(instr, + new { OpCodes.Ldarg_0 } + ); + break; + + default: + throw new NotImplementedException($"{body.Method.Name} is not a supported caller for this modification"); + } + } + } + }; } } -} +} #endif \ No newline at end of file diff --git a/OTAPI.Server.Launcher/OTAPI.Server.Launcher.csproj b/OTAPI.Server.Launcher/OTAPI.Server.Launcher.csproj index 45420852e..c292a57b1 100644 --- a/OTAPI.Server.Launcher/OTAPI.Server.Launcher.csproj +++ b/OTAPI.Server.Launcher/OTAPI.Server.Launcher.csproj @@ -1,102 +1,103 @@  - - Exe - net6.0 - true - Debug;Release - + + Exe + net9.0 + true + Debug;Release + - - - + + + - - - true - - - - - - - - - - - - - true - - - true - - + + + true + + + + + + + + + + + + + + true + + + true + + - - - ..\OTAPI.Patcher\bin\$(Configuration)\$(TargetFramework)\OTAPI.dll - true - - - ..\OTAPI.Patcher\bin\$(Configuration)\$(TargetFramework)\OTAPI.Runtime.dll - true - - + + + ..\OTAPI.Patcher\bin\$(Configuration)\$(TargetFramework)\OTAPI.dll + true + + + ..\OTAPI.Patcher\bin\$(Configuration)\$(TargetFramework)\OTAPI.Runtime.dll + true + + - + - - - + + + - - - tModLoader\%(RecursiveDir)%(Filename)%(Extension) - PreserveNewest - - - - $(DefineConstants);TML - + + + tModLoader\%(RecursiveDir)%(Filename)%(Extension) + PreserveNewest + + + + $(DefineConstants);TML + - - - + + + - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - - - PreserveNewest - - - - - - - + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + PreserveNewest + + + + + + + - - - + + + diff --git a/OTAPI.Server.Launcher/Program.cs b/OTAPI.Server.Launcher/Program.cs index 074421d80..fbe490956 100644 --- a/OTAPI.Server.Launcher/Program.cs +++ b/OTAPI.Server.Launcher/Program.cs @@ -22,7 +22,7 @@ You should have received a copy of the GNU General Public License using ReLogic.OS; #endif using System; -using System.IO; +using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -59,20 +59,73 @@ static void Program_LaunchGame(On.Terraria.Program.orig_LaunchGame orig, string[ Terraria.Main.dedServ = true; Terraria.Program.ForceLoadAssembly(GetTerrariaAssembly(), initializeStaticMembers: true); } - + TShockHooks(); #endif orig(args, monoArgs); } +static void TShockHooks() +{ + Dictionary calls = new(); + + // only print every 1s + DateTime lastUpdate = DateTime.Now; + void Print(TSender sender, TArgs args) + { + dynamic evt = args; + var name = evt.OriginalMethod.Method.Name; + if (!calls.ContainsKey(name)) + calls[name] = 0; + calls[name] += 1; + if ((DateTime.Now - lastUpdate).TotalSeconds >= 1) + { + Console.WriteLine(String.Join($"{Environment.NewLine}\t- ", calls.Keys.OrderByDescending(x => calls[x]).Select(name => $"{name}:{calls[name]}"))); + lastUpdate = DateTime.Now; + } + + //evt.ContinueExecution = false; + } + + HookEvents.Terraria.Main.Update += Print; + HookEvents.Terraria.Main.Initialize += Print; + HookEvents.Terraria.Main.checkXMas += Print; + HookEvents.Terraria.Main.checkHalloween += Print; + HookEvents.Terraria.Main.startDedInput += Print; + HookEvents.Terraria.Item.SetDefaults_Int32_Boolean_ItemVariant += Print; + HookEvents.Terraria.Item.netDefaults += Print; + HookEvents.Terraria.NetMessage.greetPlayer += Print; + HookEvents.Terraria.Netplay.StartServer += Print; + HookEvents.Terraria.Netplay.OnConnectionAccepted += Print; + HookEvents.Terraria.NPC.SetDefaults += Print; + HookEvents.Terraria.NPC.SetDefaultsFromNetId += Print; + HookEvents.Terraria.NPC.StrikeNPC += (npc, args) => args.ContinueExecution = false; + //HookEvents.Terraria.NPC.StrikeNPC += Print; + HookEvents.Terraria.NPC.Transform += Print; + HookEvents.Terraria.NPC.AI += Print; + HookEvents.Terraria.WorldGen.StartHardmode += Print; + HookEvents.Terraria.WorldGen.SpreadGrass += Print; + HookEvents.Terraria.Chat.ChatHelper.BroadcastChatMessage += Print; + HookEvents.Terraria.IO.WorldFile.SaveWorld_Boolean_Boolean += Print; + HookEvents.Terraria.Net.NetManager.SendData += Print; + HookEvents.Terraria.Projectile.SetDefaults += Print; + HookEvents.Terraria.Projectile.AI += Print; + HookEvents.Terraria.RemoteClient.Reset += Print; +} + static void Program_OnLaunched(object sender, EventArgs e) { - Console.WriteLine($"MonoMod runtime hooks active, runtime: " + DetourHelper.Runtime.GetType().Name); + //Console.WriteLine($"MonoMod runtime hooks active, runtime: " + DetourHelper.Runtime.GetType().Name); if (Common.IsTMLServer) { LazyHook("Terraria.ModLoader.Engine.HiDefGraphicsIssues", "Init", new Action(Nop)); } + HookEvents.Terraria.Main.DedServ += (_, args) => + { + Console.WriteLine($"DedServEvent"); + }; + On.Terraria.Main.ctor += Main_ctor; Hooks.MessageBuffer.ClientUUIDReceived += (_, args) => @@ -93,12 +146,12 @@ static void Program_OnLaunched(object sender, EventArgs e) On.Terraria.RemoteClient.Update += (orig, rc) => { - Console.WriteLine($"RemoteClient.Update: HOOK ID#{rc.Id} IsActive:{rc.IsActive},PT:{rc.PendingTermination}"); + //Console.WriteLine($"RemoteClient.Update: HOOK ID#{rc.Id} IsActive:{rc.IsActive},PT:{rc.PendingTermination}"); orig(rc); }; On.Terraria.RemoteClient.Reset += (orig, rc) => { - Console.WriteLine($"RemoteClient.Reset: HOOK ID#{rc.Id} IsActive:{rc.IsActive},PT:{rc.PendingTermination}"); + //Console.WriteLine($"RemoteClient.Reset: HOOK ID#{rc.Id} IsActive:{rc.IsActive},PT:{rc.PendingTermination}"); orig(rc); }; } diff --git a/build.sh b/build.sh index 79872c12a..b21f9452b 100755 --- a/build.sh +++ b/build.sh @@ -1,24 +1,24 @@ dotnet restore OTAPI.Mods.slnf dotnet restore OTAPI.Server.Launcher.slnf dotnet build OTAPI.Mods.slnf -cd OTAPI.Patcher/bin/Debug/net6.0 -dotnet run --project ../../../OTAPI.Patcher.csproj -patchTarget=p -latest=n --framework net6.0 +cd OTAPI.Patcher/bin/Debug/net9.0 +dotnet run --project ../../../OTAPI.Patcher.csproj -patchTarget=p -latest=n --framework net9.0 cd ../../../../ dotnet build OTAPI.Server.Launcher.slnf -cd OTAPI.Server.Launcher/bin/Debug/net6.0 +cd OTAPI.Server.Launcher/bin/Debug/net9.0 dotnet OTAPI.Server.Launcher.dll -test-init cd ../../../../ -cd OTAPI.Patcher/bin/Debug/net6.0 -dotnet run --project ../../../OTAPI.Patcher.csproj -patchTarget=m -latest=n --framework net6.0 +cd OTAPI.Patcher/bin/Debug/net9.0 +dotnet run --project ../../../OTAPI.Patcher.csproj -patchTarget=m -latest=n --framework net9.0 cd ../../../../ dotnet build OTAPI.Server.Launcher.slnf -cd OTAPI.Server.Launcher/bin/Debug/net6.0 +cd OTAPI.Server.Launcher/bin/Debug/net9.0 dotnet OTAPI.Server.Launcher.dll -test-init cd ../../../../ -cd OTAPI.Patcher/bin/Debug/net6.0 -dotnet run --project ../../../OTAPI.Patcher.csproj -patchTarget=t -latest=n --framework net6.0 +cd OTAPI.Patcher/bin/Debug/net9.0 +dotnet run --project ../../../OTAPI.Patcher.csproj -patchTarget=t -latest=n --framework net9.0 cd ../../../../ dotnet build OTAPI.Server.Launcher.slnf -cd OTAPI.Server.Launcher/bin/Debug/net6.0 +cd OTAPI.Server.Launcher/bin/Debug/net9.0 dotnet OTAPI.Server.Launcher.dll -test-init cd ../../../../ \ No newline at end of file diff --git a/examples/RuntimeExample.Server/MyClass.cs b/examples/RuntimeExample.Server/MyClass.cs index f6a6b4ef4..80e9e770b 100644 --- a/examples/RuntimeExample.Server/MyClass.cs +++ b/examples/RuntimeExample.Server/MyClass.cs @@ -1,5 +1,5 @@ /* -Copyright (C) 2020 DeathCradle +Copyright (C) 2020-2024 SignatureBeef This file is part of Open Terraria API v3 (OTAPI) @@ -28,7 +28,6 @@ public static class Hooks public static void OnRunning() { Console.WriteLine("[RuntimeExample Server] Hello World! from a compiled DLL"); - On.Terraria.Program.LaunchGame += Program_LaunchGame; On.Terraria.NetMessage.greetPlayer += NetMessage_greetPlayer; } @@ -37,10 +36,4 @@ private static void NetMessage_greetPlayer(On.Terraria.NetMessage.orig_greetPlay Console.WriteLine($"[RuntimeExample Server] Greet player: {plr}"); orig(plr); } - - private static void Program_LaunchGame(On.Terraria.Program.orig_LaunchGame orig, string[] args, bool monoArgs) - { - Console.WriteLine("[RuntimeExample Server] LaunchGame was called!"); - orig(args, monoArgs); - } } diff --git a/examples/RuntimeExample.Server/RuntimeExample.Server.csproj b/examples/RuntimeExample.Server/RuntimeExample.Server.csproj index 87bcff5eb..48706d8a1 100644 --- a/examples/RuntimeExample.Server/RuntimeExample.Server.csproj +++ b/examples/RuntimeExample.Server/RuntimeExample.Server.csproj @@ -1,24 +1,24 @@  - - Library - net6.0 - Debug;Release - + + Library + net9.0 + Debug;Release + - - - - + + + + - - - ..\..\OTAPI.Patcher\bin\Debug\$(TargetFramework)\OTAPI.dll - - - ..\..\OTAPI.Patcher\bin\Debug\$(TargetFramework)\OTAPI.Runtime.dll - - + + + ..\..\OTAPI.Patcher\bin\Debug\$(TargetFramework)\OTAPI.dll + + + ..\..\OTAPI.Patcher\bin\Debug\$(TargetFramework)\OTAPI.Runtime.dll + + - +