diff options
| author | TSR Berry <20988865+TSRBerry@users.noreply.github.com> | 2023-04-08 01:22:00 +0200 |
|---|---|---|
| committer | Mary <thog@protonmail.com> | 2023-04-27 23:51:14 +0200 |
| commit | cee712105850ac3385cd0091a923438167433f9f (patch) | |
| tree | 4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /Ryujinx.HLE/Loaders/Mods | |
| parent | cd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff) | |
Move solution and projects to src
Diffstat (limited to 'Ryujinx.HLE/Loaders/Mods')
| -rw-r--r-- | Ryujinx.HLE/Loaders/Mods/IPSPatcher.cs | 117 | ||||
| -rw-r--r-- | Ryujinx.HLE/Loaders/Mods/IPSwitchPatcher.cs | 275 | ||||
| -rw-r--r-- | Ryujinx.HLE/Loaders/Mods/MemPatch.cs | 96 |
3 files changed, 0 insertions, 488 deletions
diff --git a/Ryujinx.HLE/Loaders/Mods/IPSPatcher.cs b/Ryujinx.HLE/Loaders/Mods/IPSPatcher.cs deleted file mode 100644 index 510fec05..00000000 --- a/Ryujinx.HLE/Loaders/Mods/IPSPatcher.cs +++ /dev/null @@ -1,117 +0,0 @@ -using Ryujinx.Common.Logging; -using System; -using System.IO; -using System.Text; - -namespace Ryujinx.HLE.Loaders.Mods -{ - class IpsPatcher - { - MemPatch _patches; - - public IpsPatcher(BinaryReader reader) - { - _patches = ParseIps(reader); - if (_patches != null) - { - Logger.Info?.Print(LogClass.ModLoader, "IPS patch loaded successfully"); - } - } - - private static MemPatch ParseIps(BinaryReader reader) - { - ReadOnlySpan<byte> IpsHeaderMagic = "PATCH"u8; - ReadOnlySpan<byte> IpsTailMagic = "EOF"u8; - ReadOnlySpan<byte> Ips32HeaderMagic = "IPS32"u8; - ReadOnlySpan<byte> Ips32TailMagic = "EEOF"u8; - - MemPatch patches = new MemPatch(); - var header = reader.ReadBytes(IpsHeaderMagic.Length).AsSpan(); - - if (header.Length != IpsHeaderMagic.Length) - { - return null; - } - - bool is32; - ReadOnlySpan<byte> tailSpan; - - if (header.SequenceEqual(IpsHeaderMagic)) - { - is32 = false; - tailSpan = IpsTailMagic; - } - else if (header.SequenceEqual(Ips32HeaderMagic)) - { - is32 = true; - tailSpan = Ips32TailMagic; - } - else - { - return null; - } - - byte[] buf = new byte[tailSpan.Length]; - - bool ReadNext(int size) => reader.Read(buf, 0, size) != size; - - while (true) - { - if (ReadNext(buf.Length)) - { - return null; - } - - if (buf.AsSpan().SequenceEqual(tailSpan)) - { - break; - } - - int patchOffset = is32 ? buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3] - : buf[0] << 16 | buf[1] << 8 | buf[2]; - - if (ReadNext(2)) - { - return null; - } - - int patchSize = buf[0] << 8 | buf[1]; - - if (patchSize == 0) // RLE/Fill mode - { - if (ReadNext(2)) - { - return null; - } - - int fillLength = buf[0] << 8 | buf[1]; - - if (ReadNext(1)) - { - return null; - } - - patches.AddFill((uint)patchOffset, fillLength, buf[0]); - } - else // Copy mode - { - var patch = reader.ReadBytes(patchSize); - - if (patch.Length != patchSize) - { - return null; - } - - patches.Add((uint)patchOffset, patch); - } - } - - return patches; - } - - public void AddPatches(MemPatch patches) - { - patches.AddFrom(_patches); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/Loaders/Mods/IPSwitchPatcher.cs b/Ryujinx.HLE/Loaders/Mods/IPSwitchPatcher.cs deleted file mode 100644 index 416fc1b4..00000000 --- a/Ryujinx.HLE/Loaders/Mods/IPSwitchPatcher.cs +++ /dev/null @@ -1,275 +0,0 @@ -using Ryujinx.Common.Logging; -using System; -using System.IO; -using System.Text; - -namespace Ryujinx.HLE.Loaders.Mods -{ - class IPSwitchPatcher - { - const string BidHeader = "@nsobid-"; - - private enum Token - { - Normal, - String, - EscapeChar, - Comment - } - - private readonly StreamReader _reader; - public string BuildId { get; } - - public IPSwitchPatcher(StreamReader reader) - { - string header = reader.ReadLine(); - if (header == null || !header.StartsWith(BidHeader)) - { - Logger.Error?.Print(LogClass.ModLoader, "IPSwitch: Malformed PCHTXT file. Skipping..."); - - return; - } - - _reader = reader; - BuildId = header.Substring(BidHeader.Length).TrimEnd().TrimEnd('0'); - } - - // Uncomments line and unescapes C style strings within - private static string PreprocessLine(string line) - { - StringBuilder str = new StringBuilder(); - Token state = Token.Normal; - - for (int i = 0; i < line.Length; ++i) - { - char c = line[i]; - char la = i + 1 != line.Length ? line[i + 1] : '\0'; - - switch (state) - { - case Token.Normal: - state = c == '"' ? Token.String : - c == '/' && la == '/' ? Token.Comment : - c == '/' && la != '/' ? Token.Comment : // Ignore error and stop parsing - Token.Normal; - break; - case Token.String: - state = c switch - { - '"' => Token.Normal, - '\\' => Token.EscapeChar, - _ => Token.String - }; - break; - case Token.EscapeChar: - state = Token.String; - c = c switch - { - 'a' => '\a', - 'b' => '\b', - 'f' => '\f', - 'n' => '\n', - 'r' => '\r', - 't' => '\t', - 'v' => '\v', - '\\' => '\\', - _ => '?' - }; - break; - } - - if (state == Token.Comment) break; - - if (state < Token.EscapeChar) - { - str.Append(c); - } - } - - return str.ToString().Trim(); - } - - static int ParseHexByte(byte c) - { - if (c >= '0' && c <= '9') - { - return c - '0'; - } - else if (c >= 'A' && c <= 'F') - { - return c - 'A' + 10; - } - else if (c >= 'a' && c <= 'f') - { - return c - 'a' + 10; - } - else - { - return 0; - } - } - - // Big Endian - static byte[] Hex2ByteArrayBE(string hexstr) - { - if ((hexstr.Length & 1) == 1) return null; - - byte[] bytes = new byte[hexstr.Length >> 1]; - - for (int i = 0; i < hexstr.Length; i += 2) - { - int high = ParseHexByte((byte)hexstr[i]); - int low = ParseHexByte((byte)hexstr[i + 1]); - - bytes[i >> 1] = (byte)((high << 4) | low); - } - - return bytes; - } - - // Auto base discovery - private static bool ParseInt(string str, out int value) - { - if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) - { - return int.TryParse(str.AsSpan(2), System.Globalization.NumberStyles.HexNumber, null, out value); - } - else - { - return int.TryParse(str, System.Globalization.NumberStyles.Integer, null, out value); - } - } - - private MemPatch Parse() - { - if (_reader == null) - { - return null; - } - - MemPatch patches = new MemPatch(); - - bool enabled = false; - bool printValues = false; - int offset_shift = 0; - - string line; - int lineNum = 0; - - static void Print(string s) => Logger.Info?.Print(LogClass.ModLoader, $"IPSwitch: {s}"); - - void ParseWarn() => Logger.Warning?.Print(LogClass.ModLoader, $"IPSwitch: Parse error at line {lineNum} for bid={BuildId}"); - - while ((line = _reader.ReadLine()) != null) - { - if (string.IsNullOrWhiteSpace(line)) - { - enabled = false; - - continue; - } - - line = PreprocessLine(line); - lineNum += 1; - - if (line.Length == 0) - { - continue; - } - else if (line.StartsWith('#')) - { - Print(line); - } - else if (line.StartsWith("@stop")) - { - break; - } - else if (line.StartsWith("@enabled")) - { - enabled = true; - } - else if (line.StartsWith("@disabled")) - { - enabled = false; - } - else if (line.StartsWith("@flag")) - { - var tokens = line.Split(' ', 3, StringSplitOptions.RemoveEmptyEntries); - - if (tokens.Length < 2) - { - ParseWarn(); - - continue; - } - - if (tokens[1] == "offset_shift") - { - if (tokens.Length != 3 || !ParseInt(tokens[2], out offset_shift)) - { - ParseWarn(); - - continue; - } - } - else if (tokens[1] == "print_values") - { - printValues = true; - } - } - else if (line.StartsWith('@')) - { - // Ignore - } - else - { - if (!enabled) - { - continue; - } - - var tokens = line.Split(' ', 2, StringSplitOptions.RemoveEmptyEntries); - - if (tokens.Length < 2) - { - ParseWarn(); - - continue; - } - - if (!int.TryParse(tokens[0], System.Globalization.NumberStyles.HexNumber, null, out int offset)) - { - ParseWarn(); - - continue; - } - - offset += offset_shift; - - if (printValues) - { - Print($"print_values 0x{offset:x} <= {tokens[1]}"); - } - - if (tokens[1][0] == '"') - { - var patch = Encoding.ASCII.GetBytes(tokens[1].Trim('"') + "\0"); - patches.Add((uint)offset, patch); - } - else - { - var patch = Hex2ByteArrayBE(tokens[1]); - patches.Add((uint)offset, patch); - } - } - } - - return patches; - } - - public void AddPatches(MemPatch patches) - { - patches.AddFrom(Parse()); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/Loaders/Mods/MemPatch.cs b/Ryujinx.HLE/Loaders/Mods/MemPatch.cs deleted file mode 100644 index f9db7c69..00000000 --- a/Ryujinx.HLE/Loaders/Mods/MemPatch.cs +++ /dev/null @@ -1,96 +0,0 @@ -using Ryujinx.Common.Logging; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Ryujinx.HLE.Loaders.Mods -{ - public class MemPatch - { - readonly Dictionary<uint, byte[]> _patches = new Dictionary<uint, byte[]>(); - - /// <summary> - /// Adds a patch to specified offset. Overwrites if already present. - /// </summary> - /// <param name="offset">Memory offset</param> - /// <param name="patch">The patch to add</param> - public void Add(uint offset, byte[] patch) - { - _patches[offset] = patch; - } - - /// <summary> - /// Adds a patch in the form of an RLE (Fill mode). - /// </summary> - /// <param name="offset">Memory offset</param> - /// <param name="length"The fill length</param> - /// <param name="filler">The byte to fill</param> - public void AddFill(uint offset, int length, byte filler) - { - // TODO: Can be made space efficient by changing `_patches` - // Should suffice for now - byte[] patch = new byte[length]; - patch.AsSpan().Fill(filler); - - _patches[offset] = patch; - } - - /// <summary> - /// Adds all patches from an existing MemPatch - /// </summary> - /// <param name="patches">The patches to add</param> - public void AddFrom(MemPatch patches) - { - if (patches == null) - { - return; - } - - foreach (var (patchOffset, patch) in patches._patches) - { - _patches[patchOffset] = patch; - } - } - - /// <summary> - /// Applies all the patches added to this instance. - /// </summary> - /// <remarks> - /// Patches are applied in ascending order of offsets to guarantee - /// overlapping patches always apply the same way. - /// </remarks> - /// <param name="memory">The span of bytes to patch</param> - /// <param name="maxSize">The maximum size of the slice of patchable memory</param> - /// <param name="protectedOffset">A secondary offset used in special cases (NSO header)</param> - /// <returns>Successful patches count</returns> - public int Patch(Span<byte> memory, int protectedOffset = 0) - { - int count = 0; - foreach (var (offset, patch) in _patches.OrderBy(item => item.Key)) - { - int patchOffset = (int)offset; - int patchSize = patch.Length; - - if (patchOffset < protectedOffset || patchOffset > memory.Length) - { - continue; // Add warning? - } - - patchOffset -= protectedOffset; - - if (patchOffset + patchSize > memory.Length) - { - patchSize = memory.Length - patchOffset; // Add warning? - } - - Logger.Info?.Print(LogClass.ModLoader, $"Patching address offset {patchOffset:x} <= {BitConverter.ToString(patch).Replace('-', ' ')} len={patchSize}"); - - patch.AsSpan(0, patchSize).CopyTo(memory.Slice(patchOffset, patchSize)); - - count++; - } - - return count; - } - } -}
\ No newline at end of file |
