diff --git a/js/LoadSaveFile.js b/js/LoadSaveFile.js index 9f3f90b..21f2235 100644 --- a/js/LoadSaveFile.js +++ b/js/LoadSaveFile.js @@ -1,4 +1,7 @@ -const CSHARP_HEADER = [0, 1, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 0, 0, 0, 0, 6, 1, 0, 0, 0]; +const CSHARP_HEADER = [0, 1, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 0, 0, 0, 0, 6, 1, 0, 0, 0]; // 22 bytes + +const BASE64_ARRAY = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".split("").map(c => c.charCodeAt(0)); +const BASE64_DECODE_TABLE = new Map(BASE64_ARRAY.map((ord, i) => [ord, i])); function ShowFile(input) { let inputFileObject = input.files[0]; @@ -25,7 +28,6 @@ function LoadSaveFile(input) { // 2. Decode file - // base64 Decoding (ArrayBuffer) // AES decryption (ECB) removes pkcs7 padding (ArrayBuffer) // Convert ArrayBuffer to string/text TextDecoder().decode(ArrayBuffer) @@ -40,7 +42,7 @@ function FileObjectToArrayBuffer() { let inputArrayBuffer = this.result; try { - // Uint8Array(ArrayBuffer) + // Uint8Array(ArrayBuffer) uint8_t equivalent in C inputArrayBuffer = new Uint8Array(inputArrayBuffer); // ArrayBuffer.slice() @@ -50,6 +52,9 @@ function FileObjectToArrayBuffer() { // remove C# header (ArrayBuffer) inputArrayBuffer = RemoveCSharpHeader(inputArrayBuffer); + // base64 Decoding (ArrayBuffer) + inputArrayBuffer = Base64Decode(inputArrayBuffer); + alert(`File: ${inputArrayBuffer}`); } catch (error) { alert(`The file cannot be read. Error: ${error}`); @@ -73,4 +78,30 @@ function RemoveCSharpHeader(buffer) { let fixedArrayBuffer = buffer.subarray(lengthCount); return fixedArrayBuffer; +} + +// From bloodorca https://github.com/bloodorca/hollow based on KayDeeTee https://github.com/KayDeeTee/Hollow-Knight-SaveManager +function Base64Decode(buffer) { + buffer = new Uint8Array(buffer).slice(); + buffer = buffer.map(v => BASE64_DECODE_TABLE.get(v)) + { + let p = buffer.indexOf(64); + buffer = buffer.subarray(0, p != -1 ? p : buffer.length); + } + let output = new Uint8Array(3 * buffer.length / 4); + let continuous = Math.floor(buffer.length / 4) * 4; + for (let i = 0; i < continuous; i += 4) { + let k = 3 * i / 4; + output[k] = buffer[i] << 2 | buffer[i + 1] >> 4; + output[k + 1] = (buffer[i + 1] & 0x0F) << 4 | buffer[i + 2] >> 2; + output[k + 2] = (buffer[i + 2] & 0x03) << 6 | buffer[i + 3]; + } + if (buffer[continuous] != undefined) { + let k = 3 * continuous / 4; + output[k] = buffer[continuous] << 2 | buffer[continuous + 1] >> 4; + if (buffer[continuous + 2] != undefined) { + output[k + 1] = (buffer[continuous + 1] & 0x0F) << 4 | buffer[continuous + 2] >> 2; + } + } + return output; } \ No newline at end of file