boop
This commit is contained in:
parent
6266ec0fed
commit
fb17a80a37
295
src/common/Haru.ByteBanger.ts
Normal file
295
src/common/Haru.ByteBanger.ts
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
export enum DiffResultType
|
||||||
|
{
|
||||||
|
Success = 0,
|
||||||
|
OriginalFilePathInvalid,
|
||||||
|
OriginalFileNotFound,
|
||||||
|
OriginalFileReadFailed,
|
||||||
|
PatchedFilePathInvalid,
|
||||||
|
PatchedFileNotFound,
|
||||||
|
PatchedFileReadFailed,
|
||||||
|
FilesMatch
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum PatchResultType
|
||||||
|
{
|
||||||
|
Success = 0,
|
||||||
|
InputLengthMismatch,
|
||||||
|
InputChecksumMismatch,
|
||||||
|
AlreadyPatched,
|
||||||
|
OutputChecksumMismatch
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PatchItem
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PatchInfo
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
class DiffResult
|
||||||
|
{
|
||||||
|
public readonly Result: DiffResultType
|
||||||
|
public readonly PatchInfo: PatchInfo
|
||||||
|
|
||||||
|
public constructor(result: DiffResultType, patchInfo: PatchInfo)
|
||||||
|
{
|
||||||
|
this.Result = result;
|
||||||
|
this.PatchInfo = patchInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PatchResult
|
||||||
|
{
|
||||||
|
public readonly Result: PatchResultType
|
||||||
|
public readonly PatchedData: Uint8Array
|
||||||
|
|
||||||
|
public constructor(result: PatchResultType, patchedData: Uint8Array)
|
||||||
|
{
|
||||||
|
this.Result = result;
|
||||||
|
this.PatchedData = patchedData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
public class PatchItem
|
||||||
|
{
|
||||||
|
public int Offset { get; set; }
|
||||||
|
public byte[] Data { get; set; }
|
||||||
|
|
||||||
|
public static PatchItem FromReader(BinaryReader br)
|
||||||
|
{
|
||||||
|
int offset = br.ReadInt32();
|
||||||
|
int dataLength = br.ReadInt32();
|
||||||
|
byte[] data = br.ReadBytes(dataLength);
|
||||||
|
|
||||||
|
return new PatchItem
|
||||||
|
{
|
||||||
|
Offset = offset,
|
||||||
|
Data = data
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void ToWriter(BinaryWriter bw)
|
||||||
|
{
|
||||||
|
// offset // 4B
|
||||||
|
bw.Write(Offset);
|
||||||
|
|
||||||
|
// length // 4B
|
||||||
|
bw.Write(Data.Length);
|
||||||
|
|
||||||
|
// data // xB
|
||||||
|
bw.Write(Data, 0, Data.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PatchInfo
|
||||||
|
{
|
||||||
|
public const string BYBA = "BYBA";
|
||||||
|
public byte[] OriginalChecksum { get; set; }
|
||||||
|
public int OriginalLength { get; set; }
|
||||||
|
public byte[] PatchedChecksum { get; set; }
|
||||||
|
public int PatchedLength { get; set; }
|
||||||
|
public PatchItem[] Items { get; set; }
|
||||||
|
|
||||||
|
public static PatchInfo FromBytes(byte[] bytes)
|
||||||
|
{
|
||||||
|
if (bytes.Length < 82) throw new Exception("Input data too short, cannot be a valid patch");
|
||||||
|
|
||||||
|
PatchInfo pi = new PatchInfo();
|
||||||
|
|
||||||
|
using (MemoryStream ms = new MemoryStream(bytes))
|
||||||
|
using (BinaryReader br = new BinaryReader(ms))
|
||||||
|
{
|
||||||
|
byte[] buf = null;
|
||||||
|
|
||||||
|
buf = br.ReadBytes(4);
|
||||||
|
if (Encoding.ASCII.GetString(buf) != BYBA) throw new Exception("Invalid identifier");
|
||||||
|
|
||||||
|
if (br.ReadByte() != 1) throw new Exception("Invalid major file version (1 expected)");
|
||||||
|
if (br.ReadByte() != 0) throw new Exception("Invalid minor file version (0 expected)");
|
||||||
|
|
||||||
|
pi.OriginalLength = br.ReadInt32();
|
||||||
|
pi.OriginalChecksum = br.ReadBytes(32);
|
||||||
|
pi.PatchedLength = br.ReadInt32();
|
||||||
|
pi.PatchedChecksum = br.ReadBytes(32);
|
||||||
|
|
||||||
|
int itemCount = br.ReadInt32();
|
||||||
|
|
||||||
|
List<PatchItem> items = new List<PatchItem>();
|
||||||
|
for (int i = 0; i < itemCount; i++)
|
||||||
|
items.Add(PatchItem.FromReader(br));
|
||||||
|
pi.Items = items.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
return pi;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] ToBytes()
|
||||||
|
{
|
||||||
|
byte[] data;
|
||||||
|
|
||||||
|
using (MemoryStream ms = new MemoryStream())
|
||||||
|
{
|
||||||
|
using (BinaryWriter bw = new BinaryWriter(ms, Encoding.ASCII, true))
|
||||||
|
{
|
||||||
|
// identifier "BYBA" // 4B
|
||||||
|
byte[] byba = Encoding.ASCII.GetBytes(BYBA);
|
||||||
|
bw.Write(byba, 0, byba.Length);
|
||||||
|
|
||||||
|
// version "1.0" // 2B
|
||||||
|
bw.Write((byte)1);
|
||||||
|
bw.Write((byte)0);
|
||||||
|
|
||||||
|
// original len // 4B
|
||||||
|
bw.Write(OriginalLength);
|
||||||
|
|
||||||
|
// original chk // 32B
|
||||||
|
bw.Write(OriginalChecksum, 0, OriginalChecksum.Length);
|
||||||
|
|
||||||
|
// patched len // 4B
|
||||||
|
bw.Write(PatchedLength);
|
||||||
|
|
||||||
|
// patched chk // 32B
|
||||||
|
bw.Write(PatchedChecksum, 0, PatchedChecksum.Length);
|
||||||
|
|
||||||
|
// item count // 4B
|
||||||
|
bw.Write(Items.Length);
|
||||||
|
|
||||||
|
// data
|
||||||
|
foreach (PatchItem pi in Items)
|
||||||
|
pi.ToWriter(bw);
|
||||||
|
}
|
||||||
|
|
||||||
|
data = new byte[ms.Length];
|
||||||
|
ms.Seek(0, SeekOrigin.Begin);
|
||||||
|
ms.Read(data, 0, (int)ms.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PatchUtil
|
||||||
|
{
|
||||||
|
public static DiffResult Diff(byte[] original, byte[] patched)
|
||||||
|
{
|
||||||
|
PatchInfo pi = new PatchInfo
|
||||||
|
{
|
||||||
|
OriginalLength = original.Length,
|
||||||
|
PatchedLength = patched.Length
|
||||||
|
};
|
||||||
|
|
||||||
|
using (SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider())
|
||||||
|
{
|
||||||
|
pi.OriginalChecksum = sha256.ComputeHash(original);
|
||||||
|
pi.PatchedChecksum = sha256.ComputeHash(patched);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pi.OriginalLength == pi.PatchedLength) && ArraysMatch(pi.OriginalChecksum, pi.PatchedChecksum))
|
||||||
|
return new DiffResult(DiffResultType.FilesMatch, null);
|
||||||
|
|
||||||
|
int minLength = Math.Min(pi.OriginalLength, pi.PatchedLength);
|
||||||
|
|
||||||
|
List<PatchItem> items = new List<PatchItem>();
|
||||||
|
List<byte> currentData = null;
|
||||||
|
int diffOffsetStart = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < minLength; i++)
|
||||||
|
{
|
||||||
|
if (original[i] != patched[i])
|
||||||
|
{
|
||||||
|
if (currentData == null)
|
||||||
|
{
|
||||||
|
diffOffsetStart = i;
|
||||||
|
currentData = new List<byte>();
|
||||||
|
}
|
||||||
|
|
||||||
|
currentData.Add(patched[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (currentData != null)
|
||||||
|
items.Add(new PatchItem { Offset = diffOffsetStart, Data = currentData.ToArray() });
|
||||||
|
|
||||||
|
currentData = null;
|
||||||
|
diffOffsetStart = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentData != null)
|
||||||
|
items.Add(new PatchItem { Offset = diffOffsetStart, Data = currentData.ToArray() });
|
||||||
|
|
||||||
|
if (pi.PatchedLength > pi.OriginalLength)
|
||||||
|
{
|
||||||
|
byte[] buf = new byte[pi.PatchedLength - pi.OriginalLength];
|
||||||
|
Array.Copy(patched, pi.OriginalLength, buf, 0, buf.Length);
|
||||||
|
items.Add(new PatchItem { Offset = pi.OriginalLength, Data = buf });
|
||||||
|
}
|
||||||
|
|
||||||
|
pi.Items = items.ToArray();
|
||||||
|
|
||||||
|
return new DiffResult(DiffResultType.Success, pi);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DiffResult Diff(string originalFile, string patchedFile)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(originalFile)) return new DiffResult(DiffResultType.OriginalFilePathInvalid, null);
|
||||||
|
if (string.IsNullOrWhiteSpace(patchedFile)) return new DiffResult(DiffResultType.PatchedFilePathInvalid, null);
|
||||||
|
if (!File.Exists(originalFile)) return new DiffResult(DiffResultType.OriginalFileNotFound, null);
|
||||||
|
if (!File.Exists(patchedFile)) return new DiffResult(DiffResultType.PatchedFileNotFound, null);
|
||||||
|
|
||||||
|
byte[] originalData, patchedData;
|
||||||
|
|
||||||
|
try { originalData = File.ReadAllBytes(originalFile); }
|
||||||
|
catch { return new DiffResult(DiffResultType.OriginalFileReadFailed, null); }
|
||||||
|
|
||||||
|
try { patchedData = File.ReadAllBytes(patchedFile); }
|
||||||
|
catch { return new DiffResult(DiffResultType.PatchedFileReadFailed, null); }
|
||||||
|
|
||||||
|
return Diff(originalData, patchedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PatchResult Patch(byte[] input, PatchInfo pi)
|
||||||
|
{
|
||||||
|
byte[] inputHash;
|
||||||
|
using (SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider())
|
||||||
|
{
|
||||||
|
inputHash = sha256.ComputeHash(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ArraysMatch(inputHash, pi.PatchedChecksum)) return new PatchResult(PatchResultType.AlreadyPatched, null);
|
||||||
|
if (!ArraysMatch(inputHash, pi.OriginalChecksum)) return new PatchResult(PatchResultType.InputChecksumMismatch, null);
|
||||||
|
if (input.Length != pi.OriginalLength) return new PatchResult(PatchResultType.InputLengthMismatch, null);
|
||||||
|
|
||||||
|
byte[] patchedData = new byte[pi.PatchedLength];
|
||||||
|
long minLen = Math.Min(pi.OriginalLength, pi.PatchedLength);
|
||||||
|
Array.Copy(input, patchedData, minLen);
|
||||||
|
|
||||||
|
foreach (PatchItem itm in pi.Items)
|
||||||
|
Array.Copy(itm.Data, 0, patchedData, itm.Offset, itm.Data.Length);
|
||||||
|
|
||||||
|
byte[] patchedHash;
|
||||||
|
using (SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider())
|
||||||
|
{
|
||||||
|
patchedHash = sha256.ComputeHash(patchedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ArraysMatch(patchedHash, pi.PatchedChecksum)) return new PatchResult(PatchResultType.OutputChecksumMismatch, null);
|
||||||
|
|
||||||
|
return new PatchResult(PatchResultType.Success, patchedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool ArraysMatch(byte[] a, byte[] b)
|
||||||
|
{
|
||||||
|
if (a.Length != b.Length) return false;
|
||||||
|
|
||||||
|
for (int i = 0; i < a.Length; i++)
|
||||||
|
if (a[i] != b[i]) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
@ -83,6 +83,9 @@ export class NotificationServer implements IServer
|
|||||||
const message = Json.serialize(new PingNotificationModel());
|
const message = Json.serialize(new PingNotificationModel());
|
||||||
this.httpServer = new HttpServer("localhost", 8001);
|
this.httpServer = new HttpServer("localhost", 8001);
|
||||||
this.wsServer = new WsServer(this.httpServer, message);
|
this.wsServer = new WsServer(this.httpServer, message);
|
||||||
|
|
||||||
|
// add cached responses
|
||||||
|
// this.server.addService(url, cachedResponseService);
|
||||||
}
|
}
|
||||||
|
|
||||||
public start(): void
|
public start(): void
|
||||||
|
Loading…
x
Reference in New Issue
Block a user