Skip to content

Commit

Permalink
Forcefully update Hacknet to .NET 4.5
Browse files Browse the repository at this point in the history
  • Loading branch information
Windows10CE committed Sep 26, 2021
1 parent 1b1c8d3 commit 4c4ad67
Show file tree
Hide file tree
Showing 18 changed files with 106 additions and 53 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ jobs:
copy libs/BepInEx.cfg Release/BepInEx/config/BepInEx.cfg
copy PathfinderPatcher/bin/Release/PathfinderPatcher.exe Release/PathfinderPatcher.exe
copy libs/Mono.Cecil.dll Release/Mono.Cecil.dll
copy Linux/intercept.so Release/intercept.so
copy Linux/StartPathfinder.sh Release/StartPathfinder.sh
- name: Create Release ZIP
uses: TheDoctor0/zip-release@0.6.0
Expand Down
20 changes: 9 additions & 11 deletions BepInEx.Hacknet/BepInEx.Hacknet.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>BepInEx.Hacknet</RootNamespace>
<AssemblyName>BepInEx.Hacknet</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
Expand All @@ -35,18 +35,17 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="0Harmony, Version=2.5.4.0, Culture=neutral, PublicKeyToken=null">
<Reference Include="0Harmony, Version=2.5.5.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\libs\0Harmony.dll</HintPath>
</Reference>
<Reference Include="BepInEx.Core, Version=6.0.0.409, Culture=neutral, PublicKeyToken=null">
<Reference Include="BepInEx.Core, Version=6.0.0.423, Culture=neutral, PublicKeyToken=null">
<HintPath>..\libs\BepInEx.Core.dll</HintPath>
</Reference>
<Reference Include="FNA, Version=17.2.0.0, Culture=neutral, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<Reference Include="FNA, Version=17.2.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\libs\FNA.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="HacknetPathfinder">
<Reference Include="Hacknet, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\libs\HacknetPathfinder.exe</HintPath>
<Private>False</Private>
</Reference>
Expand All @@ -62,20 +61,19 @@
<Reference Include="Mono.Cecil.Rocks, Version=0.11.4.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e">
<HintPath>..\libs\Mono.Cecil.Rocks.dll</HintPath>
</Reference>
<Reference Include="MonoMod.RuntimeDetour, Version=21.8.19.1, Culture=neutral, PublicKeyToken=null">
<Reference Include="MonoMod.RuntimeDetour, Version=21.9.19.1, Culture=neutral, PublicKeyToken=null">
<HintPath>..\libs\MonoMod.RuntimeDetour.dll</HintPath>
</Reference>
<Reference Include="MonoMod.Utils, Version=21.8.19.1, Culture=neutral, PublicKeyToken=null">
<Reference Include="MonoMod.Utils, Version=21.9.19.1, Culture=neutral, PublicKeyToken=null">
<HintPath>..\libs\MonoMod.Utils.dll</HintPath>
</Reference>
<Reference Include="SemVer, Version=1.3.0.0, Culture=neutral, PublicKeyToken=a89bb7dc6f7a145c">
<HintPath>..\libs\SemVer.dll</HintPath>
<Reference Include="SemanticVersioning, Version=2.0.0.0, Culture=neutral, PublicKeyToken=a89bb7dc6f7a145c">
<HintPath>..\libs\SemanticVersioning.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
Expand Down
27 changes: 21 additions & 6 deletions BepInEx.Hacknet/HacknetChainloader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using HarmonyLib;
using Microsoft.Xna.Framework;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using HN = global::Hacknet;

Expand Down Expand Up @@ -138,13 +139,27 @@ internal static bool LoadTempPluginsPrefix(ExtensionInfo info)
[HarmonyPatch(typeof(HN.OS), nameof(HN.OS.quitGame))]
internal static void UnloadOnOSQuitPostfix() => HacknetChainloader.Instance.UnloadTemps();

