Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
29 changes: 16 additions & 13 deletions NosCore.DeveloperTools.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 18
VisualStudioVersion = 18.5.11709.299 stable
VisualStudioVersion = 18.5.11709.299
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NosCore.DeveloperTools", "src\NosCore.DeveloperTools\NosCore.DeveloperTools.csproj", "{C6B8F7A1-0001-0001-0001-000000000001}"
EndProject
Expand All @@ -11,6 +11,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{827E0CD3-B72
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NosCore.DeveloperTools.GfStub", "src\NosCore.DeveloperTools.GfStub\NosCore.DeveloperTools.GfStub.csproj", "{D3A3DE1B-5292-4AAB-A335-31D2F4885A3C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NosCore.ClientTools", "src\NosCore.ClientTools\NosCore.ClientTools.csproj", "{893C8F61-2B59-472C-ADE4-28D76A086764}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -34,29 +36,29 @@ Global
{C6B8F7A1-0001-0001-0001-000000000001}.Release|x86.ActiveCfg = Release|Any CPU
{C6B8F7A1-0001-0001-0001-000000000001}.Release|x86.Build.0 = Release|Any CPU
{C6B8F7A1-0002-0001-0001-000000000001}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C6B8F7A1-0002-0001-0001-000000000001}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C6B8F7A1-0002-0001-0001-000000000001}.Debug|x64.ActiveCfg = Debug|Any CPU
{C6B8F7A1-0002-0001-0001-000000000001}.Debug|x64.Build.0 = Debug|Any CPU
{C6B8F7A1-0002-0001-0001-000000000001}.Debug|x86.ActiveCfg = Debug|Any CPU
{C6B8F7A1-0002-0001-0001-000000000001}.Debug|x86.Build.0 = Debug|Any CPU
{C6B8F7A1-0002-0001-0001-000000000001}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C6B8F7A1-0002-0001-0001-000000000001}.Release|Any CPU.Build.0 = Release|Any CPU
{C6B8F7A1-0002-0001-0001-000000000001}.Release|x64.ActiveCfg = Release|Any CPU
{C6B8F7A1-0002-0001-0001-000000000001}.Release|x64.Build.0 = Release|Any CPU
{C6B8F7A1-0002-0001-0001-000000000001}.Release|x86.ActiveCfg = Release|Any CPU
{C6B8F7A1-0002-0001-0001-000000000001}.Release|x86.Build.0 = Release|Any CPU
{D3A3DE1B-5292-4AAB-A335-31D2F4885A3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D3A3DE1B-5292-4AAB-A335-31D2F4885A3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D3A3DE1B-5292-4AAB-A335-31D2F4885A3C}.Debug|x64.ActiveCfg = Debug|Any CPU
{D3A3DE1B-5292-4AAB-A335-31D2F4885A3C}.Debug|x64.Build.0 = Debug|Any CPU
{D3A3DE1B-5292-4AAB-A335-31D2F4885A3C}.Debug|x86.ActiveCfg = Debug|Any CPU
{D3A3DE1B-5292-4AAB-A335-31D2F4885A3C}.Debug|x86.Build.0 = Debug|Any CPU
{D3A3DE1B-5292-4AAB-A335-31D2F4885A3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D3A3DE1B-5292-4AAB-A335-31D2F4885A3C}.Release|Any CPU.Build.0 = Release|Any CPU
{D3A3DE1B-5292-4AAB-A335-31D2F4885A3C}.Release|x64.ActiveCfg = Release|Any CPU
{D3A3DE1B-5292-4AAB-A335-31D2F4885A3C}.Release|x64.Build.0 = Release|Any CPU
{D3A3DE1B-5292-4AAB-A335-31D2F4885A3C}.Release|x86.ActiveCfg = Release|Any CPU
{D3A3DE1B-5292-4AAB-A335-31D2F4885A3C}.Release|x86.Build.0 = Release|Any CPU
{893C8F61-2B59-472C-ADE4-28D76A086764}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{893C8F61-2B59-472C-ADE4-28D76A086764}.Debug|Any CPU.Build.0 = Debug|Any CPU
{893C8F61-2B59-472C-ADE4-28D76A086764}.Debug|x64.ActiveCfg = Debug|Any CPU
{893C8F61-2B59-472C-ADE4-28D76A086764}.Debug|x64.Build.0 = Debug|Any CPU
{893C8F61-2B59-472C-ADE4-28D76A086764}.Debug|x86.ActiveCfg = Debug|Any CPU
{893C8F61-2B59-472C-ADE4-28D76A086764}.Debug|x86.Build.0 = Debug|Any CPU
{893C8F61-2B59-472C-ADE4-28D76A086764}.Release|Any CPU.ActiveCfg = Release|Any CPU
{893C8F61-2B59-472C-ADE4-28D76A086764}.Release|Any CPU.Build.0 = Release|Any CPU
{893C8F61-2B59-472C-ADE4-28D76A086764}.Release|x64.ActiveCfg = Release|Any CPU
{893C8F61-2B59-472C-ADE4-28D76A086764}.Release|x64.Build.0 = Release|Any CPU
{893C8F61-2B59-472C-ADE4-28D76A086764}.Release|x86.ActiveCfg = Release|Any CPU
{893C8F61-2B59-472C-ADE4-28D76A086764}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -65,5 +67,6 @@ Global
{C6B8F7A1-0001-0001-0001-000000000001} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
{C6B8F7A1-0002-0001-0001-000000000001} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
{D3A3DE1B-5292-4AAB-A335-31D2F4885A3C} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
{893C8F61-2B59-472C-ADE4-28D76A086764} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Text;

