Pokemon Gen3 Savedata Parse
http://topia.wikidot.com/pokemon-gen3-savedata-parse/code/1
https://m.bulbapedia.bulbagarden.net/wiki/Save_data_structure_(Generation_III)
<head> <link rel="stylesheet" href="./3"> </head> <body> <label class="fLabel">.sav <input type="file" id="savefile" /> </label> <script src="./2"></script> </body>
var Sav2Binary = file => new Promise(r => { var reader = new FileReader(); reader.onload = _ => { var u = new Uint8Array(reader.result), a = new Array(u.length), i = u.length; while (i--) (a[i] = (u[i] < 16 ? '0' : '') + u[i].toString(16)); r(a); }; reader.readAsArrayBuffer(file); }); // label, offset, size var FS_OFFSET = [ ['SaveData_A', 0x00000, 0x0E000], ['SaveData_B', 0x0E000, 0x0E000], ['HallOfFame', 0x1C000, 0x02000], ['MysteryGift', 0x1E000, 0x01000], ['RecordedBattle', 0x1F000, 0x01000] ]; var SAVEDATA_SECTION_OFFSET = [ ['Data', 0x00000, 0x00F80], ['SectionId', 0x00FF4, 0x00002], ['CheckSum', 0x00FF6, 0x00002], ['SaveIndex', 0x00FFC, 0x00004] ]; var Binary2RawData = bin => { var obj = {}, clone = [...bin]; FS_OFFSET.forEach(off => { obj[off[0]] = clone.slice(off[1], off[1] + off[2]); ['SaveData_A', 'SaveData_B'].includes(off[0]) && ( obj[off[0]] = [...Array(14)] .map(_ => obj[off[0]].splice(0, 0x1000)), obj[off[0]] = obj[off[0]].map(o => { var i, n, _ = SAVEDATA_SECTION_OFFSET .reduce((p, v) => { n && (p[`${n}_buffer`] = o.slice(i, v[1])); p[v[0]] = o.slice(v[1], v[1] + v[2]); n = v[0], i = v[1] + v[2]; return p; }, {}); _[`${n}_buffer`] = o.slice(i); return _; }) ); }); obj.__all__ = [...bin]; return obj; } var Binary2Data = bin => { var rd = Binary2RawData(bin); var h = field => parseInt(rd[field][0]['SaveIndex'].join(''), 16); rd.__nextsave__ = h('SaveData_A') > h('SaveData_B') ? 'SaveData_B' : 'SaveData_A'; return rd; } var temp; (async() => { document.querySelector('#savefile').onchange = async _ => { var b = await Sav2Binary(_.target.files[0]); var rd = Binary2Data(b); console.log(rd); temp = rd; }; })();
.fLabel { background: #fff; box-shadow: 0 0 3px #aaa; color: #888; cursor: pointer; font-family: Courier, monospace; padding: .5em 1em; text-shadow: 0 0 2px #aaa; transition: all .25s; } .fLabel:active, .fLabel:hover { background: #6767a9; color: #fff; text-shadow: 0 0 2px #fff; } .fLabel > input { display: none; }
page revision: 5, last edited: 28 Jun 2021 01:46