// I would hook Hacknet.Screens.DrawExtensionInfoDetail instead, but for some reason that method is cursed, so I look here instead
[HarmonyPostfix]
[HarmonyPatch(typeof(Button), nameof(Button.doButton), new Type[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(string), typeof(Color?) })]
internal static void OnBackButtonPressPostfix(int myID, bool __result)
[HarmonyILManipulator]
[HarmonyPatch(typeof(ExtensionsMenuScreen), nameof(ExtensionsMenuScreen.DrawExtensionInfoDetail))]
internal static void OnBackButtonPressPostfix(ILContext il)
{
ILCursor c = new ILCursor(il);

c.GotoNext(MoveType.Before,
x => x.MatchLdnull(),
x => x.MatchStfld(AccessTools.Field(typeof(ExtensionsMenuScreen), nameof(ExtensionsMenuScreen.ExtensionInfoToShow)))
);

c.Emit(OpCodes.Ldsfld, AccessTools.Field(typeof(HacknetChainloader), nameof(HacknetChainloader.Instance)));
c.Emit(OpCodes.Callvirt, AccessTools.Method(typeof(HacknetChainloader), nameof(HacknetChainloader.UnloadTemps)));
}

[HarmonyPrefix]
[HarmonyPatch(typeof(AppDomain), "get_BaseDirectory")]
private static bool ReturnCorrectDirectoryPrefix(out string __result)
{
if (myID == 7900040 && __result)
HacknetChainloader.Instance.UnloadTemps();
__result = Paths.GameRootPath;
return false;
}
}

Expand Down
22 changes: 7 additions & 15 deletions ExampleMod/ExampleMod.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ExampleMod</RootNamespace>
<AssemblyName>ExampleMod</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
Expand All @@ -33,30 +33,22 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="0Harmony, Version=2.5.4.0, Culture=neutral, PublicKeyToken=null">
<Reference Include="0Harmony, Version=2.5.5.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\libs\0Harmony.dll</HintPath>
<Private>False</Private>
<Private>False</Private>
</Reference>
<Reference Include="BepInEx.Core, Version=6.0.0.409, Culture=neutral, PublicKeyToken=null">
<Reference Include="BepInEx.Core, Version=6.0.0.423, Culture=neutral, PublicKeyToken=null">
<HintPath>..\libs\BepInEx.Core.dll</HintPath>
<Private>False</Private>
<Private>False</Private>
</Reference>
<Reference Include="FNA">
<Reference Include="FNA, Version=17.2.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\libs\FNA.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="HacknetPathfinder">
<Reference Include="Hacknet, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\libs\HacknetPathfinder.exe</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Mono.Cecil, Version=0.11.4.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e">
<HintPath>..\libs\Mono.Cecil.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="MonoMod.Utils, Version=21.8.19.1, Culture=neutral, PublicKeyToken=null">
<HintPath>..\libs\MonoMod.Utils.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
Expand Down
1 change: 1 addition & 0 deletions Linux/StartPathfinder.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TERM=xterm LD_PRELOAD="$(pwd)/lib64/libcef.so $(pwd)/intercept.so /usr/lib/libmono-2.0.so.1" MONO_DEBUG=explicit-null-checks ./HacknetPathfinder.bin.x86_64
11 changes: 11 additions & 0 deletions Linux/intercept.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#define _GNU_SOURCE

#include <dlfcn.h>
#include <stdlib.h>