namespace NosCore.DeveloperTools.Services;
namespace NosCore.ClientTools;

/// <summary>
/// In-place byte patches against the Gameforge NosTale client
Expand Down Expand Up @@ -245,7 +245,7 @@ public static PatchResult PatchAllowNoArg(byte[] bytes)
public static PatchResult PatchImportName(byte[] bytes)
{
var needle = Encoding.ASCII.GetBytes("gf_wrapper.dll\0");
var replacement = Encoding.ASCII.GetBytes("noscore_gf.dll\0");
var replacement = Encoding.ASCII.GetBytes(GfStub.FileName + "\0");
if (needle.Length != replacement.Length)
{
return new PatchResult(false, "Internal error: replacement DLL name must match original length.");
Expand All @@ -259,7 +259,7 @@ public static PatchResult PatchImportName(byte[] bytes)
for (var i = 0; i < replacement.Length; i++) bytes[offset + i] = replacement[i];

return new PatchResult(true,
$"Import rename: 'gf_wrapper.dll' -> 'noscore_gf.dll' at 0x{offset:X}. Drop noscore_gf.dll next to the patched exe.");
$"Import rename: 'gf_wrapper.dll' -> '{GfStub.FileName}' at 0x{offset:X}. Drop {GfStub.FileName} next to the patched exe.");
}

private static int FindBytes(byte[] haystack, byte[] needle, int startOffset)
Expand Down
36 changes: 36 additions & 0 deletions src/NosCore.ClientTools/GfStub.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Reflection;

namespace NosCore.ClientTools;

/// <summary>
/// Access to the embedded <c>noscore_gf.dll</c> payload — the NativeAOT x86
/// replacement for the client's <c>gf_wrapper.dll</c>. A patched client
/// resolves its Gameforge imports against this file by name, so it has to sit
/// next to the patched exe under exactly <see cref="FileName"/>.
/// </summary>
public static class GfStub
{
/// <summary>
/// Import-table name the patched client loads the stub by. Must stay the
/// same length as <c>gf_wrapper.dll</c> so
/// <see cref="ClientPatcher.PatchImportName"/> can overwrite that literal
/// in place without relocating the PE import directory.
/// </summary>
public const string FileName = "noscore_gf.dll";

public static Stream OpenStream() =>
typeof(GfStub).Assembly.GetManifestResourceStream(FileName)
?? throw new FileNotFoundException(
$"{FileName} is not embedded in {Assembly.GetExecutingAssembly().GetName().Name}. " +
"Build NosCore.ClientTools so its GfStub publish target runs.");

/// <summary>Write the stub into <paramref name="directory"/> and return its full path.</summary>
public static string DeployTo(string directory)
{
var path = Path.Combine(directory, FileName);
using var source = OpenStream();
using var destination = File.Create(path);
source.CopyTo(destination);
return path;
}
}
43 changes: 43 additions & 0 deletions src/NosCore.ClientTools/NosCore.ClientTools.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<RootNamespace>NosCore.ClientTools</RootNamespace>
<AssemblyName>NosCore.ClientTools</AssemblyName>
<!-- No injection here, so no bitness constraint: consumers of this
library only spawn the client, they don't share its address space.
The x86 stub DLL travels as a prebuilt resource, not as code. -->
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>

<PropertyGroup Label="Packaging">
<IsPackable>true</IsPackable>
<PackageId>NosCore.ClientTools</PackageId>
<Description>Authenticate against a NosCore server and prepare a NosTale client to connect to it: auth-code retrieval, PE patches for server address and launch arguments, and the gf_wrapper replacement stub.</Description>
<PackageTags>noscore;nostale</PackageTags>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/NosCoreIO/NosCore.DeveloperTools</PackageProjectUrl>
<RepositoryUrl>https://github.com/NosCoreIO/NosCore.DeveloperTools</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

<PropertyGroup>
<GfStubProjectPath>$(MSBuildThisFileDirectory)..\NosCore.DeveloperTools.GfStub\NosCore.DeveloperTools.GfStub.csproj</GfStubProjectPath>
<GfStubPublishDir>$(MSBuildThisFileDirectory)..\NosCore.DeveloperTools.GfStub\bin\$(Configuration)\net10.0\win-x86\publish\</GfStubPublishDir>
<GfStubDllPath>$(GfStubPublishDir)noscore_gf.dll</GfStubDllPath>
</PropertyGroup>

