diff --git a/NLUL.Core/Client/ClientRunner.cs b/NLUL.Core/Client/ClientRunner.cs index 0e73322..1fe5c24 100644 --- a/NLUL.Core/Client/ClientRunner.cs +++ b/NLUL.Core/Client/ClientRunner.cs @@ -147,6 +147,7 @@ public void PatchClient() { this.clientPatcher.Install(ClientPatchName.ModLoader); this.clientPatcher.Install(ClientPatchName.AutoTcpUdp); + this.clientPatcher.Install(ClientPatchName.FixAssemblyVendorHologram); this.clientPatcher.Install(ClientPatchName.RemoveDLUAd); } diff --git a/NLUL.Core/Client/Patch/ClientPatcher.cs b/NLUL.Core/Client/Patch/ClientPatcher.cs index 08680f2..1e4b323 100644 --- a/NLUL.Core/Client/Patch/ClientPatcher.cs +++ b/NLUL.Core/Client/Patch/ClientPatcher.cs @@ -18,6 +18,7 @@ public enum ClientPatchName ModLoader, TcpUdp, AutoTcpUdp, + FixAssemblyVendorHologram, RemoveDLUAd, } @@ -42,6 +43,7 @@ public ClientPatcher(SystemInfo systemInfo) {ClientPatchName.ModLoader,new ModLoader(systemInfo,this.manifest)}, {ClientPatchName.TcpUdp,new TcpUdp(systemInfo,this.manifest)}, {ClientPatchName.AutoTcpUdp,new AutoTcpUdp(systemInfo,this.manifest)}, + {ClientPatchName.FixAssemblyVendorHologram,new FixAssemblyVendorHologram(systemInfo)}, {ClientPatchName.RemoveDLUAd,new RemoveDLUAd(systemInfo)}, }; } diff --git a/NLUL.Core/Client/Patch/FixAssemblyVendorHologram.cs b/NLUL.Core/Client/Patch/FixAssemblyVendorHologram.cs new file mode 100644 index 0000000..ed0282f --- /dev/null +++ b/NLUL.Core/Client/Patch/FixAssemblyVendorHologram.cs @@ -0,0 +1,119 @@ +/* + * TheNexusAvenger + * + * Patch for fixing the Assembly vendor hologram. + * For some reason, the path is set incorrectly, and + * it only is a problem in unpacked clients. + */ + +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace NLUL.Core.Client.Patch +{ + public class FixAssemblyVendorHologram : IPatch + { + private static readonly byte[] InvalidAnimPath = Encoding.ASCII.GetBytes("\x01" + "9\x00\x00\x00Z:\\lwo\\4_game\\client\\res\\mesh\\3DUI\\Assembly_Logo_Sign.nif"); // Has to be split since \x019 becomes 0b25 instead of 0b01 + '9'. + private static readonly byte[] ValidAnimPath = Encoding.ASCII.GetBytes("\x01(\x00\x00\x00.\\..\\..\\mesh\\3DUI\\Assembly_Logo_Sign.nif"); + + private string assemblySignFileLocation; + + /* + * Creates the patch. + */ + public FixAssemblyVendorHologram(SystemInfo systemInfo) + { + this.assemblySignFileLocation = Path.Combine(systemInfo.ClientLocation, "res", "animations", "3dui", "assembly_sign_anim_sm.kfm"); + } + + /* + * Returns if an update is available. + */ + public bool IsUpdateAvailable() + { + return false; + } + + /* + * Returns if the patch is installed. + */ + public bool IsInstalled() + { + return !File.Exists(this.assemblySignFileLocation) || !((IList) File.ReadAllBytes(this.assemblySignFileLocation)).Contains((byte) ':'); + } + + /* + * Installs the patch. + */ + public void Install() + { + ReplaceByteContents(this.assemblySignFileLocation, InvalidAnimPath, ValidAnimPath); + } + + /* + * Uninstalls the patch. + */ + public void Uninstall() + { + ReplaceByteContents(this.assemblySignFileLocation, ValidAnimPath, InvalidAnimPath); + } + + /* + * Replaces the byte contents of the given file. + * Only replaces 1 occurence. + */ + private static void ReplaceByteContents(string filePath, byte[] find, byte[] replace) + { + // Return if the file doesn't exist. + if (!File.Exists(filePath)) + { + return; + } + + // Find the start of the matching bytes. + var animFileData = File.ReadAllBytes(filePath); + var findIndex = -1; + for (var i = 0; i < animFileData.Length; i++) + { + if (animFileData[i] != find[0]) continue; + for (var j = 0; i < find.Length; j++) + { + if (animFileData[i + j] != find[j]) break; + if (j != find.Length - 1) continue; + findIndex = i; + break; + } + if (findIndex != -1) + { + break; + } + } + + // Return if no index was found. + if (findIndex == -1) + { + return; + } + + // Create the new bytes to write, replacing the new bytes. + var newBytes = new List(); + for (var i = 0; i < findIndex; i++) + { + newBytes.Add(animFileData[i]); + } + foreach (var t in replace) + { + newBytes.Add(t); + } + for (var i = findIndex + find.Length; i < animFileData.Length; i++) + { + newBytes.Add(animFileData[i]); + } + + // Write the bytes. + File.WriteAllBytes(filePath, newBytes.ToArray()); + } + } +} \ No newline at end of file diff --git a/NLUL.GUI/Component/Patches/PatchesView.xaml.cs b/NLUL.GUI/Component/Patches/PatchesView.xaml.cs index ed2c208..d20a5b2 100644 --- a/NLUL.GUI/Component/Patches/PatchesView.xaml.cs +++ b/NLUL.GUI/Component/Patches/PatchesView.xaml.cs @@ -35,6 +35,12 @@ public class PatchData PatchDescription = "Enables connecting to community-run LEGO Universe servers that may or may not use TCP/UDP. This is automatically managed for the requested server. Requires the Mod Loader to be installed. Do not install with TCP/UDP Shim.", PatchEnum = ClientPatchName.AutoTcpUdp, }, + new PatchData() + { + PatchName = "Fix Assembly Vendor Hologram", + PatchDescription = "Fixes the Assembly vendor at Nimbus Station showing a Missing NIF error.", + PatchEnum = ClientPatchName.FixAssemblyVendorHologram, + }, new PatchData() { PatchName = "Remove DLU Ad", PatchDescription = "Removes the advertisement for DLU from the zone loading screen.",