diff --git a/ayunEPKDecompiler.js b/ayunEPKDecompiler.js
new file mode 100644
index 0000000..52a5519
--- /dev/null
+++ b/ayunEPKDecompiler.js
@@ -0,0 +1,244 @@
+window.decompileEPK = function () {
+ let currentOffset = 0;
+
+ let numFiles = 0;
+
+ function detectOldHeader(epkData) {
+ const oldHeader = "EAGPKG!!";
+ for (let i = 0; i < oldHeader.length; i++) {
+ if (epkData[i] != oldHeader.charCodeAt(i)) return false;
+ }
+ return true;
+ }
+
+ function readASCII(epkData) {
+ const len = read(epkData);
+ let str = "";
+ for (let i = 0; i < len; i++) {
+ str += String.fromCharCode(read(epkData));
+ }
+ return str;
+ }
+
+ function read(epkData) {
+ return epkData[currentOffset++];
+ }
+
+ function skip(num) {
+ currentOffset += num;
+ }
+
+ function loadShort(epkData) {
+ return (read(epkData) << 8) | read(epkData);
+ }
+
+ function loadInt(epkData) {
+ return (read(epkData) << 24) | (read(epkData) << 16) | (read(epkData) << 8) | read(epkData);
+ }
+
+ function readUTF(epkData) {
+ const len = loadShort(epkData);
+ let str = "";
+ for (let i = 0; i < len; i++) {
+ str += String.fromCharCode(read(epkData));
+ }
+ return str;
+ }
+
+ // https://stackoverflow.com/a/18639903/6917520
+
+ const crc32 = (function() {
+ let table = new Uint32Array(256);
+
+ for (let i = 256; i--;) {
+ let tmp = i;
+
+ for (let k = 8; k--;) {
+ tmp = tmp & 1 ? 3988292384 ^ tmp >>> 1 : tmp >>> 1;
+ }
+
+ table[i] = tmp;
+ }
+
+ return function(data) {
+ let crc = -1;
+
+ for (let i = 0, l = data.length; i < l; i++) {
+ crc = crc >>> 8 ^ table[crc & 255 ^ data[i]];
+ }
+
+ return (crc ^ -1) >>> 0;
+ };
+ })();
+
+ function decompileOld(epkData) {
+ readUTF(epkData);
+
+ try {
+ let zData = pako.inflate(epkData.slice(currentOffset));
+ currentOffset = 0;
+ return readFilesOld(zData);
+ } catch (err) {
+ return null;
+ }
+ }
+
+ function decompileNew(epkData) {
+ const vers = readASCII(epkData);
+
+ if (!vers.startsWith("ver2.")) {
+ return null;
+ }
+
+ skip(read(epkData));
+ skip(loadShort(epkData));
+ skip(8);
+
+ numFiles = loadInt(epkData);
+
+ const compressionType = String.fromCharCode(read(epkData));
+
+ let zData = epkData.slice(currentOffset);
+
+ if (compressionType == "Z" || compressionType == "G") {
+ try {
+ zData = pako.inflate(zData);
+ } catch (err) {
+ return null;
+ }
+ } else if (compressionType == "0") {
+ // do nothing
+ } else {
+ return null;
+ }
+
+ currentOffset = 0;
+
+ return readFilesNew(zData);
+ }
+
+ function readFilesOld(data) {
+ let files = [];
+
+ let file;
+ while ((file = readFileOld(data)) != null) {
+ if (file == -1) return null;
+ files.push(file);
+ }
+
+ return files;
+ }
+
+ function readFileOld(data) {
+ const s = readUTF(data);
+ if (s == " end") {
+ return null;
+ } else if (s != "
Decompile EPK files in your browser!
+ Select .EPK file: +Compile EPK files in your browser!
Use legacy format: @@ -142,7 +143,7 @@ }; })(); - const downloadLink = document.querySelector('a'); + const downloadLink = document.querySelectorAll('a')[1]; const progressBar = document.querySelector('progress'); const fileElems = document.querySelectorAll('input[type=file]'); const oldBox = document.querySelector('input[type=checkbox]'); diff --git a/pako_inflate.min.js b/pako_inflate.min.js new file mode 100644 index 0000000..3431269 --- /dev/null +++ b/pako_inflate.min.js @@ -0,0 +1,2 @@ +/*! pako 2.0.4 https://github.com/nodeca/pako @license (MIT AND Zlib) */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).pako={})}(this,(function(e){"use strict";var t=(e,t,i,n)=>{let a=65535&e|0,r=e>>>16&65535|0,o=0;for(;0!==i;){o=i>2e3?2e3:i,i-=o;do{a=a+t[n++]|0,r=r+a|0}while(--o);a%=65521,r%=65521}return a|r<<16|0};const i=new Uint32Array((()=>{let e,t=[];for(var i=0;i<256;i++){e=i;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[i]=e}return t})());var n=(e,t,n,a)=>{const r=i,o=a+n;e^=-1;for(let i=a;i2;)R[a++]=y[x++],R[a++]=y[x++],R[a++]=y[x++],p-=3;p&&(R[a++]=y[x++],p>1&&(R[a++]=y[x++]))}else{x=a-v;do{R[a++]=R[x++],R[a++]=R[x++],R[a++]=R[x++],p-=3}while(p>2);p&&(R[a++]=R[x++],p>1&&(R[a++]=R[x++]))}break}}break}}while(i>>8&255,r.check=n(r.check,Y,2,0),Z=0,S=0,r.mode=2;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&Z)<<8)+(Z>>8))%31){e.msg="incorrect header check",r.mode=E;break}if((15&Z)!==x){e.msg="unknown compression method",r.mode=E;break}if(Z>>>=4,S-=4,j=8+(15&Z),0===r.wbits)r.wbits=j;else if(j>r.wbits){e.msg="invalid window size",r.mode=E;break}r.dmax=1<>>8&255,Y[2]=Z>>>16&255,Y[3]=Z>>>24&255,r.check=n(r.check,Y,4,0)),Z=0,S=0,r.mode=4;case 4:for(;S<16;){if(0===c)break e;c--,Z+=o[l++]<>8),512&r.flags&&(Y[0]=255&Z,Y[1]=Z>>>8&255,r.check=n(r.check,Y,2,0)),Z=0,S=0,r.mode=5;case 5:if(1024&r.flags){for(;S<16;){if(0===c)break e;c--,Z+=o[l++]<>>8&255,r.check=n(r.check,Y,2,0)),Z=0,S=0}else r.head&&(r.head.extra=null);r.mode=6;case 6:if(1024&r.flags&&(U=r.length,U>c&&(U=c),U&&(r.head&&(j=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Uint8Array(r.head.extra_len)),r.head.extra.set(o.subarray(l,l+U),j)),512&r.flags&&(r.check=n(r.check,o,U,l)),c-=U,l+=U,r.length-=U),r.length))break e;r.length=0,r.mode=7;case 7:if(2048&r.flags){if(0===c)break e;U=0;do{j=o[l+U++],r.head&&j&&r.length<65536&&(r.head.name+=String.fromCharCode(j))}while(j&&U>>=7&S,S-=7&S,r.mode=27;break}for(;S<3;){if(0===c)break e;c--,Z+=o[l++]<>>=1,S-=1,3&Z){case 0:r.mode=14;break;case 1:if(B(r),r.mode=20,i===w){Z>>>=2,S-=2;break e}break;case 2:r.mode=17;break;case 3:e.msg="invalid block type",r.mode=E}Z>>>=2,S-=2;break;case 14:for(Z>>>=7&S,S-=7&S;S<32;){if(0===c)break e;c--,Z+=o[l++]<>>16^65535)){e.msg="invalid stored block lengths",r.mode=E;break}if(r.length=65535&Z,Z=0,S=0,r.mode=15,i===w)break e;case 15:r.mode=16;case 16:if(U=r.length,U){if(U>c&&(U=c),U>A&&(U=A),0===U)break e;s.set(o.subarray(l,l+U),d),c-=U,l+=U,A-=U,d+=U,r.length-=U;break}r.mode=y;break;case 17:for(;S<14;){if(0===c)break e;c--,Z+=o[l++]<>>=5,S-=5,r.ndist=1+(31&Z),Z>>>=5,S-=5,r.ncode=4+(15&Z),Z>>>=4,S-=4,r.nlen>286||r.ndist>30){e.msg="too many length or distance symbols",r.mode=E;break}r.have=0,r.mode=18;case 18:for(;r.have>>=C,S-=C,r.lens[r.have++]=F;else{if(16===F){for(X=C+2;S>L)],C=P>>>24,z=P>>>16&255,F=65535&P,!(L+C<=S);){if(0===c)break e;c--,Z+=o[l++]<>>=L,S-=L,r.back+=L}if(Z>>>=C,S-=C,r.back+=C,r.length=F,0===z){r.mode=26;break}if(32&z){r.back=-1,r.mode=y;break}if(64&z){e.msg="invalid literal/length code",r.mode=E;break}r.extra=15&z,r.mode=22;case 22:if(r.extra){for(X=r.extra;S>L)],C=P>>>24,z=P>>>16&255,F=65535&P,!(L+C<=S);){if(0===c)break e;c--,Z+=o[l++]<>>=L,S-=L,r.back+=L}if(Z>>>=C,S-=C,r.back+=C,64&z){e.msg="invalid distance code",r.mode=E;break}r.offset=F,r.extra=15&z,r.mode=24;case 24:if(r.extra){for(X=r.extra;S{if(!e||!e.state)return _;let t=e.state;return t.window&&(t.window=null),e.state=null,b},inflateGetHeader:(e,t)=>{if(!e||!e.state)return _;const i=e.state;return 0==(2&i.wrap)?_:(i.head=t,t.done=!1,b)},inflateSetDictionary:(e,i)=>{const n=i.length;let a,r,o;return e&&e.state?(a=e.state,0!==a.wrap&&11!==a.mode?_:11===a.mode&&(r=1,r=t(r,i,n,0),r!==a.check)?g:(o=N(e,i,n,n),o?(a.mode=31,p):(a.havedict=1,b))):_},inflateInfo:"pako inflate (from Nodeca project)"};const z=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var F=function(e){const t=Array.prototype.slice.call(arguments,1);for(;t.length;){const i=t.shift();if(i){if("object"!=typeof i)throw new TypeError(i+"must be non-object");for(const t in i)z(i,t)&&(e[t]=i[t])}}return e},L=e=>{let t=0;for(let i=0,n=e.length;i