<!-- The stub is a NativeAOT x86 DLL, so it cannot be a ProjectReference from
an AnyCPU library — it is published separately and embedded as bytes. -->
<Target Name="BuildGfStubPayload" BeforeTargets="BeforeBuild">
<Message Importance="high" Text="Publishing NosCore.DeveloperTools.GfStub (NativeAOT x86)..." />
<!-- ILC shells out to vswhere.exe; prepend the VS Installer dir so the
shell finds it even when PATH isn't pre-configured. -->
<Exec Command="set &quot;PATH=$(MSBuildProgramFiles32)\Microsoft Visual Studio\Installer;%PATH%&quot; &amp;&amp; dotnet publish &quot;$(GfStubProjectPath)&quot; -c $(Configuration) -r win-x86 --nologo -v quiet" />
<ItemGroup>
<EmbeddedResource Include="$(GfStubDllPath)" LogicalName="noscore_gf.dll" Visible="false" />
</ItemGroup>
</Target>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using System.Text;
using System.Text.Json.Serialization;

namespace NosCore.DeveloperTools.Services;
namespace NosCore.ClientTools;

/// <summary>
/// Thin HTTP client for the NosCore auth endpoints. Two-step flow:
Expand Down
8 changes: 2 additions & 6 deletions src/NosCore.DeveloperTools/Forms/MainForm.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Concurrent;
using System.Diagnostics;
using NosCore.ClientTools;
using NosCore.DeveloperTools.Models;
using NosCore.DeveloperTools.Remote;
using NosCore.DeveloperTools.Services;
Expand Down Expand Up @@ -617,14 +618,9 @@ private static void RunPatch(string newAddress, string exePath, string outputNam
// clobber the original.
if (stubResult.Success)
{
var stubPath = Path.Combine(outDir, "noscore_gf.dll");
try
{
using var stubStream = typeof(MainForm).Assembly.GetManifestResourceStream("noscore_gf.dll")
?? throw new FileNotFoundException("Stub DLL not embedded in this build.");
using var outStream = File.Create(stubPath);
stubStream.CopyTo(outStream);
Log($"Wrote {stubPath}");
Log($"Wrote {GfStub.DeployTo(outDir)}");
}
catch (Exception ex)
{
Expand Down
2 changes: 1 addition & 1 deletion src/NosCore.DeveloperTools/Models/AppSettings.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using NosCore.DeveloperTools.Services;
using NosCore.ClientTools;

namespace NosCore.DeveloperTools.Models;

Expand Down
16 changes: 4 additions & 12 deletions src/NosCore.DeveloperTools/NosCore.DeveloperTools.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@
<EmbeddedResource Include="Resources\logger.ico" LogicalName="NosCore.DeveloperTools.logger.ico" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\NosCore.ClientTools\NosCore.ClientTools.csproj" />
</ItemGroup>

<PropertyGroup>
<HookProjectPath>$(MSBuildThisFileDirectory)..\NosCore.DeveloperTools.Hook\NosCore.DeveloperTools.Hook.csproj</HookProjectPath>
<HookPublishDir>$(MSBuildThisFileDirectory)..\NosCore.DeveloperTools.Hook\bin\$(Configuration)\net10.0\win-x86\publish\</HookPublishDir>
<HookDllPath>$(HookPublishDir)NosCore.DeveloperTools.Hook.dll</HookDllPath>

<GfStubProjectPath>$(MSBuildThisFileDirectory)..\NosCore.DeveloperTools.GfStub\NosCore.DeveloperTools.GfStub.csproj</GfStubProjectPath>
<GfStubPublishDir>$(MSBuildThisFileDirectory)..\NosCore.DeveloperTools.GfStub\bin\$(Configuration)\net10.0\win-x86\publish\</GfStubPublishDir>
<GfStubDllPath>$(GfStubPublishDir)noscore_gf.dll</GfStubDllPath>
</PropertyGroup>

<Target Name="BuildHookPayload" BeforeTargets="BeforeBuild">
Expand All @@ -59,12 +59,4 @@
</ItemGroup>
</Target>

<Target Name="BuildGfStubPayload" BeforeTargets="BeforeBuild">
<Message Importance="high" Text="Publishing NosCore.DeveloperTools.GfStub (NativeAOT x86)..." />
<Exec Command="set &quot;PATH=$(MSBuildProgramFiles32)\Microsoft Visual Studio\Installer;%PATH%&quot; &amp;&amp; dotnet publish &quot;$(GfStubProjectPath)&quot; -c $(Configuration) -r win-x86 --nologo -v quiet" />
<ItemGroup>
<EmbeddedResource Include="$(GfStubDllPath)" LogicalName="noscore_gf.dll" Visible="false" />
</ItemGroup>
</Target>

</Project>
Loading