void mono_set_dirs(char *assembly_dir,char *config_dir) {
setenv("MONO_PATH", "/usr/lib/mono/4.5", 1);

void (*set_dir_ptr)(char*,char*) = dlsym(RTLD_NEXT, "mono_set_dirs");
(*set_dir_ptr)("/usr/lib/mono/4.5", config_dir);
}
Binary file added Linux/intercept.so
Binary file not shown.
20 changes: 10 additions & 10 deletions PathfinderAPI/PathfinderAPI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Pathfinder</RootNamespace>
<AssemblyName>PathfinderAPI</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<LangVersion>8</LangVersion>
Expand All @@ -32,29 +32,29 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="0Harmony, Version=2.5.4.0, Culture=neutral, PublicKeyToken=null">
<Reference Include="0Harmony, Version=2.5.5.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\libs\0Harmony.dll</HintPath>
<Private>False</Private>
<Private>False</Private>
</Reference>
<Reference Include="BepInEx.Core, Version=6.0.0.409, Culture=neutral, PublicKeyToken=null">
<Reference Include="BepInEx.Core, Version=6.0.0.423, Culture=neutral, PublicKeyToken=null">
<HintPath>..\libs\BepInEx.Core.dll</HintPath>
<Private>False</Private>
<Private>False</Private>
</Reference>
<Reference Include="FNA">
<Reference Include="FNA, Version=17.2.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\libs\FNA.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="HacknetPathfinder">
<Reference Include="Hacknet, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\libs\HacknetPathfinder.exe</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Mono.Cecil, Version=0.11.4.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e">
<HintPath>..\libs\Mono.Cecil.dll</HintPath>
<Private>False</Private>
<Private>False</Private>
</Reference>
<Reference Include="MonoMod.Utils, Version=21.8.19.1, Culture=neutral, PublicKeyToken=null">
<Reference Include="MonoMod.Utils, Version=21.9.19.1, Culture=neutral, PublicKeyToken=null">
<HintPath>..\libs\MonoMod.Utils.dll</HintPath>
<Private>False</Private>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
Expand Down
9 changes: 6 additions & 3 deletions PathfinderInstaller/PathfinderInstaller.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@ def install_pathfinder(gen_event_callback, hacknet_directory):
try:
os.remove(patcher_exe)
os.remove(os.path.join(hacknet_directory, 'Mono.Cecil.dll'))
hacknet_exe = os.path.join(hacknet_directory, 'Hacknet.exe')
os.rename(hacknet_exe, os.path.join(hacknet_directory, 'HacknetOld.exe'))
os.rename(os.path.join(hacknet_directory, 'HacknetPathfinder.exe'), hacknet_exe)
if platform.system() == 'Windows':
hacknet_exe = os.path.join(hacknet_directory, 'Hacknet.exe')
os.rename(hacknet_exe, os.path.join(hacknet_directory, 'HacknetOld.exe'))
os.rename(os.path.join(hacknet_directory, 'HacknetPathfinder.exe'), hacknet_exe)
else:
shutil.copy(os.path.join(hacknet_directory, 'Hacknet.bin.x86_64'), os.path.join(hacknet_directory, 'HacknetPathfinder.bin.x86_64'))
except OSError:
gen_event_callback('<<InstallFailure>>')
return
Expand Down
19 changes: 15 additions & 4 deletions PathfinderPatcher/Program.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Linq;
using System.Security;
using System.Reflection;
using SR = System.Reflection;
using Mono.Cecil;
using Mono.Cecil.Cil;

Expand Down Expand Up @@ -66,17 +66,17 @@ void MakePublic(TypeDefinition type, bool nested = false)
processor.Emit(OpCodes.Ldstr, "./BepInEx/core/BepInEx.Hacknet.dll");
processor.Emit(OpCodes.Call, hn.MainModule.ImportReference(typeof(System.IO.Path).GetMethod("GetFullPath", new Type[] { typeof(string) })));
// Load BepInEx.Hacknet.dll
processor.Emit(OpCodes.Call, hn.MainModule.ImportReference(typeof(Assembly).GetMethod("LoadFile", new Type[] { typeof(string) })));
processor.Emit(OpCodes.Call, hn.MainModule.ImportReference(typeof(SR.Assembly).GetMethod("LoadFile", new Type[] { typeof(string) })));
// Get Entrypoint type
processor.Emit(OpCodes.Ldstr, "BepInEx.Hacknet.Entrypoint");
processor.Emit(OpCodes.Call, hn.MainModule.ImportReference(typeof(Assembly).GetMethod("GetType", new Type[] { typeof(string) })));
processor.Emit(OpCodes.Call, hn.MainModule.ImportReference(typeof(SR.Assembly).GetMethod("GetType", new Type[] { typeof(string) })));
// Get bootstrap method
processor.Emit(OpCodes.Ldstr, "Bootstrap");
processor.Emit(OpCodes.Call, hn.MainModule.ImportReference(typeof(Type).GetMethod("GetMethod", new Type[] { typeof(string) })));
// Call bootstrap method
processor.Emit(OpCodes.Ldnull);
processor.Emit(OpCodes.Ldnull);
processor.Emit(OpCodes.Callvirt, hn.MainModule.ImportReference(typeof(MethodBase).GetMethod("Invoke", new Type[] { typeof(object), typeof(object[]) })));
processor.Emit(OpCodes.Callvirt, hn.MainModule.ImportReference(typeof(SR.MethodBase).GetMethod("Invoke", new Type[] { typeof(object), typeof(object[]) })));
processor.Emit(OpCodes.Pop);
// Return
processor.Emit(OpCodes.Ret);
Expand All @@ -88,6 +88,17 @@ void MakePublic(TypeDefinition type, bool nested = false)
var unverifiableCtor = hn.MainModule.ImportReference(unverifiableType.Methods.First(x => x.IsConstructor && x.Parameters.Count == 0));
hn.MainModule.CustomAttributes.Add(new CustomAttribute(unverifiableCtor));

