public IpsPatcher(BinaryReader reader) { _patches = ParseIps(reader); if (_patches != null) { Logger.Info?.Print(LogClass.ModLoader, "IPS patch loaded successfully"); } }
/// <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; } }
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;
private static MemPatch ParseIps(BinaryReader reader) { Span <byte> IpsHeaderMagic = Encoding.ASCII.GetBytes("PATCH").AsSpan(); Span <byte> IpsTailMagic = Encoding.ASCII.GetBytes("EOF").AsSpan(); Span <byte> Ips32HeaderMagic = Encoding.ASCII.GetBytes("IPS32").AsSpan(); Span <byte> Ips32TailMagic = Encoding.ASCII.GetBytes("EEOF").AsSpan(); MemPatch patches = new MemPatch(); var header = reader.ReadBytes(IpsHeaderMagic.Length).AsSpan(); if (header.Length != IpsHeaderMagic.Length) { return(null); } bool is32; Span <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); }