var corlibRef = hn.MainModule.AssemblyReferences.FirstOrDefault(x => x.Name == "mscorlib");
corlibRef.PublicKey = null;
corlibRef.PublicKeyToken = null;
corlibRef.HasPublicKey = false;

var targetRuntime = hn.CustomAttributes.FirstOrDefault(x => x.AttributeType.Name == "TargetFrameworkAttribute");
targetRuntime.ConstructorArguments.Clear();
targetRuntime.ConstructorArguments.Add(new CustomAttributeArgument(hn.MainModule.TypeSystem.String, ".NETFramework,Version=v4.5"));
targetRuntime.Properties.Clear();
targetRuntime.Properties.Add(new CustomAttributeNamedArgument("FrameworkDisplayName", new CustomAttributeArgument(hn.MainModule.TypeSystem.String, ".NET Framework 4.5")));

// Write modified assembly to disk
hn.Write("HacknetPathfinder.exe");

Expand Down
18 changes: 15 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,32 @@ There are several options available to choose to install Pathfinder, the install

### Installer

If you're on Windows, it's recommended that you use the installer .exe from [here](https://github.com/Arkhist/Hacknet-Pathfinder/releases). Just run the installer and it should automatically find your Hacknet folder, then just hit install. Launching Hacknet from Steam will launch Pathfinder!
If you're on Windows, it's recommended that you use the installer .exe from [here](https://github.com/Arkhist/Hacknet-Pathfinder/releases). Just run the installer and it should automatically find your Hacknet folder, then just hit install. Launching Hacknet from Steam will launch Pathfinder (on Windows)!

If you decide to use the .py installer (or you're just on Linux and have to use it) keep in mind it requires python3 and tk to be installed before you run it.

If you're on Linux, once the installer is complete, make sure to +x StartPathfinder.sh yourself.

To uninstall, just reopen the installer and click uninstall. This will clear out all of the changes the installer made, and will also delete all of your mods with it.

### Manually
### Manually (Windows)

Get the latest ZIP from the releases page [here](https://github.com/Arkhist/Hacknet-Pathfinder/releases) and extract it to your Hacknet folder.

Run PathfinderPatcher.exe and it will create HacknetPathfinder.exe, if you want this to be launched when you launch from Steam rename Hacknet.exe and replace it with HacknetPathfinder.exe (this also applies to Linux).
Run PathfinderPatcher.exe and it will create HacknetPathfinder.exe, if you want this to be launched when you launch from Steam rename Hacknet.exe and replace it with HacknetPathfinder.exe.

To uninstall, just delete HacknetPathfinder.exe (or whatever you renamed it to) and move back the original Hacknet.exe if you renamed it. If you also want to remove all your mods and configs, delete the BepInEx directory.

### Manually (Linux)

Get the latest ZIP from the releases page [here](https://github.com/Arkhist/Hacknet-Pathfinder/releases) and extract it to your Hacknet folder.

Run PathfinderPatcher.exe and it will create HacknetPathfinder.exe.

Copy `Hacknet.bin.x86_64` to `HacknetPathfinder.bin.x86_64`

Make StartPathfinder.sh executable and run it.

## Troubleshooting

### The game crashes before it even loads! (Windows only)
Expand Down
Binary file modified libs/0Harmony.dll
Binary file not shown.
Binary file modified libs/BepInEx.Core.dll
Binary file not shown.
10 changes: 9 additions & 1 deletion libs/BepInEx.Core.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified libs/MonoMod.RuntimeDetour.dll
Binary file not shown.
Binary file modified libs/MonoMod.Utils.dll
Binary file not shown.
Binary file removed libs/SemVer.dll
Binary file not shown.
Binary file added libs/SemanticVersioning.dll
Binary file not shown.

0 comments on commit 4c4ad67

Please sign in to comment.